mirror of https://github.com/buggins/dlangui.git
state drawables; use state drawables for buttons
This commit is contained in:
parent
9e562548ba
commit
5accf91de5
|
@ -13,7 +13,7 @@
|
||||||
<verbose>0</verbose>
|
<verbose>0</verbose>
|
||||||
<vtls>0</vtls>
|
<vtls>0</vtls>
|
||||||
<symdebug>1</symdebug>
|
<symdebug>1</symdebug>
|
||||||
<optimize>1</optimize>
|
<optimize>0</optimize>
|
||||||
<cpu>0</cpu>
|
<cpu>0</cpu>
|
||||||
<isX86_64>0</isX86_64>
|
<isX86_64>0</isX86_64>
|
||||||
<isLinux>0</isLinux>
|
<isLinux>0</isLinux>
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
<noboundscheck>0</noboundscheck>
|
<noboundscheck>0</noboundscheck>
|
||||||
<useSwitchError>0</useSwitchError>
|
<useSwitchError>0</useSwitchError>
|
||||||
<useUnitTests>0</useUnitTests>
|
<useUnitTests>0</useUnitTests>
|
||||||
<useInline>1</useInline>
|
<useInline>0</useInline>
|
||||||
<release>0</release>
|
<release>0</release>
|
||||||
<preservePaths>0</preservePaths>
|
<preservePaths>0</preservePaths>
|
||||||
<warnings>0</warnings>
|
<warnings>0</warnings>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<verbose>0</verbose>
|
<verbose>0</verbose>
|
||||||
<vtls>0</vtls>
|
<vtls>0</vtls>
|
||||||
<symdebug>1</symdebug>
|
<symdebug>1</symdebug>
|
||||||
<optimize>1</optimize>
|
<optimize>0</optimize>
|
||||||
<cpu>0</cpu>
|
<cpu>0</cpu>
|
||||||
<isX86_64>0</isX86_64>
|
<isX86_64>0</isX86_64>
|
||||||
<isLinux>0</isLinux>
|
<isLinux>0</isLinux>
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
<useIn>0</useIn>
|
<useIn>0</useIn>
|
||||||
<useOut>0</useOut>
|
<useOut>0</useOut>
|
||||||
<useArrayBounds>0</useArrayBounds>
|
<useArrayBounds>0</useArrayBounds>
|
||||||
<noboundscheck>1</noboundscheck>
|
<noboundscheck>0</noboundscheck>
|
||||||
<useSwitchError>0</useSwitchError>
|
<useSwitchError>0</useSwitchError>
|
||||||
<useUnitTests>0</useUnitTests>
|
<useUnitTests>0</useUnitTests>
|
||||||
<useInline>0</useInline>
|
<useInline>0</useInline>
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:constantSize="true"
|
||||||
|
android:dither="false"
|
||||||
|
android:variablePadding="false" >
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_normal_disable_focused"
|
||||||
|
android:state_enabled="false" />
|
||||||
|
android:state_focused="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_normal_disable"
|
||||||
|
android:state_focused="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_pressed"
|
||||||
|
android:state_pressed="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_selected"
|
||||||
|
android:state_selected="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_normal_hover"
|
||||||
|
android:state_hovered="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_normal" />
|
||||||
|
</selector>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:constantSize="true"
|
||||||
|
android:dither="false"
|
||||||
|
android:variablePadding="false" >
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_normal_disable_focused"
|
||||||
|
android:state_enabled="false" />
|
||||||
|
android:state_focused="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_normal_disable"
|
||||||
|
android:state_focused="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_pressed"
|
||||||
|
android:state_pressed="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_selected"
|
||||||
|
android:state_selected="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="btn_default_small_normal_hover"
|
||||||
|
android:state_hovered="true" />
|
||||||
|
<item
|
||||||
|
android:drawable="@null" />
|
||||||
|
</selector>
|
|
@ -24,6 +24,17 @@ struct Rect {
|
||||||
top += dy;
|
top += dy;
|
||||||
bottom += 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 width() { return right - left; }
|
||||||
@property int height() { return bottom - top; }
|
@property int height() { return bottom - top; }
|
||||||
this(int x0, int y0, int x1, int y1) {
|
this(int x0, int y0, int x1, int y1) {
|
||||||
|
|
|
@ -235,14 +235,19 @@ class StateDrawable : Drawable {
|
||||||
return (stateMask & state) == stateValue;
|
return (stateMask & state) == stateValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// list of states
|
||||||
protected StateItem[] _stateList;
|
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) {
|
void addState(uint stateMask, uint stateValue, string resourceId) {
|
||||||
StateItem item;
|
StateItem item;
|
||||||
item.stateMask = stateMask;
|
item.stateMask = stateMask;
|
||||||
item.stateValue = stateValue;
|
item.stateValue = stateValue;
|
||||||
item.drawable = drawableCache.get(resourceId);
|
item.drawable = drawableCache.get(resourceId);
|
||||||
_stateList ~= item;
|
itemAdded(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addState(uint stateMask, uint stateValue, DrawableRef drawable) {
|
void addState(uint stateMask, uint stateValue, DrawableRef drawable) {
|
||||||
|
@ -250,7 +255,18 @@ class StateDrawable : Drawable {
|
||||||
item.stateMask = stateMask;
|
item.stateMask = stateMask;
|
||||||
item.stateValue = stateValue;
|
item.stateValue = stateValue;
|
||||||
item.drawable = drawable;
|
item.drawable = drawable;
|
||||||
|
itemAdded(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void itemAdded(ref StateItem item) {
|
||||||
_stateList ~= 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) {
|
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) {
|
override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) {
|
||||||
foreach(ref item; _stateList)
|
foreach(ref item; _stateList)
|
||||||
if (item.matchState(state)) {
|
if (item.matchState(state)) {
|
||||||
|
if (!item.drawable.isNull)
|
||||||
item.drawable.drawTo(buf, rc, state, tilex0, tiley0);
|
item.drawable.drawTo(buf, rc, state, tilex0, tiley0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@property override int width() {
|
@property override int width() {
|
||||||
return (_stateList.length > 0) ? _stateList[0].drawable.width : 0;
|
return _size.x;
|
||||||
}
|
}
|
||||||
@property override int height() {
|
@property override int height() {
|
||||||
return (_stateList.length > 0) ? _stateList[0].drawable.height : 0;
|
return _size.y;
|
||||||
}
|
}
|
||||||
@property override Rect padding() {
|
@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[] _resourcePaths;
|
||||||
string[string] _idToFileMap;
|
string[string] _idToFileMap;
|
||||||
DrawableCacheItem[string] _idToDrawableMap;
|
DrawableCacheItem[string] _idToDrawableMap;
|
||||||
|
DrawableRef _nullDrawable;
|
||||||
ref DrawableRef get(string id) {
|
ref DrawableRef get(string id) {
|
||||||
|
if (id.equal("@null"))
|
||||||
|
return _nullDrawable;
|
||||||
if (id in _idToDrawableMap)
|
if (id in _idToDrawableMap)
|
||||||
return _idToDrawableMap[id].drawable;
|
return _idToDrawableMap[id].drawable;
|
||||||
string resourceId = id;
|
string resourceId = id;
|
||||||
|
|
|
@ -123,7 +123,7 @@ class ImageWidget : Widget {
|
||||||
sz.x = img.width;
|
sz.x = img.width;
|
||||||
sz.y = img.height;
|
sz.y = img.height;
|
||||||
applyAlign(rc, sz);
|
applyAlign(rc, sz);
|
||||||
img.drawTo(buf, rc);
|
img.drawTo(buf, rc, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -482,7 +482,7 @@ class Style {
|
||||||
if (state == 0)
|
if (state == 0)
|
||||||
return this;
|
return this;
|
||||||
//Log.d("forState ", state, " styleId=", _id, " substates=", _substates.length);
|
//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);
|
return parentStyle.forState(state);
|
||||||
foreach(item; _substates) {
|
foreach(item; _substates) {
|
||||||
if ((item._stateMask & state) == item._stateValue)
|
if ((item._stateMask & state) == item._stateValue)
|
||||||
|
@ -584,6 +584,11 @@ class Theme : Style {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// find substyle based on widget state (e.g. focused, pressed, ...)
|
||||||
|
override const(Style) forState(uint state) const {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
void dumpStats() {
|
void dumpStats() {
|
||||||
Log.d("Theme ", _id, ": children:", _children.length, ", substates:", _substates.length, ", mapsize:", _byId.length);
|
Log.d("Theme ", _id, ": children:", _children.length, ", substates:", _substates.length, ", mapsize:", _byId.length);
|
||||||
}
|
}
|
||||||
|
@ -610,13 +615,14 @@ Theme createDefaultTheme() {
|
||||||
Log.d("Creating default theme");
|
Log.d("Creating default theme");
|
||||||
Theme res = new Theme("default");
|
Theme res = new Theme("default");
|
||||||
res.fontSize(14);
|
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));
|
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 | 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.Enabled, 0).backgroundImageId("btn_default_small_normal_disable");
|
||||||
button.createState(State.Pressed, State.Pressed).backgroundImageId("btn_default_small_pressed");
|
//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.Focused, State.Focused).backgroundImageId("btn_default_small_selected");
|
||||||
button.createState(State.Hovered, State.Hovered).backgroundImageId("btn_default_small_normal_hover");
|
//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_UP, "scrollbar_btn_up");
|
||||||
res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_DOWN, "scrollbar_btn_down");
|
res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_DOWN, "scrollbar_btn_down");
|
||||||
res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_LEFT, "scrollbar_btn_left");
|
res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_LEFT, "scrollbar_btn_left");
|
||||||
|
|
|
@ -49,6 +49,7 @@ class TabItemWidget : HorizontalLayout {
|
||||||
_label.styleId = "TAB_UP_BUTTON_TEXT";
|
_label.styleId = "TAB_UP_BUTTON_TEXT";
|
||||||
_label.state = State.Parent;
|
_label.state = State.Parent;
|
||||||
_closeButton = new ImageButton("CLOSE");
|
_closeButton = new ImageButton("CLOSE");
|
||||||
|
_closeButton.styleId = "BUTTON_TRANSPARENT";
|
||||||
_closeButton.drawableId = "close";
|
_closeButton.drawableId = "close";
|
||||||
_closeButton.onClickListener = &onClick;
|
_closeButton.onClickListener = &onClick;
|
||||||
if (_enableCloseButton) {
|
if (_enableCloseButton) {
|
||||||
|
@ -152,6 +153,7 @@ class TabControl : WidgetGroup {
|
||||||
super(ID);
|
super(ID);
|
||||||
_items = new TabItemList();
|
_items = new TabItemList();
|
||||||
_moreButton = new ImageButton("MORE", "tab_more");
|
_moreButton = new ImageButton("MORE", "tab_more");
|
||||||
|
_moreButton.styleId = "BUTTON_TRANSPARENT";
|
||||||
_moreButton.onClickListener = &onClick;
|
_moreButton.onClickListener = &onClick;
|
||||||
_enableCloseButton = true;
|
_enableCloseButton = true;
|
||||||
styleId = "TAB_UP";
|
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).
|
/// Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||||
override void measure(int parentWidth, int parentHeight) {
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
|
//Log.d("tabControl.measure enter");
|
||||||
Rect m = margins;
|
Rect m = margins;
|
||||||
Rect p = padding;
|
Rect p = padding;
|
||||||
// calc size constraints for children
|
// calc size constraints for children
|
||||||
|
@ -257,9 +260,11 @@ class TabControl : WidgetGroup {
|
||||||
sz.x += tab.measuredWidth;
|
sz.x += tab.measuredWidth;
|
||||||
}
|
}
|
||||||
measuredContent(parentWidth, parentHeight, sz.x, sz.y);
|
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).
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
override void layout(Rect rc) {
|
override void layout(Rect rc) {
|
||||||
|
//Log.d("tabControl.layout enter");
|
||||||
_needLayout = false;
|
_needLayout = false;
|
||||||
if (visibility == Visibility.Gone) {
|
if (visibility == Visibility.Gone) {
|
||||||
return;
|
return;
|
||||||
|
@ -297,9 +302,11 @@ class TabControl : WidgetGroup {
|
||||||
widget.layout(rc);
|
widget.layout(rc);
|
||||||
rc.left += w;
|
rc.left += w;
|
||||||
}
|
}
|
||||||
|
//Log.d("tabControl.layout exit");
|
||||||
}
|
}
|
||||||
/// Draw widget at its position to buffer
|
/// Draw widget at its position to buffer
|
||||||
override void onDraw(DrawBuf buf) {
|
override void onDraw(DrawBuf buf) {
|
||||||
|
//Log.d("tabControl.onDraw enter");
|
||||||
if (visibility != Visibility.Visible)
|
if (visibility != Visibility.Visible)
|
||||||
return;
|
return;
|
||||||
super.onDraw(buf);
|
super.onDraw(buf);
|
||||||
|
@ -313,6 +320,7 @@ class TabControl : WidgetGroup {
|
||||||
continue;
|
continue;
|
||||||
item.onDraw(buf);
|
item.onDraw(buf);
|
||||||
}
|
}
|
||||||
|
//Log.d("tabControl.onDraw exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected string _selectedTabId;
|
protected string _selectedTabId;
|
||||||
|
|
|
@ -77,6 +77,7 @@ class Widget {
|
||||||
/// create widget, with optional id
|
/// create widget, with optional id
|
||||||
this(string ID = null) {
|
this(string ID = null) {
|
||||||
_id = ID;
|
_id = ID;
|
||||||
|
_state = State.Enabled;
|
||||||
//Log.d("Created widget, count = ", ++_instanceCount);
|
//Log.d("Created widget, count = ", ++_instanceCount);
|
||||||
}
|
}
|
||||||
~this() {
|
~this() {
|
||||||
|
@ -413,7 +414,7 @@ class Widget {
|
||||||
applyMargins(rc);
|
applyMargins(rc);
|
||||||
DrawableRef bg = stateStyle.backgroundDrawable;
|
DrawableRef bg = stateStyle.backgroundDrawable;
|
||||||
if (!bg.isNull) {
|
if (!bg.isNull) {
|
||||||
bg.drawTo(buf, rc);
|
bg.drawTo(buf, rc, state);
|
||||||
}
|
}
|
||||||
applyPadding(rc);
|
applyPadding(rc);
|
||||||
_needDraw = false;
|
_needDraw = false;
|
||||||
|
|
Loading…
Reference in New Issue