[view] add FrameView
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
package haxework.macro;
|
package haxework.macro;
|
||||||
|
|
||||||
|
import Lambda;
|
||||||
import haxe.macro.Context;
|
import haxe.macro.Context;
|
||||||
import haxe.macro.Expr;
|
import haxe.macro.Expr;
|
||||||
import haxe.macro.Type;
|
import haxe.macro.Type;
|
||||||
import haxework.macro.PositionJsonParser;
|
import haxework.macro.PositionJsonParser;
|
||||||
|
|
||||||
|
|
||||||
class TemplateMacro {
|
class TemplateMacro {
|
||||||
|
|
||||||
private static inline var metaName:String = ':template';
|
private static inline var metaName:String = ':template';
|
||||||
@@ -14,7 +14,6 @@ class TemplateMacro {
|
|||||||
return Util.hasClassMeta(metaName, classType);
|
return Util.hasClassMeta(metaName, classType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private var classType:ClassType;
|
private var classType:ClassType;
|
||||||
private var fields:Array<Field>;
|
private var fields:Array<Field>;
|
||||||
private var bindings:Map<String, String>;
|
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 {
|
private function createValue(name:String, key:String, value:Dynamic, position:JsonKeyPosition, exprs:Array<Expr>):Dynamic {
|
||||||
return if (Std.is(value, Array)) {
|
return if (Std.is(value, Array)) {
|
||||||
value.map(function(v) {
|
value.map(function(v) {
|
||||||
@@ -117,7 +108,7 @@ class TemplateMacro {
|
|||||||
if (className != null) {
|
if (className != null) {
|
||||||
className;
|
className;
|
||||||
} else {
|
} else {
|
||||||
var type:Dynamic = getType(value, getPosition(position));
|
var type:Dynamic = getSpecField(value, "type");
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
var varName = 'a${i++}';
|
var varName = 'a${i++}';
|
||||||
if (Std.is(type, Array)) {
|
if (Std.is(type, Array)) {
|
||||||
@@ -131,7 +122,8 @@ class TemplateMacro {
|
|||||||
createElement(varName, value, exprs);
|
createElement(varName, value, exprs);
|
||||||
varName;
|
varName;
|
||||||
} else {
|
} else {
|
||||||
null;
|
createElement('${name}.${key}', value, exprs);
|
||||||
|
'${name}.${key}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -145,6 +137,7 @@ class TemplateMacro {
|
|||||||
if (bindings.exists(id)) {
|
if (bindings.exists(id)) {
|
||||||
var bind = bindings.get(id);
|
var bind = bindings.get(id);
|
||||||
exprs.push(Context.parse('this.${bind} = ${name}', getPosition()));
|
exprs.push(Context.parse('this.${bind} = ${name}', getPosition()));
|
||||||
|
bindings.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,15 +146,19 @@ class TemplateMacro {
|
|||||||
var position = Reflect.field(data, "$" + key);
|
var position = Reflect.field(data, "$" + key);
|
||||||
var value = createValue(name, key, Reflect.field(data, key), position, exprs);
|
var value = createValue(name, key, Reflect.field(data, key), position, exprs);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
if (key.charAt(0) == "+") {
|
trace(key, [key.charAt(0), key.charAt(key.length - 1)]);
|
||||||
var e:Expr = Context.parse(value, getPosition(position));
|
switch [key.charAt(0), key.charAt(key.length - 1)] {
|
||||||
e = switch (e.expr) {
|
case ["+", _]:
|
||||||
case ECall(_, _): macro function(_) ${e};
|
var e:Expr = Context.parse(value, getPosition(position));
|
||||||
case _: e;
|
e = switch (e.expr) {
|
||||||
}
|
case ECall(_, _): macro function(_) ${e};
|
||||||
exprs.push(macro $p{[name, key.substr(1)]}.connect(${e}));
|
case _: e;
|
||||||
} else {
|
}
|
||||||
exprs.push(Context.parse('${name}.${key} = ${value}', getPosition(position)));
|
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 = [];
|
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());
|
contstrExprs.push(macro build());
|
||||||
if (init) contstrExprs.push(macro init());
|
if (init) contstrExprs.push(macro init());
|
||||||
|
|
||||||
@@ -219,10 +223,18 @@ class TemplateMacro {
|
|||||||
i = 0;
|
i = 0;
|
||||||
var result:Array<Field> = fields.slice(0);
|
var result:Array<Field> = fields.slice(0);
|
||||||
var exprs:Array<Expr> = [];
|
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);
|
createElement("this", template, exprs);
|
||||||
result.push(buildBuild(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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,27 @@
|
|||||||
package haxework.view.frame;
|
package haxework.view.frame;
|
||||||
|
|
||||||
import haxework.signal.Signal;
|
|
||||||
import haxework.animate.IAnimate;
|
import haxework.animate.IAnimate;
|
||||||
import haxework.view.IView;
|
import haxework.signal.Signal;
|
||||||
import haxework.view.GroupView;
|
import haxework.view.GroupView;
|
||||||
|
import haxework.view.IView;
|
||||||
|
|
||||||
class FrameSwitcher extends GroupView {
|
class FrameSwitcher extends GroupView {
|
||||||
|
|
||||||
public var current(default, null):Null<IView<Dynamic>>;
|
public var current(default, null):Null<FrameView<Dynamic>>;
|
||||||
public var onSwitch:Signal<IView<Dynamic>> = new Signal();
|
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>;
|
public var animateFactory(default, default):Class<IAnimate>;
|
||||||
|
|
||||||
private var animate:IAnimate;
|
private var animate:IAnimate;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
frames = new Map<String, IView<Dynamic>>();
|
factory = new Map();
|
||||||
|
frames = new Map();
|
||||||
current = null;
|
current = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,13 +32,26 @@ class FrameSwitcher extends GroupView {
|
|||||||
return null;
|
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;
|
var prev = null;
|
||||||
if (current != null) {
|
if (current != null) {
|
||||||
if (current.id == id) return current;
|
if (current.frameId == id) {
|
||||||
|
current.onShow(data);
|
||||||
|
return cast current;
|
||||||
|
}
|
||||||
prev = current;
|
prev = current;
|
||||||
}
|
}
|
||||||
current = frames.get(id);
|
current = resolveFrame(id);
|
||||||
if (current == null) {
|
if (current == null) {
|
||||||
throw 'frame "$id" not found';
|
throw 'frame "$id" not found';
|
||||||
}
|
}
|
||||||
@@ -42,10 +59,13 @@ class FrameSwitcher extends GroupView {
|
|||||||
toUpdate();
|
toUpdate();
|
||||||
//update();
|
//update();
|
||||||
//ToDo:
|
//ToDo:
|
||||||
if (content.stage != null) content.stage.focus = cast(current, SpriteView).content;
|
if (content.stage != null) {
|
||||||
var onShowMethod:Dynamic = Reflect.field(current, "onShow");
|
content.stage.focus = current.content;
|
||||||
if (onShowMethod != null) Reflect.callMethod(current, onShowMethod, []);
|
}
|
||||||
if (animate != null) animate.cancel();
|
current.onShow(data);
|
||||||
|
if (animate != null) {
|
||||||
|
animate.cancel();
|
||||||
|
}
|
||||||
animate = buildAnimate(current);
|
animate = buildAnimate(current);
|
||||||
if (animate != null && prev != null) {
|
if (animate != null && prev != null) {
|
||||||
animate.start(function(_) {
|
animate.start(function(_) {
|
||||||
@@ -55,25 +75,13 @@ class FrameSwitcher extends GroupView {
|
|||||||
removePrev(prev);
|
removePrev(prev);
|
||||||
}
|
}
|
||||||
onSwitch.emit(current);
|
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) {
|
if (prev != null) {
|
||||||
var onHideMethod:Dynamic = Reflect.field(prev, "onHide");
|
prev.onHide();
|
||||||
if (onHideMethod != null) Reflect.callMethod(prev, onHideMethod, []);
|
|
||||||
removeView(prev);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/main/haxework/view/frame/FrameView.hx
Normal file
16
src/main/haxework/view/frame/FrameView.hx
Normal 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 {}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user