very basic BoxShadowDrawable

This commit is contained in:
gazer 2017-10-13 09:01:25 +03:00 committed by dayllenger
parent fe0e86d58b
commit 5310d958b7
2 changed files with 66 additions and 4 deletions

View File

@ -840,6 +840,11 @@ class DrawBuf : RefCountedObject {
}
}
/// Apply Gaussian blur on the image
void blur(uint blurSize) {
// TODO
}
/// create drawbuf with copy of current buffer with changed colors (returns this if not supported)
DrawBuf transformColors(ref ColorTransform transform) {
return this;
@ -858,20 +863,26 @@ class DrawBuf : RefCountedObject {
alias DrawBufRef = Ref!DrawBuf;
/// RAII setting/restoring of clip rectangle
/// RAII setting/restoring of a DrawBuf clip rectangle
struct ClipRectSaver {
private DrawBuf _buf;
private Rect _oldClipRect;
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;
_oldClipRect = buf.clipRect;
_oldAlpha = buf.alpha;
buf.intersectClipRect(newClipRect);
if (intersect)
buf.intersectClipRect(newClipRect);
else
buf.clipRect = newClipRect;
if (newAlpha)
buf.addAlpha(newAlpha);
}
/// restore previous clip rectangle
~this() {
_buf.clipRect = _oldClipRect;
_buf.alpha = _oldAlpha;

View File

@ -408,6 +408,46 @@ class BorderDrawable : Drawable {
}
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 = 2 * blurSize + 3;
texture = new ColorDrawBuf(size, size); // TODO: get from/put to cache
// clear
texture.fill(0xFFFFFFFF);
// 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) {
// move and expand the shadow
rc.left += _offsetX - _blurSize;
rc.right += _offsetX + _blurSize;
rc.top += _offsetY - _blurSize;
rc.bottom += _offsetY + _blurSize;
// apply new clipping to DrawBuf to draw outside of the widget
auto saver = ClipRectSaver(buf, rc, 0, false);
buf.drawRescaled(rc, texture, Rect(0, 0, texture.width, texture.height)); // TODO: nine-patch
}
@property override int width() { return 1; }
@property override int height() { return 1; }
}
enum DimensionUnits {
pixels,
points,
@ -504,6 +544,7 @@ static Drawable createColorDrawable(string s) {
string[] items = s.split(',');
uint[] values;
int[] ivalues;
if (items.length != 0) {
if (items[0] == "#linear")
type = DrawableType.LinearGradient;
@ -519,6 +560,8 @@ static Drawable createColorDrawable(string s) {
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)
@ -539,6 +582,13 @@ static Drawable createColorDrawable(string s) {
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
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);
return new EmptyDrawable(); // invalid format - just return empty drawable
@ -1155,6 +1205,7 @@ class CombinedDrawable : Drawable {
}
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
Rect backrc = rc;
backrc.left += border.padding.left;