[skin] update

This commit is contained in:
2019-02-22 15:38:34 +03:00
parent 78ecd35587
commit 5cd1bbc30a
19 changed files with 199 additions and 203 deletions

View File

@@ -1,5 +1,7 @@
package demo; package demo;
import haxework.resources.Resources;
import haxework.resources.IResources;
import haxework.gui.frame.IFrameSwitcher; import haxework.gui.frame.IFrameSwitcher;
import haxework.net.manage.LoaderManager; import haxework.net.manage.LoaderManager;
import haxework.net.manage.ILoaderManager; import haxework.net.manage.ILoaderManager;
@@ -9,11 +11,14 @@ import haxework.gui.VGroupView;
@:template class Demo extends VGroupView { @:template class Demo extends VGroupView {
@:provide static var resources:IResources;
@:provide static var manager:ILoaderManager; @:provide static var manager:ILoaderManager;
public static function main() { public static function main() {
L.push(new TraceLogger()); L.push(new TraceLogger());
resources = new Resources();
manager = new LoaderManager(); manager = new LoaderManager();
Style.register();
var demo = new Demo(); var demo = new Demo();
demo.switcher.change("list_form"); demo.switcher.change("list_form");
Root.bind(demo); Root.bind(demo);

View File

@@ -1,27 +1,31 @@
--- ---
pWidth: 100 pWidth: 100
pHeight: 100 pHeight: 100
skin: [ $type: [haxework.gui.skin.Skin.color, 0x333333] ] skin: $r:skin:background
views: views:
- $type: haxework.gui.HGroupView - $type: haxework.gui.HGroupView
layoutMargin: 10 layoutMargin: 5
layoutHAlign: LEFT
leftPadding: 5
pWidth: 100 pWidth: 100
height: 40 height: 40
views: views:
- $type: haxework.gui.ButtonView - $type: haxework.gui.ButtonView
skin: $raw:Style.buttonSkin skin: $r:skin:button
contentSize: true contentSize: true
paddings: 8 paddings: 8
text: List Form text: List Form
+onPress: "$raw:function(_) switcher.change('list_form')" +onPress: "$code:function(_) switcher.change('list_form')"
- $type: haxework.gui.ButtonView - $type: haxework.gui.ButtonView
skin: $raw:Style.buttonSkin skin: $r:skin:button
contentSize: true contentSize: true
paddings: 8 paddings: 8
text: Tail Form text: Tail Form
+onPress: "$raw:function(_) switcher.change('tail_form')" +onPress: "$code:function(_) switcher.change('tail_form')"
- id: switcher - id: switcher
$type: haxework.gui.frame.FrameSwitcher $type: haxework.gui.frame.FrameSwitcher
skin: [ $type: [ haxework.gui.skin.Skin.border, 0x33aa33, 1, 2 ] ]
paddings: 5
pWidth: 100 pWidth: 100
pHeight: 100 pHeight: 100
views: views:

View File

@@ -1,23 +1,45 @@
package demo; package demo;
import haxework.gui.list.ScrollBarSkin;
import haxework.resources.IResources;
import haxework.gui.skin.ISkin; import haxework.gui.skin.ISkin;
import haxework.gui.skin.ButtonColorSkin; import haxework.gui.skin.ButtonSkin;
import haxework.gui.skin.TextSkin;
import haxework.gui.skin.Skin; import haxework.gui.skin.Skin;
import haxework.gui.skin.ISkin.SkinSet; import haxework.gui.skin.TextSkin;
class Style { class Style {
public static var textSkin = new TextSkin(0xffffff, "Courirer"); @:provide static var resources:IResources;
public static var buttonSkin: SkinSet = [ public static var backColor = 0x33aa33;
new ButtonColorSkin(0x33aa33), public static var textColor = 0xffffff;
textSkin, public static var borderColor = 0xffffff;
public static var text:ISkin<Dynamic> = new TextSkin(textColor, "Courirer");
public static var background:SkinSet = [
Skin.color(0x00000),
]; ];
public static var viewSkin:SkinSet = [ public static var button:SkinSet = [
Skin.color(0x33aa33), ButtonSkin.color(backColor),
Skin.border(0xffffff), text,
textSkin,
]; ];
public static var view:SkinSet = [
Skin.color(backColor),
Skin.border(borderColor),
text,
];
public static var scroll:SkinSet = [
ScrollBarSkin.vertical(0x55cc55, 0xccffcc),
];
public static function register():Void {
resources.skin.put("background", background);
resources.skin.put("button", button);
resources.skin.put("view", view);
resources.skin.put("scroll", scroll);
}
} }

View File

@@ -1,8 +1,6 @@
--- ---
$type: haxework.gui.VGroupView $type: haxework.gui.VGroupView
paddings: 20
layoutMargin: 10 layoutMargin: 10
skin: [ $type: [haxework.gui.skin.Skin.color, 0x333333] ]
views: views:
- id: list - id: list
$type: haxework.gui.list.VListView<String> $type: haxework.gui.list.VListView<String>
@@ -12,36 +10,7 @@ views:
pHeight: 100 pHeight: 100
scroll: scroll:
$type: haxework.gui.list.VScrollBarView $type: haxework.gui.list.VScrollBarView
skin: $r:skin:scroll
width: 10 width: 10
pHeight: 100 pHeight: 100
skin: [ $type: [haxework.gui.list.ScrollBarSkin.vertical, 0x55cc55, 0xccffcc] ]
skin: [ $type: [haxework.gui.skin.Skin.color, 0xffffff] ]
- id: panel
$type: haxework.gui.HGroupView
pWidth: 100
height: 60
# contentSize: true
layoutMargin: 10
skin: [ $type: [haxework.gui.skin.Skin.color, 0x555555] ]
views:
- id: button1
$type: haxework.gui.ButtonView
+onPress: $this:onPress
contentSize: true
paddings: 8
skin: $raw:Style.buttonSkin
text: OK
- id: button2
$type: haxework.gui.ButtonView
+onPress: $this:onPress
contentSize: true
paddings: 8
skin: $raw:Style.buttonSkin
text: Apply
- id: button3
$type: haxework.gui.ButtonView
+onPress: $this:onPress
contentSize: true
paddings: 8
skin: $raw:Style.buttonSkin
text: Cancel

View File

@@ -14,7 +14,7 @@ import haxework.gui.TextView;
var view = new TextView(); var view = new TextView();
view.width = 100 + 100 * Math.random(); view.width = 100 + 100 * Math.random();
view.height = 100 + 100 * Math.random(); view.height = 100 + 100 * Math.random();
view.skin = Style.viewSkin; view.skin = Style.view;
view.text = 'View #${i}'; view.text = 'View #${i}';
group.addView(view); group.addView(view);
} }

View File

@@ -3,18 +3,16 @@ pWidth: 100
pHeight: 100 pHeight: 100
views: views:
- $type: haxework.gui.ScrollView - $type: haxework.gui.ScrollView
skin: [ $type: [haxework.gui.skin.Skin.color, 0xff0000] ]
pWidth: 100 pWidth: 100
pHeight: 100 pHeight: 100
scroll: scroll:
$type: haxework.gui.list.VScrollBarView $type: haxework.gui.list.VScrollBarView
skin: $r:skin:scroll
width: 10 width: 10
pHeight: 100 pHeight: 100
skin: [ $type: [haxework.gui.list.ScrollBarSkin.vertical, 0x55cc55, 0xccffcc] ]
view: view:
id: group id: group
$type: haxework.gui.GroupView $type: haxework.gui.GroupView
skin: [ $type: [haxework.gui.skin.Skin.color, 0xffff00] ]
pWidth: 100 pWidth: 100
contentSize: true contentSize: true
layoutMargin: 5 layoutMargin: 5

View File

@@ -21,7 +21,7 @@ class ImageView extends SpriteView {
private function set_image(value:BitmapData):BitmapData { private function set_image(value:BitmapData):BitmapData {
if (image != value) { if (image != value) {
image = value; image = value;
skin = cast new BitmapSkin(image, FillType.CONTAIN); skin = [new BitmapSkin(image, FillType.CONTAIN)];
invalidate(); invalidate();
} }
return image; return image;

View File

@@ -18,7 +18,7 @@ class ScrollView extends HGroupView {
public function new() { public function new() {
super(); super();
skin = [Skin.color(0x0000FF, 1.0)]; skin = [Skin.color(0x000000, 0.0)];
mask = new Shape(); mask = new Shape();
content.addChild(mask); content.addChild(mask);
content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent); content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelEvent);

View File

@@ -1,12 +1,12 @@
package haxework.gui; package haxework.gui;
import flash.display.Sprite; import flash.display.Sprite;
import haxework.gui.skin.ISkin; import haxework.gui.skin.ISkin.SkinSet;
class ToggleButtonView extends ButtonView { class ToggleButtonView extends ButtonView {
public var on(default, set):Bool; public var on(default, set):Bool;
public var onSkin(default, set):ISkin<Dynamic>; public var onSkin(default, set):SkinSet;
public var onText(default, set):String; public var onText(default, set):String;
@@ -20,13 +20,13 @@ class ToggleButtonView extends ButtonView {
return on; return on;
} }
private function set_onSkin(value:ISkin<Dynamic>):ISkin<Dynamic> { private function set_onSkin(value:SkinSet):SkinSet {
onSkin = value; onSkin = value;
invalidate(); invalidate();
return onSkin; return onSkin;
} }
override private function currentSkin():ISkin<Dynamic> { private function currentSkin():SkinSet {
return on ? onSkin : skin; return on ? onSkin : skin;
} }

View File

@@ -4,7 +4,7 @@ import flash.display.BitmapData;
import flash.geom.Rectangle; import flash.geom.Rectangle;
import haxework.gui.utils.DrawUtil; import haxework.gui.utils.DrawUtil;
class BitmapSkin implements ISkin<SpriteView> implements ISize { class BitmapSkin implements ISkin<SpriteView> {
public var width(default, null):Float; public var width(default, null):Float;
public var height(default, null):Float; public var height(default, null):Float;

View File

@@ -14,7 +14,7 @@ class BorderSkin implements ISkin<SpriteView> {
public function draw(view:SpriteView):Void { public function draw(view:SpriteView):Void {
view.content.graphics.lineStyle(tickness, color, alpha, true); view.content.graphics.lineStyle(tickness, color, alpha, true);
view.content.graphics.drawRect(0, 0, view.width, view.height); view.content.graphics.drawRect(0, 0, view.width - tickness, view.height - tickness);
view.content.graphics.lineStyle(); view.content.graphics.lineStyle();
} }
} }

View File

@@ -1,10 +1,10 @@
package haxework.macro; package haxework.macro;
import yaml.YamlException;
import yaml.Parser; import yaml.Parser;
import yaml.Yaml; import yaml.Yaml;
import haxe.macro.Context; import haxe.macro.Context;
class FileUtil { class FileUtil {
public static function loadJsonFile(path:String):Dynamic { public static function loadJsonFile(path:String):Dynamic {
@@ -21,16 +21,17 @@ class FileUtil {
} }
public static function loadYamlFile(path:String):Dynamic { public static function loadYamlFile(path:String):Dynamic {
path = sys.FileSystem.absolutePath(path);
Context.registerModuleDependency(Context.getLocalModule(), path); Context.registerModuleDependency(Context.getLocalModule(), path);
var content = sys.io.File.getContent(path); var content = sys.io.File.getContent(path);
var result = null; var result = null;
try { try {
// ToDo: extract poisiton info
result = Yaml.parse(content, Parser.options().useObjects()); result = Yaml.parse(content, Parser.options().useObjects());
} catch (error:Dynamic) { PositionYamlParser.parse(path, content, result);
Context.error(error, Context.makePosition({min:0, max:0, file:path})); } catch (error:YamlException) {
Context.error(Std.string(error), Context.makePosition({min:0, max:0, file:path}));
} }
//Context.parse(content, Context.makePosition({min:0, max:0, file:path})); Context.parse('/*$content*/""', Context.makePosition({min:0, max:0, file:path}));
return result; return result;
} }

View File

@@ -0,0 +1,44 @@
package haxework.macro;
class PositionYamlParser {
private var filename:String;
private var content:String;
private var cache:Map<String, Int>;
private var result:Dynamic;
private function new(filename:String, content:String, result:Dynamic) {
this.filename = filename;
this.content = content;
this.result = result;
this.cache = new Map();
}
private function parseAll():Void {
parseBlock(result);
}
private function parseBlock(result:Dynamic):Void {
for (field in Reflect.fields(result)) {
var offset = content.indexOf(field, cache.get(field));
cache.set(field, offset);
Reflect.setField(result, "$" + field, {
min:offset,
max:offset + field.length,
file:filename,
});
var value = Reflect.field(result, field);
if (Std.is(value, Array)) {
for (item in cast(value, Array<Dynamic>)) {
parseBlock(item);
}
} else {
parseBlock(value);
}
}
}
public static function parse(filename:String, content:String, result:Dynamic):Void {
new PositionYamlParser(filename, content, result).parseAll();
}
}

View File

@@ -0,0 +1,23 @@
package haxework.macro;
import haxe.macro.Expr;
class ResourceMacro {
public static function has(field:Field):Bool {
return Util.hasFieldMeta(":resource", field);
}
private var field:Field;
public function new(field:Field) {
this.field = field;
}
public function apply():Array<Field> {
var result:Array<Field> = [];
return result;
}
}

View File

@@ -1,42 +0,0 @@
package haxework.macro;
import haxe.macro.Expr.MetadataEntry;
import haxe.macro.Context;
import haxe.macro.Type.ClassType;
class StyleMacro {
private static inline var metaName:String = ':style';
public static function has(classType:ClassType):Bool {
return Util.hasClassMeta(metaName, classType);
}
public static var style:Dynamic;
private var classType:ClassType;
private var bindings:Map<String, String>;
private var meta(get, never):MetadataEntry;
private var styleFile:String;
private function get_meta():MetadataEntry {
for (md in classType.meta.get()) if (md.name == metaName) {
return md;
}
return null;
}
public function new(classType:ClassType) {
this.classType = classType;
var params = Util.getMetaParams(meta);
var filePath = params[0];
if (filePath == null) {
filePath = classType.pack.join("/") + "/" + classType.name + ".yaml";
}
styleFile = Context.resolvePath(filePath);
style = FileUtil.loadFile(styleFile);
}
}

View File

@@ -22,7 +22,6 @@ class TemplateMacro {
private var meta(get, never):MetadataEntry; private var meta(get, never):MetadataEntry;
private var templateFile:String; private var templateFile:String;
private var template:Dynamic; private var template:Dynamic;
private var style:Dynamic;
private var i:Int; private var i:Int;
private function get_meta():MetadataEntry { private function get_meta():MetadataEntry {
@@ -42,12 +41,6 @@ class TemplateMacro {
} }
templateFile = Context.resolvePath(filePath); templateFile = Context.resolvePath(filePath);
template = FileUtil.loadFile(templateFile); template = FileUtil.loadFile(templateFile);
if (params.length > 1) {
var styleFile = params.length > 1 ? Context.resolvePath(params[1]) : null;
style = FileUtil.loadFile(styleFile);
} else {
style = StyleMacro.style;
}
bindings = findViewsBindings(fields); bindings = findViewsBindings(fields);
} }
@@ -63,8 +56,8 @@ class TemplateMacro {
} }
private function getPosition(?position:JsonKeyPosition):Position { private function getPosition(?position:JsonKeyPosition):Position {
var min = position == null ? 1 : position.min + 32; // :-( var min = position == null ? 1 : position.min; // :-(
var max = position == null ? 1 : position.max + 32; var max = position == null ? 1 : position.max;
var file = position == null || position.file == null ? templateFile : position.file; var file = position == null || position.file == null ? templateFile : position.file;
return Context.makePosition({min:min, max:max, file:file}); return Context.makePosition({min:min, max:max, file:file});
} }
@@ -78,13 +71,13 @@ class TemplateMacro {
case _: case _:
a[2]; a[2];
} }
case "res": case "res" | "r":
var bindExpr = 'haxework.provider.Provider.get(haxework.resources.IResources).${a[1]}.bind("${[2]}", "${name}", "${key}")'; var bindExpr = 'haxework.provider.Provider.get(haxework.resources.IResources).${a[1]}.bind("${a[2]}", ${name}, "${key}")';
exprs.push(Context.parse(bindExpr, getPosition(position))); exprs.push(Context.parse(bindExpr, getPosition(position)));
null; null;
case "locale": case "locale":
'new haxework.locale.LString("${[1]}")'; 'new haxework.locale.LString("${[1]}")';
case "raw": case "code":
a[1]; a[1];
case "this": case "this":
'this.${a[1]}'; 'this.${a[1]}';
@@ -99,7 +92,7 @@ class TemplateMacro {
private static function getType(value:Dynamic, position:Position):Dynamic { private static function getType(value:Dynamic, position:Position):Dynamic {
var type:Dynamic = getSpecField(value, "type"); var type:Dynamic = getSpecField(value, "type");
if (type == null) { if (type == null) {
Context.error("Need @type field", position); Context.error("Need $type field", position);
} }
return type; return type;
} }
@@ -147,17 +140,6 @@ class TemplateMacro {
} }
private function createElement(name:String, data:Dynamic, exprs:Array<Expr>):String { private function createElement(name:String, data:Dynamic, exprs:Array<Expr>):String {
var s = getSpecField(data, "style");
if (s != null) {
var s = Reflect.field(style, s);
for (key in Reflect.fields(s)) {
if (key.charAt(0) != "$" && !Reflect.hasField(data, key)) {
Reflect.setField(data, key, Reflect.field(s, key));
Reflect.setField(data, "$" + key, Reflect.field(s, "$" + key));
}
}
}
if (Reflect.hasField(data, "id")) { if (Reflect.hasField(data, "id")) {
var id = Reflect.field(data, "id"); var id = Reflect.field(data, "id");
if (bindings.exists(id)) { if (bindings.exists(id)) {

View File

@@ -1,12 +1,10 @@
package haxework.parser; package haxework.parser;
import haxework.macro.StyleMacro;
import haxe.macro.Context; import haxe.macro.Context;
import haxe.macro.Expr; import haxe.macro.Expr;
import haxe.macro.Type.ClassType;
import haxe.macro.Type.Ref;
import haxe.macro.Type; import haxe.macro.Type;
import haxework.macro.ProvideMacro; import haxework.macro.ProvideMacro;
import haxework.macro.ResourceMacro;
import haxework.macro.TemplateMacro; import haxework.macro.TemplateMacro;
@@ -31,6 +29,10 @@ class Parser {
modify = true; modify = true;
var provide = new ProvideMacro(field); var provide = new ProvideMacro(field);
result = result.concat(provide.apply()); result = result.concat(provide.apply());
} else if (ResourceMacro.has(field)) {
modify = true;
var resource = new ResourceMacro(field);
result = result.concat(resource.apply());
} else { } else {
result.push(field); result.push(field);
} }
@@ -39,9 +41,6 @@ class Parser {
fields = result; fields = result;
} }
// process class meta // process class meta
if (StyleMacro.has(ct)) {
new StyleMacro(ct);
}
if (TemplateMacro.has(ct)) { if (TemplateMacro.has(ct)) {
modify = true; modify = true;
var template = new TemplateMacro(ct, fields); var template = new TemplateMacro(ct, fields);

View File

@@ -1,5 +1,6 @@
package haxework.resources; package haxework.resources;
import haxework.gui.skin.ISkin.SkinSet;
import flash.display.MovieClip; import flash.display.MovieClip;
import haxework.resources.Resources.ResMap; import haxework.resources.Resources.ResMap;
import flash.display.BitmapData; import flash.display.BitmapData;
@@ -11,8 +12,6 @@ interface IResources {
public var text(default, null):ResMap<String>; public var text(default, null):ResMap<String>;
public var float(default, null):ResMap<Float>; public var float(default, null):ResMap<Float>;
public var int(default, null):ResMap<Int>; public var int(default, null):ResMap<Int>;
public var styles(default, null):ResMap<Dynamic>;
public var any(default, null):ResMap<Dynamic>; public var any(default, null):ResMap<Dynamic>;
public var skin(default, null):ResMap<SkinSet>;
public function loadStyles(asset:String):Void;
} }

View File

@@ -1,77 +1,69 @@
package haxework.resources; package haxework.resources;
import openfl.Assets; import haxework.gui.skin.ISkin.SkinSet;
import haxe.Json;
import flash.display.MovieClip;
import haxework.core.Tuple;
import haxe.ds.StringMap;
import flash.display.BitmapData; import flash.display.BitmapData;
import flash.display.MovieClip;
import haxe.ds.StringMap;
import haxework.core.Tuple;
private typedef F = Tuple2<Dynamic, String> private typedef F = Tuple2<Dynamic, String>
class ResMap<T> extends StringMap<T> { class ResMap<T> extends StringMap<T> {
private var listeners:Map<String, Array<F>>; private var listeners:Map<String, Array<F>>;
public function new() { public function new() {
super(); super();
listeners = new Map<String, Array<F>>(); listeners = new Map<String, Array<F>>();
}
public function put(key:String, value:T):Void {
set(key, value);
if (listeners.exists(key)) {
for (f in listeners.get(key)) call(f, value);
} }
}
public function bind(key:String, object:Dynamic, field:String):Void { public function put(key:String, value:T):Void {
var f:F = Tuple.two(object, field); set(key, value);
if (listeners.exists(key)) { if (listeners.exists(key)) {
listeners.get(key).push(f); for (f in listeners.get(key)) call(f, value);
} else { }
listeners.set(key, [f]);
} }
if (exists(key)) call(f, get(key));
}
private function call(field:F, value:T):Void { public function bind(key:String, object:Dynamic, field:String):Void {
Reflect.setProperty(field.first, field.second, value); var f:F = Tuple.two(object, field);
} if (listeners.exists(key)) {
listeners.get(key).push(f);
public function merge(value:Dynamic<T>):Void { } else {
for (field in Reflect.fields(value)) { listeners.set(key, [f]);
put(field, Reflect.field(value, field)); }
if (exists(key)) call(f, get(key));
}
private function call(field:F, value:T):Void {
Reflect.setProperty(field.first, field.second, value);
}
public function merge(value:Dynamic<T>):Void {
for (field in Reflect.fields(value)) {
put(field, Reflect.field(value, field));
}
} }
}
} }
class Resources implements IResources { class Resources implements IResources {
public var image(default, null):ResMap<BitmapData>; public var image(default, null):ResMap<BitmapData>;
public var color(default, null):ResMap<Int>; public var color(default, null):ResMap<Int>;
public var movie(default, null):ResMap<MovieClip>; public var movie(default, null):ResMap<MovieClip>;
public var text(default, null):ResMap<String>; public var text(default, null):ResMap<String>;
public var float(default, null):ResMap<Float>; public var float(default, null):ResMap<Float>;
public var int(default, null):ResMap<Int>; public var int(default, null):ResMap<Int>;
public var styles(default, null):ResMap<Dynamic>; public var any(default, null):ResMap<Dynamic>;
public var any(default, null):ResMap<Dynamic>; public var skin(default, null):ResMap<SkinSet>;
public function new() { public function new() {
image = new ResMap<BitmapData>(); image = new ResMap<BitmapData>();
color = new ResMap<Int>(); color = new ResMap<Int>();
movie = new ResMap<MovieClip>(); movie = new ResMap<MovieClip>();
text = new ResMap<String>(); text = new ResMap<String>();
float = new ResMap<Float>(); float = new ResMap<Float>();
int = new ResMap<Int>(); int = new ResMap<Int>();
styles = new ResMap<Dynamic>(); any = new ResMap<Dynamic>();
any = new ResMap<Dynamic>(); skin = new ResMap<SkinSet>();
}
public function loadStyles(asset:String):Void {
var stylesData = Json.parse(Assets.getText(asset));
for (key in Reflect.fields(stylesData)) {
styles.put(key, Reflect.field(stylesData, key));
} }
}
} }