[macro] add StyleMacro
This commit is contained in:
@@ -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<Field> {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
220
src/main/haxework/macro/StyleMacro.hx
Normal file
220
src/main/haxework/macro/StyleMacro.hx
Normal file
@@ -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<T> = {
|
||||
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<Field>;
|
||||
private var overrideStyle:Bool;
|
||||
|
||||
public function new(classType:ClassType, fields:Array<Field>) {
|
||||
this.classType = classType;
|
||||
this.fields = fields;
|
||||
this.overrideStyle = classType.getClassMeta(":style").params.length > 0;
|
||||
}
|
||||
|
||||
private static function processPropertyField(field:Field):Array<Field> {
|
||||
var result:Array<Field> = [];
|
||||
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<Field> {
|
||||
var type:ComplexType = field.getComplexType();
|
||||
var result:Array<Field> = [];
|
||||
field.kind = FProp("default", "set", type);
|
||||
var expr:Array<Expr> = [];
|
||||
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<Field> {
|
||||
var result:Array<Field> = [];
|
||||
var type:ComplexType = "String".toComplex();
|
||||
if (!overrideField) {
|
||||
result.push({
|
||||
name: "styleKey",
|
||||
access: [APublic],
|
||||
pos: Context.currentPos(),
|
||||
kind: FProp("default", "set", type),
|
||||
});
|
||||
}
|
||||
var expr:Array<Expr> = [];
|
||||
if (overrideField) {
|
||||
expr.push(macro super.styleKey = value);
|
||||
}
|
||||
expr.push(macro styleKey = value);
|
||||
expr.push(macro return styleKey);
|
||||
var access:Array<Access> = [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<Field>, styleds:Array<Field>, hasOnStyle:Bool, overrideField:Bool):Array<Field> {
|
||||
var result:Array<Field> = [];
|
||||
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<Expr> = [];
|
||||
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<Access> = [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<Field> {
|
||||
var result:Array<Field> = fields.slice(0);
|
||||
var styleds:Array<Field> = [];
|
||||
var properties:Array<Field> = [];
|
||||
var newFields:Array<Field> = [];
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<Field>;
|
||||
private var bindings:Map<String, String>;
|
||||
|
||||
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<Field>) {
|
||||
this.classType = classType;
|
||||
this.meta = classType.getClassMeta(metaName);
|
||||
this.fields = fields;
|
||||
var params = Util.getMetaParams(meta);
|
||||
var filePath = params[0];
|
||||
|
||||
@@ -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<String> {
|
||||
@@ -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<MetadataEntry> {
|
||||
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<MetadataEntry> {
|
||||
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<ComplexType> {
|
||||
return switch field.kind {
|
||||
case FProp(get, set, t, e): t;
|
||||
case FVar(t, e): t;
|
||||
case _: null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function getField(fields:Array<Field>, name:String):Null<Field> {
|
||||
return Lambda.find(fields, function(field:Field):Bool return field.name == name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -9,8 +9,8 @@ import haxework.view.skin.ISkin;
|
||||
import haxework.view.theme.StyleId;
|
||||
|
||||
interface IView<C:DisplayObject> {
|
||||
@:style public var geometry(default, default):Geometry;
|
||||
@:style public var skin(default, set):ISkin<Dynamic>;
|
||||
public var geometry(default, set):Geometry;
|
||||
public var skin(default, set):ISkin<Dynamic>;
|
||||
|
||||
public var id(default, default):String;
|
||||
|
||||
|
||||
@@ -73,4 +73,19 @@ class Root {
|
||||
onResize.dispose();
|
||||
}
|
||||
|
||||
private static function getViews(view:IView<Dynamic>):Array<IView<Dynamic>> {
|
||||
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<IView<Dynamic>> {
|
||||
return getViews(view);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<C:DisplayObject> implements IView<C> {
|
||||
@:style class View<C:DisplayObject> implements IView<C> {
|
||||
|
||||
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<Dynamic>;
|
||||
public var style(default, set):StyleId;
|
||||
@:style public var geometry(default, default):Geometry;
|
||||
@:style public var skin(default, default):ISkin<Dynamic>;
|
||||
|
||||
public var id(default, default):String;
|
||||
|
||||
@@ -56,7 +54,11 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
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<C:DisplayObject> implements IView<C> {
|
||||
return y;
|
||||
}
|
||||
|
||||
private function set_skin(value:ISkin<Dynamic>):ISkin<Dynamic> {
|
||||
// ToDo:
|
||||
/*private function set_skin(value:ISkin<Dynamic>):ISkin<Dynamic> {
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -69,11 +69,11 @@ abstract Box(Array<Float>) {
|
||||
return new Box(this);
|
||||
}
|
||||
|
||||
@:from static public inline function fromArray(value:Array<Float>):Box {
|
||||
@:from static public function fromArray(value:Array<Float>):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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Float>;
|
||||
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 {
|
||||
|
||||
@@ -4,7 +4,7 @@ import flash.display.BitmapData;
|
||||
import flash.geom.Rectangle;
|
||||
import haxework.view.utils.DrawUtil;
|
||||
|
||||
class BitmapSkin implements ISkin<SpriteView> {
|
||||
@:style class BitmapSkin implements ISkin<SpriteView> {
|
||||
public var image(null, set):BitmapData;
|
||||
public var color(default, default):Int;
|
||||
public var fillType(default, default):FillType;
|
||||
|
||||
@@ -7,7 +7,7 @@ import haxework.view.form.ButtonView;
|
||||
import haxework.view.utils.BitmapUtil;
|
||||
import haxework.view.utils.DrawUtil;
|
||||
|
||||
class ButtonBitmapSkin implements ISkin<ButtonView> {
|
||||
@:style class ButtonBitmapSkin implements ISkin<ButtonView> {
|
||||
|
||||
public var fillType(default, default):FillType;
|
||||
public var color(default, default):Int;
|
||||
|
||||
@@ -10,21 +10,21 @@ import haxework.view.form.ToggleButtonView;
|
||||
|
||||
using haxework.color.ColorUtil;
|
||||
|
||||
class ButtonColorSkin implements ISkin<ButtonView> {
|
||||
@:style class ButtonColorSkin implements ISkin<ButtonView> {
|
||||
|
||||
public var color(default, default):Color;
|
||||
@:style(0xffffff) public var color(default, default):Null<Color>;
|
||||
public var borderColor(default, default):Null<Color>;
|
||||
public var round(default, default):Float;
|
||||
private var colors:Map<ButtonState, Int>;
|
||||
|
||||
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) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package haxework.view.skin;
|
||||
import haxework.color.ColorUtil;
|
||||
import haxework.view.list.ScrollBarView;
|
||||
|
||||
class HScrollBarSkin implements ISkin<ScrollBarView> {
|
||||
@:style class HScrollBarSkin implements ISkin<ScrollBarView> {
|
||||
public var foreColor(default, default):Int;
|
||||
public var backColor(default, default):Int;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package haxework.view.skin;
|
||||
|
||||
interface ISkin<V:IView<Dynamic>> {
|
||||
import haxework.view.theme.IStylable;
|
||||
|
||||
interface ISkin<V:IView<Dynamic>> extends IStylable {
|
||||
public function draw(view:V):Void;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package haxework.view.skin;
|
||||
import flash.display.Graphics;
|
||||
import haxework.view.skin.ISkin;
|
||||
|
||||
class ProgressSkin implements ISkin<ProgressView> {
|
||||
@:style class ProgressSkin implements ISkin<ProgressView> {
|
||||
|
||||
public var foreColor:Int;
|
||||
public var backColor:Int;
|
||||
|
||||
@@ -14,10 +14,10 @@ typedef Background = {
|
||||
@:optional var alpha:Float;
|
||||
}
|
||||
|
||||
class SpriteSkin implements ISkin<SpriteView> {
|
||||
@:style class SpriteSkin implements ISkin<SpriteView> {
|
||||
|
||||
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<SpriteView> {
|
||||
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<SpriteView> {
|
||||
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 {
|
||||
|
||||
@@ -3,7 +3,7 @@ package haxework.view.skin;
|
||||
import haxework.color.ColorUtil;
|
||||
import haxework.view.list.ScrollBarView;
|
||||
|
||||
class VScrollBarSkin implements ISkin<ScrollBarView> {
|
||||
@:style class VScrollBarSkin implements ISkin<ScrollBarView> {
|
||||
public var foreColor(default, default):Int;
|
||||
public var backColor(default, default):Int;
|
||||
|
||||
|
||||
@@ -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<Color>;
|
||||
public var size(default, default):Null<Int>;
|
||||
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<Bool>;
|
||||
@:style(0xffffff) public var color(default, default):Null<Color>;
|
||||
@:style(16) public var size(default, default):Null<Int>;
|
||||
@:style(false) public var bold(default, default):Null<Bool>;
|
||||
@:style(TextFormatAlign.LEFT) public var align(default, default):TextFormatAlign;
|
||||
|
||||
public function new(?family:String, ?embed:Bool, ?color:Color, ?size:Int,
|
||||
?bold:Bool, ?align:TextFormatAlign) {
|
||||
|
||||
@@ -5,8 +5,8 @@ import haxework.view.IView;
|
||||
import haxework.view.layout.ILayout;
|
||||
|
||||
interface ITextView extends IView<Dynamic> {
|
||||
@: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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
6
src/main/haxework/view/theme/IStylable.hx
Normal file
6
src/main/haxework/view/theme/IStylable.hx
Normal file
@@ -0,0 +1,6 @@
|
||||
package haxework.view.theme;
|
||||
|
||||
interface IStylable {
|
||||
public var styleKey(default, set):String;
|
||||
public var style(default, set):StyleId;
|
||||
}
|
||||
@@ -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<Dynamic>):Void;
|
||||
public var updateSignal(default, null):Signal0;
|
||||
public function resolve<T>(key:String, style:StyleId):T;
|
||||
}
|
||||
|
||||
@@ -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<String, Map<String, Dynamic>>;
|
||||
|
||||
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<T>(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 = {};
|
||||
|
||||
Reference in New Issue
Block a user