diff --git a/src/main/haxework/macro/ProvideMacro.hx b/src/main/haxework/macro/ProvideMacro.hx index fdc0006..807894f 100644 --- a/src/main/haxework/macro/ProvideMacro.hx +++ b/src/main/haxework/macro/ProvideMacro.hx @@ -3,12 +3,14 @@ package haxework.macro; import haxe.macro.Context; import haxe.macro.Expr; +using haxework.macro.Util; + class ProvideMacro { private static var metaName = ":provide"; public static function has(field:Field):Bool { - return Util.hasFieldMeta(metaName, field); + return field.getFieldMeta(metaName) != null; } private var field:Field; @@ -16,7 +18,7 @@ class ProvideMacro { public function new(field:Field) { this.field = field; - this.meta = Util.getFieldMeta(metaName, field); + this.meta = field.getFieldMeta(metaName); } public function apply():Array { diff --git a/src/main/haxework/macro/ResourceMacro.hx b/src/main/haxework/macro/ResourceMacro.hx index e6b1e66..ca47335 100644 --- a/src/main/haxework/macro/ResourceMacro.hx +++ b/src/main/haxework/macro/ResourceMacro.hx @@ -2,14 +2,13 @@ package haxework.macro; import haxe.macro.Expr; +using haxework.macro.Util; class ResourceMacro { - public static function has(field:Field):Bool { - return Util.hasFieldMeta(":resource", field); + return field.getFieldMeta(":resource") != null; } - private var field:Field; public function new(field:Field) { diff --git a/src/main/haxework/macro/StyleMacro.hx b/src/main/haxework/macro/StyleMacro.hx new file mode 100644 index 0000000..f2a2b6a --- /dev/null +++ b/src/main/haxework/macro/StyleMacro.hx @@ -0,0 +1,220 @@ +package haxework.macro; + +import haxe.macro.Context; +import haxe.macro.Expr; +import haxe.macro.Type; + +using haxe.macro.ComplexTypeTools; +using haxework.macro.Util; +using haxe.macro.MacroStringTools; + +typedef TProperty = { + var field: Field; + var defaultValue: T; +} + +class StyleMacro { + private static inline var metaName:String = ':style'; + + public static function has(classType:ClassType):Bool { + return classType.getClassMeta(metaName) != null; + } + + private var classType:ClassType; + private var fields:Array; + private var overrideStyle:Bool; + + public function new(classType:ClassType, fields:Array) { + this.classType = classType; + this.fields = fields; + this.overrideStyle = classType.getClassMeta(":style").params.length > 0; + } + + private static function processPropertyField(field:Field):Array { + var result:Array = []; + var type:ComplexType = field.getComplexType(); + var meta = field.getFieldMeta(":style"); + var defaultValue:Expr = meta.params.length > 0 ? meta.params[0] : null; + field.kind = FProp("get", "set", type); + var defaultName = 'default_${field.name}'; + result.push({ + name: defaultName, + access: [APrivate], + pos: field.pos, + kind: FVar(type, defaultValue), + }); + var currentName = 'current_${field.name}'; + result.push({ + name: currentName, + access: [APrivate], + pos: field.pos, + kind: FVar(type), + }); + var themeName = 'theme_${field.name}'; + result.push({ + name: themeName, + access: [APrivate], + pos: field.pos, + kind: FVar(type), + }); + var getter = []; + getter.push(macro var result = $i{currentName}); + getter.push(macro if (result == null) result = $i{themeName}); + getter.push(macro if (result == null) result = $i{defaultName}); + getter.push(macro return result); + result.push({ + name: 'get_${field.name}', + access: [APrivate], + pos: field.pos, + kind: FFun({ + args: [], + expr: macro $b{getter}, + params: [], + ret: type, + }) + }); + result.push({ + name: 'set_${field.name}', + access: [APrivate], + pos: field.pos, + kind: FFun({ + args: [{name: "value", type: type}], + expr: macro $b{[ + macro $i{currentName} = value, + macro return $i{field.name} + ]}, + params: [], + ret: type, + }) + }); + return result; + } + + private static function processStyledField(field:Field):Array { + var type:ComplexType = field.getComplexType(); + var result:Array = []; + field.kind = FProp("default", "set", type); + var expr:Array = []; + expr.push(macro value.styleKey = (styleKey!=null?(styleKey+"."):"")+$v{field.name}); + expr.push(macro value.style = style); + expr.push(macro $i{field.name} = value); + expr.push(macro return $i{field.name}); + result.push({ + name: 'set_${field.name}', + access: [APrivate], + pos: field.pos, + kind: FFun({ + args: [{name: "value", type: type}], + expr: macro $b{expr}, + params: [], + ret: type, + }) + }); + return result; + } + + private static function buildStyleKeyField(overrideField:Bool):Array { + var result:Array = []; + var type:ComplexType = "String".toComplex(); + if (!overrideField) { + result.push({ + name: "styleKey", + access: [APublic], + pos: Context.currentPos(), + kind: FProp("default", "set", type), + }); + } + var expr:Array = []; + if (overrideField) { + expr.push(macro super.styleKey = value); + } + expr.push(macro styleKey = value); + expr.push(macro return styleKey); + var access:Array = [APrivate]; + if (overrideField) { + access.push(AOverride); + } + result.push({ + name: 'set_styleKey', + access: access, + pos: Context.currentPos(), + kind: FFun({ + args: [{name: "value", type: type}], + expr: macro $b{expr}, + params: [], + ret: type, + }) + }); + return result; + } + + private static function buildStyleField(properties:Array, styleds:Array, hasOnStyle:Bool, overrideField:Bool):Array { + var result:Array = []; + var type:ComplexType = "haxework.view.theme.StyleId".toComplex(); + if (!overrideField) { + result.push({ + name: "style", + access: [APublic], + pos: Context.currentPos(), + kind: FProp("default", "set", type), + }); + } + var expr:Array = []; + if (overrideField) { + expr.push(macro super.style = value); + } + expr.push(macro style = value); + for (field in styleds) { + expr.push(macro $i{field.name}.style = style); + } + for (field in properties) { + 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)); + } + if (hasOnStyle) { + expr.push(macro onStyle()); + } + expr.push(macro return style); + var access:Array = [APrivate]; + if (overrideField) { + access.push(AOverride); + } + result.push({ + name: 'set_style', + access: access, + pos: Context.currentPos(), + kind: FFun({ + args: [{name: "value", type: type}], + expr: macro $b{expr}, + params: [], + ret: type, + }) + }); + return result; + } + + public function apply():Array { + var result:Array = fields.slice(0); + var styleds:Array = []; + var properties:Array = []; + var newFields:Array = []; + var hasOnStyle:Bool = fields.getField("onStyle") != null; + for (field in fields) if (field.meta != null) { + var meta = field.getFieldMeta(":style"); + if (meta != null) { + if (meta.params.length > 0) { + newFields = newFields.concat(processPropertyField(field)); + properties.push(field); + } else { + newFields = newFields.concat(processStyledField(field)); + styleds.push(field); + } + } + } + result = result + .concat(newFields) + .concat(buildStyleKeyField(overrideStyle)) + .concat(buildStyleField(properties, styleds, hasOnStyle, overrideStyle)); + return result; + } +} diff --git a/src/main/haxework/macro/TemplateMacro.hx b/src/main/haxework/macro/TemplateMacro.hx index 7a32a76..1e35bd5 100644 --- a/src/main/haxework/macro/TemplateMacro.hx +++ b/src/main/haxework/macro/TemplateMacro.hx @@ -6,32 +6,29 @@ import haxe.macro.Expr; import haxe.macro.Type; import haxework.macro.PositionJsonParser; +using haxework.macro.Util; + class TemplateMacro { private static inline var metaName:String = ':template'; public static function has(classType:ClassType):Bool { - return Util.hasClassMeta(metaName, classType); + return classType.getClassMeta(metaName) != null; } private var classType:ClassType; private var fields:Array; private var bindings:Map; - private var meta(get, never):MetadataEntry; + private var meta:MetadataEntry; private var templateFile:String; private var template:Dynamic; private var i:Int; - private function get_meta():MetadataEntry { - for (md in classType.meta.get()) if (md.name == metaName) { - return md; - } - return null; - } public function new(classType:ClassType, fields:Array) { this.classType = classType; + this.meta = classType.getClassMeta(metaName); this.fields = fields; var params = Util.getMetaParams(meta); var filePath = params[0]; diff --git a/src/main/haxework/macro/Util.hx b/src/main/haxework/macro/Util.hx index 87e8859..85a69d2 100644 --- a/src/main/haxework/macro/Util.hx +++ b/src/main/haxework/macro/Util.hx @@ -3,7 +3,6 @@ package haxework.macro; import haxe.macro.Type.ClassType; import haxe.macro.Expr; - class Util { public static function getMetaParams(meta:MetadataEntry):Array { @@ -17,21 +16,14 @@ class Util { return ComplexType.TPath({name:'Dynamic', pack:[], params:[]}); } - public static function hasClassMeta(metaName:String, classType:ClassType):Bool { + public static function getClassMeta(classType:ClassType, metaName:String):Null { for (md in classType.meta.get()) if (md.name == metaName) { - return true; + return md; } - return false; + return null; } - public static function hasFieldMeta(metaName:String, field:Field):Bool { - for (md in field.meta) if (md.name == metaName) { - return true; - } - return false; - } - - public static function getFieldMeta(metaName:String, field:Field):MetadataEntry { + public static function getFieldMeta(field:Field, metaName:String):Null { for (md in field.meta) if (md.name == metaName) { return md; } @@ -44,4 +36,16 @@ class Util { case _: null; } } + + public static function getComplexType(field:Field):Null { + return switch field.kind { + case FProp(get, set, t, e): t; + case FVar(t, e): t; + case _: null; + } + } + + public static function getField(fields:Array, name:String):Null { + return Lambda.find(fields, function(field:Field):Bool return field.name == name); + } } diff --git a/src/main/haxework/parser/Parser.hx b/src/main/haxework/parser/Parser.hx index 0b5b779..ffc3d5f 100644 --- a/src/main/haxework/parser/Parser.hx +++ b/src/main/haxework/parser/Parser.hx @@ -1,5 +1,6 @@ package haxework.parser; +import haxework.macro.StyleMacro; import haxe.macro.TypeTools; import haxe.macro.Context; import haxe.macro.Expr; @@ -57,6 +58,11 @@ class Parser { var dispatcher = new DispatcherMacro(ct, fields); fields = dispatcher.apply(); } + if (StyleMacro.has(ct)) { + modify = true; + var style = new StyleMacro(ct, fields); + fields = style.apply(); + } processed.set(localName, true); modify ? fields : null; default: null; diff --git a/src/main/haxework/view/IView.hx b/src/main/haxework/view/IView.hx index c20d65e..59d991f 100755 --- a/src/main/haxework/view/IView.hx +++ b/src/main/haxework/view/IView.hx @@ -9,8 +9,8 @@ import haxework.view.skin.ISkin; import haxework.view.theme.StyleId; interface IView { - @:style public var geometry(default, default):Geometry; - @:style public var skin(default, set):ISkin; + public var geometry(default, set):Geometry; + public var skin(default, set):ISkin; public var id(default, default):String; diff --git a/src/main/haxework/view/Root.hx b/src/main/haxework/view/Root.hx index 97b5b34..31b2c77 100755 --- a/src/main/haxework/view/Root.hx +++ b/src/main/haxework/view/Root.hx @@ -73,4 +73,19 @@ class Root { onResize.dispose(); } + private static function getViews(view:IView):Array> { + var result = []; + result.push(view); + if (Std.is(view, IGroupView)) { + for (v in cast(view, IGroupView).views) { + result = result.concat(getViews(v)); + } + } + return result; + } + + public function views():Array> { + return getViews(view); + } + } diff --git a/src/main/haxework/view/View.hx b/src/main/haxework/view/View.hx index 5707bc0..66fd889 100755 --- a/src/main/haxework/view/View.hx +++ b/src/main/haxework/view/View.hx @@ -9,18 +9,16 @@ import haxework.view.geometry.SizeSet; import haxework.view.group.IGroupView; import haxework.view.skin.ISkin; import haxework.view.theme.ITheme; -import haxework.view.theme.StyleId; -class View implements IView { +@:style class View implements IView { private static var counter:Int = 0; public static var updater(default, null):ViewUpdater = new ViewUpdater(); @:provide var theme:ITheme; - public var geometry(default, default):Geometry; - public var skin(default, set):ISkin; - public var style(default, set):StyleId; + @:style public var geometry(default, default):Geometry; + @:style public var skin(default, default):ISkin; public var id(default, default):String; @@ -56,7 +54,11 @@ class View implements IView { geometry = new Geometry(); visible = true; index = -1; - skin = null; + } + + private function onStyle():Void { + toUpdate(); + toRedraw(); } public function toRedraw():Void { @@ -118,22 +120,13 @@ class View implements IView { return y; } - private function set_skin(value:ISkin):ISkin { + // ToDo: + /*private function set_skin(value:ISkin):ISkin { this.skin = value; toRedraw(); return this.skin; } - - private function set_style(value:StyleId):StyleId { - if (value != null && style != value) { - style = value; - if (theme != null) { - theme.bind(style, this); - } - } - return style; - } - +*/ private function set_visible(value:Bool):Bool { if (visible != value) { visible = value; diff --git a/src/main/haxework/view/form/ButtonView.hx b/src/main/haxework/view/form/ButtonView.hx index c324dc7..195d34f 100755 --- a/src/main/haxework/view/form/ButtonView.hx +++ b/src/main/haxework/view/form/ButtonView.hx @@ -1,5 +1,6 @@ package haxework.view.form; +import haxework.view.skin.ButtonColorSkin; import haxework.signal.Signal; import flash.events.MouseEvent; @@ -23,6 +24,7 @@ class ButtonView extends LabelView { public function new() { super(); + skin = new ButtonColorSkin(); style = "button"; overed = false; downed = false; diff --git a/src/main/haxework/view/geometry/Box.hx b/src/main/haxework/view/geometry/Box.hx index 44dc00b..55f1f50 100644 --- a/src/main/haxework/view/geometry/Box.hx +++ b/src/main/haxework/view/geometry/Box.hx @@ -69,11 +69,11 @@ abstract Box(Array) { return new Box(this); } - @:from static public inline function fromArray(value:Array):Box { + @:from static public function fromArray(value:Array):Box { return new Box(value); } - @:from static public inline function fromFloat(value:Float):Box { + @:from static public function fromFloat(value:Float):Box { return new Box([value]); } } diff --git a/src/main/haxework/view/geometry/Geometry.hx b/src/main/haxework/view/geometry/Geometry.hx index 20b429f..dfc147a 100644 --- a/src/main/haxework/view/geometry/Geometry.hx +++ b/src/main/haxework/view/geometry/Geometry.hx @@ -1,25 +1,17 @@ package haxework.view.geometry; -class Geometry { - public var width(default, default):SizeValue; - public var height(default, default):SizeValue; - public var padding(default, default):Box; - public var margin(default, default):Box; - public var hAlign(default, default):HAlign; - public var vAlign(default, default):VAlign; - public var position(default, default):Position; - public var ratio(default, default):Float; +@:style class Geometry { + @:style(0) public var width(default, default):SizeValue; + @:style(0) public var height(default, default):SizeValue; + @:style(0) public var padding(default, default):Box; + @:style(0) public var margin(default, default):Box; + @:style(HAlign.NONE) public var hAlign(default, default):HAlign; + @:style(VAlign.NONE) public var vAlign(default, default):VAlign; + @:style(Position.LAYOUT) public var position(default, default):Position; + @:style(-1) public var ratio(default, default):Null; public var stretch(null, set):Bool; public function new() { - this.padding = []; - this.margin = []; - this.width = 0; - this.height = 0; - this.hAlign = HAlign.NONE; - this.vAlign = VAlign.NONE; - this.position = Position.LAYOUT; - this.ratio = -1; } private function set_stretch(value:Bool):Bool { diff --git a/src/main/haxework/view/skin/BitmapSkin.hx b/src/main/haxework/view/skin/BitmapSkin.hx index 11e43ee..97d354a 100755 --- a/src/main/haxework/view/skin/BitmapSkin.hx +++ b/src/main/haxework/view/skin/BitmapSkin.hx @@ -4,7 +4,7 @@ import flash.display.BitmapData; import flash.geom.Rectangle; import haxework.view.utils.DrawUtil; -class BitmapSkin implements ISkin { +@:style class BitmapSkin implements ISkin { public var image(null, set):BitmapData; public var color(default, default):Int; public var fillType(default, default):FillType; diff --git a/src/main/haxework/view/skin/ButtonBitmapSkin.hx b/src/main/haxework/view/skin/ButtonBitmapSkin.hx index d23db94..f3f5827 100755 --- a/src/main/haxework/view/skin/ButtonBitmapSkin.hx +++ b/src/main/haxework/view/skin/ButtonBitmapSkin.hx @@ -7,7 +7,7 @@ import haxework.view.form.ButtonView; import haxework.view.utils.BitmapUtil; import haxework.view.utils.DrawUtil; -class ButtonBitmapSkin implements ISkin { +@:style class ButtonBitmapSkin implements ISkin { public var fillType(default, default):FillType; public var color(default, default):Int; diff --git a/src/main/haxework/view/skin/ButtonColorSkin.hx b/src/main/haxework/view/skin/ButtonColorSkin.hx index fd71181..ba04a01 100644 --- a/src/main/haxework/view/skin/ButtonColorSkin.hx +++ b/src/main/haxework/view/skin/ButtonColorSkin.hx @@ -10,21 +10,21 @@ import haxework.view.form.ToggleButtonView; using haxework.color.ColorUtil; -class ButtonColorSkin implements ISkin { +@:style class ButtonColorSkin implements ISkin { - public var color(default, default):Color; + @:style(0xffffff) public var color(default, default):Null; public var borderColor(default, default):Null; public var round(default, default):Float; private var colors:Map; public function new(?color:Color, ?borderColor:Color, round:Float = 15) { - this.color = color != null ? color : 0xffffff; + this.color = color; this.borderColor = borderColor; this.round = round; } public function draw(view:ButtonView):Void { - var color:Color = stateColor(color, view.state); + var color = color; var borderColor:Color = borderColor != null ? borderColor : color.multiply(1.5); if (Std.is(view, ToggleButtonView)) { if (!cast(view, ToggleButtonView).on) { diff --git a/src/main/haxework/view/skin/HScrollBarSkin.hx b/src/main/haxework/view/skin/HScrollBarSkin.hx index f3594c0..6d694f7 100644 --- a/src/main/haxework/view/skin/HScrollBarSkin.hx +++ b/src/main/haxework/view/skin/HScrollBarSkin.hx @@ -3,7 +3,7 @@ package haxework.view.skin; import haxework.color.ColorUtil; import haxework.view.list.ScrollBarView; -class HScrollBarSkin implements ISkin { +@:style class HScrollBarSkin implements ISkin { public var foreColor(default, default):Int; public var backColor(default, default):Int; diff --git a/src/main/haxework/view/skin/ISkin.hx b/src/main/haxework/view/skin/ISkin.hx index 7a7971d..f1dcd3b 100644 --- a/src/main/haxework/view/skin/ISkin.hx +++ b/src/main/haxework/view/skin/ISkin.hx @@ -1,5 +1,7 @@ package haxework.view.skin; -interface ISkin> { +import haxework.view.theme.IStylable; + +interface ISkin> extends IStylable { public function draw(view:V):Void; } diff --git a/src/main/haxework/view/skin/ProgressSkin.hx b/src/main/haxework/view/skin/ProgressSkin.hx index bd0d39d..9bc58a0 100755 --- a/src/main/haxework/view/skin/ProgressSkin.hx +++ b/src/main/haxework/view/skin/ProgressSkin.hx @@ -3,7 +3,7 @@ package haxework.view.skin; import flash.display.Graphics; import haxework.view.skin.ISkin; -class ProgressSkin implements ISkin { +@:style class ProgressSkin implements ISkin { public var foreColor:Int; public var backColor:Int; diff --git a/src/main/haxework/view/skin/SpriteSkin.hx b/src/main/haxework/view/skin/SpriteSkin.hx index 78c45e0..42fa867 100644 --- a/src/main/haxework/view/skin/SpriteSkin.hx +++ b/src/main/haxework/view/skin/SpriteSkin.hx @@ -14,10 +14,10 @@ typedef Background = { @:optional var alpha:Float; } -class SpriteSkin implements ISkin { +@:style class SpriteSkin implements ISkin { - public var border(default, default):Border; - public var background(default, default):Background; + @:style({}) public var border(default, default):Border; + @:style({}) public var background(default, default):Background; public function new(?background:Background, ?border:Border) { this.background = resolveBackground(background); @@ -28,7 +28,7 @@ class SpriteSkin implements ISkin { 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 { @@ -36,7 +36,7 @@ class SpriteSkin implements ISkin { 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 { diff --git a/src/main/haxework/view/skin/VScrollBarSkin.hx b/src/main/haxework/view/skin/VScrollBarSkin.hx index 841fd05..5a772d0 100644 --- a/src/main/haxework/view/skin/VScrollBarSkin.hx +++ b/src/main/haxework/view/skin/VScrollBarSkin.hx @@ -3,7 +3,7 @@ package haxework.view.skin; import haxework.color.ColorUtil; import haxework.view.list.ScrollBarView; -class VScrollBarSkin implements ISkin { +@:style class VScrollBarSkin implements ISkin { public var foreColor(default, default):Int; public var backColor(default, default):Int; diff --git a/src/main/haxework/view/text/FontPreset.hx b/src/main/haxework/view/text/FontPreset.hx index 4a1c31e..aa9c199 100644 --- a/src/main/haxework/view/text/FontPreset.hx +++ b/src/main/haxework/view/text/FontPreset.hx @@ -3,13 +3,13 @@ package haxework.view.text; import haxework.color.Color; import flash.text.TextFormatAlign; -class FontPreset { - public var family(default, default):String; - public var embed(default, default):Bool; - public var color(default, default):Null; - public var size(default, default):Null; - public var bold(default, default):Bool; - public var align(default, default):TextFormatAlign; +@:style class FontPreset { + @:style("Courirer") public var family(default, default):String; + @:style(false) public var embed(default, default):Null; + @:style(0xffffff) public var color(default, default):Null; + @:style(16) public var size(default, default):Null; + @:style(false) public var bold(default, default):Null; + @:style(TextFormatAlign.LEFT) public var align(default, default):TextFormatAlign; public function new(?family:String, ?embed:Bool, ?color:Color, ?size:Int, ?bold:Bool, ?align:TextFormatAlign) { diff --git a/src/main/haxework/view/text/ITextView.hx b/src/main/haxework/view/text/ITextView.hx index 9426d77..1c7961e 100755 --- a/src/main/haxework/view/text/ITextView.hx +++ b/src/main/haxework/view/text/ITextView.hx @@ -5,8 +5,8 @@ import haxework.view.IView; import haxework.view.layout.ILayout; interface ITextView extends IView { - @:style public var font(default, default):FontPreset; - @:style public var layout(default, default):ILayout; + public var font(default, set):FontPreset; + public var layout(default, default):ILayout; public var textField(default, null):TextField; public var text(get, set):String; diff --git a/src/main/haxework/view/text/TextView.hx b/src/main/haxework/view/text/TextView.hx index bc8ca1b..fdcfff7 100755 --- a/src/main/haxework/view/text/TextView.hx +++ b/src/main/haxework/view/text/TextView.hx @@ -11,8 +11,8 @@ import haxework.view.geometry.VAlign; import haxework.view.layout.ILayout; import haxework.view.layout.Layout; -class TextView extends SpriteView implements ITextView { - public var font(default, default):FontPreset; +@:style(true) class TextView extends SpriteView implements ITextView { + @:style public var font(default, default):FontPreset; public var layout(default, default):ILayout; public var textField(default, null):TextField; diff --git a/src/main/haxework/view/theme/IStylable.hx b/src/main/haxework/view/theme/IStylable.hx new file mode 100644 index 0000000..40dad61 --- /dev/null +++ b/src/main/haxework/view/theme/IStylable.hx @@ -0,0 +1,6 @@ +package haxework.view.theme; + +interface IStylable { + public var styleKey(default, set):String; + public var style(default, set):StyleId; +} diff --git a/src/main/haxework/view/theme/ITheme.hx b/src/main/haxework/view/theme/ITheme.hx index ad85637..b0215ad 100644 --- a/src/main/haxework/view/theme/ITheme.hx +++ b/src/main/haxework/view/theme/ITheme.hx @@ -1,5 +1,6 @@ package haxework.view.theme; +import haxework.signal.Signal; import haxework.color.Color; typedef ThemeFont = { @@ -18,5 +19,6 @@ typedef ThemeColors = { interface ITheme { public var font(default, set):ThemeFont; public var colors(default, set):ThemeColors; - public function bind(style:StyleId, view:IView):Void; + public var updateSignal(default, null):Signal0; + public function resolve(key:String, style:StyleId):T; } diff --git a/src/main/haxework/view/theme/Theme.hx b/src/main/haxework/view/theme/Theme.hx index c2d7ef5..5aa752d 100644 --- a/src/main/haxework/view/theme/Theme.hx +++ b/src/main/haxework/view/theme/Theme.hx @@ -1,9 +1,11 @@ package haxework.view.theme; +import haxework.view.geometry.Box; import flash.text.Font; import flash.text.FontType; import haxe.ds.StringMap; import haxework.color.Color; +import haxework.signal.Signal; import haxework.view.geometry.Geometry; import haxework.view.skin.Skin; import haxework.view.skin.SpriteSkin; @@ -61,11 +63,16 @@ class Theme implements ITheme { public var font(default, set):ThemeFont; public var colors(default, set):ThemeColors; + public var updateSignal(default, null):Signal0; private var styles:StyleMap; + private var data:Map>; + public function new(?font:ThemeFont, ?colors:ThemeColors) { styles = new StyleMap(); + updateSignal = new Signal0(); + data = new Map(); this.font = font; this.colors = colors; L.d("Theme", 'font: ${this.font}'); @@ -90,6 +97,37 @@ class Theme implements ITheme { private function reload():Void { + data.set("background", [ + "skin.background" => {color: colors.dark, alpha: 1}, + ]); + data.set("text", [ + "font.color" => colors.text, + "font.family" => font.name, + "font.embed" => font.embed, + ]); + data.set("button", [ + "skin.color" => colors.light, + "geometry.padding" => Box.fromArray([25, 8]), + "font.color" => colors.text, + "font.family" => font.name, + "font.embed" => font.embed, + ]); + data.set("button.tab", [ + "skin.color" => colors.light, + "geometry.padding" => Box.fromArray([25, 8]), + "font.color" => colors.text, + "font.family" => font.name, + "font.embed" => font.embed, + ]); + + // ToDo: hardcode update views + if (Root.instance != null) { + for (view in Root.instance.views()) { + view.style = view.style; + } + } + 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))])); @@ -162,6 +200,10 @@ class Theme implements ITheme { styles.disconnect(view); } + public function resolve(key:String, style:StyleId):T { + return style != null && data.exists(style) ? data.get(style).get(key) : null; + } + private static function resolveFont(font:ThemeFont):ThemeFont { if (font == null) { font = {};