diff --git a/dlanguilib.visualdproj b/dlanguilib.visualdproj index a3290833..68c1fdd7 100644 --- a/dlanguilib.visualdproj +++ b/dlanguilib.visualdproj @@ -89,7 +89,6 @@ $(OutDir)\$(ProjectName).lib 1 - 2 @@ -184,7 +183,6 @@ $(OutDir)\$(ProjectName).lib 1 - 1 @@ -357,6 +355,7 @@ + diff --git a/examples/example1/example1.visualdproj b/examples/example1/example1.visualdproj index a7d67fa0..8170912c 100644 --- a/examples/example1/example1.visualdproj +++ b/examples/example1/example1.visualdproj @@ -89,7 +89,6 @@ $(OutDir)\$(ProjectName).exe 1 - 2 -profile @@ -184,7 +183,6 @@ $(OutDir)\$(ProjectName).exe 1 - 1 diff --git a/examples/example1/src/main.d b/examples/example1/src/main.d index 2d4a3bd8..408a89ac 100644 --- a/examples/example1/src/main.d +++ b/examples/example1/src/main.d @@ -424,15 +424,34 @@ extern (C) int UIAppMain(string[] args) { } { - LinearLayout layout3 = new LinearLayout("tab3"); + LinearLayout layout3 = new VerticalLayout("tab3"); + // 3 types of buttons: Button, ImageButton, ImageTextButton layout3.addChild(new TextWidget(null, "Buttons in HorizontalLayout"d)); WidgetGroup buttons1 = new HorizontalLayout(); - buttons1.addChild(new Button("btn1", "Button 1"d)); - buttons1.addChild(new Button("btn2", "Button 2"d)); - buttons1.addChild(new Button("btn3", "Button 3"d)); - buttons1.addChild(new ResizerWidget()); - buttons1.addChild(new Button("btn4", "Button 4"d)); + buttons1.addChild(new TextWidget(null, "Button widgets: "d)); + buttons1.addChild(new Button("btn1", "Button"d)); + buttons1.addChild((new Button("btn2", "Disabled Button"d)).enabled(false)); + buttons1.addChild(new TextWidget(null, "ImageButton widgets: "d)); + buttons1.addChild(new ImageButton("btn3", "text-plain")); + buttons1.addChild(new TextWidget(null, "disabled: "d)); + buttons1.addChild((new ImageButton("btn4", "folder")).enabled(false)); + buttons1.addChild(new TextWidget(null, "ImageTextButton widgets: "d)); + buttons1.addChild(new ImageTextButton("btn5", "text-plain", "Enabled"d)); + buttons1.addChild((new ImageTextButton("btn6", "folder", "Disabled"d)).enabled(false)); layout3.addChild(buttons1); + + WidgetGroup buttons11 = new HorizontalLayout(); + buttons11.addChild(new TextWidget(null, "Construct buttons by action (Button, ImageButton, ImageTextButton): "d)); + Action FILE_OPEN_ACTION = new Action(ACTION_FILE_OPEN, "MENU_FILE_OPEN"c, "document-open", KeyCode.KEY_O, KeyFlag.Control); + buttons11.addChild(new Button(FILE_OPEN_ACTION)); + buttons11.addChild(new ImageButton(FILE_OPEN_ACTION)); + buttons11.addChild(new ImageTextButton(FILE_OPEN_ACTION)); + buttons11.addChild(new TextWidget(null, "The same in disabled state: "d)); + buttons11.addChild((new Button(FILE_OPEN_ACTION)).enabled(false)); + buttons11.addChild((new ImageButton(FILE_OPEN_ACTION)).enabled(false)); + buttons11.addChild((new ImageTextButton(FILE_OPEN_ACTION)).enabled(false)); + layout3.addChild(buttons11); + layout3.addChild(new VSpacer()); layout3.addChild(new TextWidget(null, "CheckBoxes in HorizontalLayout"d)); WidgetGroup buttons2 = new HorizontalLayout(); @@ -463,7 +482,7 @@ extern (C) int UIAppMain(string[] args) { layout3.addChild(new VSpacer()); layout3.addChild(new TextWidget(null, "In vertical layouts:"d)); HorizontalLayout hlayout2 = new HorizontalLayout(); - hlayout2.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); + hlayout2.layoutHeight(FILL_PARENT); //layoutWidth(FILL_PARENT). buttons1 = new VerticalLayout(); buttons1.addChild(new TextWidget(null, "Buttons"d)); @@ -528,13 +547,19 @@ extern (C) int UIAppMain(string[] args) { table.addChild((new TextWidget(null, "Parameter 2 name bla bla"d)).alignment(Align.Right | Align.VCenter)); table.addChild((new EditLine("edit2", "Some text for parameter 2"d)).layoutWidth(FILL_PARENT)); // row 3 - table.addChild((new TextWidget(null, "Param 3"d)).alignment(Align.Right | Align.VCenter)); - table.addChild((new EditLine("edit3", "Parameter 3 value"d)).layoutWidth(FILL_PARENT)); - + table.addChild((new TextWidget(null, "Param 3 is disabled"d)).alignment(Align.Right | Align.VCenter).enabled(false)); + table.addChild((new EditLine("edit3", "Parameter 3 value"d)).layoutWidth(FILL_PARENT).enabled(false)); + // normal readonly combo box ComboBox combo1 = new ComboBox("combo1", ["item value 1"d, "item value 2"d, "item value 3"d, "item value 4"d, "item value 5"d, "item value 6"d]); table.addChild((new TextWidget(null, "Combo box param"d)).alignment(Align.Right | Align.VCenter)); - combo1.selectedItemIndex(3); + combo1.selectedItemIndex = 3; table.addChild(combo1).layoutWidth(FILL_PARENT); + // disabled readonly combo box + ComboBox combo2 = new ComboBox("combo2", ["item value 1"d, "item value 2"d, "item value 3"d]); + table.addChild((new TextWidget(null, "Disabled combo box"d)).alignment(Align.Right | Align.VCenter)); + combo2.enabled = false; + combo2.selectedItemIndex = 0; + table.addChild(combo2).layoutWidth(FILL_PARENT); table.margins(Rect(10,10,10,10)).layoutWidth(FILL_PARENT); tabs.addTab(table, "TAB_TABLE_LAYOUT"c); @@ -639,11 +664,11 @@ extern (C) int UIAppMain(string[] args) { table2.addChild((new TextWidget(null, "Param 5 - edit text here - blah blah blah"d)).alignment(Align.Right | Align.VCenter)); table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT)); // row 6 - table2.addChild((new TextWidget(null, "Param 6 - just to fill content widget"d)).alignment(Align.Right | Align.VCenter)); - table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT)); + table2.addChild((new TextWidget(null, "Param 6 - just to fill content widget (DISABLED)"d)).alignment(Align.Right | Align.VCenter).enabled(false)); + table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT).enabled(false)); // row 7 - table2.addChild((new TextWidget(null, "Param 7 - just to fill content widget"d)).alignment(Align.Right | Align.VCenter)); - table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT)); + table2.addChild((new TextWidget(null, "Param 7 - just to fill content widget (DISABLED)"d)).alignment(Align.Right | Align.VCenter).enabled(false)); + table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT).enabled(false)); // row 8 table2.addChild((new TextWidget(null, "Param 8 - just to fill content widget"d)).alignment(Align.Right | Align.VCenter)); table2.addChild((new EditLine("edit3", "Parameter 5 value"d)).layoutWidth(FILL_PARENT)); diff --git a/res/btn_background.xml b/res/btn_background.xml new file mode 100644 index 00000000..066aed5b --- /dev/null +++ b/res/btn_background.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/res/btn_background_transparent.xml b/res/btn_background_transparent.xml new file mode 100644 index 00000000..74b8b30a --- /dev/null +++ b/res/btn_background_transparent.xml @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/res/btn_check.xml b/res/btn_check.xml index c8c2bee0..172c177c 100644 --- a/res/btn_check.xml +++ b/res/btn_check.xml @@ -1,65 +1,45 @@ - - - - - + android:drawable="@drawable/btn_check_on_pressed" /> + android:drawable="@drawable/btn_check_off_pressed" /> + android:drawable="@drawable/btn_check_on_focused" /> + android:drawable="@drawable/btn_check_off_focused" /> + + + + android:drawable="@drawable/btn_check_off" /> + android:drawable="@drawable/btn_check_on" /> - - + + - - - - - + + diff --git a/res/btn_radio.xml b/res/btn_radio.xml index e2f1f84c..4b0b6e01 100644 --- a/res/btn_radio.xml +++ b/res/btn_radio.xml @@ -1,59 +1,34 @@ - - - - - + android:drawable="@drawable/btn_radio_on_pressed" /> + android:drawable="@drawable/btn_radio_off_pressed" /> + android:drawable="@drawable/btn_radio_on_focused" /> + android:drawable="@drawable/btn_radio_off_focused" /> + + + + android:drawable="@drawable/btn_radio_off" /> + android:drawable="@drawable/btn_radio_on" /> - - - - - - - - + + diff --git a/res/combobox_background.xml b/res/combobox_background.xml new file mode 100644 index 00000000..f9bedd80 --- /dev/null +++ b/res/combobox_background.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/res/editbox_background.xml b/res/editbox_background.xml index dce9c53f..1b19d1e1 100644 --- a/res/editbox_background.xml +++ b/res/editbox_background.xml @@ -1,26 +1,8 @@ - - - - - + + + + diff --git a/res/expander_close_holo_light.9.png b/res/expander_close_holo_light.9.png deleted file mode 100644 index 54149e9a..00000000 Binary files a/res/expander_close_holo_light.9.png and /dev/null differ diff --git a/res/mdpi/btn_check_off.png b/res/mdpi/btn_check_off.png new file mode 100644 index 00000000..ae0bd562 Binary files /dev/null and b/res/mdpi/btn_check_off.png differ diff --git a/res/mdpi/btn_check_off_disabled.png b/res/mdpi/btn_check_off_disabled.png new file mode 100644 index 00000000..7f9630a7 Binary files /dev/null and b/res/mdpi/btn_check_off_disabled.png differ diff --git a/res/mdpi/btn_check_off_disabled_focused_holo_light.png b/res/mdpi/btn_check_off_disabled_focused_holo_light.png deleted file mode 100644 index 42442e8f..00000000 Binary files a/res/mdpi/btn_check_off_disabled_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_off_disabled_holo_light.png b/res/mdpi/btn_check_off_disabled_holo_light.png deleted file mode 100644 index db190430..00000000 Binary files a/res/mdpi/btn_check_off_disabled_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_off_focused.png b/res/mdpi/btn_check_off_focused.png new file mode 100644 index 00000000..d248d50d Binary files /dev/null and b/res/mdpi/btn_check_off_focused.png differ diff --git a/res/mdpi/btn_check_off_focused_holo_light.png b/res/mdpi/btn_check_off_focused_holo_light.png deleted file mode 100644 index 3fc71fd2..00000000 Binary files a/res/mdpi/btn_check_off_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_off_holo_light.png b/res/mdpi/btn_check_off_holo_light.png deleted file mode 100644 index 5e04a57b..00000000 Binary files a/res/mdpi/btn_check_off_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_off_normal_holo_light.png b/res/mdpi/btn_check_off_normal_holo_light.png deleted file mode 100644 index b39ad3d6..00000000 Binary files a/res/mdpi/btn_check_off_normal_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_off_pressed.png b/res/mdpi/btn_check_off_pressed.png new file mode 100644 index 00000000..2e64acc2 Binary files /dev/null and b/res/mdpi/btn_check_off_pressed.png differ diff --git a/res/mdpi/btn_check_off_pressed_holo_light.png b/res/mdpi/btn_check_off_pressed_holo_light.png deleted file mode 100644 index 1109c20f..00000000 Binary files a/res/mdpi/btn_check_off_pressed_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_on.png b/res/mdpi/btn_check_on.png new file mode 100644 index 00000000..816fcbf0 Binary files /dev/null and b/res/mdpi/btn_check_on.png differ diff --git a/res/mdpi/btn_check_on_disabled.png b/res/mdpi/btn_check_on_disabled.png new file mode 100644 index 00000000..683aaeb7 Binary files /dev/null and b/res/mdpi/btn_check_on_disabled.png differ diff --git a/res/mdpi/btn_check_on_disabled_focused_holo_light.png b/res/mdpi/btn_check_on_disabled_focused_holo_light.png deleted file mode 100644 index 997045de..00000000 Binary files a/res/mdpi/btn_check_on_disabled_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_on_disabled_holo_light.png b/res/mdpi/btn_check_on_disabled_holo_light.png deleted file mode 100644 index 20e2aab1..00000000 Binary files a/res/mdpi/btn_check_on_disabled_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_on_focused.png b/res/mdpi/btn_check_on_focused.png new file mode 100644 index 00000000..84b5e2c4 Binary files /dev/null and b/res/mdpi/btn_check_on_focused.png differ diff --git a/res/mdpi/btn_check_on_focused_holo_light.png b/res/mdpi/btn_check_on_focused_holo_light.png deleted file mode 100644 index a3b49165..00000000 Binary files a/res/mdpi/btn_check_on_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_on_holo_light.png b/res/mdpi/btn_check_on_holo_light.png deleted file mode 100644 index f657c5b2..00000000 Binary files a/res/mdpi/btn_check_on_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_check_on_pressed.png b/res/mdpi/btn_check_on_pressed.png new file mode 100644 index 00000000..6e782667 Binary files /dev/null and b/res/mdpi/btn_check_on_pressed.png differ diff --git a/res/mdpi/btn_check_on_pressed_holo_light.png b/res/mdpi/btn_check_on_pressed_holo_light.png deleted file mode 100644 index e9f5f06c..00000000 Binary files a/res/mdpi/btn_check_on_pressed_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_default.9.png b/res/mdpi/btn_default.9.png new file mode 100644 index 00000000..9cbe49ae Binary files /dev/null and b/res/mdpi/btn_default.9.png differ diff --git a/res/mdpi/btn_disabled.9.png b/res/mdpi/btn_disabled.9.png new file mode 100644 index 00000000..7722ed22 Binary files /dev/null and b/res/mdpi/btn_disabled.9.png differ diff --git a/res/mdpi/btn_hover.9.png b/res/mdpi/btn_hover.9.png new file mode 100644 index 00000000..8f50cd26 Binary files /dev/null and b/res/mdpi/btn_hover.9.png differ diff --git a/res/mdpi/btn_normal.9.png b/res/mdpi/btn_normal.9.png new file mode 100644 index 00000000..816d6a40 Binary files /dev/null and b/res/mdpi/btn_normal.9.png differ diff --git a/res/mdpi/btn_pressed.9.png b/res/mdpi/btn_pressed.9.png new file mode 100644 index 00000000..6084c61d Binary files /dev/null and b/res/mdpi/btn_pressed.9.png differ diff --git a/res/mdpi/btn_radio_off.png b/res/mdpi/btn_radio_off.png new file mode 100644 index 00000000..1137dbfd Binary files /dev/null and b/res/mdpi/btn_radio_off.png differ diff --git a/res/mdpi/btn_radio_off_disabled.png b/res/mdpi/btn_radio_off_disabled.png new file mode 100644 index 00000000..5d51d6fb Binary files /dev/null and b/res/mdpi/btn_radio_off_disabled.png differ diff --git a/res/mdpi/btn_radio_off_disabled_focused_holo_light.png b/res/mdpi/btn_radio_off_disabled_focused_holo_light.png deleted file mode 100644 index 4dac84cf..00000000 Binary files a/res/mdpi/btn_radio_off_disabled_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_off_disabled_holo_light.png b/res/mdpi/btn_radio_off_disabled_holo_light.png deleted file mode 100644 index a67375ec..00000000 Binary files a/res/mdpi/btn_radio_off_disabled_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_off_focused.png b/res/mdpi/btn_radio_off_focused.png new file mode 100644 index 00000000..8bb12f47 Binary files /dev/null and b/res/mdpi/btn_radio_off_focused.png differ diff --git a/res/mdpi/btn_radio_off_focused_holo_light.png b/res/mdpi/btn_radio_off_focused_holo_light.png deleted file mode 100644 index 6753d087..00000000 Binary files a/res/mdpi/btn_radio_off_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_off_holo_light.png b/res/mdpi/btn_radio_off_holo_light.png deleted file mode 100644 index 665cb171..00000000 Binary files a/res/mdpi/btn_radio_off_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_off_pressed.png b/res/mdpi/btn_radio_off_pressed.png new file mode 100644 index 00000000..1137dbfd Binary files /dev/null and b/res/mdpi/btn_radio_off_pressed.png differ diff --git a/res/mdpi/btn_radio_off_pressed_holo_light.png b/res/mdpi/btn_radio_off_pressed_holo_light.png deleted file mode 100644 index 2a7d0d52..00000000 Binary files a/res/mdpi/btn_radio_off_pressed_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_on.png b/res/mdpi/btn_radio_on.png new file mode 100644 index 00000000..7920f239 Binary files /dev/null and b/res/mdpi/btn_radio_on.png differ diff --git a/res/mdpi/btn_radio_on_disabled.png b/res/mdpi/btn_radio_on_disabled.png new file mode 100644 index 00000000..5f0dcff4 Binary files /dev/null and b/res/mdpi/btn_radio_on_disabled.png differ diff --git a/res/mdpi/btn_radio_on_disabled_focused_holo_light.png b/res/mdpi/btn_radio_on_disabled_focused_holo_light.png deleted file mode 100644 index c9be37e9..00000000 Binary files a/res/mdpi/btn_radio_on_disabled_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_on_disabled_holo_light.png b/res/mdpi/btn_radio_on_disabled_holo_light.png deleted file mode 100644 index 4583c3e1..00000000 Binary files a/res/mdpi/btn_radio_on_disabled_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_on_focused.png b/res/mdpi/btn_radio_on_focused.png new file mode 100644 index 00000000..228b8a38 Binary files /dev/null and b/res/mdpi/btn_radio_on_focused.png differ diff --git a/res/mdpi/btn_radio_on_focused_holo_light.png b/res/mdpi/btn_radio_on_focused_holo_light.png deleted file mode 100644 index db3b30a1..00000000 Binary files a/res/mdpi/btn_radio_on_focused_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_on_holo_light.png b/res/mdpi/btn_radio_on_holo_light.png deleted file mode 100644 index 53dc1536..00000000 Binary files a/res/mdpi/btn_radio_on_holo_light.png and /dev/null differ diff --git a/res/mdpi/btn_radio_on_pressed.png b/res/mdpi/btn_radio_on_pressed.png new file mode 100644 index 00000000..06fec87e Binary files /dev/null and b/res/mdpi/btn_radio_on_pressed.png differ diff --git a/res/mdpi/btn_radio_on_pressed_holo_light.png b/res/mdpi/btn_radio_on_pressed_holo_light.png deleted file mode 100644 index 34dd059b..00000000 Binary files a/res/mdpi/btn_radio_on_pressed_holo_light.png and /dev/null differ diff --git a/res/mdpi/editbox_background_disabled.9.png b/res/mdpi/editbox_background_disabled.9.png index 7a9597ac..ff8ed95d 100644 Binary files a/res/mdpi/editbox_background_disabled.9.png and b/res/mdpi/editbox_background_disabled.9.png differ diff --git a/res/mdpi/editbox_background_disabled_focus.9.png b/res/mdpi/editbox_background_disabled_focus.9.png new file mode 100644 index 00000000..ddfc4bb7 Binary files /dev/null and b/res/mdpi/editbox_background_disabled_focus.9.png differ diff --git a/res/mdpi/editbox_background_disabled_focus_yellow.9.png b/res/mdpi/editbox_background_disabled_focus_yellow.9.png deleted file mode 100644 index f9039977..00000000 Binary files a/res/mdpi/editbox_background_disabled_focus_yellow.9.png and /dev/null differ diff --git a/res/mdpi/editbox_background_focus.9.png b/res/mdpi/editbox_background_focus.9.png new file mode 100644 index 00000000..30929e17 Binary files /dev/null and b/res/mdpi/editbox_background_focus.9.png differ diff --git a/res/mdpi/editbox_background_focus_yellow.9.png b/res/mdpi/editbox_background_focus_yellow.9.png deleted file mode 100644 index faf52ede..00000000 Binary files a/res/mdpi/editbox_background_focus_yellow.9.png and /dev/null differ diff --git a/res/mdpi/editbox_background_normal.9.png b/res/mdpi/editbox_background_normal.9.png index 9b8be770..02a21213 100644 Binary files a/res/mdpi/editbox_background_normal.9.png and b/res/mdpi/editbox_background_normal.9.png differ diff --git a/res/theme_default.xml b/res/theme_default.xml index 8aed3d80..0db58e07 100644 --- a/res/theme_default.xml +++ b/res/theme_default.xml @@ -1,25 +1,68 @@ + + * @@ -1092,6 +1235,33 @@ Theme loadTheme(string resourceId) { return null; } +/// custom drawable attribute container for styles +class DrawableAttribute { + protected string _id; + protected string _drawableId; + protected DrawableRef _drawable; + protected bool _initialized; + this(string id, string drawableId) { + _id = id; + _drawableId = drawableId; + } + @property string id() const { return _id; } + @property string drawableId() const { return _drawableId; } + @property void drawableId(string newDrawable) { _drawableId = newDrawable; clear(); } + @property ref DrawableRef drawable() const { + if (!_drawable.isNull) + return (cast(DrawableAttribute)this)._drawable; + (cast(DrawableAttribute)this)._drawable = drawableCache.get(_id); + (cast(DrawableAttribute)this)._initialized = true; + return (cast(DrawableAttribute)this)._drawable; + } + void clear() { + _drawable.clear(); + _initialized = false; + } +} + + shared static ~this() { currentTheme = null; } diff --git a/src/dlangui/widgets/tabs.d b/src/dlangui/widgets/tabs.d index daaa9a52..2be382c1 100644 --- a/src/dlangui/widgets/tabs.d +++ b/src/dlangui/widgets/tabs.d @@ -67,14 +67,14 @@ class TabItemWidget : HorizontalLayout { @property TabItem tabItem() { return _item; } @property TabControl tabControl() { return cast(TabControl)parent; } this(TabItem item, bool enableCloseButton = true) { - styleId = "TAB_UP_BUTTON"; + styleId = STYLE_TAB_UP_BUTTON; _enableCloseButton = enableCloseButton; _icon = new ImageWidget(); _label = new TextWidget(); - _label.styleId = "TAB_UP_BUTTON_TEXT"; + _label.styleId = STYLE_TAB_UP_BUTTON_TEXT; _label.state = State.Parent; _closeButton = new ImageButton("CLOSE"); - _closeButton.styleId = "BUTTON_TRANSPARENT"; + _closeButton.styleId = STYLE_BUTTON_TRANSPARENT; _closeButton.drawableId = "close"; _closeButton.trackHover = true; _closeButton.onClickListener = &onClick; @@ -167,7 +167,7 @@ class TabItemList { } /// tab header - tab labels, with optional More button -class TabControl : WidgetGroup { +class TabControl : WidgetGroupDefaultDrawing { protected TabItemList _items; protected ImageButton _moreButton; protected bool _enableCloseButton; @@ -186,11 +186,11 @@ class TabControl : WidgetGroup { super(ID); _items = new TabItemList(); _moreButton = new ImageButton("MORE", "tab_more"); - _moreButton.styleId = "BUTTON_TRANSPARENT"; + _moreButton.styleId = STYLE_BUTTON_TRANSPARENT; _moreButton.onClickListener = &onClick; _moreButton.margins(Rect(3,3,3,6)); _enableCloseButton = true; - styleId = "TAB_UP"; + styleId = STYLE_TAB_UP; addChild(_moreButton); // first child is always MORE button, the rest corresponds to tab list } /// returns tab count @@ -338,24 +338,6 @@ class TabControl : WidgetGroup { } //Log.d("tabControl.layout exit"); } - /// Draw widget at its position to buffer - override void onDraw(DrawBuf buf) { - //Log.d("tabControl.onDraw enter"); - if (visibility != Visibility.Visible) - return; - super.onDraw(buf); - Rect rc = _pos; - applyMargins(rc); - applyPadding(rc); - auto saver = ClipRectSaver(buf, rc); - for (int i = 0; i < _children.count; i++) { - Widget item = _children.get(i); - if (item.visibility != Visibility.Visible) - continue; - item.onDraw(buf); - } - //Log.d("tabControl.onDraw exit"); - } protected string _selectedTabId; @@ -388,7 +370,7 @@ class TabHost : FrameLayout, TabHandler { _tabControl = tabControl; if (_tabControl !is null) _tabControl.onTabChangedListener = &onTabChanged; - styleId = "TAB_HOST"; + styleId = STYLE_TAB_HOST; } protected TabControl _tabControl; /// get currently set control widget @@ -478,7 +460,7 @@ class TabWidget : VerticalLayout, TabHandler { _tabControl = new TabControl("TAB_CONTROL"); _tabHost = new TabHost("TAB_HOST", _tabControl); _tabControl.onTabChangedListener.connect(this); - styleId = "TAB_WIDGET"; + styleId = STYLE_TAB_WIDGET; addChild(_tabControl); addChild(_tabHost); } diff --git a/src/dlangui/widgets/tree.d b/src/dlangui/widgets/tree.d index e2140dea..aeafcc09 100644 --- a/src/dlangui/widgets/tree.d +++ b/src/dlangui/widgets/tree.d @@ -122,6 +122,10 @@ class TreeItem { p = p._parent; return cast(TreeItems)p; } + + void clear() { + _children.clear(); + } @property TreeItem parent() { return _parent; } @property protected TreeItem parent(TreeItem p) { _parent = p; return this; } @@ -197,6 +201,29 @@ class TreeItem { return _parent.topParent; } + + protected int _intParam; + protected Object _objectParam; + + @property int intParam() { + return _intParam; + } + + @property TreeItem intParam(int value) { + _intParam = value; + return this; + } + + @property Object objectParam() { + return _objectParam; + } + + @property TreeItem objectParam(Object value) { + _objectParam = value; + return this; + } + + /// returns true if item has at least one child @property bool hasChildren() { return childCount > 0; } @@ -440,7 +467,7 @@ class TreeItemWidget : HorizontalLayout { this(TreeItem item) { super(item.id); - styleId = "TREE_ITEM"; + styleId = STYLE_TREE_ITEM; clickable = true; focusable = true; @@ -458,7 +485,7 @@ class TreeItemWidget : HorizontalLayout { _tab.maxWidth = w; if (_item.hasChildren) { _expander = new ImageWidget("expander", _item.hasChildren && _item.expanded ? "arrow_right_down_black" : "arrow_right_hollow"); - _expander.styleId = "TREE_ITEM_EXPAND_ICON"; + _expander.styleId = STYLE_TREE_ITEM_EXPAND_ICON; _expander.clickable = true; _expander.trackHover = true; //_expander.setState(State.Parent); @@ -484,11 +511,11 @@ class TreeItemWidget : HorizontalLayout { }; if (_item.iconRes.length > 0) { _icon = new ImageWidget("icon", _item.iconRes); - _icon.styleId = "TREE_ITEM_ICON"; + _icon.styleId = STYLE_TREE_ITEM_ICON; _icon.setState(State.Parent); } _label = new TextWidget("label", _item.text); - _label.styleId = "TREE_ITEM_LABEL"; + _label.styleId = STYLE_TREE_ITEM_LABEL; _label.setState(State.Parent); // append children addChild(_tab); @@ -643,7 +670,7 @@ class TreeWidgetBase : ScrollWidget, OnTreeContentChangeListener, OnTreeStateCh super.layout(rc); } - /// Measure widget according to desired width and height constraints. (Step 1 of two phase layout). + /// Measure widget according to desired width and height constraints. (Step 1 of two phase layout). override void measure(int parentWidth, int parentHeight) { if (visibility == Visibility.Gone) { return; diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index 3ecd6571..e14cf24f 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -38,6 +38,7 @@ module dlangui.widgets.widget; public import dlangui.core.types; public import dlangui.core.events; public import dlangui.core.i18n; +public import dlangui.core.collections; public import dlangui.widgets.styles; public import dlangui.graphics.drawbuf; @@ -315,8 +316,9 @@ class Widget { requestLayout(); return this; } + immutable static int FOCUS_RECT_PADDING = 2; /// get padding (between background bounds and content of widget) - @property Rect padding() const { + @property Rect padding() const { // get max padding from style padding and background drawable padding Rect p = style.padding; DrawableRef d = backgroundDrawable; @@ -331,6 +333,10 @@ class Widget { if (p.bottom < dp.bottom) p.bottom = dp.bottom; } + if ((focusable || ((state & State.Parent) && parent.focusable)) && focusRectColors) { + // add two pixels to padding when focus rect is required - one pixel for focus rect, one for additional space + p.offset(FOCUS_RECT_PADDING, FOCUS_RECT_PADDING); + } return p; } /// set padding for widget - override one from style @@ -358,7 +364,12 @@ class Widget { ownStyle.backgroundImageId = imageId; return this; } - + + /// returns colors to draw focus rectangle (one for solid, two for vertical gradient) or null if no focus rect should be drawn for style + @property const(uint[]) focusRectColors() const { + return style.focusRectColors; + } + /// background drawable @property DrawableRef backgroundDrawable() const { return stateStyle.backgroundDrawable; @@ -588,10 +599,10 @@ class Widget { protected bool _focusable; /// whether widget can be focused - @property bool focusable() { return _focusable; } + @property bool focusable() const { return _focusable; } @property Widget focusable(bool flg) { _focusable = flg; return this; } - @property bool focused() { + @property bool focused() const { return (window !is null && window.focusedWidget is this && (state & State.Focused)); } @@ -694,7 +705,7 @@ class Widget { applyPadding(rc); if (!rc.intersects(clipRect)) return; // out of clip rectangle - if (focusable) { + if (canFocus) { TabOrderInfo item = new TabOrderInfo(this, rc); results ~= item; return; @@ -839,9 +850,9 @@ class Widget { return parent.visible; } - /// returns true if widget is focusable and visible + /// returns true if widget is focusable and visible and enabled @property bool canFocus() { - return focusable && visible; + return focusable && visible && enabled; } /// sets focus to this widget or suitable focusable child, returns previously focused widget @@ -1056,19 +1067,31 @@ class Widget { // summarize margins, padding, and content size int dx = m.left + m.right + p.left + p.right + contentWidth; int dy = m.top + m.bottom + p.top + p.bottom + contentHeight; + // check for fixed size set in layoutWidth, layoutHeight + int lh = layoutHeight; + int lw = layoutWidth; + if (!isSpecialSize(lh)) + dy = lh; + if (!isSpecialSize(lw)) + dx = lw; // apply min/max width and height constraints int minw = minWidth; int maxw = maxWidth; int minh = minHeight; int maxh = maxHeight; - if (dx < minw) + if (minw != SIZE_UNSPECIFIED && dx < minw) dx = minw; - if (dy < minh) + if (minh != SIZE_UNSPECIFIED && dy < minh) dy = minh; if (maxw != SIZE_UNSPECIFIED && dx > maxw) dx = maxw; if (maxh != SIZE_UNSPECIFIED && dy > maxh) dy = maxh; + // apply FILL_PARENT + //if (parentWidth != SIZE_UNSPECIFIED && layoutWidth == FILL_PARENT) + // dx = parentWidth; + //if (parentHeight != SIZE_UNSPECIFIED && layoutHeight == FILL_PARENT) + // dy = parentHeight; // apply max parent size constraint if (parentWidth != SIZE_UNSPECIFIED && dx > parentWidth) dx = parentWidth; @@ -1095,6 +1118,14 @@ class Widget { _needLayout = false; } + /// draws focus rectangle, if enabled in styles + void drawFocusRect(DrawBuf buf, Rect rc) { + const uint[] colors = focusRectColors; + if (colors) { + buf.drawFocusRect(rc, colors); + } + } + /// Draw widget at its position to buffer void onDraw(DrawBuf buf) { if (visibility != Visibility.Visible) @@ -1107,6 +1138,10 @@ class Widget { bg.drawTo(buf, rc, state); } applyPadding(rc); + if (state & State.Focused) { + rc.expand(FOCUS_RECT_PADDING, FOCUS_RECT_PADDING); + drawFocusRect(buf, rc); + } _needDraw = false; } @@ -1229,15 +1264,15 @@ class Widget { } /// returns parent widget, null for top level widget - @property Widget parent() { return _parent; } + @property Widget parent() const { return cast(Widget)_parent; } /// sets parent for widget @property Widget parent(Widget parent) { _parent = parent; return this; } /// returns window (if widget or its parent is attached to window) - @property Window window() { - Widget p = this; + @property Window window() const { + Widget p = cast(Widget)this; while (p !is null) { if (p._window !is null) - return p._window; + return cast(Window)p._window; p = p.parent; } return null; @@ -1251,80 +1286,6 @@ class Widget { } -/** object list holder, owning its objects - on destroy of holder, all own objects will be destroyed */ -struct ObjectList(T) { - protected T[] _list; - protected int _count; - /** returns count of items */ - @property int count() const { return _count; } - /** get item by index */ - T get(int index) { - assert(index >= 0 && index < _count, "child index out of range"); - return _list[index]; - } - /** add item to list */ - T add(T item) { - if (_list.length <= _count) // resize - _list.length = _list.length < 4 ? 4 : _list.length * 2; - _list[_count++] = item; - return item; - } - /** add item to list */ - T insert(T item, int index = -1) { - if (index > _count || index < 0) - index = _count; - if (_list.length <= _count) // resize - _list.length = _list.length < 4 ? 4 : _list.length * 2; - for (int i = _count; i > index; i--) - _list[i] = _list[i - 1]; - _list[index] = item; - _count++; - return item; - } - /** find child index for item, return -1 if not found */ - int indexOf(T item) { - for (int i = 0; i < _count; i++) - if (_list[i] == item) - return i; - return -1; - } - /** find child index for item by id, return -1 if not found */ - static if (__traits(hasMember, T, "compareId")) { - int indexOf(string id) { - for (int i = 0; i < _count; i++) - if (_list[i].compareId(id)) - return i; - return -1; - } - } - /** remove item from list, return removed item */ - T remove(int index) { - assert(index >= 0 && index < _count, "child index out of range"); - T item = _list[index]; - for (int i = index; i < _count - 1; i++) - _list[i] = _list[i + 1]; - _count--; - return item; - } - /** Replace item with another value, destroy old value. */ - void replace(T item, int index) { - T old = _list[index]; - _list[index] = item; - destroy(old); - } - /** remove and destroy all items */ - void clear() { - for (int i = 0; i < _count; i++) { - destroy(_list[i]); - _list[i] = null; - } - _count = 0; - } - ~this() { - clear(); - } -} - /** Widget list holder. */ alias WidgetList = ObjectList!Widget; @@ -1375,6 +1336,34 @@ class WidgetGroup : Widget { } +/** WidgetGroup with default drawing of children (just draw all children) */ +class WidgetGroupDefaultDrawing : WidgetGroup { + /// empty parameter list constructor - for usage by factory + this() { + this(null); + } + /// create with ID parameter + this(string ID) { + super(ID); + } + /// Draw widget at its position to buffer + override void onDraw(DrawBuf buf) { + if (visibility != Visibility.Visible) + return; + super.onDraw(buf); + Rect rc = _pos; + applyMargins(rc); + applyPadding(rc); + auto saver = ClipRectSaver(buf, rc); + for (int i = 0; i < _children.count; i++) { + Widget item = _children.get(i); + if (item.visibility != Visibility.Visible) + continue; + item.onDraw(buf); + } + } +} + immutable long ONE_SECOND = 10000000L; /// Helper to handle animation progress