diff --git a/dlanguilib.visualdproj b/dlanguilib.visualdproj
index e36b0deb..116e67b3 100644
--- a/dlanguilib.visualdproj
+++ b/dlanguilib.visualdproj
@@ -13,7 +13,7 @@
0
0
1
- 1
+ 0
0
0
0
@@ -32,7 +32,7 @@
0
0
0
- 1
+ 0
0
0
0
diff --git a/examples/example1/example1.visualdproj b/examples/example1/example1.visualdproj
index a058304d..cba3de88 100644
--- a/examples/example1/example1.visualdproj
+++ b/examples/example1/example1.visualdproj
@@ -13,7 +13,7 @@
0
0
1
- 1
+ 0
0
0
0
@@ -29,7 +29,7 @@
0
0
0
- 1
+ 0
0
0
0
diff --git a/examples/example1/res/btn_default_small.xml b/examples/example1/res/btn_default_small.xml
new file mode 100644
index 00000000..0ad26807
--- /dev/null
+++ b/examples/example1/res/btn_default_small.xml
@@ -0,0 +1,24 @@
+
+
+
+ android:state_focused="true" />
+
+
+
+
+
+
diff --git a/examples/example1/res/btn_default_small_transparent.xml b/examples/example1/res/btn_default_small_transparent.xml
new file mode 100644
index 00000000..2f38acbe
--- /dev/null
+++ b/examples/example1/res/btn_default_small_transparent.xml
@@ -0,0 +1,24 @@
+
+
+
+ android:state_focused="true" />
+
+
+
+
+
+
diff --git a/src/dlangui/core/types.d b/src/dlangui/core/types.d
index de72071c..5dde1419 100644
--- a/src/dlangui/core/types.d
+++ b/src/dlangui/core/types.d
@@ -24,6 +24,17 @@ struct Rect {
top += dy;
bottom += dy;
}
+ /// for all fields, sets this.field to rc.field if rc.field > this.field
+ void setMax(Rect rc) {
+ if (left < rc.left)
+ left = rc.left;
+ if (right < rc.right)
+ right = rc.right;
+ if (top < rc.top)
+ top = rc.top;
+ if (bottom < rc.bottom)
+ bottom = rc.bottom;
+ }
@property int width() { return right - left; }
@property int height() { return bottom - top; }
this(int x0, int y0, int x1, int y1) {
diff --git a/src/dlangui/graphics/resources.d b/src/dlangui/graphics/resources.d
index 6609d819..1697e5f3 100644
--- a/src/dlangui/graphics/resources.d
+++ b/src/dlangui/graphics/resources.d
@@ -235,14 +235,19 @@ class StateDrawable : Drawable {
return (stateMask & state) == stateValue;
}
}
+ // list of states
protected StateItem[] _stateList;
+ // max paddings for all states
+ protected Rect _paddings;
+ // max drawable size for all states
+ protected Point _size;
void addState(uint stateMask, uint stateValue, string resourceId) {
StateItem item;
item.stateMask = stateMask;
item.stateValue = stateValue;
item.drawable = drawableCache.get(resourceId);
- _stateList ~= item;
+ itemAdded(item);
}
void addState(uint stateMask, uint stateValue, DrawableRef drawable) {
@@ -250,7 +255,18 @@ class StateDrawable : Drawable {
item.stateMask = stateMask;
item.stateValue = stateValue;
item.drawable = drawable;
+ itemAdded(item);
+ }
+
+ private void itemAdded(ref StateItem item) {
_stateList ~= item;
+ if (!item.drawable.isNull) {
+ if (_size.x < item.drawable.width)
+ _size.x = item.drawable.width;
+ if (_size.y < item.drawable.height)
+ _size.y = item.drawable.height;
+ _paddings.setMax(item.drawable.padding);
+ }
}
bool load(Element element) {
@@ -296,19 +312,20 @@ class StateDrawable : Drawable {
override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) {
foreach(ref item; _stateList)
if (item.matchState(state)) {
- item.drawable.drawTo(buf, rc, state, tilex0, tiley0);
+ if (!item.drawable.isNull)
+ item.drawable.drawTo(buf, rc, state, tilex0, tiley0);
return;
}
}
@property override int width() {
- return (_stateList.length > 0) ? _stateList[0].drawable.width : 0;
+ return _size.x;
}
@property override int height() {
- return (_stateList.length > 0) ? _stateList[0].drawable.height : 0;
+ return _size.y;
}
@property override Rect padding() {
- return (_stateList.length > 0) ? _stateList[0].drawable.padding : Rect(0,0,0,0);
+ return _paddings;
}
}
@@ -498,7 +515,10 @@ class DrawableCache {
string[] _resourcePaths;
string[string] _idToFileMap;
DrawableCacheItem[string] _idToDrawableMap;
+ DrawableRef _nullDrawable;
ref DrawableRef get(string id) {
+ if (id.equal("@null"))
+ return _nullDrawable;
if (id in _idToDrawableMap)
return _idToDrawableMap[id].drawable;
string resourceId = id;
diff --git a/src/dlangui/widgets/controls.d b/src/dlangui/widgets/controls.d
index ef5c85d6..13ad4a61 100644
--- a/src/dlangui/widgets/controls.d
+++ b/src/dlangui/widgets/controls.d
@@ -123,7 +123,7 @@ class ImageWidget : Widget {
sz.x = img.width;
sz.y = img.height;
applyAlign(rc, sz);
- img.drawTo(buf, rc);
+ img.drawTo(buf, rc, state);
}
}
}
diff --git a/src/dlangui/widgets/styles.d b/src/dlangui/widgets/styles.d
index 7d51c8b9..99097585 100644
--- a/src/dlangui/widgets/styles.d
+++ b/src/dlangui/widgets/styles.d
@@ -482,7 +482,7 @@ class Style {
if (state == 0)
return this;
//Log.d("forState ", state, " styleId=", _id, " substates=", _substates.length);
- if (parentStyle !is null && _substates.length == 0) //id is null &&
+ if (parentStyle !is null && _substates.length == 0 && parentStyle._substates.length > 0) //id is null &&
return parentStyle.forState(state);
foreach(item; _substates) {
if ((item._stateMask & state) == item._stateValue)
@@ -584,6 +584,11 @@ class Theme : Style {
return this;
}
+ /// find substyle based on widget state (e.g. focused, pressed, ...)
+ override const(Style) forState(uint state) const {
+ return this;
+ }
+
void dumpStats() {
Log.d("Theme ", _id, ": children:", _children.length, ", substates:", _substates.length, ", mapsize:", _byId.length);
}
@@ -610,13 +615,14 @@ Theme createDefaultTheme() {
Log.d("Creating default theme");
Theme res = new Theme("default");
res.fontSize(14);
- Style button = res.createSubstyle("BUTTON").backgroundImageId("btn_default_small_normal").alignment(Align.Center);
+ Style button = res.createSubstyle("BUTTON").backgroundImageId("btn_default_small").alignment(Align.Center);
+ Style buttonTransparent = res.createSubstyle("BUTTON_TRANSPARENT").backgroundImageId("btn_default_small_transparent").alignment(Align.Center);
Style text = res.createSubstyle("TEXT").margins(Rect(2,2,2,2)).padding(Rect(1,1,1,1));
- button.createState(State.Enabled | State.Focused, State.Focused).backgroundImageId("btn_default_small_normal_disable_focused");
- button.createState(State.Enabled, 0).backgroundImageId("btn_default_small_normal_disable");
- button.createState(State.Pressed, State.Pressed).backgroundImageId("btn_default_small_pressed");
- button.createState(State.Focused, State.Focused).backgroundImageId("btn_default_small_selected");
- button.createState(State.Hovered, State.Hovered).backgroundImageId("btn_default_small_normal_hover");
+ //button.createState(State.Enabled | State.Focused, State.Focused).backgroundImageId("btn_default_small_normal_disable_focused");
+ //button.createState(State.Enabled, 0).backgroundImageId("btn_default_small_normal_disable");
+ //button.createState(State.Pressed, State.Pressed).backgroundImageId("btn_default_small_pressed");
+ //button.createState(State.Focused, State.Focused).backgroundImageId("btn_default_small_selected");
+ //button.createState(State.Hovered, State.Hovered).backgroundImageId("btn_default_small_normal_hover");
res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_UP, "scrollbar_btn_up");
res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_DOWN, "scrollbar_btn_down");
res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_LEFT, "scrollbar_btn_left");
diff --git a/src/dlangui/widgets/tabs.d b/src/dlangui/widgets/tabs.d
index d9cedfc9..240ed975 100644
--- a/src/dlangui/widgets/tabs.d
+++ b/src/dlangui/widgets/tabs.d
@@ -49,6 +49,7 @@ class TabItemWidget : HorizontalLayout {
_label.styleId = "TAB_UP_BUTTON_TEXT";
_label.state = State.Parent;
_closeButton = new ImageButton("CLOSE");
+ _closeButton.styleId = "BUTTON_TRANSPARENT";
_closeButton.drawableId = "close";
_closeButton.onClickListener = &onClick;
if (_enableCloseButton) {
@@ -152,6 +153,7 @@ class TabControl : WidgetGroup {
super(ID);
_items = new TabItemList();
_moreButton = new ImageButton("MORE", "tab_more");
+ _moreButton.styleId = "BUTTON_TRANSPARENT";
_moreButton.onClickListener = &onClick;
_enableCloseButton = true;
styleId = "TAB_UP";
@@ -231,6 +233,7 @@ class TabControl : WidgetGroup {
}
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
override void measure(int parentWidth, int parentHeight) {
+ //Log.d("tabControl.measure enter");
Rect m = margins;
Rect p = padding;
// calc size constraints for children
@@ -257,9 +260,11 @@ class TabControl : WidgetGroup {
sz.x += tab.measuredWidth;
}
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
+ //Log.d("tabControl.measure exit");
}
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
override void layout(Rect rc) {
+ //Log.d("tabControl.layout enter");
_needLayout = false;
if (visibility == Visibility.Gone) {
return;
@@ -297,9 +302,11 @@ class TabControl : WidgetGroup {
widget.layout(rc);
rc.left += w;
}
+ //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);
@@ -313,6 +320,7 @@ class TabControl : WidgetGroup {
continue;
item.onDraw(buf);
}
+ //Log.d("tabControl.onDraw exit");
}
protected string _selectedTabId;
diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d
index 4a519408..58016671 100644
--- a/src/dlangui/widgets/widget.d
+++ b/src/dlangui/widgets/widget.d
@@ -77,6 +77,7 @@ class Widget {
/// create widget, with optional id
this(string ID = null) {
_id = ID;
+ _state = State.Enabled;
//Log.d("Created widget, count = ", ++_instanceCount);
}
~this() {
@@ -413,7 +414,7 @@ class Widget {
applyMargins(rc);
DrawableRef bg = stateStyle.backgroundDrawable;
if (!bg.isNull) {
- bg.drawTo(buf, rc);
+ bg.drawTo(buf, rc, state);
}
applyPadding(rc);
_needDraw = false;