GuiBuilder => Builder
This commit is contained in:
152
haxework/gui/Builder.hx
Normal file
152
haxework/gui/Builder.hx
Normal file
@@ -0,0 +1,152 @@
|
||||
package haxework.gui;
|
||||
|
||||
import haxework.resources.Resources.ResMap;
|
||||
import haxework.resources.IResources;
|
||||
import haxework.provider.Provider;
|
||||
import openfl.Assets;
|
||||
import haxework.locale.LString;
|
||||
import haxe.Json;
|
||||
import flash.errors.TypeError;
|
||||
import flash.errors.Error;
|
||||
|
||||
enum Value {
|
||||
SIMPLE(v:Dynamic);
|
||||
RESOURCE(res:ResMap<Dynamic>, key:String);
|
||||
LINK(key:String);
|
||||
BUILDER(v:Builder);
|
||||
ARRAY(v:Array<Value>);
|
||||
}
|
||||
|
||||
class Field {
|
||||
|
||||
public var key(default, null):String;
|
||||
public var value(default, null):Value;
|
||||
|
||||
public function new(key:String, value:Dynamic) {
|
||||
this.key = key;
|
||||
this.value = fieldValue(value);
|
||||
}
|
||||
|
||||
public static function buildValue(value:Value, ?links:Dynamic):Dynamic {
|
||||
return switch (value) {
|
||||
case Value.SIMPLE(v):
|
||||
v;
|
||||
case Value.BUILDER(v):
|
||||
v.build(links);
|
||||
case Value.ARRAY(v):
|
||||
v.map(function(i) return buildValue(i, links));
|
||||
case Value.RESOURCE(r, k):
|
||||
r.get(k);
|
||||
case Value.LINK(k):
|
||||
Reflect.field(links, k);
|
||||
}
|
||||
}
|
||||
|
||||
private static function specialValue(value):Value {
|
||||
var a = value.split(":");
|
||||
return switch (a[0]) {
|
||||
case "asset":
|
||||
switch (a[1]) {
|
||||
case "image":
|
||||
Value.SIMPLE(Assets.getBitmapData(a[2]));
|
||||
case _:
|
||||
Value.SIMPLE(value);
|
||||
}
|
||||
case "res":
|
||||
//Reflect.field(Provider.get(IResources), a[1]).bind(a[2], object, field);
|
||||
Value.RESOURCE(Reflect.field(Provider.get(IResources), a[1]), a[2]);
|
||||
case "locale":
|
||||
Value.SIMPLE(new LString(a[1]));
|
||||
case "class":
|
||||
Value.SIMPLE(Type.resolveClass(a[1]));
|
||||
case "layout":
|
||||
var data = Json.parse(Assets.getText(a[1]));
|
||||
Value.BUILDER(new Builder(data));
|
||||
case "link":
|
||||
Value.LINK(a[1]); //ToDo
|
||||
case _:
|
||||
throw new Error("Unsupported prefix \"" + a[0] + "\"");
|
||||
//Value.SIMPLE(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static function fieldValue(value:Dynamic):Value {
|
||||
return if (Std.is(value, Array)) {
|
||||
Value.ARRAY(value.map(fieldValue));
|
||||
} else if (Std.is(value, String)) {
|
||||
if (value.charAt(0) == "@") {
|
||||
specialValue(value.substr(1));
|
||||
} else if (~/0x[A-Fa-f\d]{6}/.match(value)) {
|
||||
Value.SIMPLE(Std.parseInt(value));
|
||||
} else {
|
||||
Value.SIMPLE(value);
|
||||
}
|
||||
} else if (Std.is(value, Float) || (Std.is(value, Bool))) {
|
||||
Value.SIMPLE(value);
|
||||
} else if (value != null) {
|
||||
if (Reflect.hasField(value, "type")) {
|
||||
Value.BUILDER(new Builder(value));
|
||||
} else {
|
||||
Value.SIMPLE(value);
|
||||
}
|
||||
} else {
|
||||
Value.SIMPLE(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Builder {
|
||||
|
||||
private var factory:Class<Dynamic>;
|
||||
private var fields:Map<String, Field>;
|
||||
|
||||
public function new(data:Dynamic) {
|
||||
if (Reflect.hasField(data, "type")) {
|
||||
var type = Reflect.field(data, "type");
|
||||
this.factory = Type.resolveClass(type);
|
||||
if (factory == null) throw new TypeError("Class \"" + type + "\" not found");
|
||||
}
|
||||
this.fields = new Map<String, Field>();
|
||||
if (Reflect.hasField(data, "style")) {
|
||||
var style = Provider.get(IResources).styles.get(Reflect.field(data, "style"));
|
||||
for (key in Reflect.fields(style)) {
|
||||
fields.set(key, new Field(key, Reflect.field(style, key)));
|
||||
}
|
||||
}
|
||||
for (key in Reflect.fields(data)) {
|
||||
switch (key) {
|
||||
case "type":
|
||||
case "style":
|
||||
case _: fields.set(key, new Field(key, Reflect.field(data, key)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function build(?links:Dynamic):Dynamic {
|
||||
var instance:Dynamic = Type.createInstance(factory, []);
|
||||
instance = fill(instance, links);
|
||||
var initMethod:Dynamic = Reflect.field(instance, "init");
|
||||
if (initMethod != null) Reflect.callMethod(instance, initMethod, []);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public function fill(instance:Dynamic, ?links:Dynamic):Dynamic {
|
||||
for (field in fields) {
|
||||
Reflect.setProperty(instance, field.key, Field.buildValue(field.value, links));
|
||||
switch (field.value) {
|
||||
case Value.RESOURCE(r, k):
|
||||
r.bind(k, instance, field.key);
|
||||
case _:
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static function createFromAsset(asset:String, ?key:String):Dynamic {
|
||||
var data = Json.parse(Assets.getText(asset));
|
||||
if (key != null) {
|
||||
data = Reflect.field(data, key);
|
||||
}
|
||||
return new Builder(data);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import haxework.dispath.IDispatcher;
|
||||
import haxework.gui.IGroupView;
|
||||
import haxework.gui.ButtonView;
|
||||
import haxework.gui.skin.ColorSkin;
|
||||
import haxework.gui.GuiBuilder;
|
||||
import haxework.gui.GroupView;
|
||||
|
||||
class PopupView extends GroupView {
|
||||
@@ -26,7 +25,7 @@ class PopupView extends GroupView {
|
||||
inLayout = false;
|
||||
skin = new ColorSkin(0x000000, 0.6);
|
||||
|
||||
contentView = GuiBuilder.buildFromAssets(resource, key, {listener:this});
|
||||
contentView = Builder.createFromAsset(resource, key).build({listener:this});
|
||||
addView(contentView);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user