[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

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

View File

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

View File

@@ -1,12 +1,12 @@
package haxework.gui;
import flash.display.Sprite;
import haxework.gui.skin.ISkin;
import haxework.gui.skin.ISkin.SkinSet;
class ToggleButtonView extends ButtonView {
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;
@@ -20,13 +20,13 @@ class ToggleButtonView extends ButtonView {
return on;
}
private function set_onSkin(value:ISkin<Dynamic>):ISkin<Dynamic> {
private function set_onSkin(value:SkinSet):SkinSet {
onSkin = value;
invalidate();
return onSkin;
}
override private function currentSkin():ISkin<Dynamic> {
private function currentSkin():SkinSet {
return on ? onSkin : skin;
}
@@ -41,4 +41,4 @@ class ToggleButtonView extends ButtonView {
override private function currentText():String {
return on && onText != null ? onText : super.currentText();
}
}
}

View File

@@ -4,7 +4,7 @@ import flash.display.BitmapData;
import flash.geom.Rectangle;
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 height(default, null):Float;

View File

@@ -14,7 +14,7 @@ class BorderSkin implements ISkin<SpriteView> {
public function draw(view:SpriteView):Void {
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 File

@@ -1,10 +1,10 @@
package haxework.macro;
import yaml.YamlException;
import yaml.Parser;
import yaml.Yaml;
import haxe.macro.Context;
class FileUtil {
public static function loadJsonFile(path:String):Dynamic {
@@ -21,16 +21,17 @@ class FileUtil {
}
public static function loadYamlFile(path:String):Dynamic {
path = sys.FileSystem.absolutePath(path);
Context.registerModuleDependency(Context.getLocalModule(), path);
var content = sys.io.File.getContent(path);
var result = null;
try {
// ToDo: extract poisiton info
result = Yaml.parse(content, Parser.options().useObjects());
} catch (error:Dynamic) {
Context.error(error, Context.makePosition({min:0, max:0, file:path}));
PositionYamlParser.parse(path, content, result);
} 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;
}
@@ -42,4 +43,4 @@ class FileUtil {
case x: throw 'Unsupported file format: "${x}"';
}
}
}
}

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 templateFile:String;
private var template:Dynamic;
private var style:Dynamic;
private var i:Int;
private function get_meta():MetadataEntry {
@@ -42,12 +41,6 @@ class TemplateMacro {
}
templateFile = Context.resolvePath(filePath);
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);
}
@@ -63,8 +56,8 @@ class TemplateMacro {
}
private function getPosition(?position:JsonKeyPosition):Position {
var min = position == null ? 1 : position.min + 32; // :-(
var max = position == null ? 1 : position.max + 32;
var min = position == null ? 1 : position.min; // :-(
var max = position == null ? 1 : position.max;
var file = position == null || position.file == null ? templateFile : position.file;
return Context.makePosition({min:min, max:max, file:file});
}
@@ -78,13 +71,13 @@ class TemplateMacro {
case _:
a[2];
}
case "res":
var bindExpr = 'haxework.provider.Provider.get(haxework.resources.IResources).${a[1]}.bind("${[2]}", "${name}", "${key}")';
case "res" | "r":
var bindExpr = 'haxework.provider.Provider.get(haxework.resources.IResources).${a[1]}.bind("${a[2]}", ${name}, "${key}")';
exprs.push(Context.parse(bindExpr, getPosition(position)));
null;
case "locale":
'new haxework.locale.LString("${[1]}")';
case "raw":
case "code":
a[1];
case "this":
'this.${a[1]}';
@@ -99,7 +92,7 @@ class TemplateMacro {
private static function getType(value:Dynamic, position:Position):Dynamic {
var type:Dynamic = getSpecField(value, "type");
if (type == null) {
Context.error("Need @type field", position);
Context.error("Need $type field", position);
}
return type;
}
@@ -147,17 +140,6 @@ class TemplateMacro {
}
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")) {
var id = Reflect.field(data, "id");
if (bindings.exists(id)) {

View File

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

View File

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

View File

@@ -1,77 +1,69 @@
package haxework.resources;
import openfl.Assets;
import haxe.Json;
import flash.display.MovieClip;
import haxework.core.Tuple;
import haxe.ds.StringMap;
import haxework.gui.skin.ISkin.SkinSet;
import flash.display.BitmapData;
import flash.display.MovieClip;
import haxe.ds.StringMap;
import haxework.core.Tuple;
private typedef F = Tuple2<Dynamic, String>
class ResMap<T> extends StringMap<T> {
private var listeners:Map<String, Array<F>>;
private var listeners:Map<String, Array<F>>;
public function new() {
super();
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 new() {
super();
listeners = new Map<String, Array<F>>();
}
}
public function bind(key:String, object:Dynamic, field:String):Void {
var f:F = Tuple.two(object, field);
if (listeners.exists(key)) {
listeners.get(key).push(f);
} else {
listeners.set(key, [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);
}
}
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));
public function bind(key:String, object:Dynamic, field:String):Void {
var f:F = Tuple.two(object, field);
if (listeners.exists(key)) {
listeners.get(key).push(f);
} else {
listeners.set(key, [f]);
}
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 {
public var image(default, null):ResMap<BitmapData>;
public var color(default, null):ResMap<Int>;
public var movie(default, null):ResMap<MovieClip>;
public var text(default, null):ResMap<String>;
public var float(default, null):ResMap<Float>;
public var int(default, null):ResMap<Int>;
public var styles(default, null):ResMap<Dynamic>;
public var any(default, null):ResMap<Dynamic>;
public var image(default, null):ResMap<BitmapData>;
public var color(default, null):ResMap<Int>;
public var movie(default, null):ResMap<MovieClip>;
public var text(default, null):ResMap<String>;
public var float(default, null):ResMap<Float>;
public var int(default, null):ResMap<Int>;
public var any(default, null):ResMap<Dynamic>;
public var skin(default, null):ResMap<SkinSet>;
public function new() {
image = new ResMap<BitmapData>();
color = new ResMap<Int>();
movie = new ResMap<MovieClip>();
text = new ResMap<String>();
float = new ResMap<Float>();
int = new ResMap<Int>();
styles = new ResMap<Dynamic>();
any = new ResMap<Dynamic>();
}
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));
public function new() {
image = new ResMap<BitmapData>();
color = new ResMap<Int>();
movie = new ResMap<MovieClip>();
text = new ResMap<String>();
float = new ResMap<Float>();
int = new ResMap<Int>();
any = new ResMap<Dynamic>();
skin = new ResMap<SkinSet>();
}
}
}
}