diff --git a/examples/example1/res/scrollbar_indicator_horizontal.png b/examples/example1/res/scrollbar_indicator_horizontal.png new file mode 100644 index 00000000..1151c1e8 Binary files /dev/null and b/examples/example1/res/scrollbar_indicator_horizontal.png differ diff --git a/examples/example1/res/scrollbar_indicator_vertical.png b/examples/example1/res/scrollbar_indicator_vertical.png new file mode 100644 index 00000000..ac0e1ae2 Binary files /dev/null and b/examples/example1/res/scrollbar_indicator_vertical.png differ diff --git a/src/dlangui/core/types.d b/src/dlangui/core/types.d index c3df2200..3a82229b 100644 --- a/src/dlangui/core/types.d +++ b/src/dlangui/core/types.d @@ -91,7 +91,7 @@ struct Glyph class RefCountedObject { protected int _refCount; - @property int refCount() { return _refCount; } + @property int refCount() const { return _refCount; } void addRef() { _refCount++; } @@ -105,8 +105,8 @@ class RefCountedObject { struct Ref(T) { // if (T is RefCountedObject) private T _data; alias get this; - @property bool isNull() { return _data is null; } - @property int refCount() { return _data !is null ? _data.refCount : 0; } + @property bool isNull() const { return _data is null; } + @property int refCount() const { return _data !is null ? _data.refCount : 0; } this(T data) { _data = data; if (_data !is null) diff --git a/src/dlangui/graphics/drawbuf.d b/src/dlangui/graphics/drawbuf.d index b886c52a..100c93dd 100644 --- a/src/dlangui/graphics/drawbuf.d +++ b/src/dlangui/graphics/drawbuf.d @@ -683,6 +683,13 @@ class Drawable : RefCountedObject { @property Rect padding() { return Rect(0,0,0,0); } } +class EmptyDrawable : Drawable { + override void drawTo(DrawBuf buf, Rect rc, int tilex0 = 0, int tiley0 = 0) { + } + @property override int width() { return 0; } + @property override int height() { return 0; } +} + class SolidFillDrawable : Drawable { protected uint _color; this(uint color) { diff --git a/src/dlangui/widgets/controls.d b/src/dlangui/widgets/controls.d index ab4c28d1..9388ef21 100644 --- a/src/dlangui/widgets/controls.d +++ b/src/dlangui/widgets/controls.d @@ -283,9 +283,9 @@ class ScrollBar : WidgetGroup, OnClickHandler { @property ScrollBar orientation(Orientation value) { if (_orientation != value) { _orientation = value; - _btnBack.drawableId = _orientation == Orientation.Vertical ? "scrollbar_btn_up" : "scrollbar_btn_left"; - _btnForward.drawableId = _orientation == Orientation.Vertical ? "scrollbar_btn_down" : "scrollbar_btn_right"; - _indicator.drawableId = _orientation == Orientation.Vertical ? "scrollbar_indicator_vertical" : "scrollbar_indicator_horizontal"; + _btnBack.drawableId = style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_UP : ATTR_SCROLLBAR_BUTTON_LEFT); + _btnForward.drawableId = style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_DOWN : ATTR_SCROLLBAR_BUTTON_RIGHT); + _indicator.drawableId = style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_INDICATOR_VERTICAL : ATTR_SCROLLBAR_INDICATOR_HORIZONTAL); requestLayout(); } return this; @@ -295,9 +295,9 @@ class ScrollBar : WidgetGroup, OnClickHandler { super(ID); styleId = "BUTTON"; _orientation = orient; - _btnBack = new ImageButton("BACK", _orientation == Orientation.Vertical ? "scrollbar_btn_up" : "scrollbar_btn_left"); - _btnForward = new ImageButton("FORWARD", _orientation == Orientation.Vertical ? "scrollbar_btn_down" : "scrollbar_btn_right"); - _indicator = new IndicatorButton(_orientation == Orientation.Vertical ? "scrollbar_indicator_vertical" : "scrollbar_indicator_horizontal"); + _btnBack = new ImageButton("BACK", style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_UP : ATTR_SCROLLBAR_BUTTON_LEFT)); + _btnForward = new ImageButton("FORWARD", style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_BUTTON_DOWN : ATTR_SCROLLBAR_BUTTON_RIGHT)); + _indicator = new IndicatorButton(style.customDrawableId(_orientation == Orientation.Vertical ? ATTR_SCROLLBAR_INDICATOR_VERTICAL : ATTR_SCROLLBAR_INDICATOR_HORIZONTAL)); addChild(_btnBack); addChild(_btnForward); addChild(_indicator); diff --git a/src/dlangui/widgets/styles.d b/src/dlangui/widgets/styles.d index 972b70dd..5a3dadb9 100644 --- a/src/dlangui/widgets/styles.d +++ b/src/dlangui/widgets/styles.d @@ -39,6 +39,31 @@ enum Align : ubyte { TopLeft = Left | Top, } +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; + } +} + /// style properties class Style { protected string _id; @@ -69,6 +94,8 @@ class Style { protected Style[] _substates; protected Style[] _children; + protected DrawableAttribute[string] _customDrawables; + protected FontRef _font; protected DrawableRef _backgroundDrawable; @@ -115,6 +142,30 @@ class Style { return (cast(Style)this)._backgroundDrawable; } + /// get custom drawable attribute + @property ref DrawableRef customDrawable(string id) { + if (id in _customDrawables) + return _customDrawables[id].drawable; + return parentStyle.customDrawable(id); + } + + /// get custom drawable attribute + @property string customDrawableId(string id) const { + if (id in _customDrawables) + return _customDrawables[id].drawableId; + return parentStyle.customDrawableId(id); + } + + /// sets custom drawable attribute for style + Style setCustomDrawable(string id, string resourceId) { + if (id in _customDrawables) + _customDrawables[id].drawableId = resourceId; + else + _customDrawables[id] = new DrawableAttribute(id, resourceId); + return this; + } + + //=================================================== // font properties @@ -510,6 +561,19 @@ class Theme : Style { return _maxHeight; } + private DrawableRef _emptyDrawable; + @property override ref DrawableRef customDrawable(string id) const { + if (id in _customDrawables) + return _customDrawables[id].drawable; + return (cast(Theme)this)._emptyDrawable; + } + + @property override string customDrawableId(string id) const { + if (id in _customDrawables) + return _customDrawables[id].drawableId; + return null; + } + /// create new named style override Style createSubstyle(string id) { Style style = new Style(this, id); @@ -541,6 +605,12 @@ private __gshared Theme _currentTheme; _currentTheme = theme; } +immutable ATTR_SCROLLBAR_BUTTON_UP = "scrollbar_button_up"; +immutable ATTR_SCROLLBAR_BUTTON_DOWN = "scrollbar_button_down"; +immutable ATTR_SCROLLBAR_BUTTON_LEFT = "scrollbar_button_left"; +immutable ATTR_SCROLLBAR_BUTTON_RIGHT = "scrollbar_button_right"; +immutable ATTR_SCROLLBAR_INDICATOR_VERTICAL = "scrollbar_indicator_vertical"; +immutable ATTR_SCROLLBAR_INDICATOR_HORIZONTAL = "scrollbar_indicator_horizontal"; Theme createDefaultTheme() { Log.d("Creating default theme"); @@ -551,6 +621,12 @@ Theme createDefaultTheme() { button.createState(State.Disabled, State.Disabled).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"); + 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"); + res.setCustomDrawable(ATTR_SCROLLBAR_BUTTON_RIGHT, "scrollbar_btn_right"); + res.setCustomDrawable(ATTR_SCROLLBAR_INDICATOR_VERTICAL, "scrollbar_indicator_vertical"); + res.setCustomDrawable(ATTR_SCROLLBAR_INDICATOR_HORIZONTAL, "scrollbar_indicator_horizontal"); res.dumpStats(); return res; }