From f11435e4b623a90a266010f18cb5f93a5f5a2afd Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Mon, 26 Jan 2015 16:07:35 +0300 Subject: [PATCH] tab and tree controls fixes --- src/dlangui/core/events.d | 8 ++++++ src/dlangui/core/stdaction.d | 35 +++++++++---------------- src/dlangui/widgets/tabs.d | 50 +++++++++++++++++++++++++++++++++++- src/dlangui/widgets/tree.d | 8 +++++- views/res/i18n/std_en.ini | 1 + views/res/theme_default.xml | 1 + 6 files changed, 78 insertions(+), 25 deletions(-) diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d index 2d5f745d..d861b2c4 100644 --- a/src/dlangui/core/events.d +++ b/src/dlangui/core/events.d @@ -171,6 +171,14 @@ class Action { _id = newId; return this; } + /// compares id of this action with another action id + bool opEquals(int anotherActionId) const { + return _id == anotherActionId; + } + /// compares id of this action with another action id + bool opEquals(const Action action) const { + return _id == action._id; + } /// sets label string resource id @property Action label(string resourceId) { _label = resourceId; diff --git a/src/dlangui/core/stdaction.d b/src/dlangui/core/stdaction.d index d9d57fbf..43b95875 100644 --- a/src/dlangui/core/stdaction.d +++ b/src/dlangui/core/stdaction.d @@ -30,29 +30,18 @@ enum StandardAction : int { Ignore, Open, Save, + DiscardChanges, } -const Action ACTION_OK; -const Action ACTION_CANCEL; -const Action ACTION_YES; -const Action ACTION_NO; -const Action ACTION_CLOSE; -const Action ACTION_ABORT; -const Action ACTION_RETRY; -const Action ACTION_IGNORE; -const Action ACTION_OPEN; -const Action ACTION_SAVE; +const Action ACTION_OK = new Action(StandardAction.Ok, "ACTION_OK"c); +const Action ACTION_CANCEL = new Action(StandardAction.Cancel, "ACTION_CANCEL"c); +const Action ACTION_YES = new Action(StandardAction.Yes, "ACTION_YES"c); +const Action ACTION_NO = new Action(StandardAction.No, "ACTION_NO"c); +const Action ACTION_CLOSE = new Action(StandardAction.Close, "ACTION_CLOSE"c); +const Action ACTION_ABORT = new Action(StandardAction.Abort, "ACTION_ABORT"c); +const Action ACTION_RETRY = new Action(StandardAction.Retry, "ACTION_RETRY"c); +const Action ACTION_IGNORE = new Action(StandardAction.Ignore, "ACTION_IGNORE"c); +const Action ACTION_OPEN = new Action(StandardAction.Open, "ACTION_OPEN"c); +const Action ACTION_SAVE = new Action(StandardAction.Save, "ACTION_SAVE"c); +const Action ACTION_DISCARD_CHANGES = new Action(StandardAction.DiscardChanges, "ACTION_DISCARD_CHANGES"c); -static this() -{ - ACTION_OK = new Action(StandardAction.Ok, "ACTION_OK"c); - ACTION_CANCEL = cast(immutable(Action)) new Action(StandardAction.Cancel, "ACTION_CANCEL"c); - ACTION_YES = cast(immutable(Action)) new Action(StandardAction.Yes, "ACTION_YES"c); - ACTION_NO = cast(immutable(Action)) new Action(StandardAction.No, "ACTION_NO"c); - ACTION_CLOSE = cast(immutable(Action)) new Action(StandardAction.Close, "ACTION_CLOSE"c); - ACTION_ABORT = cast(immutable(Action)) new Action(StandardAction.Abort, "ACTION_ABORT"c); - ACTION_RETRY = cast(immutable(Action)) new Action(StandardAction.Retry, "ACTION_RETRY"c); - ACTION_IGNORE = cast(immutable(Action)) new Action(StandardAction.Ignore, "ACTION_IGNORE"c); - ACTION_OPEN = cast(immutable(Action)) new Action(StandardAction.Open, "ACTION_OPEN"c); - ACTION_SAVE = cast(immutable(Action)) new Action(StandardAction.Save, "ACTION_SAVE"c); -} diff --git a/src/dlangui/widgets/tabs.d b/src/dlangui/widgets/tabs.d index 699c1830..5a48c981 100644 --- a/src/dlangui/widgets/tabs.d +++ b/src/dlangui/widgets/tabs.d @@ -26,10 +26,18 @@ import dlangui.core.signals; import dlangui.widgets.layouts; import dlangui.widgets.controls; +import std.algorithm; + +/// current tab is changed handler interface TabHandler { void onTabChanged(string newActiveTabId, string previousTabId); } +/// tab close button pressed handler +interface TabCloseHandler { + void onTabClose(string tabId); +} + /// tab item metadata class TabItem { @@ -86,6 +94,7 @@ class TabItemWidget : HorizontalLayout { private ImageButton _closeButton; private TabItem _item; private bool _enableCloseButton; + Signal!TabCloseHandler onTabCloseListener; @property TabItem tabItem() { return _item; } @property TabControl tabControl() { return cast(TabControl)parent; } this(TabItem item, bool enableCloseButton = true) { @@ -119,6 +128,8 @@ class TabItemWidget : HorizontalLayout { protected bool onClick(Widget source) { if (source.compareId("CLOSE")) { Log.d("tab close button pressed"); + if (onTabCloseListener.assigned) + onTabCloseListener(_item.id); } return true; } @@ -217,6 +228,9 @@ class TabControl : WidgetGroupDefaultDrawing { /// signal of tab change (e.g. by clicking on tab header) Signal!TabHandler onTabChangedListener; + /// signal on tab close button + Signal!TabCloseHandler onTabCloseListener; + /// empty parameter list constructor - for usage by factory this() { this(null); @@ -299,12 +313,29 @@ class TabControl : WidgetGroupDefaultDrawing { /// remove tab TabControl removeTab(string id) { + string nextId; + if (id.equal(_selectedTabId)) { + // current tab is being closed: remember next tab id + int nextIndex = getNextItemIndex(1); + if (nextIndex < 0) + nextIndex = getNextItemIndex(-1); + if (nextIndex >= 0) + nextId = _items[nextIndex].id; + } int index = _items.indexById(id); if (index >= 0) { _children.remove(index + 1); _items.remove(index); + if (id.equal(_selectedTabId)) + _selectedTabId = null; requestLayout(); } + if (nextId) { + index = _items.indexById(nextId); + if (index >= 0) { + selectTab(index, true); + } + } return this; } @@ -329,6 +360,10 @@ class TabControl : WidgetGroupDefaultDrawing { } } + protected void onTabClose(string tabId) { + if (onTabCloseListener.assigned) + onTabCloseListener(tabId); + } /// add new tab TabControl addTab(TabItem item, int index = -1, bool enableCloseButton = false) { @@ -337,6 +372,7 @@ class TabControl : WidgetGroupDefaultDrawing { widget.parent = this; widget.onClickListener = &onClick; widget.setStyles(_tabButtonStyle, _tabButtonTextStyle); + widget.onTabCloseListener = &onTabClose; _children.insert(widget, index); updateTabs(); requestLayout(); @@ -440,6 +476,10 @@ class TabControl : WidgetGroupDefaultDrawing { protected string _selectedTabId; + @property string selectedTabId() const { + return _selectedTabId; + } + void updateAccessTs() { int index = _items.indexById(_selectedTabId); if (index >= 0) @@ -566,7 +606,7 @@ class TabHost : FrameLayout, TabHandler { /// compound widget - contains from TabControl widget (tabs header) and TabHost (content pages) -class TabWidget : VerticalLayout, TabHandler { +class TabWidget : VerticalLayout, TabHandler, TabCloseHandler { protected TabControl _tabControl; protected TabHost _tabHost; /// empty parameter list constructor - for usage by factory @@ -579,6 +619,7 @@ class TabWidget : VerticalLayout, TabHandler { _tabControl = new TabControl("TAB_CONTROL"); _tabHost = new TabHost("TAB_HOST", _tabControl); _tabControl.onTabChangedListener.connect(this); + _tabControl.onTabCloseListener.connect(this); styleId = STYLE_TAB_WIDGET; addChild(_tabControl); addChild(_tabHost); @@ -587,6 +628,13 @@ class TabWidget : VerticalLayout, TabHandler { /// signal of tab change (e.g. by clicking on tab header) Signal!TabHandler onTabChangedListener; + /// signal on tab close button + Signal!TabCloseHandler onTabCloseListener; + + protected override void onTabClose(string tabId) { + if (onTabCloseListener.assigned) + onTabCloseListener(tabId); + } protected override void onTabChanged(string newActiveTabId, string previousTabId) { // forward to listener diff --git a/src/dlangui/widgets/tree.d b/src/dlangui/widgets/tree.d index 0a6927dc..41b1877c 100644 --- a/src/dlangui/widgets/tree.d +++ b/src/dlangui/widgets/tree.d @@ -738,9 +738,15 @@ class TreeWidgetBase : ScrollWidget, OnTreeContentChangeListener, OnTreeStateCh } } + void clearSelection() { + _tree.selectItem(null); + } + void selectItem(TreeItem item, bool makeVisible = true) { - if (!item) + if (!item) { + clearSelection(); return; + } _tree.selectItem(item); if (makeVisible) makeItemVisible(item); diff --git a/views/res/i18n/std_en.ini b/views/res/i18n/std_en.ini index 8e1611ce..253bc157 100644 --- a/views/res/i18n/std_en.ini +++ b/views/res/i18n/std_en.ini @@ -10,3 +10,4 @@ ACTION_RETRY=Retry ACTION_IGNORE=Ignore ACTION_OPEN=Open ACTION_SAVE=Save +ACTION_DISCARD_CHANGES=Discard changes diff --git a/views/res/theme_default.xml b/views/res/theme_default.xml index f18ac6cf..b7460ee0 100644 --- a/views/res/theme_default.xml +++ b/views/res/theme_default.xml @@ -111,6 +111,7 @@ >