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 @@
+ focusRectColors="#000"
+ textFlags="UnderlineHotKeys"
+ >
+
+
+
-
+
+
+
+
+
+
+
+ align="Left|VCenter"
+ >
+
+
+
+
+
+
@@ -134,43 +181,39 @@
-
+
+
+
+
*
@@ -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