mirror of https://github.com/buggins/dlangui.git
update styles for buttons and checkboxes; refactoring - extract color related definitions to colors.d
This commit is contained in:
parent
9a8eb66e6b
commit
37d5f1efcd
|
@ -355,6 +355,7 @@
|
||||||
<File path="src\dlangui\dialogs\msgbox.d" />
|
<File path="src\dlangui\dialogs\msgbox.d" />
|
||||||
</Folder>
|
</Folder>
|
||||||
<Folder name="graphics">
|
<Folder name="graphics">
|
||||||
|
<File path="src\dlangui\graphics\colors.d" />
|
||||||
<File path="src\dlangui\graphics\drawbuf.d" />
|
<File path="src\dlangui\graphics\drawbuf.d" />
|
||||||
<File path="src\dlangui\graphics\fonts.d" />
|
<File path="src\dlangui\graphics\fonts.d" />
|
||||||
<File path="src\dlangui\graphics\ftfonts.d" />
|
<File path="src\dlangui\graphics\ftfonts.d" />
|
||||||
|
|
|
@ -424,15 +424,30 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
LinearLayout layout3 = new LinearLayout("tab3");
|
LinearLayout layout3 = new VerticalLayout("tab3");
|
||||||
|
// 3 types of buttons: Button, ImageButton, ImageTextButton
|
||||||
layout3.addChild(new TextWidget(null, "Buttons in HorizontalLayout"d));
|
layout3.addChild(new TextWidget(null, "Buttons in HorizontalLayout"d));
|
||||||
WidgetGroup buttons1 = new HorizontalLayout();
|
WidgetGroup buttons1 = new HorizontalLayout();
|
||||||
buttons1.addChild(new Button("btn1", "Button 1"d));
|
buttons1.addChild(new TextWidget(null, "Button widgets: "d));
|
||||||
buttons1.addChild(new Button("btn2", "Button 2"d));
|
buttons1.addChild(new Button("btn1", "Button"d));
|
||||||
buttons1.addChild(new Button("btn3", "Button 3"d));
|
buttons1.addChild((new Button("btn2", "Disabled Button"d)).enabled(false));
|
||||||
buttons1.addChild(new ResizerWidget());
|
buttons1.addChild(new TextWidget(null, "ImageButton widgets: "d));
|
||||||
buttons1.addChild(new Button("btn4", "Button 4"d));
|
buttons1.addChild(new ImageButton("btn3", "text-plain"));
|
||||||
|
buttons1.addChild(new TextWidget(null, "disabled: "d));
|
||||||
|
buttons1.addChild((new ImageButton("btn4", "folder")).enabled(false));
|
||||||
|
buttons1.addChild(new TextWidget(null, "ImageTextButton widgets: "d));
|
||||||
|
buttons1.addChild(new ImageTextButton("btn5", "text-plain", "Enabled"d));
|
||||||
|
buttons1.addChild((new ImageTextButton("btn6", "folder", "Disabled"d)).enabled(false));
|
||||||
layout3.addChild(buttons1);
|
layout3.addChild(buttons1);
|
||||||
|
|
||||||
|
WidgetGroup buttons11 = new HorizontalLayout();
|
||||||
|
buttons11.addChild(new TextWidget(null, "Construct buttons by action: "d));
|
||||||
|
Action FILE_OPEN_ACTION = new Action(ACTION_FILE_OPEN, "MENU_FILE_OPEN"c, "document-open", KeyCode.KEY_O, KeyFlag.Control);
|
||||||
|
buttons11.addChild(new Button(FILE_OPEN_ACTION));
|
||||||
|
buttons11.addChild(new ImageButton(FILE_OPEN_ACTION));
|
||||||
|
buttons11.addChild(new ImageTextButton(FILE_OPEN_ACTION));
|
||||||
|
layout3.addChild(buttons11);
|
||||||
|
|
||||||
layout3.addChild(new VSpacer());
|
layout3.addChild(new VSpacer());
|
||||||
layout3.addChild(new TextWidget(null, "CheckBoxes in HorizontalLayout"d));
|
layout3.addChild(new TextWidget(null, "CheckBoxes in HorizontalLayout"d));
|
||||||
WidgetGroup buttons2 = new HorizontalLayout();
|
WidgetGroup buttons2 = new HorizontalLayout();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
align="Center"
|
align="Center"
|
||||||
margins="5,5,5,5"
|
margins="5,5,5,5"
|
||||||
focusRectColors="#000"
|
focusRectColors="#000"
|
||||||
|
textFlags="UnderlineHotKeys"
|
||||||
/>
|
/>
|
||||||
<style id="BUTTON_TRANSPARENT"
|
<style id="BUTTON_TRANSPARENT"
|
||||||
backgroundImageId="btn_background_transparent"
|
backgroundImageId="btn_background_transparent"
|
||||||
|
@ -12,7 +13,9 @@
|
||||||
/>
|
/>
|
||||||
<style id="BUTTON_LABEL"
|
<style id="BUTTON_LABEL"
|
||||||
layoutWidth="FILL_PARENT"
|
layoutWidth="FILL_PARENT"
|
||||||
|
margins="2,2,2,2"
|
||||||
align="Left|VCenter"
|
align="Left|VCenter"
|
||||||
|
textFlags="UnderlineHotKeys"
|
||||||
/>
|
/>
|
||||||
<style id="BUTTON_ICON"
|
<style id="BUTTON_ICON"
|
||||||
align="Center"
|
align="Center"
|
||||||
|
@ -20,7 +23,10 @@
|
||||||
<style id="TEXT"
|
<style id="TEXT"
|
||||||
margins="2,2,2,2"
|
margins="2,2,2,2"
|
||||||
padding="1,1,1,1"
|
padding="1,1,1,1"
|
||||||
/>
|
align="Left|VCenter"
|
||||||
|
>
|
||||||
|
<state state_enabled="false" textColor="#A0000000"/>
|
||||||
|
</style>
|
||||||
<style id="HSPACER"
|
<style id="HSPACER"
|
||||||
layoutWidth="FILL_PARENT"
|
layoutWidth="FILL_PARENT"
|
||||||
layoutWeight="100"
|
layoutWeight="100"
|
||||||
|
|
|
@ -64,6 +64,7 @@ public import dlangui.widgets.grid;
|
||||||
public import dlangui.widgets.tree;
|
public import dlangui.widgets.tree;
|
||||||
public import dlangui.widgets.combobox;
|
public import dlangui.widgets.combobox;
|
||||||
public import dlangui.widgets.popup;
|
public import dlangui.widgets.popup;
|
||||||
|
public import dlangui.graphics.colors;
|
||||||
public import dlangui.graphics.fonts;
|
public import dlangui.graphics.fonts;
|
||||||
public import dlangui.graphics.drawbuf;
|
public import dlangui.graphics.drawbuf;
|
||||||
public import dlangui.platforms.common.platform;
|
public import dlangui.platforms.common.platform;
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
module dlangui.graphics.colors;
|
||||||
|
|
||||||
|
private import std.string : strip;
|
||||||
|
|
||||||
|
/// special color constant to identify value as not a color (to use default/parent value instead)
|
||||||
|
immutable uint COLOR_UNSPECIFIED = 0xFFDEADFF;
|
||||||
|
/// transparent color constant
|
||||||
|
immutable uint COLOR_TRANSPARENT = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
immutable uint COLOR_TRANSFORM_OFFSET_NONE = 0x80808080;
|
||||||
|
immutable uint COLOR_TRANSFORM_MULTIPLY_NONE = 0x40404040;
|
||||||
|
|
||||||
|
uint makeRGBA(T)(T r, T g, T b, T a) {
|
||||||
|
return (cast(uint)a << 24)|(cast(uint)r << 16)|(cast(uint)g << 8)|(cast(uint)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// blend two RGB pixels using alpha
|
||||||
|
uint blendARGB(uint dst, uint src, uint alpha) {
|
||||||
|
uint dstalpha = dst >> 24;
|
||||||
|
if (dstalpha > 0x80)
|
||||||
|
return src;
|
||||||
|
uint srcr = (src >> 16) & 0xFF;
|
||||||
|
uint srcg = (src >> 8) & 0xFF;
|
||||||
|
uint srcb = (src >> 0) & 0xFF;
|
||||||
|
uint dstr = (dst >> 16) & 0xFF;
|
||||||
|
uint dstg = (dst >> 8) & 0xFF;
|
||||||
|
uint dstb = (dst >> 0) & 0xFF;
|
||||||
|
uint ialpha = 256 - alpha;
|
||||||
|
uint r = ((srcr * ialpha + dstr * alpha) >> 8) & 0xFF;
|
||||||
|
uint g = ((srcg * ialpha + dstg * alpha) >> 8) & 0xFF;
|
||||||
|
uint b = ((srcb * ialpha + dstb * alpha) >> 8) & 0xFF;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// applies additional alpha to color
|
||||||
|
uint addAlpha(uint color, uint alpha) {
|
||||||
|
alpha = blendAlpha(color >> 24, alpha);
|
||||||
|
return (color & 0xFFFFFF) | (alpha << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
ubyte rgbToGray(uint color) {
|
||||||
|
uint srcr = (color >> 16) & 0xFF;
|
||||||
|
uint srcg = (color >> 8) & 0xFF;
|
||||||
|
uint srcb = (color >> 0) & 0xFF;
|
||||||
|
return cast(uint)(((srcr + srcg + srcg + srcb) >> 2) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// todo
|
||||||
|
struct ColorTransformHandler {
|
||||||
|
void init(ref ColorTransform transform) {
|
||||||
|
|
||||||
|
}
|
||||||
|
uint transform(uint color) {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint transformComponent(int src, int addBefore, int multiply, int addAfter) {
|
||||||
|
int add1 = (cast(int)(addBefore << 1)) - 0x100;
|
||||||
|
int add2 = (cast(int)(addAfter << 1)) - 0x100;
|
||||||
|
int mul = cast(int)(multiply << 2);
|
||||||
|
int res = (((src + add1) * mul) >> 8) + add2;
|
||||||
|
if (res < 0)
|
||||||
|
res = 0;
|
||||||
|
else if (res > 255)
|
||||||
|
res = 255;
|
||||||
|
return cast(uint)res;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint transformRGBA(uint src, uint addBefore, uint multiply, uint addAfter) {
|
||||||
|
uint a = transformComponent(src >> 24, addBefore >> 24, multiply >> 24, addAfter >> 24);
|
||||||
|
uint r = transformComponent((src >> 16) & 0xFF, (addBefore >> 16) & 0xFF, (multiply >> 16) & 0xFF, (addAfter >> 16) & 0xFF);
|
||||||
|
uint g = transformComponent((src >> 8) & 0xFF, (addBefore >> 8) & 0xFF, (multiply >> 8) & 0xFF, (addAfter >> 8) & 0xFF);
|
||||||
|
uint b = transformComponent(src & 0xFF, addBefore & 0xFF, multiply & 0xFF, addAfter & 0xFF);
|
||||||
|
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ColorTransform {
|
||||||
|
uint addBefore = COLOR_TRANSFORM_OFFSET_NONE;
|
||||||
|
uint multiply = COLOR_TRANSFORM_MULTIPLY_NONE;
|
||||||
|
uint addAfter = COLOR_TRANSFORM_OFFSET_NONE;
|
||||||
|
@property bool empty() const {
|
||||||
|
return addBefore == COLOR_TRANSFORM_OFFSET_NONE
|
||||||
|
&& multiply == COLOR_TRANSFORM_MULTIPLY_NONE
|
||||||
|
&& addAfter == COLOR_TRANSFORM_OFFSET_NONE;
|
||||||
|
}
|
||||||
|
uint transform(uint color) {
|
||||||
|
return transformRGBA(color, addBefore, multiply, addAfter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// blend two RGB pixels using alpha
|
||||||
|
ubyte blendGray(ubyte dst, ubyte src, uint alpha) {
|
||||||
|
uint ialpha = 256 - alpha;
|
||||||
|
return cast(ubyte)(((src * ialpha + dst * alpha) >> 8) & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns true if color is #FFxxxxxx (color alpha is 255)
|
||||||
|
bool isFullyTransparentColor(uint color) pure nothrow {
|
||||||
|
return (color >> 24) == 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// decodes hex digit (0..9, a..f, A..F), returns uint.max if invalid
|
||||||
|
uint decodeHexDigit(char ch) {
|
||||||
|
if (ch >= '0' && ch <= '9')
|
||||||
|
return ch - '0';
|
||||||
|
else if (ch >= 'a' && ch <= 'f')
|
||||||
|
return ch - 'a' + 10;
|
||||||
|
else if (ch >= 'A' && ch <= 'F')
|
||||||
|
return ch - 'A' + 10;
|
||||||
|
return uint.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// decode color string supported formats: #RGB #ARGB #RRGGBB #AARRGGBB
|
||||||
|
uint decodeHexColor(string s, uint defValue = 0) {
|
||||||
|
s = strip(s);
|
||||||
|
switch (s) {
|
||||||
|
case "@null":
|
||||||
|
case "transparent":
|
||||||
|
return COLOR_TRANSPARENT;
|
||||||
|
case "black":
|
||||||
|
return 0x000000;
|
||||||
|
case "white":
|
||||||
|
return 0xFFFFFF;
|
||||||
|
case "red":
|
||||||
|
return 0xFF0000;
|
||||||
|
case "green":
|
||||||
|
return 0x00FF00;
|
||||||
|
case "blue":
|
||||||
|
return 0x0000FF;
|
||||||
|
case "gray":
|
||||||
|
return 0x808080;
|
||||||
|
case "lightgray":
|
||||||
|
case "silver":
|
||||||
|
return 0xC0C0C0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (s.length != 4 && s.length != 5 && s.length != 7 && s.length != 9)
|
||||||
|
return defValue;
|
||||||
|
if (s[0] != '#')
|
||||||
|
return defValue;
|
||||||
|
uint value = 0;
|
||||||
|
for (int i = 1; i < s.length; i++) {
|
||||||
|
uint digit = decodeHexDigit(s[i]);
|
||||||
|
if (digit == uint.max)
|
||||||
|
return defValue;
|
||||||
|
value = (value << 4) | digit;
|
||||||
|
if (s.length < 7) // double the same digit for short forms
|
||||||
|
value = (value << 4) | digit;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
|
@ -19,109 +19,8 @@ module dlangui.graphics.drawbuf;
|
||||||
|
|
||||||
public import dlangui.core.types;
|
public import dlangui.core.types;
|
||||||
import dlangui.core.logger;
|
import dlangui.core.logger;
|
||||||
|
import dlangui.graphics.colors;
|
||||||
|
|
||||||
immutable uint COLOR_TRANSFORM_OFFSET_NONE = 0x80808080;
|
|
||||||
immutable uint COLOR_TRANSFORM_MULTIPLY_NONE = 0x40404040;
|
|
||||||
|
|
||||||
uint makeRGBA(T)(T r, T g, T b, T a) {
|
|
||||||
return (cast(uint)a << 24)|(cast(uint)r << 16)|(cast(uint)g << 8)|(cast(uint)b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// blend two RGB pixels using alpha
|
|
||||||
uint blendARGB(uint dst, uint src, uint alpha) {
|
|
||||||
uint dstalpha = dst >> 24;
|
|
||||||
if (dstalpha > 0x80)
|
|
||||||
return src;
|
|
||||||
uint srcr = (src >> 16) & 0xFF;
|
|
||||||
uint srcg = (src >> 8) & 0xFF;
|
|
||||||
uint srcb = (src >> 0) & 0xFF;
|
|
||||||
uint dstr = (dst >> 16) & 0xFF;
|
|
||||||
uint dstg = (dst >> 8) & 0xFF;
|
|
||||||
uint dstb = (dst >> 0) & 0xFF;
|
|
||||||
uint ialpha = 256 - alpha;
|
|
||||||
uint r = ((srcr * ialpha + dstr * alpha) >> 8) & 0xFF;
|
|
||||||
uint g = ((srcg * ialpha + dstg * alpha) >> 8) & 0xFF;
|
|
||||||
uint b = ((srcb * ialpha + dstb * alpha) >> 8) & 0xFF;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// applies additional alpha to color
|
|
||||||
uint addAlpha(uint color, uint alpha) {
|
|
||||||
alpha = blendAlpha(color >> 24, alpha);
|
|
||||||
return (color & 0xFFFFFF) | (alpha << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
ubyte rgbToGray(uint color) {
|
|
||||||
uint srcr = (color >> 16) & 0xFF;
|
|
||||||
uint srcg = (color >> 8) & 0xFF;
|
|
||||||
uint srcb = (color >> 0) & 0xFF;
|
|
||||||
return cast(uint)(((srcr + srcg + srcg + srcb) >> 2) & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo
|
|
||||||
struct ColorTransformHandler {
|
|
||||||
void init(ref ColorTransform transform) {
|
|
||||||
|
|
||||||
}
|
|
||||||
uint transform(uint color) {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint transformComponent(int src, int addBefore, int multiply, int addAfter) {
|
|
||||||
int add1 = (cast(int)(addBefore << 1)) - 0x100;
|
|
||||||
int add2 = (cast(int)(addAfter << 1)) - 0x100;
|
|
||||||
int mul = cast(int)(multiply << 2);
|
|
||||||
int res = (((src + add1) * mul) >> 8) + add2;
|
|
||||||
if (res < 0)
|
|
||||||
res = 0;
|
|
||||||
else if (res > 255)
|
|
||||||
res = 255;
|
|
||||||
return cast(uint)res;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint transformRGBA(uint src, uint addBefore, uint multiply, uint addAfter) {
|
|
||||||
uint a = transformComponent(src >> 24, addBefore >> 24, multiply >> 24, addAfter >> 24);
|
|
||||||
uint r = transformComponent((src >> 16) & 0xFF, (addBefore >> 16) & 0xFF, (multiply >> 16) & 0xFF, (addAfter >> 16) & 0xFF);
|
|
||||||
uint g = transformComponent((src >> 8) & 0xFF, (addBefore >> 8) & 0xFF, (multiply >> 8) & 0xFF, (addAfter >> 8) & 0xFF);
|
|
||||||
uint b = transformComponent(src & 0xFF, addBefore & 0xFF, multiply & 0xFF, addAfter & 0xFF);
|
|
||||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ColorTransform {
|
|
||||||
uint addBefore = COLOR_TRANSFORM_OFFSET_NONE;
|
|
||||||
uint multiply = COLOR_TRANSFORM_MULTIPLY_NONE;
|
|
||||||
uint addAfter = COLOR_TRANSFORM_OFFSET_NONE;
|
|
||||||
@property bool empty() const {
|
|
||||||
return addBefore == COLOR_TRANSFORM_OFFSET_NONE
|
|
||||||
&& multiply == COLOR_TRANSFORM_MULTIPLY_NONE
|
|
||||||
&& addAfter == COLOR_TRANSFORM_OFFSET_NONE;
|
|
||||||
}
|
|
||||||
uint transform(uint color) {
|
|
||||||
return transformRGBA(color, addBefore, multiply, addAfter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// blend two RGB pixels using alpha
|
|
||||||
ubyte blendGray(ubyte dst, ubyte src, uint alpha) {
|
|
||||||
uint ialpha = 256 - alpha;
|
|
||||||
return cast(ubyte)(((src * ialpha + dst * alpha) >> 8) & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// returns true if color is #FFxxxxxx (color alpha is 255)
|
|
||||||
bool isFullyTransparentColor(uint color) pure nothrow {
|
|
||||||
return (color >> 24) == 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 9-patch image scaling information (see Android documentation).
|
* 9-patch image scaling information (see Android documentation).
|
||||||
|
|
|
@ -39,6 +39,7 @@ version (USE_DLIBIMAGE) {
|
||||||
|
|
||||||
import dlangui.core.logger;
|
import dlangui.core.logger;
|
||||||
import dlangui.core.types;
|
import dlangui.core.types;
|
||||||
|
import dlangui.graphics.colors;
|
||||||
import dlangui.graphics.drawbuf;
|
import dlangui.graphics.drawbuf;
|
||||||
import std.stream;
|
import std.stream;
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
|
|
|
@ -28,6 +28,7 @@ module dlangui.graphics.resources;
|
||||||
|
|
||||||
import dlangui.graphics.images;
|
import dlangui.graphics.images;
|
||||||
import dlangui.graphics.drawbuf;
|
import dlangui.graphics.drawbuf;
|
||||||
|
import dlangui.graphics.colors;
|
||||||
import dlangui.core.logger;
|
import dlangui.core.logger;
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
|
@ -93,22 +94,7 @@ class FrameDrawable : Drawable {
|
||||||
@property override Rect padding() { return _frameWidths; }
|
@property override Rect padding() { return _frameWidths; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// decode color string #AARRGGBB, e.g. #5599AA
|
|
||||||
static uint decodeHexColor(string s) {
|
|
||||||
uint value = 0;
|
|
||||||
foreach(c; s) {
|
|
||||||
int digit = -1;
|
|
||||||
if (c >='0' && c <= '9')
|
|
||||||
digit = c - '0';
|
|
||||||
else if (c >='a' && c <= 'f')
|
|
||||||
digit = c - 'a' + 10;
|
|
||||||
else if (c >='A' && c <= 'F')
|
|
||||||
digit = c - 'A' + 10;
|
|
||||||
if (digit >= 0)
|
|
||||||
value = (value << 4) | digit;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
/// decode size string, e.g. 1px or 2 or 3pt
|
/// decode size string, e.g. 1px or 2 or 3pt
|
||||||
static uint decodeDimension(string s) {
|
static uint decodeDimension(string s) {
|
||||||
uint value = 0;
|
uint value = 0;
|
||||||
|
|
|
@ -397,7 +397,7 @@ class Button : Widget {
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
Point sz = font.textSize(text);
|
Point sz = font.textSize(text);
|
||||||
applyAlign(rc, sz);
|
applyAlign(rc, sz);
|
||||||
font.drawText(buf, rc.left, rc.top, text, textColor);
|
font.drawText(buf, rc.left, rc.top, text, textColor, 4, 0, textFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,12 @@ private import std.string;
|
||||||
private import std.algorithm;
|
private import std.algorithm;
|
||||||
|
|
||||||
import dlangui.core.types;
|
import dlangui.core.types;
|
||||||
|
import dlangui.graphics.colors;
|
||||||
import dlangui.graphics.fonts;
|
import dlangui.graphics.fonts;
|
||||||
import dlangui.graphics.drawbuf;
|
import dlangui.graphics.drawbuf;
|
||||||
import dlangui.graphics.resources;
|
import dlangui.graphics.resources;
|
||||||
|
|
||||||
immutable ubyte ALIGN_UNSPECIFIED = 0;
|
immutable ubyte ALIGN_UNSPECIFIED = 0;
|
||||||
immutable uint COLOR_UNSPECIFIED = 0xFFDEADFF;
|
|
||||||
/// transparent color constant
|
|
||||||
immutable uint COLOR_TRANSPARENT = 0xFFFFFFFF;
|
|
||||||
/// unspecified font size constant - to take parent style property value
|
/// unspecified font size constant - to take parent style property value
|
||||||
immutable ushort FONT_SIZE_UNSPECIFIED = 0xFFFF;
|
immutable ushort FONT_SIZE_UNSPECIFIED = 0xFFFF;
|
||||||
/// unspecified font weight constant - to take parent style property value
|
/// unspecified font weight constant - to take parent style property value
|
||||||
|
@ -95,32 +93,6 @@ enum TextFlag : uint {
|
||||||
Underline = 8
|
Underline = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// custom drawable attribute container for styles
|
|
||||||
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
|
/// style properties
|
||||||
class Style {
|
class Style {
|
||||||
protected string _id;
|
protected string _id;
|
||||||
|
@ -905,58 +877,6 @@ Rect decodeRect(string s) {
|
||||||
return Rect(0,0,0,0);
|
return Rect(0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// decodes hex digit (0..9, a..f, A..F), returns uint.max if invalid
|
|
||||||
uint decodeHexDigit(char ch) {
|
|
||||||
if (ch >= '0' && ch <= '9')
|
|
||||||
return ch - '0';
|
|
||||||
else if (ch >= 'a' && ch <= 'f')
|
|
||||||
return ch - 'a' + 10;
|
|
||||||
else if (ch >= 'A' && ch <= 'F')
|
|
||||||
return ch - 'A' + 10;
|
|
||||||
return uint.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// supported formats: #RGB #ARGB #RRGGBB #AARRGGBB
|
|
||||||
uint decodeColor(string s, uint defValue) {
|
|
||||||
s = strip(s);
|
|
||||||
switch (s) {
|
|
||||||
case "@null":
|
|
||||||
case "transparent":
|
|
||||||
return COLOR_TRANSPARENT;
|
|
||||||
case "black":
|
|
||||||
return 0x000000;
|
|
||||||
case "white":
|
|
||||||
return 0xFFFFFF;
|
|
||||||
case "red":
|
|
||||||
return 0xFF0000;
|
|
||||||
case "green":
|
|
||||||
return 0x00FF00;
|
|
||||||
case "blue":
|
|
||||||
return 0x0000FF;
|
|
||||||
case "gray":
|
|
||||||
return 0x808080;
|
|
||||||
case "lightgray":
|
|
||||||
case "silver":
|
|
||||||
return 0xC0C0C0;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (s.length != 4 && s.length != 5 && s.length != 7 && s.length != 9)
|
|
||||||
return defValue;
|
|
||||||
if (s[0] != '#')
|
|
||||||
return defValue;
|
|
||||||
uint value = 0;
|
|
||||||
for (int i = 1; i < s.length; i++) {
|
|
||||||
uint digit = decodeHexDigit(s[i]);
|
|
||||||
if (digit == uint.max)
|
|
||||||
return defValue;
|
|
||||||
value = (value << 4) | digit;
|
|
||||||
if (s.length < 7) // double the same digit for short forms
|
|
||||||
value = (value << 4) | digit;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private import std.array : split;
|
private import std.array : split;
|
||||||
|
|
||||||
/// Decode color list attribute, e.g.: "#84A, #99FFFF" -> [0x8844aa, 0x99ffff]
|
/// Decode color list attribute, e.g.: "#84A, #99FFFF" -> [0x8844aa, 0x99ffff]
|
||||||
|
@ -966,7 +886,7 @@ uint[] decodeFocusRectColors(string s) {
|
||||||
return null;
|
return null;
|
||||||
uint[] res = new uint[colors.length];
|
uint[] res = new uint[colors.length];
|
||||||
for (int i = 0; i < colors.length; i++) {
|
for (int i = 0; i < colors.length; i++) {
|
||||||
uint cl = decodeColor(colors[i], COLOR_UNSPECIFIED);
|
uint cl = decodeHexColor(colors[i], COLOR_UNSPECIFIED);
|
||||||
if (cl == COLOR_UNSPECIFIED)
|
if (cl == COLOR_UNSPECIFIED)
|
||||||
return null;
|
return null;
|
||||||
res[i] = cl;
|
res[i] = cl;
|
||||||
|
@ -1120,7 +1040,7 @@ bool loadStyleAttributes(Style style, Element elem, bool allowStates) {
|
||||||
// <color id="buttons_panel_color" value="#303080"/>
|
// <color id="buttons_panel_color" value="#303080"/>
|
||||||
string colorid = attrValue(item, "id");
|
string colorid = attrValue(item, "id");
|
||||||
string colorvalue = attrValue(item, "value");
|
string colorvalue = attrValue(item, "value");
|
||||||
uint color = decodeColor(colorvalue, COLOR_TRANSPARENT);
|
uint color = decodeHexColor(colorvalue, COLOR_TRANSPARENT);
|
||||||
if (colorid)
|
if (colorid)
|
||||||
style.setCustomColor(colorid, color);
|
style.setCustomColor(colorid, color);
|
||||||
}
|
}
|
||||||
|
@ -1217,6 +1137,33 @@ Theme loadTheme(string resourceId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// custom drawable attribute container for styles
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
shared static ~this() {
|
shared static ~this() {
|
||||||
currentTheme = null;
|
currentTheme = null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue