mirror of https://github.com/buggins/dlangui.git
borders for widgets - initial working implementation
This commit is contained in:
parent
b5eb939a46
commit
e8f11036c9
|
@ -334,6 +334,7 @@ class GradientDrawable : Drawable {
|
||||||
protected uint _color2; // bottom left
|
protected uint _color2; // bottom left
|
||||||
protected uint _color3; // top right
|
protected uint _color3; // top right
|
||||||
protected uint _color4; // bottom right
|
protected uint _color4; // bottom right
|
||||||
|
|
||||||
this(uint angle, uint color1, uint color2) {
|
this(uint angle, uint color1, uint color2) {
|
||||||
// rotate a gradient; angle goes clockwise
|
// rotate a gradient; angle goes clockwise
|
||||||
import std.math;
|
import std.math;
|
||||||
|
@ -370,35 +371,42 @@ class GradientDrawable : 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) {
|
||||||
buf.fillGradientRect(rc, _color1, _color2, _color3, _color4);
|
buf.fillGradientRect(rc, _color1, _color2, _color3, _color4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@property override int width() { return 1; }
|
@property override int width() { return 1; }
|
||||||
@property override int height() { return 1; }
|
@property override int height() { return 1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// solid borders (may be of different width) and, optionally, solid inner area
|
/// solid borders (may be of different width) and, optionally, solid inner area
|
||||||
class FrameDrawable : Drawable {
|
class BorderDrawable : Drawable {
|
||||||
protected uint _frameColor; // frame color
|
protected uint _borderColor;
|
||||||
protected Rect _frameWidths; // left, top, right, bottom border widths, in pixels
|
protected Rect _borderWidths; // left, top, right, bottom border widths, in pixels
|
||||||
protected uint _middleColor; // middle area color (may be transparent)
|
protected uint _middleColor; // middle area color (may be transparent)
|
||||||
this(uint frameColor, Rect borderWidths, uint innerAreaColor = 0xFFFFFFFF) {
|
|
||||||
_frameColor = frameColor;
|
this(uint borderColor, Rect borderWidths, uint innerAreaColor = 0xFFFFFFFF) {
|
||||||
_frameWidths = borderWidths;
|
_borderColor = borderColor;
|
||||||
|
_borderWidths = borderWidths;
|
||||||
_middleColor = innerAreaColor;
|
_middleColor = innerAreaColor;
|
||||||
}
|
}
|
||||||
this(uint frameColor, int borderWidth, uint innerAreaColor = 0xFFFFFFFF) {
|
|
||||||
_frameColor = frameColor;
|
this(uint borderColor, int borderWidth, uint innerAreaColor = 0xFFFFFFFF) {
|
||||||
_frameWidths = Rect(borderWidth, borderWidth, borderWidth, borderWidth);
|
_borderColor = borderColor;
|
||||||
|
_borderWidths = Rect(borderWidth, borderWidth, borderWidth, borderWidth);
|
||||||
_middleColor = innerAreaColor;
|
_middleColor = innerAreaColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
buf.drawFrame(rc, _frameColor, _frameWidths, _middleColor);
|
buf.drawFrame(rc, _borderColor, _borderWidths, _middleColor);
|
||||||
}
|
}
|
||||||
@property override int width() { return 1 + _frameWidths.left + _frameWidths.right; }
|
|
||||||
@property override int height() { return 1 + _frameWidths.top + _frameWidths.bottom; }
|
@property override int width() { return 1 + _borderWidths.left + _borderWidths.right; }
|
||||||
@property override Rect padding() { return _frameWidths; }
|
@property override int height() { return 1 + _borderWidths.top + _borderWidths.bottom; }
|
||||||
|
@property override Rect padding() { return _borderWidths; }
|
||||||
}
|
}
|
||||||
|
deprecated alias FrameDrawable = BorderDrawable;
|
||||||
|
|
||||||
enum DimensionUnits {
|
enum DimensionUnits {
|
||||||
pixels,
|
pixels,
|
||||||
|
@ -480,18 +488,18 @@ static if (BACKEND_CONSOLE) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// decode solid color / gradient / frame drawable from string like #AARRGGBB, e.g. #5599AA
|
/// decode solid color / gradient / border drawable from string like #AARRGGBB, e.g. #5599AA
|
||||||
///
|
///
|
||||||
/// SolidFillDrawable: #AARRGGBB - e.g. #8090A0 or #80ffffff
|
/// SolidFillDrawable: #AARRGGBB - e.g. #8090A0 or #80ffffff
|
||||||
/// GradientDrawable: #linear,Ndeg,#firstColor,#secondColor
|
/// GradientDrawable: #linear,Ndeg,#firstColor,#secondColor
|
||||||
/// FrameDrawable: #frameColor,frameWidth[,#middleColor]
|
/// BorderDrawable: #borderColor,borderWidth[,#middleColor]
|
||||||
/// or #frameColor,leftBorderWidth,topBorderWidth,rightBorderWidth,bottomBorderWidth[,#middleColor]
|
/// or #borderColor,leftBorderWidth,topBorderWidth,rightBorderWidth,bottomBorderWidth[,#middleColor]
|
||||||
/// e.g. #000000,2,#C0FFFFFF - black frame of width 2 with 75% transparent white middle
|
/// e.g. #000000,2,#C0FFFFFF - black border of width 2 with 75% transparent white middle
|
||||||
/// e.g. #0000FF,2,3,4,5,#FFFFFF - blue frame with left,top,right,bottom borders of width 2,3,4,5 and white inner area
|
/// e.g. #0000FF,2,3,4,5,#FFFFFF - blue border with left,top,right,bottom borders of width 2,3,4,5 and white inner area
|
||||||
static Drawable createColorDrawable(string s) {
|
static Drawable createColorDrawable(string s) {
|
||||||
Log.d("creating color drawable ", s);
|
Log.d("creating color drawable ", s);
|
||||||
|
|
||||||
enum DrawableType { SolidColor, LinearGradient, Frame }
|
enum DrawableType { SolidColor, LinearGradient, Border }
|
||||||
auto type = DrawableType.SolidColor;
|
auto type = DrawableType.SolidColor;
|
||||||
|
|
||||||
string[] items = s.split(',');
|
string[] items = s.split(',');
|
||||||
|
@ -505,7 +513,7 @@ static Drawable createColorDrawable(string s) {
|
||||||
values ~= decodeAngle(item);
|
values ~= decodeAngle(item);
|
||||||
else {
|
else {
|
||||||
values ~= decodeDimension(item);
|
values ~= decodeDimension(item);
|
||||||
type = DrawableType.Frame;
|
type = DrawableType.Border;
|
||||||
}
|
}
|
||||||
if (i >= 6)
|
if (i >= 6)
|
||||||
break;
|
break;
|
||||||
|
@ -515,15 +523,15 @@ static Drawable createColorDrawable(string s) {
|
||||||
return new SolidFillDrawable(values[0]);
|
return new SolidFillDrawable(values[0]);
|
||||||
else if (type == DrawableType.LinearGradient && values.length == 3) // angle and two gradient colors
|
else if (type == DrawableType.LinearGradient && values.length == 3) // angle and two gradient colors
|
||||||
return new GradientDrawable(values[0], values[1], values[2]);
|
return new GradientDrawable(values[0], values[1], values[2]);
|
||||||
else if (type == DrawableType.Frame) {
|
else if (type == DrawableType.Border) {
|
||||||
if (values.length == 2) // frame color and frame width, with transparent inner area - #AARRGGBB,NN
|
if (values.length == 2) // border color and border width, with transparent inner area - #AARRGGBB,NN
|
||||||
return new FrameDrawable(values[0], values[1]);
|
return new BorderDrawable(values[0], values[1]);
|
||||||
else if (values.length == 3) // frame color, frame width, inner area color - #AARRGGBB,NN,#AARRGGBB
|
else if (values.length == 3) // border color, border width, inner area color - #AARRGGBB,NN,#AARRGGBB
|
||||||
return new FrameDrawable(values[0], values[1], values[2]);
|
return new BorderDrawable(values[0], values[1], values[2]);
|
||||||
else if (values.length == 5) // frame color, frame widths for left,top,right,bottom and transparent inner area - #AARRGGBB,NNleft,NNtop,NNright,NNbottom
|
else if (values.length == 5) // border color, border widths for left,top,right,bottom and transparent inner area - #AARRGGBB,NNleft,NNtop,NNright,NNbottom
|
||||||
return new FrameDrawable(values[0], Rect(values[1], values[2], values[3], values[4]));
|
return new BorderDrawable(values[0], Rect(values[1], values[2], values[3], values[4]));
|
||||||
else if (values.length == 6) // frame color, frame widths for left,top,right,bottom, inner area color - #AARRGGBB,NNleft,NNtop,NNright,NNbottom,#AARRGGBB
|
else if (values.length == 6) // border color, border widths for left,top,right,bottom, inner area color - #AARRGGBB,NNleft,NNtop,NNright,NNbottom,#AARRGGBB
|
||||||
return new FrameDrawable(values[0], Rect(values[1], values[2], values[3], values[4]), values[5]);
|
return new BorderDrawable(values[0], Rect(values[1], values[2], values[3], values[4]), values[5]);
|
||||||
}
|
}
|
||||||
Log.e("Invalid drawable string format: ", s);
|
Log.e("Invalid drawable string format: ", s);
|
||||||
return new EmptyDrawable(); // invalid format - just return empty drawable
|
return new EmptyDrawable(); // invalid format - just return empty drawable
|
||||||
|
@ -1122,6 +1130,44 @@ class StateDrawable : Drawable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Drawable which allows to combine together background image, gradient, borders, box shadows, etc.
|
||||||
|
class CombinedDrawable : Drawable {
|
||||||
|
|
||||||
|
DrawableRef background;
|
||||||
|
Drawable border;
|
||||||
|
|
||||||
|
this(string backgroundImageId, string borderDescription) {
|
||||||
|
background = backgroundImageId !is null ? drawableCache.get(backgroundImageId) : new EmptyDrawable;
|
||||||
|
border = borderDescription !is null ? createColorDrawable(borderDescription) : new EmptyDrawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
~this() {
|
||||||
|
destroy(background);
|
||||||
|
destroy(border);
|
||||||
|
background = null;
|
||||||
|
border = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) {
|
||||||
|
// make background image smaller to fit borders
|
||||||
|
Rect backrc = rc;
|
||||||
|
backrc.left += border.padding.left;
|
||||||
|
backrc.top += border.padding.top;
|
||||||
|
backrc.right -= border.padding.right;
|
||||||
|
backrc.bottom -= border.padding.bottom;
|
||||||
|
background.drawTo(buf, backrc, state, tilex0, tiley0);
|
||||||
|
border.drawTo(buf, rc, state, tilex0, tiley0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property override int width() { return background.width + border.padding.left + border.padding.right; }
|
||||||
|
@property override int height() { return background.height + border.padding.top + border.padding.bottom; }
|
||||||
|
@property override Rect padding() {
|
||||||
|
return Rect(background.padding.left + border.padding.left, background.padding.top + border.padding.top,
|
||||||
|
background.padding.right + border.padding.right, background.padding.bottom + border.padding.bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
alias DrawableRef = Ref!Drawable;
|
alias DrawableRef = Ref!Drawable;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1336,7 +1382,7 @@ class DrawableCache {
|
||||||
if (!_drawable)
|
if (!_drawable)
|
||||||
_error = true;
|
_error = true;
|
||||||
} else if (_filename.startsWith("#")) {
|
} else if (_filename.startsWith("#")) {
|
||||||
// color reference #AARRGGBB, e.g. #5599AA, or FrameDrawable description string #frameColor,frameSize,#innerColor
|
// color reference #AARRGGBB, e.g. #5599AA, or a gradient, or BorderDrawable description
|
||||||
_drawable = createColorDrawable(_filename);
|
_drawable = createColorDrawable(_filename);
|
||||||
} else if (_filename.startsWith("{")) {
|
} else if (_filename.startsWith("{")) {
|
||||||
// json in {} with text drawable description
|
// json in {} with text drawable description
|
||||||
|
|
|
@ -324,6 +324,7 @@ protected:
|
||||||
uint _alpha;
|
uint _alpha;
|
||||||
string _fontFace;
|
string _fontFace;
|
||||||
string _backgroundImageId;
|
string _backgroundImageId;
|
||||||
|
string _border;
|
||||||
Rect _padding;
|
Rect _padding;
|
||||||
Rect _margins;
|
Rect _margins;
|
||||||
int _minWidth = SIZE_UNSPECIFIED;
|
int _minWidth = SIZE_UNSPECIFIED;
|
||||||
|
@ -411,7 +412,9 @@ public:
|
||||||
if (!(cast(Style)this)._backgroundDrawable.isNull)
|
if (!(cast(Style)this)._backgroundDrawable.isNull)
|
||||||
return (cast(Style)this)._backgroundDrawable;
|
return (cast(Style)this)._backgroundDrawable;
|
||||||
string image = backgroundImageId;
|
string image = backgroundImageId;
|
||||||
if (image !is null) {
|
if (border !is null) {
|
||||||
|
(cast(Style)this)._backgroundDrawable = new CombinedDrawable(image, border);
|
||||||
|
} else if (image !is null) {
|
||||||
(cast(Style)this)._backgroundDrawable = drawableCache.get(image);
|
(cast(Style)this)._backgroundDrawable = drawableCache.get(image);
|
||||||
} else {
|
} else {
|
||||||
uint color = backgroundColor;
|
uint color = backgroundColor;
|
||||||
|
@ -527,6 +530,15 @@ public:
|
||||||
return parentStyle.fontSize;
|
return parentStyle.fontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// border
|
||||||
|
@property string border() const {
|
||||||
|
if (_border !is null)
|
||||||
|
return _border;
|
||||||
|
else {
|
||||||
|
return parentStyle.border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===================================================
|
//===================================================
|
||||||
// layout parameters: margins / padding
|
// layout parameters: margins / padding
|
||||||
|
|
||||||
|
@ -587,7 +599,7 @@ public:
|
||||||
return parentStyle.backgroundColor;
|
return parentStyle.backgroundColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// font size
|
/// background image id
|
||||||
@property string backgroundImageId() const {
|
@property string backgroundImageId() const {
|
||||||
if (_backgroundImageId == COLOR_DRAWABLE)
|
if (_backgroundImageId == COLOR_DRAWABLE)
|
||||||
return null;
|
return null;
|
||||||
|
@ -779,6 +791,12 @@ public:
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property Style border(string s) {
|
||||||
|
_border = s;
|
||||||
|
_backgroundDrawable.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@property Style margins(Rect rc) {
|
@property Style margins(Rect rc) {
|
||||||
_margins = rc;
|
_margins = rc;
|
||||||
return this;
|
return this;
|
||||||
|
@ -890,6 +908,7 @@ public:
|
||||||
res._alpha = _alpha;
|
res._alpha = _alpha;
|
||||||
res._fontFace = _fontFace;
|
res._fontFace = _fontFace;
|
||||||
res._backgroundImageId = _backgroundImageId;
|
res._backgroundImageId = _backgroundImageId;
|
||||||
|
res._border = _border;
|
||||||
res._padding = _padding;
|
res._padding = _padding;
|
||||||
res._margins = _margins;
|
res._margins = _margins;
|
||||||
res._minWidth = _minWidth;
|
res._minWidth = _minWidth;
|
||||||
|
@ -1019,6 +1038,10 @@ class Theme : Style {
|
||||||
@property override string backgroundImageId() const {
|
@property override string backgroundImageId() const {
|
||||||
return _backgroundImageId;
|
return _backgroundImageId;
|
||||||
}
|
}
|
||||||
|
/// border
|
||||||
|
@property override string border() const {
|
||||||
|
return _border;
|
||||||
|
}
|
||||||
/// minimal width constraint, 0 if limit is not set
|
/// minimal width constraint, 0 if limit is not set
|
||||||
@property override uint minWidth() const {
|
@property override uint minWidth() const {
|
||||||
return _minWidth;
|
return _minWidth;
|
||||||
|
@ -1483,19 +1506,16 @@ bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
|
||||||
//Log.d("Theme: loadStyleAttributes ", style.id, " ", elem.tag.attr);
|
//Log.d("Theme: loadStyleAttributes ", style.id, " ", elem.tag.attr);
|
||||||
if ("backgroundImageId" in elem.tag.attr)
|
if ("backgroundImageId" in elem.tag.attr)
|
||||||
style.backgroundImageId = elem.tag.attr["backgroundImageId"];
|
style.backgroundImageId = elem.tag.attr["backgroundImageId"];
|
||||||
if ("backgroundColor" in elem.tag.attr) {
|
if ("backgroundColor" in elem.tag.attr)
|
||||||
uint col = decodeHexColor(elem.tag.attr["backgroundColor"]);
|
style.backgroundColor = decodeHexColor(elem.tag.attr["backgroundColor"]);
|
||||||
style.backgroundColor = col;
|
|
||||||
//Log.d(" background color=", col);
|
|
||||||
} else {
|
|
||||||
//Log.d(" no background color attr");
|
|
||||||
}
|
|
||||||
if ("textColor" in elem.tag.attr)
|
if ("textColor" in elem.tag.attr)
|
||||||
style.textColor = decodeHexColor(elem.tag.attr["textColor"]);
|
style.textColor = decodeHexColor(elem.tag.attr["textColor"]);
|
||||||
if ("margins" in elem.tag.attr)
|
if ("margins" in elem.tag.attr)
|
||||||
style.margins = decodeRect(elem.tag.attr["margins"]);
|
style.margins = decodeRect(elem.tag.attr["margins"]);
|
||||||
if ("padding" in elem.tag.attr)
|
if ("padding" in elem.tag.attr)
|
||||||
style.padding = decodeRect(elem.tag.attr["padding"]);
|
style.padding = decodeRect(elem.tag.attr["padding"]);
|
||||||
|
if ("border" in elem.tag.attr)
|
||||||
|
style.border = elem.tag.attr["border"];
|
||||||
if ("align" in elem.tag.attr)
|
if ("align" in elem.tag.attr)
|
||||||
style.alignment = decodeAlignment(elem.tag.attr["align"]);
|
style.alignment = decodeAlignment(elem.tag.attr["align"]);
|
||||||
if ("minWidth" in elem.tag.attr)
|
if ("minWidth" in elem.tag.attr)
|
||||||
|
@ -1549,7 +1569,7 @@ bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
|
||||||
if (colorid)
|
if (colorid)
|
||||||
style.setCustomColor(colorid, color);
|
style.setCustomColor(colorid, color);
|
||||||
} else if (item.tag.name.equal("length")) {
|
} else if (item.tag.name.equal("length")) {
|
||||||
// <color id="buttons_panel_color" value="#303080"/>
|
// <length id="overlap" value="2"/>
|
||||||
string lenid = attrValue(item, "id");
|
string lenid = attrValue(item, "id");
|
||||||
string lenvalue = attrValue(item, "value");
|
string lenvalue = attrValue(item, "value");
|
||||||
uint len = decodeDimension(lenvalue);
|
uint len = decodeDimension(lenvalue);
|
||||||
|
|
Loading…
Reference in New Issue