[macro] update StyleMacro

This commit is contained in:
2019-07-16 14:53:31 +03:00
parent d52d8ff4f3
commit 451b107f6b
14 changed files with 129 additions and 146 deletions

View File

@@ -1,8 +1,6 @@
package demo; package demo;
import haxework.color.Color; import haxework.color.Color;
import haxework.view.skin.Skin;
import haxework.view.theme.SkinStyle;
import haxework.view.theme.Theme; import haxework.view.theme.Theme;
using haxework.color.ColorUtil; using haxework.color.ColorUtil;
@@ -15,7 +13,7 @@ class AppTheme extends Theme {
override private function reload():Void { override private function reload():Void {
super.reload(); super.reload();
styles.put("view", text().concat(background(colors.light, true))); data.set("view", create(["skin.background.color" => colors.light], ["text"]));
styles.put("test", [new SkinStyle(Skin.color(0x00ffff))]); data.set("test", create(["skin.background.color" => Color.fromInt(0x00ffff)]));
} }
} }

View File

@@ -95,6 +95,7 @@ class StyleMacro {
var result:Array<Field> = []; var result:Array<Field> = [];
field.kind = FProp("default", "set", type); field.kind = FProp("default", "set", type);
var expr:Array<Expr> = []; var expr:Array<Expr> = [];
expr.push(macro if (value == null) return null);
expr.push(macro value.styleKey = (styleKey!=null?(styleKey+"."):"")+$v{field.name}); expr.push(macro value.styleKey = (styleKey!=null?(styleKey+"."):"")+$v{field.name});
expr.push(macro value.style = style); expr.push(macro value.style = style);
expr.push(macro $i{field.name} = value); expr.push(macro $i{field.name} = value);
@@ -113,7 +114,7 @@ class StyleMacro {
return result; return result;
} }
private static function buildStyleKeyField(overrideField:Bool):Array<Field> { private static function buildStyleKeyField(styleds:Array<Field>, overrideField:Bool):Array<Field> {
var result:Array<Field> = []; var result:Array<Field> = [];
var type:ComplexType = "String".toComplex(); var type:ComplexType = "String".toComplex();
if (!overrideField) { if (!overrideField) {
@@ -129,6 +130,9 @@ class StyleMacro {
expr.push(macro super.styleKey = value); expr.push(macro super.styleKey = value);
} }
expr.push(macro styleKey = value); expr.push(macro styleKey = value);
for (field in styleds) {
expr.push(macro $i{field.name}.styleKey = styleKey+"."+$v{field.name});
}
expr.push(macro return styleKey); expr.push(macro return styleKey);
var access:Array<Access> = [APrivate]; var access:Array<Access> = [APrivate];
if (overrideField) { if (overrideField) {
@@ -171,6 +175,10 @@ class StyleMacro {
var propertyName = 'theme_${field.name}'; var propertyName = 'theme_${field.name}';
expr.push(macro $i{propertyName} = haxework.provider.Provider.get(haxework.view.theme.ITheme).resolve((styleKey!=null?(styleKey+"."):"")+$v{field.name}, style)); expr.push(macro $i{propertyName} = haxework.provider.Provider.get(haxework.view.theme.ITheme).resolve((styleKey!=null?(styleKey+"."):"")+$v{field.name}, style));
} }
for (field in styleds) {
var propertyName = '${field.name}';
expr.push(macro $i{propertyName} = haxework.provider.Provider.get(haxework.view.theme.ITheme).resolve((styleKey!=null?(styleKey+"."):"")+$v{field.name}, style));
}
if (hasOnStyle) { if (hasOnStyle) {
expr.push(macro onStyle()); expr.push(macro onStyle());
} }
@@ -213,7 +221,7 @@ class StyleMacro {
} }
result = result result = result
.concat(newFields) .concat(newFields)
.concat(buildStyleKeyField(overrideStyle)) .concat(buildStyleKeyField(styleds, overrideStyle))
.concat(buildStyleField(properties, styleds, hasOnStyle, overrideStyle)); .concat(buildStyleField(properties, styleds, hasOnStyle, overrideStyle));
return result; return result;
} }

View File

@@ -23,7 +23,7 @@ class ScrollView extends HGroupView {
public function new() { public function new() {
super(); super();
layout.overflow = true; layout.overflow = true;
skin = Skin.transparent; skin = Skin.transparent();
mask = new Sprite(); mask = new Sprite();
content.addChild(mask); content.addChild(mask);
content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent); content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent);

View File

@@ -1,13 +1,13 @@
package haxework.view; package haxework.view;
import flash.display.Sprite; import flash.display.Sprite;
import haxework.view.skin.Skin; import haxework.view.skin.SpriteSkin;
class SpriteView extends View<Sprite> { class SpriteView extends View<Sprite> {
public function new() { public function new() {
super(new Sprite()); super(new Sprite());
skin = Skin.transparent; skin = new SpriteSkin();
} }
override public function redraw():Void { override public function redraw():Void {

View File

@@ -63,7 +63,7 @@ class SelectView<D> extends GroupView {
public function new() { public function new() {
super(new VerticalLayout()); super(new VerticalLayout());
skin = Skin.transparent; skin = Skin.transparent();
currentView = new ButtonView(); currentView = new ButtonView();
currentView.onPress.connect(function(_) toggle()); currentView.onPress.connect(function(_) toggle());
dataView = new DataView(); dataView = new DataView();

View File

@@ -1,14 +1,14 @@
package haxework.view.list; package haxework.view.list;
import flash.geom.Point; import flash.geom.Point;
import haxework.view.skin.HScrollBarSkin;
class HScrollBarView extends ScrollBarView { class HScrollBarView extends ScrollBarView {
public function new() { public function new() {
super(); super();
skin = new HScrollBarSkin();
style = "scroll.horizontal"; style = "scroll.horizontal";
geometry.width.percent = 100;
geometry.height.fixed = 10;
} }
override private function onMouseDown(p:Point):Void { override private function onMouseDown(p:Point):Void {

View File

@@ -1,14 +1,14 @@
package haxework.view.list; package haxework.view.list;
import flash.geom.Point; import flash.geom.Point;
import haxework.view.skin.VScrollBarSkin;
class VScrollBarView extends ScrollBarView { class VScrollBarView extends ScrollBarView {
public function new() { public function new() {
super(); super();
skin = new VScrollBarSkin();
style = "scroll.vertical"; style = "scroll.vertical";
geometry.height.percent = 100;
geometry.width.fixed = 10;
} }
override private function onMouseDown(p:Point):Void { override private function onMouseDown(p:Point):Void {

View File

@@ -0,0 +1,13 @@
package haxework.view.skin;
import haxework.color.Color;
@:style class Background {
@:style(null) public var color(default, default):Null<Color>;
@:style(1) public var alpha(default, default):Null<Float>;
public function new(?color:Color, ?alpha:Float) {
this.color = color;
this.alpha = alpha;
}
}

View File

@@ -0,0 +1,15 @@
package haxework.view.skin;
import haxework.color.Color;
@:style class Border {
@:style(null) public var color(default, default):Null<Color>;
@:style(2) public var thickness(default, default):Null<Float>;
@:style(1) public var alpha(default, default):Null<Float>;
public function new(?color:Color, ?thickness:Float, ?alpha:Float) {
this.color = color;
this.thickness = thickness;
this.alpha = alpha;
}
}

View File

@@ -1,13 +1,14 @@
package haxework.view.skin; package haxework.view.skin;
import haxework.color.Color;
import haxework.color.ColorUtil; import haxework.color.ColorUtil;
import haxework.view.list.ScrollBarView; import haxework.view.list.ScrollBarView;
@:style class HScrollBarSkin implements ISkin<ScrollBarView> { @:style class HScrollBarSkin implements ISkin<ScrollBarView> {
public var foreColor(default, default):Int; @:style(0) public var foreColor(default, default):Null<Color>;
public var backColor(default, default):Int; @:style(0) public var backColor(default, default):Null<Color>;
public function new(foreColor:Int = 0, backColor:Int = 0) { public function new(?foreColor:Color, ?backColor:Color) {
this.foreColor = foreColor; this.foreColor = foreColor;
this.backColor = backColor; this.backColor = backColor;
} }

View File

@@ -7,14 +7,16 @@ import haxework.view.utils.DrawUtil;
class Skin { class Skin {
public static var transparent(default, never):ISkin<SpriteView> = new SpriteSkin({color: 0, alpha: 0}); public static function transparent():ISkin<SpriteView> {
return new SpriteSkin(new Background(0, 0));
}
public static function bitmap(image:BitmapData, fillType:FillType = null):ISkin<SpriteView> { public static function bitmap(image:BitmapData, fillType:FillType = null):ISkin<SpriteView> {
return new BitmapSkin(image, fillType); return new BitmapSkin(image, fillType);
} }
public static function color(color:Int, alpha:Float = 1.0):ISkin<SpriteView> { public static function color(color:Int, alpha:Float = 1.0):ISkin<SpriteView> {
return new SpriteSkin({color: color, alpha: alpha}); return new SpriteSkin(new Background(color, alpha));
} }
public static function buttonColor(color:Color, ?borderColor:Color):ISkin<ButtonView> { public static function buttonColor(color:Color, ?borderColor:Color):ISkin<ButtonView> {

View File

@@ -1,42 +1,15 @@
package haxework.view.skin; package haxework.view.skin;
import flash.display.Graphics; import flash.display.Graphics;
import haxework.color.Color;
typedef Border = {
@:optional var color:Color;
@:optional var thickness:Float;
@:optional var alpha:Float;
}
typedef Background = {
@:optional var color:Color;
@:optional var alpha:Float;
}
@:style class SpriteSkin implements ISkin<SpriteView> { @:style class SpriteSkin implements ISkin<SpriteView> {
@:style({}) public var border(default, default):Border; @:style public var border(default, default):Border;
@:style({}) public var background(default, default):Background; @:style public var background(default, default):Background;
public function new(?background:Background, ?border:Border) { public function new(?background:Background, ?border:Border) {
this.background = resolveBackground(background); this.background = background != null ? background : new Background();
this.border = resolveBorder(border); this.border = border != null ? border : new Border();
}
private static function resolveBackground(value:Background):Background {
return value != null ? {
color: value.color != null ? value.color : 0x000000,
alpha: value.alpha != null ? value.alpha : 1.0
} : null;
}
private static function resolveBorder(value:Border):Border {
return value != null ? {
color: value.color != null ? value.color : 0x000000,
alpha: value.alpha != null ? value.alpha : 1.0,
thickness: value.thickness != null ? value.thickness : 1
} : null;
} }
public function draw(view:SpriteView):Void { public function draw(view:SpriteView):Void {
@@ -47,6 +20,8 @@ typedef Background = {
} }
if (background.color != null) { if (background.color != null) {
graphics.beginFill(background.color, background.alpha); graphics.beginFill(background.color, background.alpha);
} else {
graphics.beginFill(0, 0);
} }
graphics.drawRect(0, 0, view.width, view.height); graphics.drawRect(0, 0, view.width, view.height);
graphics.lineStyle(); graphics.lineStyle();

View File

@@ -1,13 +1,14 @@
package haxework.view.skin; package haxework.view.skin;
import haxework.color.Color;
import haxework.color.ColorUtil; import haxework.color.ColorUtil;
import haxework.view.list.ScrollBarView; import haxework.view.list.ScrollBarView;
@:style class VScrollBarSkin implements ISkin<ScrollBarView> { @:style class VScrollBarSkin implements ISkin<ScrollBarView> {
public var foreColor(default, default):Int; @:style(0xff0000) public var foreColor(default, default):Null<Color>;
public var backColor(default, default):Int; @:style(0xffff00) public var backColor(default, default):Null<Color>;
public function new(foreColor:Int = 0, backColor:Int = 0) { public function new(?foreColor:Color, ?backColor:Color) {
this.foreColor = foreColor; this.foreColor = foreColor;
this.backColor = backColor; this.backColor = backColor;
} }

View File

@@ -1,15 +1,14 @@
package haxework.view.theme; package haxework.view.theme;
import haxework.view.geometry.Box;
import flash.text.Font; import flash.text.Font;
import flash.text.FontType; import flash.text.FontType;
import haxe.ds.StringMap; import haxe.ds.StringMap;
import haxework.color.Color; import haxework.color.Color;
import haxework.signal.Signal; import haxework.signal.Signal;
import haxework.view.geometry.Geometry; import haxework.view.geometry.Box;
import haxework.view.skin.Skin; import haxework.view.geometry.SizeValue;
import haxework.view.skin.SpriteSkin; import haxework.view.skin.ButtonColorSkin;
import haxework.view.text.FontPreset; import haxework.view.skin.TabColorSkin;
import haxework.view.theme.ITheme; import haxework.view.theme.ITheme;
using haxework.color.ColorUtil; using haxework.color.ColorUtil;
@@ -65,12 +64,9 @@ class Theme implements ITheme {
public var colors(default, set):ThemeColors; public var colors(default, set):ThemeColors;
public var updateSignal(default, null):Signal0; public var updateSignal(default, null):Signal0;
private var styles:StyleMap;
private var data:Map<String, Map<String, Dynamic>>; private var data:Map<String, Map<String, Dynamic>>;
public function new(?font:ThemeFont, ?colors:ThemeColors) { public function new(?font:ThemeFont, ?colors:ThemeColors) {
styles = new StyleMap();
updateSignal = new Signal0(); updateSignal = new Signal0();
data = new Map(); data = new Map();
this.font = font; this.font = font;
@@ -95,30 +91,70 @@ class Theme implements ITheme {
return colors; return colors;
} }
private function create(values:Map<String, Dynamic>, ?parents:Array<String>):Map<String, Dynamic> {
if (parents != null) {
for (key in parents) {
var parent = data.get(key);
for (property in parent.keys()) {
if (!values.exists(property)) {
values.set(property, parent.get(property));
}
}
}
}
return values;
}
private function reload():Void { private function reload():Void {
data.set("background", [ data.set("background", [
"skin.background" => {color: colors.dark, alpha: 1}, "skin.background.color" => colors.dark,
]); ]);
data.set("border", [
"skin.border.color" => colors.border,
]);
data.set("frame", create([
"geometry.padding" => Box.fromFloat(2),
], ["background", "border"]));
data.set("text", [ data.set("text", [
"font.color" => colors.text, "font.color" => colors.text,
"font.family" => font.name, "font.family" => font.name,
"font.embed" => font.embed, "font.embed" => font.embed,
]); ]);
data.set("button", [ data.set("text0", create([
"font.color" => colors.light.diff(-16),
], ["text"]));
data.set("text1", create([
"font.color" => colors.light.diff(16),
], ["text"]));
data.set("label", create([
"geometry.padding" => Box.fromArray([8, 2]),
], ["text"]));
data.set("button", create([
"skin" => function() return new ButtonColorSkin(),
"skin.color" => colors.light, "skin.color" => colors.light,
"geometry.padding" => Box.fromArray([25, 8]), "geometry.padding" => Box.fromArray([25, 8]),
"font.color" => colors.text, ], ["text"]));
"font.family" => font.name, data.set("button.active", create([
"font.embed" => font.embed, "skin.color" => colors.active,
]); ], ["button"]));
data.set("button.tab", [ data.set("button.tab", create([
"skin.color" => colors.light, "skin" => function() return new TabColorSkin(),
"geometry.padding" => Box.fromArray([25, 8]), ], ["button"]));
"font.color" => colors.text, data.set("dropdown", create([
"font.family" => font.name, "_" => null,
"font.embed" => font.embed, ], ["background", "border"]));
]); data.set("scroll.vertical", create([
"skin.foreColor" => colors.light,
"skin.backColor" => colors.dark,
"geometry.width" => SizeValue.fromFloat(10),
"geometry.height" => SizeValue.fromString("100%"),
]));
data.set("scroll.horizontal", create([
"skin.foreColor" => colors.light,
"skin.backColor" => colors.dark,
"geometry.width" => SizeValue.fromString("100%"),
"geometry.height" => SizeValue.fromFloat(10),
]));
// ToDo: hardcode update views // ToDo: hardcode update views
if (Root.instance != null) { if (Root.instance != null) {
@@ -127,81 +163,15 @@ class Theme implements ITheme {
} }
} }
updateSignal.emit(); updateSignal.emit();
styles.put("background", background());
styles.put("border", background(null, true));
styles.put("frame", background(null, true).concat([new GeometryStyle(new Geometry().setPadding(2))]));
styles.put("text", text());
styles.put("label", text().concat([new GeometryStyle(new Geometry().setPadding([8, 2]))]));
styles.put("button", button());
styles.put("button.active", button(null, null, colors.active));
styles.put("dropdown", background(null, true));
styles.put("button.tab", text().concat([
new SkinStyle(Skin.tabColor(this.colors.light)),
new GeometryStyle(new Geometry().setPadding([25, 8]))
]));
styles.put("text0", text().concat(background(this.colors.light.diff(-16))));
styles.put("text1", text().concat(background(this.colors.light.diff(16))));
styles.put("scroll.vertical", [
new SkinStyle(Skin.scrollVertical(this.colors.light, this.colors.dark)),
]);
styles.put("scroll.horizontal", [
new SkinStyle(Skin.scrollHorizontal(this.colors.light, this.colors.dark)),
]);
}
public function background(?color:Color, border:Bool = false):StyleSet {
if (color == null) {
color = colors.dark;
}
return [
new SkinStyle(new SpriteSkin(
{color: color},
border ? {color: colors.light, thickness: 2} : null
)),
];
}
public function text(?color:Color, ?size:Null<Int>):StyleSet {
if (color == null) {
color = colors.text;
}
if (size == null) {
size = baseFontSize;
}
return [
new FontStyle(new FontPreset(font.name, font.embed, color, size)),
];
}
public function button(?color:Color, ?textColor:Color, ?borderColor:Color):StyleSet {
if (color == null) {
color = colors.light;
}
return text(textColor).concat([
new SkinStyle(Skin.buttonColor(color, borderColor)),
new GeometryStyle(new Geometry().setPadding([25, 8])),
]);
}
public function textBox(?color:Color):StyleSet {
return text(color).concat([
new SkinStyle(new SpriteSkin({color: 0, alpha: 0.1}, {color: colors.light, thickness: 2})),
]);
}
public function bind(style:StyleId, view:IView<Dynamic>):Void {
styles.connect(style, view);
}
public function unbind(view:IView<Dynamic>):Void {
styles.disconnect(view);
} }
public function resolve<T>(key:String, style:StyleId):T { public function resolve<T>(key:String, style:StyleId):T {
return style != null && data.exists(style) ? data.get(style).get(key) : null; trace("resolve", key, style != null ? style : "");
var result:Dynamic = style != null && data.exists(style) ? data.get(style).get(key) : null;
if (Reflect.isFunction(result)) {
result = result();
}
return result;
} }
private static function resolveFont(font:ThemeFont):ThemeFont { private static function resolveFont(font:ThemeFont):ThemeFont {