| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 |
- // ================================================================================
- // == This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås ==
- // == See tb_core.h for more information. ==
- // ================================================================================
- #include "tb_select.h"
- #include "tb_menu_window.h"
- #include "tb_widgets_listener.h"
- #include "tb_language.h"
- #include <assert.h>
- #include <stdlib.h>
- namespace tb {
- /** TBSimpleLayoutItemWidget is a item containing a layout with the following:
- -TBSkinImage showing the item image.
- -TBTextField showing the item string.
- -TBSkinImage showing the arrow for items with a submenu.
- It also handles submenu events. */
- class TBSimpleLayoutItemWidget : public TBLayout, private TBWidgetListener
- {
- public:
- TBSimpleLayoutItemWidget(TBID image, TBSelectItemSource *source, const char *str);
- ~TBSimpleLayoutItemWidget();
- virtual bool OnEvent(const TBWidgetEvent &ev);
- private:
- TBSelectItemSource *m_source;
- TBTextField m_textfield;
- TBSkinImage m_image;
- TBSkinImage m_image_arrow;
- TBMenuWindow *m_menu; ///< Points to the submenu window if opened
- virtual void OnWidgetDelete(TBWidget *widget);
- void OpenSubMenu();
- void CloseSubMenu();
- };
- // == TBSimpleLayoutItemWidget ==============================================================================
- TBSimpleLayoutItemWidget::TBSimpleLayoutItemWidget(TBID image, TBSelectItemSource *source, const char *str)
- : m_source(source)
- , m_menu(nullptr)
- {
- SetSkinBg(TBIDC("TBSelectItem"));
- SetLayoutDistribution(LAYOUT_DISTRIBUTION_AVAILABLE);
- SetPaintOverflowFadeout(false);
- if (image)
- {
- m_image.SetSkinBg(image);
- m_image.SetIgnoreInput(true);
- AddChild(&m_image);
- }
- m_textfield.SetText(str);
- m_textfield.SetTextAlign(TB_TEXT_ALIGN_LEFT);
- m_textfield.SetIgnoreInput(true);
- AddChild(&m_textfield);
- if (source)
- {
- m_image_arrow.SetSkinBg(TBIDC("arrow.right"));
- m_image_arrow.SetIgnoreInput(true);
- AddChild(&m_image_arrow);
- }
- }
- TBSimpleLayoutItemWidget::~TBSimpleLayoutItemWidget()
- {
- if (m_image_arrow.GetParent())
- RemoveChild(&m_image_arrow);
- RemoveChild(&m_textfield);
- if (m_image.GetParent())
- RemoveChild(&m_image);
- CloseSubMenu();
- }
- bool TBSimpleLayoutItemWidget::OnEvent(const TBWidgetEvent &ev)
- {
- if (m_source && ev.type == EVENT_TYPE_CLICK && ev.target == this)
- {
- OpenSubMenu();
- return true;
- }
- return false;
- }
- void TBSimpleLayoutItemWidget::OnWidgetDelete(TBWidget *widget)
- {
- assert(widget == m_menu);
- CloseSubMenu();
- }
- void TBSimpleLayoutItemWidget::OpenSubMenu()
- {
- if (m_menu)
- return;
- // Open a new menu window for the submenu with this widget as target
- m_menu = new TBMenuWindow(this, TBIDC("submenu"));
- if (m_menu)
- {
- SetState(WIDGET_STATE_SELECTED, true);
- m_menu->AddListener(this);
- m_menu->Show(m_source, TBPopupAlignment(TB_ALIGN_RIGHT), -1);
- }
- }
- void TBSimpleLayoutItemWidget::CloseSubMenu()
- {
- if (!m_menu)
- return;
- SetState(WIDGET_STATE_SELECTED, false);
- m_menu->RemoveListener(this);
- if (!m_menu->GetIsDying())
- m_menu->Close();
- m_menu = nullptr;
- }
- // == TBSelectItemViewer ==============================================================================
- void TBSelectItemViewer::SetSource(TBSelectItemSource *source)
- {
- if (m_source == source)
- return;
- if (m_source)
- m_source->m_viewers.Remove(this);
- m_source = source;
- if (m_source)
- m_source->m_viewers.AddLast(this);
- OnSourceChanged();
- }
- // == TBSelectItemSource ====================================================================================
- TBSelectItemSource::~TBSelectItemSource()
- {
- TBLinkListOf<TBSelectItemViewer>::Iterator iter = m_viewers.IterateForward();
- while (TBSelectItemViewer *viewer = iter.GetAndStep())
- {
- viewer->SetSource(nullptr);
- }
- m_viewers.RemoveAll();
- // If this assert trig, you are deleting a model that's still set on some
- // TBSelect widget. That might be dangerous.
- assert(!m_viewers.HasLinks());
- }
- bool TBSelectItemSource::Filter(int index, const char *filter)
- {
- const char *str = GetItemString(index);
- if (str && stristr(str, filter))
- return true;
- return false;
- }
- TBWidget *TBSelectItemSource::CreateItemWidget(int index, TBSelectItemViewer *viewer)
- {
- const char *string = GetItemString(index);
- TBSelectItemSource *sub_source = GetItemSubSource(index);
- TBID image = GetItemImage(index);
- if (sub_source || image)
- {
- if (TBSimpleLayoutItemWidget *itemwidget = new TBSimpleLayoutItemWidget(image, sub_source, string))
- return itemwidget;
- }
- else if (string && *string == '-')
- {
- if (TBSeparator *separator = new TBSeparator)
- {
- separator->SetGravity(WIDGET_GRAVITY_ALL);
- separator->SetSkinBg(TBIDC("TBSelectItem.separator"));
- return separator;
- }
- }
- else if (TBTextField *textfield = new TBTextField)
- {
- textfield->SetSkinBg("TBSelectItem");
- textfield->SetText(string);
- textfield->SetTextAlign(TB_TEXT_ALIGN_LEFT);
- return textfield;
- }
- return nullptr;
- }
- void TBSelectItemSource::InvokeItemChanged(int index, TBSelectItemViewer *exclude_viewer)
- {
- TBLinkListOf<TBSelectItemViewer>::Iterator iter = m_viewers.IterateForward();
- while (TBSelectItemViewer *viewer = iter.GetAndStep())
- if (viewer != exclude_viewer)
- viewer->OnItemChanged(index);
- }
- void TBSelectItemSource::InvokeItemAdded(int index)
- {
- TBLinkListOf<TBSelectItemViewer>::Iterator iter = m_viewers.IterateForward();
- while (TBSelectItemViewer *viewer = iter.GetAndStep())
- viewer->OnItemAdded(index);
- }
- void TBSelectItemSource::InvokeItemRemoved(int index)
- {
- TBLinkListOf<TBSelectItemViewer>::Iterator iter = m_viewers.IterateForward();
- while (TBSelectItemViewer *viewer = iter.GetAndStep())
- viewer->OnItemRemoved(index);
- }
- void TBSelectItemSource::InvokeAllItemsRemoved()
- {
- TBLinkListOf<TBSelectItemViewer>::Iterator iter = m_viewers.IterateForward();
- while (TBSelectItemViewer *viewer = iter.GetAndStep())
- viewer->OnAllItemsRemoved();
- }
- }; // namespace tb
|