mirror of https://github.com/buggins/dlangui.git
commit
29ff80b049
|
@ -858,20 +858,26 @@ class DrawBuf : RefCountedObject {
|
||||||
|
|
||||||
alias DrawBufRef = Ref!DrawBuf;
|
alias DrawBufRef = Ref!DrawBuf;
|
||||||
|
|
||||||
/// RAII setting/restoring of clip rectangle
|
/// RAII setting/restoring of a DrawBuf clip rectangle
|
||||||
struct ClipRectSaver {
|
struct ClipRectSaver {
|
||||||
private DrawBuf _buf;
|
private DrawBuf _buf;
|
||||||
private Rect _oldClipRect;
|
private Rect _oldClipRect;
|
||||||
private uint _oldAlpha;
|
private uint _oldAlpha;
|
||||||
/// apply (intersect) new clip rectangle and alpha to draw buf; restore
|
|
||||||
this(DrawBuf buf, ref Rect newClipRect, uint newAlpha = 0) {
|
/// apply (intersect) new clip rectangle and alpha to draw buf
|
||||||
|
/// set `intersect` parameter to `false`, if you want to draw something outside of the widget
|
||||||
|
this(DrawBuf buf, ref Rect newClipRect, uint newAlpha = 0, bool intersect = true) {
|
||||||
_buf = buf;
|
_buf = buf;
|
||||||
_oldClipRect = buf.clipRect;
|
_oldClipRect = buf.clipRect;
|
||||||
_oldAlpha = buf.alpha;
|
_oldAlpha = buf.alpha;
|
||||||
buf.intersectClipRect(newClipRect);
|
if (intersect)
|
||||||
|
buf.intersectClipRect(newClipRect);
|
||||||
|
else
|
||||||
|
buf.clipRect = newClipRect;
|
||||||
if (newAlpha)
|
if (newAlpha)
|
||||||
buf.addAlpha(newAlpha);
|
buf.addAlpha(newAlpha);
|
||||||
}
|
}
|
||||||
|
/// restore previous clip rectangle
|
||||||
~this() {
|
~this() {
|
||||||
_buf.clipRect = _oldClipRect;
|
_buf.clipRect = _oldClipRect;
|
||||||
_buf.alpha = _oldAlpha;
|
_buf.alpha = _oldAlpha;
|
||||||
|
@ -1224,7 +1230,6 @@ class ColorDrawBufBase : DrawBuf {
|
||||||
row[x] = blendARGB(row[x], color, alpha);
|
row[x] = blendARGB(row[x], color, alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class GrayDrawBuf : DrawBuf {
|
class GrayDrawBuf : DrawBuf {
|
||||||
|
@ -1469,6 +1474,7 @@ class GrayDrawBuf : DrawBuf {
|
||||||
|
|
||||||
class ColorDrawBuf : ColorDrawBufBase {
|
class ColorDrawBuf : ColorDrawBufBase {
|
||||||
uint[] _buf;
|
uint[] _buf;
|
||||||
|
|
||||||
/// create ARGB8888 draw buf of specified width and height
|
/// create ARGB8888 draw buf of specified width and height
|
||||||
this(int width, int height) {
|
this(int width, int height) {
|
||||||
resize(width, height);
|
resize(width, height);
|
||||||
|
@ -1525,11 +1531,13 @@ class ColorDrawBuf : ColorDrawBufBase {
|
||||||
pixel ^= 0xFF000000;
|
pixel ^= 0xFF000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override uint * scanLine(int y) {
|
override uint * scanLine(int y) {
|
||||||
if (y >= 0 && y < _dy)
|
if (y >= 0 && y < _dy)
|
||||||
return _buf.ptr + _dx * y;
|
return _buf.ptr + _dx * y;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
override void resize(int width, int height) {
|
override void resize(int width, int height) {
|
||||||
if (_dx == width && _dy == height)
|
if (_dx == width && _dy == height)
|
||||||
return;
|
return;
|
||||||
|
@ -1538,6 +1546,7 @@ class ColorDrawBuf : ColorDrawBufBase {
|
||||||
_buf.length = _dx * _dy;
|
_buf.length = _dx * _dy;
|
||||||
resetClipping();
|
resetClipping();
|
||||||
}
|
}
|
||||||
|
|
||||||
override void fill(uint color) {
|
override void fill(uint color) {
|
||||||
if (hasClipping) {
|
if (hasClipping) {
|
||||||
fillRect(_clipRect, color);
|
fillRect(_clipRect, color);
|
||||||
|
@ -1548,6 +1557,7 @@ class ColorDrawBuf : ColorDrawBufBase {
|
||||||
foreach(i; 0 .. len)
|
foreach(i; 0 .. len)
|
||||||
p[i] = color;
|
p[i] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
override DrawBuf transformColors(ref ColorTransform transform) {
|
override DrawBuf transformColors(ref ColorTransform transform) {
|
||||||
if (transform.empty)
|
if (transform.empty)
|
||||||
return this;
|
return this;
|
||||||
|
@ -1572,6 +1582,71 @@ class ColorDrawBuf : ColorDrawBufBase {
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Apply Gaussian blur on the image
|
||||||
|
void blur(uint blurSize) {
|
||||||
|
if (blurSize == 0)
|
||||||
|
return; // trivial case
|
||||||
|
|
||||||
|
// utility functions to get and set color
|
||||||
|
float[4] get(uint[] buf, uint x, uint y) {
|
||||||
|
uint c = buf[x + y * _dx];
|
||||||
|
float a = 255 - (c >> 24);
|
||||||
|
float r = (c >> 16) & 0xFF;
|
||||||
|
float g = (c >> 8) & 0xFF;
|
||||||
|
float b = (c >> 0) & 0xFF;
|
||||||
|
return [r, g, b, a];
|
||||||
|
}
|
||||||
|
void set(uint[] buf, uint x, uint y, float[4] c) {
|
||||||
|
buf[x + y * _dx] = makeRGBA(c[0], c[1], c[2], 255 - c[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
import std.algorithm : max, min;
|
||||||
|
import std.math;
|
||||||
|
|
||||||
|
// Gaussian function
|
||||||
|
float weight(in float x, in float sigma) pure nothrow {
|
||||||
|
enum inv_sqrt_2pi = 1 / sqrt(2 * PI);
|
||||||
|
return exp(- x ^^ 2 / (2 * sigma ^^ 2)) * inv_sqrt_2pi / sigma;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blurOneDimension(uint[] bufIn, uint[] bufOut, uint blurSize, bool horizontally) {
|
||||||
|
|
||||||
|
float sigma = blurSize > 2 ? blurSize / 3.0 : blurSize / 2.0;
|
||||||
|
|
||||||
|
foreach (x; 0 .. _dx) {
|
||||||
|
foreach (y; 0 .. _dy) {
|
||||||
|
float[4] c;
|
||||||
|
c[] = 0;
|
||||||
|
|
||||||
|
float sum = 0;
|
||||||
|
foreach (int i; 1 .. blurSize + 1) {
|
||||||
|
float[4] c1 = get(bufIn,
|
||||||
|
horizontally ? min(x + i, _dx - 1) : x,
|
||||||
|
horizontally ? y : min(y + i, _dy - 1)
|
||||||
|
);
|
||||||
|
float[4] c2 = get(bufIn,
|
||||||
|
horizontally ? max(x - i, 0) : x,
|
||||||
|
horizontally ? y : max(y - i, 0)
|
||||||
|
);
|
||||||
|
float w = weight(i, sigma);
|
||||||
|
c[] += (c1[] + c2[]) * w;
|
||||||
|
sum += 2 * w;
|
||||||
|
}
|
||||||
|
c[] += get(bufIn, x, y)[] * (1 - sum);
|
||||||
|
set(bufOut, x, y, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// intermediate buffer for image
|
||||||
|
uint[] tmpbuf;
|
||||||
|
tmpbuf.length = _buf.length;
|
||||||
|
// do horizontal blur
|
||||||
|
blurOneDimension(_buf, tmpbuf, blurSize, true);
|
||||||
|
// then do vertical blur
|
||||||
|
blurOneDimension(tmpbuf, _buf, blurSize, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -408,6 +408,71 @@ class BorderDrawable : Drawable {
|
||||||
}
|
}
|
||||||
deprecated alias FrameDrawable = BorderDrawable;
|
deprecated alias FrameDrawable = BorderDrawable;
|
||||||
|
|
||||||
|
/// box shadows, can be blurred
|
||||||
|
class BoxShadowDrawable : Drawable {
|
||||||
|
protected int _offsetX;
|
||||||
|
protected int _offsetY;
|
||||||
|
protected int _blurSize;
|
||||||
|
protected uint _color;
|
||||||
|
protected Ref!ColorDrawBuf texture;
|
||||||
|
|
||||||
|
this(int offsetX, int offsetY, uint blurSize = 0, uint color = 0x0) {
|
||||||
|
_offsetX = offsetX;
|
||||||
|
_offsetY = offsetY;
|
||||||
|
_blurSize = blurSize;
|
||||||
|
_color = color;
|
||||||
|
// now create a texture which will contain the shadow
|
||||||
|
uint size = 4 * blurSize + 1;
|
||||||
|
texture = new ColorDrawBuf(size, size); // TODO: get from/put to cache
|
||||||
|
// clear
|
||||||
|
texture.fill(color | 0xFF000000);
|
||||||
|
// draw a square in center of the texture
|
||||||
|
texture.fillRect(Rect(blurSize, blurSize, size - blurSize, size - blurSize), color);
|
||||||
|
// blur the square
|
||||||
|
texture.blur(blurSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
override void drawTo(DrawBuf buf, Rect rc, uint state = 0, int tilex0 = 0, int tiley0 = 0) {
|
||||||
|
// this is a size of blurred part
|
||||||
|
uint b = _blurSize + _blurSize / 2 + 1;
|
||||||
|
// move and expand the shadow
|
||||||
|
rc.left += _offsetX - b;
|
||||||
|
rc.top += _offsetY - b;
|
||||||
|
rc.right += _offsetX + b;
|
||||||
|
rc.bottom += _offsetY + b;
|
||||||
|
|
||||||
|
// apply new clipping to the DrawBuf to draw outside of the widget
|
||||||
|
auto saver = ClipRectSaver(buf, rc, 0, false);
|
||||||
|
|
||||||
|
if (_blurSize > 0) {
|
||||||
|
// Manual nine-patch
|
||||||
|
uint w = texture.width;
|
||||||
|
uint h = texture.height;
|
||||||
|
|
||||||
|
buf.drawFragment(rc.left, rc.top, texture, Rect(0, 0, b, b)); // top left
|
||||||
|
buf.drawRescaled(Rect(rc.left + b, rc.top, rc.right - b, rc.top + b), texture, Rect(b, 0, w - b, b)); // top center
|
||||||
|
buf.drawFragment(rc.right - b, rc.top, texture, Rect(w - b, 0, w, b)); // top right
|
||||||
|
|
||||||
|
buf.drawRescaled(Rect(rc.left, rc.top + b, rc.left + b, rc.bottom - b), texture, Rect(0, b, b, h - b)); // middle left
|
||||||
|
buf.drawRescaled(Rect(rc.left + b, rc.top + b, rc.right - b, rc.bottom - b), texture, Rect(b, b, w - b, h - b)); // middle center
|
||||||
|
buf.drawRescaled(Rect(rc.right - b, rc.top + b, rc.right, rc.bottom - b), texture, Rect(w - b, b, w, h - b)); // middle right
|
||||||
|
|
||||||
|
buf.drawFragment(rc.left, rc.bottom - b, texture, Rect(0, h - b, b, h)); // bottom left
|
||||||
|
buf.drawRescaled(Rect(rc.left + b, rc.bottom - b, rc.right - b, rc.bottom), texture, Rect(b, h - b, w - b, h)); // bottom center
|
||||||
|
buf.drawFragment(rc.right - b, rc.bottom - b, texture, Rect(w - b, h - b, w, h)); // bottom right
|
||||||
|
|
||||||
|
// debug
|
||||||
|
//~ buf.drawFragment(rc.left, rc.top, texture, Rect(0, 0, w, h));
|
||||||
|
} else {
|
||||||
|
buf.fillRect(rc, _color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@property override int width() { return 1; }
|
||||||
|
@property override int height() { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum DimensionUnits {
|
enum DimensionUnits {
|
||||||
pixels,
|
pixels,
|
||||||
points,
|
points,
|
||||||
|
@ -491,32 +556,42 @@ static if (BACKEND_CONSOLE) {
|
||||||
/// decode solid color / gradient / border 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
|
||||||
/// BorderDrawable: #borderColor,borderWidth[,#middleColor]
|
/// BorderDrawable: #border,borderColor,borderWidth[,middleColor]
|
||||||
/// or #borderColor,leftBorderWidth,topBorderWidth,rightBorderWidth,bottomBorderWidth[,#middleColor]
|
/// or #border,borderColor,leftBorderWidth,topBorderWidth,rightBorderWidth,bottomBorderWidth[,middleColor]
|
||||||
/// e.g. #000000,2,#C0FFFFFF - black border of width 2 with 75% transparent white middle
|
/// e.g. #border,#000000,2,#C0FFFFFF - black border of width 2 with 75% transparent white middle
|
||||||
/// 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
|
/// e.g. #border,#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, Border }
|
enum DrawableType { SolidColor, LinearGradient, Border, BoxShadow }
|
||||||
auto type = DrawableType.SolidColor;
|
auto type = DrawableType.SolidColor;
|
||||||
|
|
||||||
string[] items = s.split(',');
|
string[] items = s.split(',');
|
||||||
uint[] values;
|
uint[] values;
|
||||||
foreach (i, item; items) {
|
int[] ivalues;
|
||||||
if (item == "#linear")
|
if (items.length != 0) {
|
||||||
|
if (items[0] == "#linear")
|
||||||
type = DrawableType.LinearGradient;
|
type = DrawableType.LinearGradient;
|
||||||
else if (item.startsWith("#"))
|
else if (items[0] == "#border")
|
||||||
values ~= decodeHexColor(item);
|
|
||||||
else if (item.endsWith("deg"))
|
|
||||||
values ~= decodeAngle(item);
|
|
||||||
else {
|
|
||||||
values ~= decodeDimension(item);
|
|
||||||
type = DrawableType.Border;
|
type = DrawableType.Border;
|
||||||
|
else if (items[0] == "#box-shadow")
|
||||||
|
type = DrawableType.BoxShadow;
|
||||||
|
else if (items[0].startsWith("#"))
|
||||||
|
values ~= decodeHexColor(items[0]);
|
||||||
|
|
||||||
|
foreach (i, item; items[1 .. $]) {
|
||||||
|
if (item.startsWith("#"))
|
||||||
|
values ~= decodeHexColor(item);
|
||||||
|
else if (item.endsWith("deg"))
|
||||||
|
values ~= decodeAngle(item);
|
||||||
|
else if (type == DrawableType.BoxShadow) // offsets may be negative
|
||||||
|
ivalues ~= item.startsWith("-") ? -decodeDimension(item) : decodeDimension(item);
|
||||||
|
else
|
||||||
|
values ~= decodeDimension(item);
|
||||||
|
if (i >= 6)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (i >= 6)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == DrawableType.SolidColor && values.length == 1) // only color #AARRGGBB
|
if (type == DrawableType.SolidColor && values.length == 1) // only color #AARRGGBB
|
||||||
|
@ -532,6 +607,13 @@ static Drawable createColorDrawable(string s) {
|
||||||
return new BorderDrawable(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) // border color, border 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 BorderDrawable(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]);
|
||||||
|
} else if (type == DrawableType.BoxShadow) {
|
||||||
|
if (ivalues.length == 2 && values.length == 0) // shadow X and Y offsets
|
||||||
|
return new BoxShadowDrawable(ivalues[0], ivalues[1]);
|
||||||
|
else if (ivalues.length == 3 && values.length == 0) // shadow offsets and blur size
|
||||||
|
return new BoxShadowDrawable(ivalues[0], ivalues[1], ivalues[2]);
|
||||||
|
else if (ivalues.length == 3 && values.length == 1) // shadow offsets, blur size and color
|
||||||
|
return new BoxShadowDrawable(ivalues[0], ivalues[1], ivalues[2], values[0]);
|
||||||
}
|
}
|
||||||
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
|
||||||
|
@ -1133,19 +1215,22 @@ class StateDrawable : Drawable {
|
||||||
/// Drawable which allows to combine together background image, gradient, borders, box shadows, etc.
|
/// Drawable which allows to combine together background image, gradient, borders, box shadows, etc.
|
||||||
class CombinedDrawable : Drawable {
|
class CombinedDrawable : Drawable {
|
||||||
|
|
||||||
|
DrawableRef boxShadow;
|
||||||
DrawableRef background;
|
DrawableRef background;
|
||||||
DrawableRef border;
|
DrawableRef border;
|
||||||
|
|
||||||
this(uint backgroundColor, string backgroundImageId, string borderDescription) {
|
this(uint backgroundColor, string backgroundImageId, string borderDescription, string boxShadowDescription) {
|
||||||
|
boxShadow = boxShadowDescription !is null ? drawableCache.get("#box-shadow," ~ boxShadowDescription) : new EmptyDrawable;
|
||||||
background =
|
background =
|
||||||
(backgroundImageId !is null) ? drawableCache.get(backgroundImageId) :
|
(backgroundImageId !is null) ? drawableCache.get(backgroundImageId) :
|
||||||
(!backgroundColor.isFullyTransparentColor) ? new SolidFillDrawable(backgroundColor) : null;
|
(!backgroundColor.isFullyTransparentColor) ? new SolidFillDrawable(backgroundColor) : null;
|
||||||
if (background is null)
|
if (background is null)
|
||||||
background = new EmptyDrawable;
|
background = new EmptyDrawable;
|
||||||
border = borderDescription !is null ? drawableCache.get(borderDescription) : new EmptyDrawable;
|
border = borderDescription !is null ? drawableCache.get("#border," ~ borderDescription) : new EmptyDrawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
boxShadow.drawTo(buf, rc, state, tilex0, tiley0);
|
||||||
// make background image smaller to fit borders
|
// make background image smaller to fit borders
|
||||||
Rect backrc = rc;
|
Rect backrc = rc;
|
||||||
backrc.left += border.padding.left;
|
backrc.left += border.padding.left;
|
||||||
|
|
|
@ -324,6 +324,7 @@ protected:
|
||||||
uint _alpha;
|
uint _alpha;
|
||||||
string _fontFace;
|
string _fontFace;
|
||||||
string _backgroundImageId;
|
string _backgroundImageId;
|
||||||
|
string _boxShadow;
|
||||||
string _border;
|
string _border;
|
||||||
Rect _padding;
|
Rect _padding;
|
||||||
Rect _margins;
|
Rect _margins;
|
||||||
|
@ -413,8 +414,10 @@ public:
|
||||||
return (cast(Style)this)._backgroundDrawable;
|
return (cast(Style)this)._backgroundDrawable;
|
||||||
string image = backgroundImageId;
|
string image = backgroundImageId;
|
||||||
uint color = backgroundColor;
|
uint color = backgroundColor;
|
||||||
if (border !is null) {
|
string borders = border;
|
||||||
(cast(Style)this)._backgroundDrawable = new CombinedDrawable(color, image, border);
|
string shadows = boxShadow;
|
||||||
|
if (borders !is null || shadows !is null) {
|
||||||
|
(cast(Style)this)._backgroundDrawable = new CombinedDrawable(color, image, borders, shadows);
|
||||||
} else if (image !is null) {
|
} else if (image !is null) {
|
||||||
(cast(Style)this)._backgroundDrawable = drawableCache.get(image);
|
(cast(Style)this)._backgroundDrawable = drawableCache.get(image);
|
||||||
} else {
|
} else {
|
||||||
|
@ -530,6 +533,15 @@ public:
|
||||||
return parentStyle.fontSize;
|
return parentStyle.fontSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// box shadow
|
||||||
|
@property string boxShadow() const {
|
||||||
|
if (_boxShadow !is null)
|
||||||
|
return _boxShadow;
|
||||||
|
else {
|
||||||
|
return parentStyle.boxShadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// border
|
/// border
|
||||||
@property string border() const {
|
@property string border() const {
|
||||||
if (_border !is null)
|
if (_border !is null)
|
||||||
|
@ -791,6 +803,12 @@ public:
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@property Style boxShadow(string s) {
|
||||||
|
_boxShadow = s;
|
||||||
|
_backgroundDrawable.clear();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@property Style border(string s) {
|
@property Style border(string s) {
|
||||||
_border = s;
|
_border = s;
|
||||||
_backgroundDrawable.clear();
|
_backgroundDrawable.clear();
|
||||||
|
@ -908,6 +926,7 @@ public:
|
||||||
res._alpha = _alpha;
|
res._alpha = _alpha;
|
||||||
res._fontFace = _fontFace;
|
res._fontFace = _fontFace;
|
||||||
res._backgroundImageId = _backgroundImageId;
|
res._backgroundImageId = _backgroundImageId;
|
||||||
|
res._boxShadow = _boxShadow;
|
||||||
res._border = _border;
|
res._border = _border;
|
||||||
res._padding = _padding;
|
res._padding = _padding;
|
||||||
res._margins = _margins;
|
res._margins = _margins;
|
||||||
|
@ -1038,6 +1057,10 @@ class Theme : Style {
|
||||||
@property override string backgroundImageId() const {
|
@property override string backgroundImageId() const {
|
||||||
return _backgroundImageId;
|
return _backgroundImageId;
|
||||||
}
|
}
|
||||||
|
/// box shadow
|
||||||
|
@property override string boxShadow() const {
|
||||||
|
return _boxShadow;
|
||||||
|
}
|
||||||
/// border
|
/// border
|
||||||
@property override string border() const {
|
@property override string border() const {
|
||||||
return _border;
|
return _border;
|
||||||
|
@ -1527,6 +1550,11 @@ string sanitizeBorderProperty(string s) pure {
|
||||||
return cast(string)res;
|
return cast(string)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// remove superfluous space characters from a box shadow property
|
||||||
|
string sanitizeBoxShadowProperty(string s) pure {
|
||||||
|
return sanitizeBorderProperty(s);
|
||||||
|
}
|
||||||
|
|
||||||
/// load style attributes from XML element
|
/// load style attributes from XML element
|
||||||
bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
|
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);
|
||||||
|
@ -1542,6 +1570,8 @@ bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
|
||||||
style.padding = decodeRect(elem.tag.attr["padding"]);
|
style.padding = decodeRect(elem.tag.attr["padding"]);
|
||||||
if ("border" in elem.tag.attr)
|
if ("border" in elem.tag.attr)
|
||||||
style.border = sanitizeBorderProperty(elem.tag.attr["border"]);
|
style.border = sanitizeBorderProperty(elem.tag.attr["border"]);
|
||||||
|
if ("boxShadow" in elem.tag.attr)
|
||||||
|
style.boxShadow = sanitizeBoxShadowProperty(elem.tag.attr["boxShadow"]);
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue