diff --git a/examples/example1/main.d b/examples/example1/main.d index 329a344f..fc9df270 100644 --- a/examples/example1/main.d +++ b/examples/example1/main.d @@ -47,16 +47,10 @@ extern (C) int UIAppMain(string[] args) { Window window = Platform.instance().createWindow("My Window", null); static if (true) { - LinearLayout layout = new LinearLayout(); - TabWidget tabs = new TabWidget("TABS"); - tabs.addTab((new TextWidget()).id("tab1").textColor(0x00802000).text("Tab 1 contents"), "Tab 1"d); - tabs.addTab((new TextWidget()).id("tab2").textColor(0x00802000).text("Tab 2 contents"), "Tab 2"d); - tabs.addTab((new TextWidget()).id("tab3").textColor(0x00802000).text("Tab 3 contents"), "Tab 3"d); - tabs.addTab((new TextWidget()).id("tab4").textColor(0x00802000).text("Tab 4 contents"), "Tab 4"d); - tabs.addTab((new TextWidget()).id("tab5").textColor(0x00802000).text("Tab 5 contents"), "Tab 5"d); - tabs.selectTab("tab1"); - layout.addChild(tabs); + tabs.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); + + LinearLayout layout = new LinearLayout("tab1"); layout.addChild((new TextWidget()).textColor(0x00802000).text("Text widget 0")); layout.addChild((new TextWidget()).textColor(0x40FF4000).text("Text widget")); @@ -117,7 +111,15 @@ extern (C) int UIAppMain(string[] args) { layout.layoutHeight(FILL_PARENT).layoutWidth(FILL_PARENT); - window.mainWidget = layout; + tabs.addTab(layout, "Tab 1"d); + tabs.addTab((new TextWidget()).id("tab2").textColor(0x00802000).text("Tab 2 contents bla bla bla"), "Tab 2"d); + tabs.addTab((new TextWidget()).id("tab3").textColor(0x00802000).text("Tab 3 contents"), "Tab 3"d); + tabs.addTab((new TextWidget()).id("tab4").textColor(0x00802000).text("Tab 4 contents some long string"), "Tab 4"d); + tabs.addTab((new TextWidget()).id("tab5").textColor(0x00802000).text("Tab 5 contents"), "Tab 5"d); + + tabs.selectTab("tab1"); + + window.mainWidget = tabs; } else { window.mainWidget = (new Button()).text("sample button"); } diff --git a/examples/example1/res/frame_blue.9.png b/examples/example1/res/frame_blue.9.png new file mode 100644 index 00000000..faae7a3f Binary files /dev/null and b/examples/example1/res/frame_blue.9.png differ diff --git a/examples/example1/res/tab_btn_up_hover.9.png b/examples/example1/res/tab_btn_up_hover.9.png index fa378fe1..df0c1f5d 100644 Binary files a/examples/example1/res/tab_btn_up_hover.9.png and b/examples/example1/res/tab_btn_up_hover.9.png differ diff --git a/src/dlangui/widgets/styles.d b/src/dlangui/widgets/styles.d index 38d06cde..c29960d8 100644 --- a/src/dlangui/widgets/styles.d +++ b/src/dlangui/widgets/styles.d @@ -646,11 +646,11 @@ Theme createDefaultTheme() { tabUp.layoutWidth(FILL_PARENT); tabUp.createState(State.Selected, State.Selected).backgroundImageId("tab_up_backgrond_selected"); Style tabUpButtonText = res.createSubstyle("TAB_UP_BUTTON_TEXT"); - tabUpButtonText.textColor(0xFFFFFF).fontSize(12); + tabUpButtonText.textColor(0xFFFFFF).fontSize(12).alignment(Align.Center); tabUpButtonText.createState(State.Selected, State.Selected).textColor(0x000000); tabUpButtonText.createState(State.Selected|State.Focused, State.Selected|State.Focused).textColor(0x000000); tabUpButtonText.createState(State.Focused, State.Focused).textColor(0x000000); - tabUpButtonText.createState(State.Hover, State.Hover).textColor(0x404000); + tabUpButtonText.createState(State.Hover, State.Hover).textColor(0xFFE0E0); Style tabUpButton = res.createSubstyle("TAB_UP_BUTTON"); tabUpButton.backgroundImageId("tab_btn_up_normal"); tabUpButton.createState(State.Selected, State.Selected).backgroundImageId("tab_btn_up_selected"); @@ -659,6 +659,9 @@ Theme createDefaultTheme() { tabUpButton.createState(State.Hover, State.Hover).backgroundImageId("tab_btn_up_hover"); Style tabHost = res.createSubstyle("TAB_HOST"); tabHost.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); + tabHost.backgroundColor(0xF0F0F0); + Style tabWidget = res.createSubstyle("TAB_WIDGET"); + tabWidget.backgroundImageId("frame_blue"); //res.dumpStats(); return res; } diff --git a/src/dlangui/widgets/tabs.d b/src/dlangui/widgets/tabs.d index f78bc47a..0ed57104 100644 --- a/src/dlangui/widgets/tabs.d +++ b/src/dlangui/widgets/tabs.d @@ -3,6 +3,10 @@ module dlangui.widgets.tabs; import dlangui.widgets.layouts; import dlangui.widgets.controls; +interface TabHandler { + void onTabChanged(string newActiveTabId, string previousTabId); +} + class TabItem { private string _iconRes; private string _id; @@ -140,6 +144,10 @@ class TabControl : WidgetGroup { protected bool _enableCloseButton; protected TabItemWidget[] _sortedItems; + protected void delegate(string newActiveTabId, string previousTabId) _onTabChanged; + @property void delegate(string newActiveTabId, string previousTabId) onTabChangedListener() { return _onTabChanged; } + @property TabControl onTabChangedListener(void delegate(string newActiveTabId, string previousTabId) listener) { _onTabChanged = listener; return this; } + this(string ID) { super(ID); _items = new TabItemList(); @@ -307,29 +315,56 @@ class TabControl : WidgetGroup { } } + protected string _selectedTabId; + void selectTab(int index) { + if (_children.get(index + 1).compareId(_selectedTabId)) + return; // already selected + string previousSelectedTab = _selectedTabId; for (int i = 1; i < _children.count; i++) { if (index == i - 1) { _children.get(i).state = State.Selected; + _selectedTabId = _children.get(i).id; } else { _children.get(i).state = State.Normal; } } + if (_onTabChanged !is null) + _onTabChanged(_selectedTabId, previousSelectedTab); } } /// container for widgets controlled by TabControl -class TabHost : FrameLayout { - this(string ID, TabControl tabControl) { +class TabHost : FrameLayout, TabHandler { + this(string ID, TabControl tabControl = null) { super(ID); _tabControl = tabControl; + if (_tabControl !is null) + _tabControl.onTabChangedListener = &onTabChanged; styleId = "TAB_HOST"; } protected TabControl _tabControl; /// get currently set control widget @property TabControl tabControl() { return _tabControl; } /// set new control widget - @property TabHost tabControl(TabControl newWidget) { _tabControl = newWidget; return this; } + @property TabHost tabControl(TabControl newWidget) { + _tabControl = newWidget; + if (_tabControl !is null) + _tabControl.onTabChangedListener = &onTabChanged; + return this; + } + + protected void delegate(string newActiveTabId, string previousTabId) _onTabChanged; + @property void delegate(string newActiveTabId, string previousTabId) onTabChangedListener() { return _onTabChanged; } + @property TabHost onTabChangedListener(void delegate(string newActiveTabId, string previousTabId) listener) { _onTabChanged = listener; return this; } + + protected override void onTabChanged(string newActiveTabId, string previousTabId) { + if (newActiveTabId !is null) { + showChild(newActiveTabId); + } + if (_onTabChanged !is null) + _onTabChanged(newActiveTabId, previousTabId); + } /// remove tab TabHost removeTab(string id) { @@ -348,6 +383,7 @@ class TabHost : FrameLayout { assert(widget.id !is null, "ID for tab host page is mandatory"); assert(_children.indexOf(id) == -1, "duplicate ID for tab host page"); _tabControl.addTab(widget.id, label, iconId, enableCloseButton); + addChild(widget); return this; } /// add new tab by id and label string resource id @@ -356,7 +392,7 @@ class TabHost : FrameLayout { assert(widget.id !is null, "ID for tab host page is mandatory"); assert(_children.indexOf(id) == -1, "duplicate ID for tab host page"); _tabControl.addTab(widget.id, labelResourceId, iconId, enableCloseButton); - TabItem item = new TabItem(id, labelResourceId); + addChild(widget); return this; } /// select tab @@ -369,16 +405,28 @@ class TabHost : FrameLayout { } /// compound widget - contains from TabControl widget (tabs header) and TabHost (content pages) -class TabWidget : VerticalLayout { +class TabWidget : VerticalLayout, TabHandler { protected TabControl _tabControl; protected TabHost _tabHost; this(string ID) { super(ID); _tabControl = new TabControl("TAB_CONTROL"); _tabHost = new TabHost("TAB_HOST", _tabControl); + styleId = "TAB_WIDGET"; addChild(_tabControl); addChild(_tabHost); } + + protected void delegate(string newActiveTabId, string previousTabId) _onTabChanged; + @property void delegate(string newActiveTabId, string previousTabId) onTabChangedListener() { return _onTabChanged; } + @property TabWidget onTabChangedListener(void delegate(string newActiveTabId, string previousTabId) listener) { _onTabChanged = listener; return this; } + + protected override void onTabChanged(string newActiveTabId, string previousTabId) { + // forward to listener + if (_onTabChanged !is null) + _onTabChanged(newActiveTabId, previousTabId); + } + /// add new tab by id and label string resource id TabWidget addTab(Widget widget, string labelResourceId, string iconId = null, bool enableCloseButton = false) { _tabHost.addTab(widget, labelResourceId, iconId, enableCloseButton); diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index e1b4e2f8..c2cb4249 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -283,11 +283,13 @@ class Widget { /// returns widget visibility (Visible, Invisible, Gone) @property Visibility visibility() { return _visibility; } /// sets widget visibility (Visible, Invisible, Gone) - @property Widget visibility(Visibility visible) { + @property Widget visibility(Visibility visible) { if (_visibility != visible) { if ((_visibility == Visibility.Gone) || (visible == Visibility.Gone)) - _visibility = visible; - requestLayout(); + requestLayout(); + else + invalidate(); + _visibility = visible; } return this; }