[view] add FrameView

This commit is contained in:
2019-06-24 22:09:22 +03:00
parent cdfc3fd344
commit 09d18808b4
3 changed files with 89 additions and 53 deletions

View File

@@ -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<Field>;
private var bindings:Map<String, String>;
@@ -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<Expr>):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,14 +146,18 @@ 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) == "+") {
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}));
} else {
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 = [];
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<Field> = fields.slice(0);
var exprs:Array<Expr> = [];
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;
}
}

View File

@@ -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<IView<Dynamic>>;
public var onSwitch:Signal<IView<Dynamic>> = new Signal();
public var current(default, null):Null<FrameView<Dynamic>>;
public var onSwitch:Signal<FrameView<Dynamic>> = new Signal();
private var frames:Map<String, IView<Dynamic>>;
public var factory(default, default):Map<String, Class<FrameView<Dynamic>>>;
public var frames(default, default):Map<String, FrameView<Dynamic>>;
public var animateFactory(default, default):Class<IAnimate>;
private var animate:IAnimate;
public function new() {
super();
frames = new Map<String, IView<Dynamic>>();
factory = new Map();
frames = new Map();
current = null;
}
@@ -28,13 +32,26 @@ class FrameSwitcher extends GroupView {
return null;
}
public function change(id:String):IView<Dynamic> {
private function resolveFrame<T>(id:String):FrameView<T> {
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<T>(id:String, data:T = null):FrameView<T> {
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<IView<Dynamic>>):Void {
private function removePrev(prev:Null<FrameView<Dynamic>>):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<IView<Dynamic>>):Array<IView<Dynamic>> {
views = [];
if (value.length > 0) {
for (view in value) {
view.geometry.size.stretch = true;
frames.set(view.id, view);
}
}
return value;
}
}

View File

@@ -0,0 +1,16 @@
package haxework.view.frame;
import haxework.view.layout.ILayout;
class FrameView<D> 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 {}
}