mirror of https://github.com/buggins/dlangui.git
implement APLHA support for widgets; use semitransparency for icons in disabled menu items; reduce excessive logging
This commit is contained in:
parent
6d518ed5c0
commit
8a04d6aea6
|
@ -23,6 +23,11 @@
|
|||
<Includes>
|
||||
<Includes>
|
||||
<Path>../../src</Path>
|
||||
<Path>../../../DerelictUtil/source</Path>
|
||||
<Path>../../../DerelictFI/source</Path>
|
||||
<Path>../../../DerelictFT/source</Path>
|
||||
<Path>../../../DerelictSDL2/source</Path>
|
||||
<Path>../../../DerelictGL3/source</Path>
|
||||
</Includes>
|
||||
</Includes>
|
||||
</PropertyGroup>
|
||||
|
@ -36,6 +41,12 @@
|
|||
<Target>Executable</Target>
|
||||
<Externalconsole>true</Externalconsole>
|
||||
<DebugLevel>0</DebugLevel>
|
||||
<VersionIds>
|
||||
<VersionIds>
|
||||
<String>USE_SDL</String>
|
||||
<String>USE_OPENGL</String>
|
||||
</VersionIds>
|
||||
</VersionIds>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<OutputPath>bin\Release</OutputPath>
|
||||
|
|
|
@ -43,6 +43,15 @@ uint blendARGB(uint dst, uint src, uint alpha) {
|
|||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
/// blend two alpha values 0..255 (255 is fully transparent, 0 is opaque)
|
||||
uint blendAlpha(uint a1, uint a2) {
|
||||
if (!a1)
|
||||
return a2;
|
||||
if (!a2)
|
||||
return a1;
|
||||
return (((a1 ^ 0xFF) * (a2 ^ 0xFF)) >> 8) ^ 0xFF;
|
||||
}
|
||||
|
||||
ubyte rgbToGray(uint color) {
|
||||
uint srcr = (color >> 16) & 0xFF;
|
||||
uint srcg = (color >> 8) & 0xFF;
|
||||
|
@ -127,6 +136,33 @@ version (USE_OPENGL) {
|
|||
class DrawBuf : RefCountedObject {
|
||||
protected Rect _clipRect;
|
||||
protected NinePatch * _ninePatch;
|
||||
protected uint _alpha;
|
||||
|
||||
/// get current alpha setting (to be applied to all drawing operations)
|
||||
@property uint alpha() { return _alpha; }
|
||||
/// set new alpha setting (to be applied to all drawing operations)
|
||||
@property void alpha(uint alpha) {
|
||||
_alpha = alpha;
|
||||
if (_alpha > 0xFF)
|
||||
_alpha = 0xFF;
|
||||
}
|
||||
|
||||
/// apply additional transparency to current drawbuf alpha value
|
||||
void addAlpha(uint alpha) {
|
||||
_alpha = blendAlpha(_alpha, alpha);
|
||||
}
|
||||
|
||||
/// applies current drawbuf alpha to argb color value
|
||||
uint applyAlpha(uint argb) {
|
||||
if (!_alpha)
|
||||
return argb; // no drawbuf alpha
|
||||
uint a1 = (argb >> 24) & 0xFF;
|
||||
if (a1 == 0xFF)
|
||||
return argb; // fully transparent
|
||||
uint a2 = _alpha & 0xFF;
|
||||
uint a = blendAlpha(a1, a2);
|
||||
return (argb & 0xFFFFFF) | (a << 24);
|
||||
}
|
||||
|
||||
version (USE_OPENGL) {
|
||||
protected uint _id;
|
||||
|
@ -291,7 +327,7 @@ class DrawBuf : RefCountedObject {
|
|||
return !rc.empty() && !rc2.empty();
|
||||
}
|
||||
/// reserved for hardware-accelerated drawing - begins drawing batch
|
||||
void beforeDrawing() { }
|
||||
void beforeDrawing() { _alpha = 0; }
|
||||
/// reserved for hardware-accelerated drawing - ends drawing batch
|
||||
void afterDrawing() { }
|
||||
/// returns buffer bits per pixel
|
||||
|
@ -372,13 +408,18 @@ alias DrawBufRef = Ref!DrawBuf;
|
|||
struct ClipRectSaver {
|
||||
private DrawBuf _buf;
|
||||
private Rect _oldClipRect;
|
||||
this(DrawBuf buf, ref Rect newClipRect) {
|
||||
private uint _oldAlpha;
|
||||
this(DrawBuf buf, ref Rect newClipRect, uint newAlpha = 0) {
|
||||
_buf = buf;
|
||||
_oldClipRect = buf.clipRect;
|
||||
_oldAlpha = buf.alpha;
|
||||
buf.intersectClipRect(newClipRect);
|
||||
if (newAlpha)
|
||||
buf.addAlpha(newAlpha);
|
||||
}
|
||||
~this() {
|
||||
_buf.clipRect = _oldClipRect;
|
||||
_buf.alpha = _oldAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,7 +448,7 @@ class ColorDrawBufBase : DrawBuf {
|
|||
uint * dstrow = scanLine(dstrect.top + yy) + dstrect.left;
|
||||
for (int i = 0; i < dx; i++) {
|
||||
uint pixel = srcrow[i];
|
||||
uint alpha = pixel >> 24;
|
||||
uint alpha = blendAlpha(_alpha, pixel >> 24);
|
||||
if (!alpha)
|
||||
dstrow[i] = pixel;
|
||||
else if (alpha < 255) {
|
||||
|
@ -447,8 +488,8 @@ class ColorDrawBufBase : DrawBuf {
|
|||
for (int x = 0; x < dx; x++) {
|
||||
uint srcpixel = srcrow[xmap[x]];
|
||||
uint dstpixel = dstrow[x];
|
||||
uint alpha = (srcpixel >> 24) & 255;
|
||||
if (!alpha)
|
||||
uint alpha = blendAlpha(_alpha, srcpixel >> 24);
|
||||
if (!alpha)
|
||||
dstrow[x] = srcpixel;
|
||||
else if (alpha < 255) {
|
||||
// apply blending
|
||||
|
@ -537,6 +578,7 @@ class ColorDrawBufBase : DrawBuf {
|
|||
int srcdx = glyph.blackBoxX;
|
||||
int srcdy = glyph.blackBoxY;
|
||||
bool clipping = !_clipRect.empty();
|
||||
color = applyAlpha(color);
|
||||
for (int yy = 0; yy < srcdy; yy++) {
|
||||
int liney = y + yy;
|
||||
if (clipping && (liney < _clipRect.top || liney >= _clipRect.bottom))
|
||||
|
|
|
@ -350,7 +350,7 @@ class FreeTypeFont : Font {
|
|||
// Log.d("ft _glyphCache.find took ", duration / 10, " ns");
|
||||
if (found !is null)
|
||||
return found;
|
||||
Log.v("Glyph ", ch, " is not found in cache, getting from font");
|
||||
//Log.v("Glyph ", ch, " is not found in cache, getting from font");
|
||||
FT_UInt index;
|
||||
FreeTypeFontFile file;
|
||||
if (!findGlyph(ch, 0, index, file)) {
|
||||
|
|
|
@ -53,6 +53,7 @@ class GLDrawBuf : DrawBuf {
|
|||
|
||||
/// reserved for hardware-accelerated drawing - begins drawing batch
|
||||
override void beforeDrawing() {
|
||||
_alpha = 0;
|
||||
if (_scene !is null) {
|
||||
_scene.reset();
|
||||
}
|
||||
|
@ -77,12 +78,12 @@ class GLDrawBuf : DrawBuf {
|
|||
/// fill the whole buffer with solid color (no clipping applied)
|
||||
override void fill(uint color) {
|
||||
assert(_scene !is null);
|
||||
_scene.add(new SolidRectSceneItem(Rect(0, 0, _dx, _dy), color));
|
||||
_scene.add(new SolidRectSceneItem(Rect(0, 0, _dx, _dy), applyAlpha(color)));
|
||||
}
|
||||
/// fill rectangle with solid color (clipping is applied)
|
||||
override void fillRect(Rect rc, uint color) {
|
||||
assert(_scene !is null);
|
||||
_scene.add(new SolidRectSceneItem(rc, color));
|
||||
_scene.add(new SolidRectSceneItem(rc, applyAlpha(color)));
|
||||
}
|
||||
/// draw 8bit alpha image - usually font glyph using specified color (clipping is applied)
|
||||
override void drawGlyph(int x, int y, Glyph * glyph, uint color) {
|
||||
|
@ -93,7 +94,7 @@ class GLDrawBuf : DrawBuf {
|
|||
if (applyClipping(dstrect, srcrect)) {
|
||||
if (!glGlyphCache.get(glyph.id))
|
||||
glGlyphCache.put(glyph);
|
||||
_scene.add(new GlyphSceneItem(glyph.id, dstrect, srcrect, color, null));
|
||||
_scene.add(new GlyphSceneItem(glyph.id, dstrect, srcrect, applyAlpha(color), null));
|
||||
}
|
||||
}
|
||||
/// draw source buffer rectangle contents to destination buffer
|
||||
|
@ -104,7 +105,7 @@ class GLDrawBuf : DrawBuf {
|
|||
if (applyClipping(dstrect, srcrect)) {
|
||||
if (!glImageCache.get(src.id))
|
||||
glImageCache.put(src);
|
||||
_scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0));
|
||||
_scene.add(new TextureSceneItem(src.id, dstrect, srcrect, applyAlpha(0xFFFFFF), 0, null, 0));
|
||||
}
|
||||
}
|
||||
/// draw source buffer rectangle contents to destination buffer rectangle applying rescaling
|
||||
|
@ -114,7 +115,7 @@ class GLDrawBuf : DrawBuf {
|
|||
if (applyClipping(dstrect, srcrect)) {
|
||||
if (!glImageCache.get(src.id))
|
||||
glImageCache.put(src);
|
||||
_scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0));
|
||||
_scene.add(new TextureSceneItem(src.id, dstrect, srcrect, applyAlpha(0xFFFFFF), 0, null, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,8 @@ class Window {
|
|||
p.animate(interval);
|
||||
}
|
||||
|
||||
static immutable int PERFORMANCE_LOGGING_THRESHOLD_MS = 20;
|
||||
|
||||
void onDraw(DrawBuf buf) {
|
||||
bool needDraw = false;
|
||||
bool needLayout = false;
|
||||
|
@ -173,10 +175,12 @@ class Window {
|
|||
long measureStart = currentTimeMillis;
|
||||
measure();
|
||||
long measureEnd = currentTimeMillis;
|
||||
Log.d("measure took ", measureEnd - measureStart, " ms");
|
||||
if (measureEnd - measureStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
|
||||
Log.d("measure took ", measureEnd - measureStart, " ms");
|
||||
layout();
|
||||
long layoutEnd = currentTimeMillis;
|
||||
Log.d("layout took ", layoutEnd - measureEnd, " ms");
|
||||
if (layoutEnd - measureEnd > PERFORMANCE_LOGGING_THRESHOLD_MS)
|
||||
Log.d("layout took ", layoutEnd - measureEnd, " ms");
|
||||
//checkUpdateNeeded(needDraw, needLayout, animationActive);
|
||||
}
|
||||
long drawStart = currentTimeMillis;
|
||||
|
@ -186,7 +190,8 @@ class Window {
|
|||
foreach(p; _popups)
|
||||
p.onDraw(buf);
|
||||
long drawEnd = currentTimeMillis;
|
||||
Log.d("draw took ", drawEnd - drawStart, " ms");
|
||||
if (drawEnd - drawStart > PERFORMANCE_LOGGING_THRESHOLD_MS)
|
||||
Log.d("draw took ", drawEnd - drawStart, " ms");
|
||||
lastDrawTs = ts;
|
||||
if (animationActive)
|
||||
scheduleAnimation();
|
||||
|
@ -291,9 +296,9 @@ class Window {
|
|||
}
|
||||
// if not processed by children, offer event to root
|
||||
if (sendAndCheckOverride(root, event)) {
|
||||
Log.d("MouseEvent is processed");
|
||||
debug(mouse) Log.d("MouseEvent is processed");
|
||||
if (event.action == MouseAction.ButtonDown && _mouseCaptureWidget is null && !event.doNotTrackButtonDown) {
|
||||
Log.d("Setting active widget");
|
||||
debug(mouse) Log.d("Setting active widget");
|
||||
setCaptureWidget(root, event);
|
||||
} else if (event.action == MouseAction.Move) {
|
||||
addTracking(root);
|
||||
|
@ -431,7 +436,7 @@ class Window {
|
|||
res = sendAndCheckOverride(_mouseCaptureWidget, event);
|
||||
if (!currentButtons) {
|
||||
// usable capturing - no more buttons pressed
|
||||
Log.d("unsetting active widget");
|
||||
debug(mouse) Log.d("unsetting active widget");
|
||||
_mouseCaptureWidget = null;
|
||||
}
|
||||
return res;
|
||||
|
|
|
@ -255,7 +255,7 @@ version(USE_SDL) {
|
|||
MouseEvent event = new MouseEvent(action, btn, flags, cast(short)x, cast(short)y);
|
||||
bool res = dispatchMouseEvent(event);
|
||||
if (res) {
|
||||
Log.d("Calling update() after mouse event");
|
||||
debug(mouse) Log.d("Calling update() after mouse event");
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -660,19 +660,19 @@ version(USE_SDL) {
|
|||
Log.d("SDL_WINDOWEVENT_MAXIMIZED");
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
Log.d("SDL_WINDOWEVENT_MAXIMIZED");
|
||||
Log.d("SDL_WINDOWEVENT_RESTORED");
|
||||
break;
|
||||
case SDL_WINDOWEVENT_ENTER:
|
||||
Log.d("SDL_WINDOWEVENT_MAXIMIZED");
|
||||
Log.d("SDL_WINDOWEVENT_ENTER");
|
||||
break;
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
Log.d("SDL_WINDOWEVENT_MAXIMIZED");
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
Log.d("SDL_WINDOWEVENT_MAXIMIZED");
|
||||
Log.d("SDL_WINDOWEVENT_FOCUS_GAINED");
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
Log.d("SDL_WINDOWEVENT_MAXIMIZED");
|
||||
Log.d("SDL_WINDOWEVENT_FOCUS_LOST");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -103,8 +103,8 @@ class TextWidget : Widget {
|
|||
super.onDraw(buf);
|
||||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
applyPadding(rc);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
applyPadding(rc);
|
||||
FontRef font = font();
|
||||
Point sz = font.textSize(text);
|
||||
applyAlign(rc, sz);
|
||||
|
@ -167,8 +167,8 @@ class ImageWidget : Widget {
|
|||
super.onDraw(buf);
|
||||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
applyPadding(rc);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
applyPadding(rc);
|
||||
DrawableRef img = drawable;
|
||||
if (!img.isNull) {
|
||||
Point sz;
|
||||
|
@ -330,8 +330,8 @@ class Button : Widget {
|
|||
applyMargins(rc);
|
||||
buf.fillRect(_pos, backgroundColor);
|
||||
applyPadding(rc);
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
FontRef font = font();
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
FontRef font = font();
|
||||
Point sz = font.textSize(text);
|
||||
applyAlign(rc, sz);
|
||||
font.drawText(buf, rc.left, rc.top, text, textColor);
|
||||
|
@ -778,8 +778,8 @@ class ScrollBar : AbstractSlider, OnClickHandler {
|
|||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
applyPadding(rc);
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
_btnForward.onDraw(buf);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
_btnForward.onDraw(buf);
|
||||
_btnBack.onDraw(buf);
|
||||
_pageUp.onDraw(buf);
|
||||
_pageDown.onDraw(buf);
|
||||
|
|
|
@ -1849,8 +1849,8 @@ class EditLine : EditWidgetBase {
|
|||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
applyPadding(rc);
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
FontRef font = font();
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
FontRef font = font();
|
||||
dstring txt = text;
|
||||
Point sz = font.textSize(txt);
|
||||
//applyAlign(rc, sz);
|
||||
|
@ -2373,7 +2373,7 @@ class EditBox : EditWidgetBase, OnScrollHandler {
|
|||
_hscrollbar.onDraw(buf);
|
||||
_vscrollbar.onDraw(buf);
|
||||
Rect rc = _clientRc;
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
|
||||
FontRef font = font();
|
||||
//dstring txt = text;
|
||||
|
|
|
@ -595,8 +595,8 @@ class ListWidget : WidgetGroup, OnScrollHandler {
|
|||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
applyPadding(rc);
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
// draw scrollbar
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
// draw scrollbar
|
||||
if (_needScrollbar)
|
||||
_scrollbar.onDraw(buf);
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ class MenuItemWidget : WidgetGroup {
|
|||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
applyPadding(rc);
|
||||
auto saver = ClipRectSaver(buf, rc);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
for (int i = 0; i < _children.count; i++) {
|
||||
Widget item = _children.get(i);
|
||||
if (item.visibility != Visibility.Visible)
|
||||
|
|
|
@ -108,6 +108,7 @@ class Style {
|
|||
protected uint _backgroundColor = COLOR_UNSPECIFIED;
|
||||
protected uint _textColor = COLOR_UNSPECIFIED;
|
||||
protected uint _textFlags = 0;
|
||||
protected uint _alpha;
|
||||
protected string _fontFace;
|
||||
protected string _backgroundImageId;
|
||||
protected Rect _padding;
|
||||
|
@ -267,6 +268,14 @@ class Style {
|
|||
return _margins;
|
||||
}
|
||||
|
||||
/// alpha (0=opaque .. 255=transparent)
|
||||
@property uint alpha() const {
|
||||
if (_alpha != COLOR_UNSPECIFIED)
|
||||
return _alpha;
|
||||
else
|
||||
return parentStyle.alpha;
|
||||
}
|
||||
|
||||
/// text color
|
||||
@property uint textColor() const {
|
||||
if (_textColor != COLOR_UNSPECIFIED)
|
||||
|
@ -451,6 +460,11 @@ class Style {
|
|||
return this;
|
||||
}
|
||||
|
||||
@property Style alpha(uint alpha) {
|
||||
_alpha = alpha;
|
||||
return this;
|
||||
}
|
||||
|
||||
@property Style textFlags(uint flags) {
|
||||
_textFlags = flags;
|
||||
return this;
|
||||
|
@ -536,7 +550,7 @@ class Style {
|
|||
/// create state substyle for this style
|
||||
Style createState(uint stateMask = 0, uint stateValue = 0) {
|
||||
assert(stateMask != 0);
|
||||
Log.d("Creating substate ", stateMask);
|
||||
debug(styles) Log.d("Creating substate ", stateMask);
|
||||
Style child = (_theme !is null ? _theme : currentTheme).createSubstyle(null);
|
||||
child._parentStyle = this;
|
||||
child._stateMask = stateMask;
|
||||
|
@ -756,7 +770,7 @@ Theme createDefaultTheme() {
|
|||
menuItem.createState(State.Pressed, State.Pressed).backgroundColor(0x4080C000);
|
||||
menuItem.createState(State.Selected, State.Selected).backgroundColor(0x00F8F9Fa);
|
||||
menuItem.createState(State.Hovered, State.Hovered).backgroundColor(0xC0FFFF00);
|
||||
res.createSubstyle("MENU_ICON").setMargins(2,2,2,2).alignment(Align.VCenter|Align.Left);
|
||||
res.createSubstyle("MENU_ICON").setMargins(2,2,2,2).alignment(Align.VCenter|Align.Left).createState(State.Enabled,0).alpha(0xA0);
|
||||
res.createSubstyle("MENU_LABEL").setMargins(4,2,4,2).alignment(Align.VCenter|Align.Left).textFlags(TextFlag.UnderlineHotKeys).createState(State.Enabled,0).textColor(0x80404040);
|
||||
res.createSubstyle("MAIN_MENU_LABEL").setMargins(4,2,4,2).alignment(Align.VCenter|Align.Left).textFlags(TEXT_FLAGS_USE_PARENT).createState(State.Enabled,0).textColor(0x80404040);
|
||||
res.createSubstyle("MENU_ACCEL").setMargins(4,2,4,2).alignment(Align.VCenter|Align.Left).createState(State.Enabled,0).textColor(0x80404040);
|
||||
|
|
|
@ -291,7 +291,15 @@ class Widget {
|
|||
invalidate();
|
||||
return this;
|
||||
}
|
||||
/// get text color (ARGB 32 bit value)
|
||||
/// widget drawing alpha value (0=opaque .. 255=transparent)
|
||||
@property uint alpha() const { return stateStyle.alpha; }
|
||||
/// set widget drawing alpha value (0=opaque .. 255=transparent)
|
||||
@property Widget alpha(uint value) {
|
||||
ownStyle.alpha = value;
|
||||
invalidate();
|
||||
return this;
|
||||
}
|
||||
/// get text color (ARGB 32 bit value)
|
||||
@property uint textColor() const { return stateStyle.textColor; }
|
||||
/// set text color (ARGB 32 bit value)
|
||||
@property Widget textColor(uint value) {
|
||||
|
@ -879,20 +887,20 @@ class Widget {
|
|||
if (trackHover) {
|
||||
if (event.action == MouseAction.FocusOut || event.action == MouseAction.Cancel) {
|
||||
if ((state & State.Hovered)) {
|
||||
Log.d("Hover off ", id);
|
||||
debug(mouse) Log.d("Hover off ", id);
|
||||
resetState(State.Hovered);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (event.action == MouseAction.Move) {
|
||||
if (!(state & State.Hovered)) {
|
||||
Log.d("Hover ", id);
|
||||
debug(mouse) Log.d("Hover ", id);
|
||||
setState(State.Hovered);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (event.action == MouseAction.Leave) {
|
||||
Log.d("Leave ", id);
|
||||
debug(mouse) Log.d("Leave ", id);
|
||||
resetState(State.Hovered);
|
||||
return true;
|
||||
}
|
||||
|
@ -992,6 +1000,7 @@ class Widget {
|
|||
return;
|
||||
Rect rc = _pos;
|
||||
applyMargins(rc);
|
||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||
DrawableRef bg = stateStyle.backgroundDrawable;
|
||||
if (!bg.isNull) {
|
||||
bg.drawTo(buf, rc, state);
|
||||
|
|
Loading…
Reference in New Issue