This commit is contained in:
2015-07-02 15:09:21 +03:00
parent 2113d81475
commit 1df0857db3
3 changed files with 74 additions and 62 deletions

View File

@@ -7,53 +7,37 @@ import haxe.macro.Context;
@:remove @:autoBuild(haxework.gui.ViewBuilderImpl.build()) @:remove @:autoBuild(haxework.gui.ViewBuilderImpl.build())
extern interface ViewBuilder {} extern interface ViewBuilder {}
typedef BuildData = {
var fields:Array<Field>;
var exprs:Array<Expr>;
var style:Dynamic;
}
class ViewBuilderImpl { class ViewBuilderImpl {
#if macro #if macro
static function loadFileAsString(path:String, json:Bool = true) { static function loadFile(path:String, json:Bool = true) {
try { var p = Context.resolvePath(path);
var p = Context.resolvePath(path); Context.registerModuleDependency(Context.getLocalModule(), p);
Context.registerModuleDependency(Context.getLocalModule(), p); var content = sys.io.File.getContent(p);
var content = sys.io.File.getContent(p); return json ? Json.parse(content) : content;
return json ? Json.parse(content) : content;
}
catch(e:Dynamic) {
return haxe.macro.Context.error("Failed to load file $path: $e", Context.currentPos());
}
} }
private static function getTemplate():Array<Dynamic> { private static function getMeta(key:String):Array<String> {
var template = null;
var style = null;
var c = Context.getLocalClass().get(); var c = Context.getLocalClass().get();
for (m in c.meta.get()) { for (meta in c.meta.get()) {
if (m.name == ":template") { if (meta.name == key) {
template = switch(m.params[0].expr) { return meta.params.map(function(param) return switch(param.expr) {
case ExprDef.EConst(Constant.CString(value)): value; case ExprDef.EConst(Constant.CString(value)): value;
case _: null; case _: null;
} });
if (template != null) {
var t = template.split("@");
template = loadFileAsString(t[0]);
if (t[1] != null) template = Reflect.field(template, t[1]);
}
style = switch(m.params[1].expr) {
case ExprDef.EConst(Constant.CString(value)): value;
case _: null;
}
if (style != null) {
style = loadFileAsString(style);
}
} }
} }
return [ return [];
template,
style
];
} }
private static var i = 0; private static var i = 0;
private static function specialValue(data:Array<Expr>, name:String, style:Dynamic, key:String, a:Array<String>):Dynamic { private static function specialValue(data:BuildData, name:String, key:String, a:Array<String>):Dynamic {
return switch (a[0]) { return switch (a[0]) {
case "asset": case "asset":
switch (a[1]) { switch (a[1]) {
@@ -65,7 +49,7 @@ class ViewBuilderImpl {
case "res": case "res":
var res = "haxework.provider.Provider.get(haxework.resources.IResources)." + a[1]; var res = "haxework.provider.Provider.get(haxework.resources.IResources)." + a[1];
var bindExpr = res + ".bind(\"" + a[2] + "\", " + name + ", \"" + key + "\")"; var bindExpr = res + ".bind(\"" + a[2] + "\", " + name + ", \"" + key + "\")";
data.push(Context.parse(bindExpr, Context.currentPos())); data.exprs.push(Context.parse(bindExpr, Context.currentPos()));
//res + ".get(\"" + a[2] + "\")"; //res + ".get(\"" + a[2] + "\")";
null; null;
case "locale": case "locale":
@@ -73,8 +57,8 @@ class ViewBuilderImpl {
case "class": case "class":
a[1]; a[1];
case "layout": case "layout":
var template = Json.parse(loadFileAsString(a[1])); var template = loadFile(a[1]);
return getValue(data, name, style, key, template); return getValue(data, name, key, template);
case "link": case "link":
"(links == null) ? untyped this : Reflect.field(links, \"" + a[1] + "\")"; "(links == null) ? untyped this : Reflect.field(links, \"" + a[1] + "\")";
case _: case _:
@@ -82,12 +66,12 @@ class ViewBuilderImpl {
} }
} }
private static function getValue(data:Array<Expr>, name:String, style:Dynamic, key:String, value:Dynamic):Dynamic { private static function getValue(data:BuildData, name:String, key:String, value:Dynamic):Dynamic {
return if (Std.is(value, Array)) { return if (Std.is(value, Array)) {
value.map(function(v) { return getValue(data, null, style, null, v); }); value.map(function(v) { return getValue(data, null, null, v); });
} else if (Std.is(value, String)) { } else if (Std.is(value, String)) {
if (value.charAt(0) == "@") { if (value.charAt(0) == "@") {
specialValue(data, name, style, key, value.substring(1, value.length).split(":")); specialValue(data, name, key, value.substring(1, value.length).split(":"));
} else if (~/(0x|#)[A-Fa-f\d]{6}/.match(value)) { } else if (~/(0x|#)[A-Fa-f\d]{6}/.match(value)) {
Std.parseInt(StringTools.replace(Std.string(value), "#", "0x")); Std.parseInt(StringTools.replace(Std.string(value), "#", "0x"));
} else { } else {
@@ -99,8 +83,8 @@ class ViewBuilderImpl {
if (Reflect.hasField(value, "type")) { if (Reflect.hasField(value, "type")) {
var n = "a" + i++; var n = "a" + i++;
var type = Reflect.field(value, "type"); var type = Reflect.field(value, "type");
data.push(Context.parse("var " + n + " = new " + type + "()", Context.currentPos())); data.exprs.push(Context.parse("var " + n + " = new " + type + "()", Context.currentPos()));
createElement(data, value, n, style); createElement(data, value, n);
n; n;
} else { } else {
value; value;
@@ -110,30 +94,58 @@ class ViewBuilderImpl {
} }
} }
private static function createElement(data:Array<Expr>, template:Dynamic, name:String, style:Dynamic):String { private static function createElement(data:BuildData, template:Dynamic, name:String):String {
if (Reflect.hasField(template, "style")) { if (Reflect.hasField(template, "style")) {
var s = Reflect.field(style, Reflect.field(template, "style")); var s = Reflect.field(data.style, Reflect.field(template, "style"));
for (key in Reflect.fields(s)) if (!Reflect.hasField(template, key)) { for (key in Reflect.fields(s)) if (!Reflect.hasField(template, key)) {
Reflect.setField(template, key, Reflect.field(s, key)); Reflect.setField(template, key, Reflect.field(s, key));
} }
} }
if (Reflect.hasField(template, "id")) {
var id = Reflect.field(template, "id");
var type = Reflect.field(template, "type");
var expr = Context.parse("var a:" + type, Context.currentPos());
var type = switch (expr.expr) {
case EVars(vars): vars[0].type;
case _: null;
}
data.fields.push({
name: id,
access: [APublic],
pos: Context.currentPos(),
kind: FProp("default", "null", type)
});
data.exprs.push(Context.parse("this." + id + " = " + name, Context.currentPos()));
}
for (key in Reflect.fields(template)) { for (key in Reflect.fields(template)) {
if (["type", "style"].indexOf(key) > -1) continue; if (["type", "style"].indexOf(key) > -1) continue;
var value = getValue(data, name, style, key, Reflect.field(template, key)); var value = getValue(data, name, key, Reflect.field(template, key));
if (value != null) { if (value != null) {
data.push(Context.parse(name + "." + key + " = cast " + value, Context.currentPos())); data.exprs.push(Context.parse(name + "." + key + " = cast " + value, Context.currentPos()));
} }
} }
return name; return name;
} }
public static function build() { public static function build() {
var template = getTemplate(); //trace("Build: " + Context.getLocalClass().get().module);
var templateMeta = getMeta(":template");
var templatePath = templateMeta[0].split("@");
var template = loadFile(templatePath[0]);
if (templatePath[1] != null) template = Reflect.field(template, templatePath[1]);
var style = templateMeta[1] == null ? {} : loadFile(templateMeta[1]);
var fields = Context.getBuildFields(); var fields = Context.getBuildFields();
var data = []; var data = {
fields: fields,
exprs: [],
style: style
};
i = 0; i = 0;
createElement(data, template[0], "this", template[1]); createElement(data, template, "this");
var init = false; var init = false;
for (f in fields) if (f.name == "init") { for (f in fields) if (f.name == "init") {
@@ -147,16 +159,16 @@ class ViewBuilderImpl {
pos: Context.currentPos(), pos: Context.currentPos(),
kind: FFun({ kind: FFun({
args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}], args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}],
expr: macro $b{data}, expr: macro $b{data.exprs},
params: [], params: [],
ret: null ret: null
}) })
}); });
data = []; var contrExprs = [];
data.push(macro super()); contrExprs.push(macro super());
data.push(macro build(links)); contrExprs.push(macro build(links));
if (init) data.push(macro init()); if (init) contrExprs.push(macro init());
fields.push({ fields.push({
name: "new", name: "new",
@@ -164,7 +176,7 @@ class ViewBuilderImpl {
pos: Context.currentPos(), pos: Context.currentPos(),
kind: FFun({ kind: FFun({
args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}], args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}],
expr: macro $b{data}, expr: macro $b{contrExprs},
params: [], params: [],
ret: null ret: null
}) })

View File

@@ -9,13 +9,13 @@ class PopupManager {
public var showAnimateFactory(default, default):Class<IAnimate>; public var showAnimateFactory(default, default):Class<IAnimate>;
public var closeAnimateFactory(default, default):Class<IAnimate>; public var closeAnimateFactory(default, default):Class<IAnimate>;
private var popups:Array<PopupView>; private var popups:Array<PopupView<Dynamic>>;
public function new() { public function new() {
popups = new Array<PopupView>(); popups = new Array<PopupView<Dynamic>>();
} }
public function show(popup:PopupView):Void { public function show(popup:PopupView<Dynamic>):Void {
cast(Root.instance.view, IGroupView<Dynamic>).addView(popup); cast(Root.instance.view, IGroupView<Dynamic>).addView(popup);
if (showAnimateFactory != null) { if (showAnimateFactory != null) {
Type.createInstance(showAnimateFactory, [popup]).start(null); Type.createInstance(showAnimateFactory, [popup]).start(null);
@@ -24,7 +24,7 @@ class PopupManager {
popup.onShow(); popup.onShow();
} }
public function close(popup:PopupView):Void { public function close(popup:PopupView<Dynamic>):Void {
popups.remove(popup); popups.remove(popup);
if (closeAnimateFactory != null) { if (closeAnimateFactory != null) {
Type.createInstance(closeAnimateFactory, [popup]).start(function(_) { Type.createInstance(closeAnimateFactory, [popup]).start(function(_) {

View File

@@ -11,13 +11,13 @@ import haxework.gui.ButtonView;
import haxework.gui.skin.ColorSkin; import haxework.gui.skin.ColorSkin;
import haxework.gui.GroupView; import haxework.gui.GroupView;
class PopupView extends GroupView { class PopupView<V:IView<Dynamic>> extends GroupView {
private var buttonId:String; private var buttonId:String;
private var contentView:IGroupView<Dynamic>; private var contentView:V;
private var callback:ICallback<String>; private var callback:ICallback<String>;
public function new(contentViewFactory:Class<IGroupView<Dynamic>>) { public function new(contentViewFactory:Class<V>) {
super(); super();
pWidth = 100; pWidth = 100;