From 09d18808b46271b05b5cb3f37be4611d9c9266ca Mon Sep 17 00:00:00 2001 From: shmyga Date: Mon, 24 Jun 2019 22:09:22 +0300 Subject: [PATCH] [view] add FrameView --- src/main/haxework/macro/TemplateMacro.hx | 62 ++++++++++-------- src/main/haxework/view/frame/FrameSwitcher.hx | 64 +++++++++++-------- src/main/haxework/view/frame/FrameView.hx | 16 +++++ 3 files changed, 89 insertions(+), 53 deletions(-) create mode 100644 src/main/haxework/view/frame/FrameView.hx diff --git a/src/main/haxework/macro/TemplateMacro.hx b/src/main/haxework/macro/TemplateMacro.hx index a3228a5..8302795 100644 --- a/src/main/haxework/macro/TemplateMacro.hx +++ b/src/main/haxework/macro/TemplateMacro.hx @@ -1,11 +1,11 @@ package haxework.macro; +import Lambda; import haxe.macro.Context; import haxe.macro.Expr; import haxe.macro.Type; import haxework.macro.PositionJsonParser; - class TemplateMacro { private static inline var metaName:String = ':template'; @@ -14,7 +14,6 @@ class TemplateMacro { return Util.hasClassMeta(metaName, classType); } - private var classType:ClassType; private var fields:Array; private var bindings:Map; @@ -89,14 +88,6 @@ 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); - } - return type; - } - private function createValue(name:String, key:String, value:Dynamic, position:JsonKeyPosition, exprs:Array):Dynamic { return if (Std.is(value, Array)) { value.map(function(v) { @@ -117,7 +108,7 @@ class TemplateMacro { if (className != null) { className; } else { - var type:Dynamic = getType(value, getPosition(position)); + var type:Dynamic = getSpecField(value, "type"); if (type != null) { var varName = 'a${i++}'; if (Std.is(type, Array)) { @@ -131,7 +122,8 @@ class TemplateMacro { createElement(varName, value, exprs); varName; } else { - null; + createElement('${name}.${key}', value, exprs); + '${name}.${key}'; } } } else { @@ -145,6 +137,7 @@ class TemplateMacro { if (bindings.exists(id)) { var bind = bindings.get(id); exprs.push(Context.parse('this.${bind} = ${name}', getPosition())); + bindings.remove(id); } } @@ -153,15 +146,19 @@ class TemplateMacro { var position = Reflect.field(data, "$" + key); var value = createValue(name, key, Reflect.field(data, key), position, exprs); if (value != null) { - if (key.charAt(0) == "+") { - var e:Expr = Context.parse(value, getPosition(position)); - e = switch (e.expr) { - case ECall(_, _): macro function(_) ${e}; - case _: e; - } - exprs.push(macro $p{[name, key.substr(1)]}.connect(${e})); - } else { - exprs.push(Context.parse('${name}.${key} = ${value}', getPosition(position))); + trace(key, [key.charAt(0), key.charAt(key.length - 1)]); + switch [key.charAt(0), key.charAt(key.length - 1)] { + case ["+", _]: + var e:Expr = Context.parse(value, getPosition(position)); + e = switch (e.expr) { + case ECall(_, _): macro function(_) ${e}; + case _: e; + } + exprs.push(macro $p{[name, key.substr(1)]}.connect(${e})); + case ["_", "_"]: + exprs.push(Context.parse('${name}["${key.substr(1, key.length - 2)}"] = ${value}', getPosition(position))); + case _: + exprs.push(Context.parse('${name}.${key} = ${value}', getPosition(position))); } } } @@ -183,9 +180,16 @@ class TemplateMacro { } } - private function buildConstructor(init:Bool):Field { + private function buildConstructor(init:Bool, constructor:Field = null):Field { var contstrExprs = []; - contstrExprs.push(macro super()); + if (constructor != null) { + switch constructor.kind { + case FFun(f): contstrExprs.push(f.expr); + case _: + } + } else { + contstrExprs.push(macro super()); + } contstrExprs.push(macro build()); if (init) contstrExprs.push(macro init()); @@ -219,10 +223,18 @@ class TemplateMacro { i = 0; var result:Array = fields.slice(0); var exprs:Array = []; - var init = Lambda.exists(result, function(f) return f.name == 'init'); + var init = Lambda.exists(result, function(f) return f.name == "init"); createElement("this", template, exprs); result.push(buildBuild(exprs)); - result.push(buildConstructor(init)); + var constructor = Lambda.find(result, function(f) return f.name == "new"); + if (constructor != null) { + result.remove(constructor); + } + result.push(buildConstructor(init, constructor)); + if (Lambda.count(bindings) > 0) { + var keys = Lambda.map({iterator: bindings.keys}, function(k) return '"${k}"').join(","); + Context.error('Invalid @:view bindings: $keys', getPosition()); + } return result; } } diff --git a/src/main/haxework/view/frame/FrameSwitcher.hx b/src/main/haxework/view/frame/FrameSwitcher.hx index 75eb017..b6bd510 100755 --- a/src/main/haxework/view/frame/FrameSwitcher.hx +++ b/src/main/haxework/view/frame/FrameSwitcher.hx @@ -1,23 +1,27 @@ package haxework.view.frame; -import haxework.signal.Signal; import haxework.animate.IAnimate; -import haxework.view.IView; +import haxework.signal.Signal; import haxework.view.GroupView; +import haxework.view.IView; class FrameSwitcher extends GroupView { - public var current(default, null):Null>; - public var onSwitch:Signal> = new Signal(); + public var current(default, null):Null>; + public var onSwitch:Signal> = new Signal(); - private var frames:Map>; + public var factory(default, default):Map>>; + + public var frames(default, default):Map>; public var animateFactory(default, default):Class; + private var animate:IAnimate; public function new() { super(); - frames = new Map>(); + factory = new Map(); + frames = new Map(); current = null; } @@ -28,13 +32,26 @@ class FrameSwitcher extends GroupView { return null; } - public function change(id:String):IView { + private function resolveFrame(id:String):FrameView { + if (!frames.exists(id)) { + if (!factory.exists(id)) { + throw 'frame "$id" not found'; + } + frames.set(id, Type.createInstance(factory.get(id), [])); + } + return cast frames.get(id); + } + + public function change(id:String, data:T = null):FrameView { var prev = null; if (current != null) { - if (current.id == id) return current; + if (current.frameId == id) { + current.onShow(data); + return cast current; + } prev = current; } - current = frames.get(id); + current = resolveFrame(id); if (current == null) { throw 'frame "$id" not found'; } @@ -42,10 +59,13 @@ class FrameSwitcher extends GroupView { toUpdate(); //update(); //ToDo: - if (content.stage != null) content.stage.focus = cast(current, SpriteView).content; - var onShowMethod:Dynamic = Reflect.field(current, "onShow"); - if (onShowMethod != null) Reflect.callMethod(current, onShowMethod, []); - if (animate != null) animate.cancel(); + if (content.stage != null) { + content.stage.focus = current.content; + } + current.onShow(data); + if (animate != null) { + animate.cancel(); + } animate = buildAnimate(current); if (animate != null && prev != null) { animate.start(function(_) { @@ -55,25 +75,13 @@ class FrameSwitcher extends GroupView { removePrev(prev); } onSwitch.emit(current); - return current; + return cast current; } - private function removePrev(prev:Null>):Void { + private function removePrev(prev:Null>):Void { if (prev != null) { - var onHideMethod:Dynamic = Reflect.field(prev, "onHide"); - if (onHideMethod != null) Reflect.callMethod(prev, onHideMethod, []); + prev.onHide(); removeView(prev); } } - - override public function set_views(value:Array>):Array> { - views = []; - if (value.length > 0) { - for (view in value) { - view.geometry.size.stretch = true; - frames.set(view.id, view); - } - } - return value; - } } diff --git a/src/main/haxework/view/frame/FrameView.hx b/src/main/haxework/view/frame/FrameView.hx new file mode 100644 index 0000000..8462d2f --- /dev/null +++ b/src/main/haxework/view/frame/FrameView.hx @@ -0,0 +1,16 @@ +package haxework.view.frame; + +import haxework.view.layout.ILayout; + +class FrameView extends GroupView { + public var frameId(default, null):String; + + public function new(frameId:String, ?layout:ILayout) { + super(layout); + this.frameId = frameId; + } + + public function onShow(data:D):Void {} + + public function onHide():Void {} +}