[gui] update
This commit is contained in:
@@ -1,38 +1,50 @@
|
||||
package demo;
|
||||
|
||||
import haxework.gui.frame.IFrameSwitcher;
|
||||
import haxework.net.JsonLoader;
|
||||
import demo.popup.ColorPopup;
|
||||
import haxework.App;
|
||||
import haxework.gui.frame.FrameSwitcher;
|
||||
import haxework.gui.IGroupView;
|
||||
import haxework.gui.IView;
|
||||
import haxework.gui.Root;
|
||||
import haxework.gui.ToggleButtonView;
|
||||
import haxework.gui.VGroupView;
|
||||
import haxework.log.TraceLogger;
|
||||
import haxework.net.manage.ILoaderManager;
|
||||
import haxework.net.manage.LoaderManager;
|
||||
import haxework.resources.IResources;
|
||||
import haxework.resources.Resources;
|
||||
|
||||
@:template class Demo extends VGroupView {
|
||||
|
||||
@:provide static var resources:IResources;
|
||||
@:provide static var manager:ILoaderManager;
|
||||
|
||||
public static function main() {
|
||||
L.push(new TraceLogger());
|
||||
resources = new Resources();
|
||||
manager = new LoaderManager();
|
||||
resources.image.put("logo", HaxeLogo.resolve());
|
||||
Theme.setColor(0x33aa33);
|
||||
var demo = new Demo();
|
||||
demo.switcher.change("list_form");
|
||||
Root.bind(demo);
|
||||
Root.instance.onResize.connect(function(rect) trace("resize", rect));
|
||||
}
|
||||
|
||||
@:view var switcher:IFrameSwitcher;
|
||||
@:template class DemoView extends VGroupView {
|
||||
@:view var switcher:FrameSwitcher;
|
||||
@:view var tabs:IGroupView;
|
||||
|
||||
private function init():Void {
|
||||
switcher.change("list_form");
|
||||
}
|
||||
|
||||
private function onFrameSwitch(frame:IView<Dynamic>):Void {
|
||||
for (view in tabs.views) cast(view, ToggleButtonView).on = view.id == frame.id;
|
||||
}
|
||||
|
||||
private function choiceColor():Void {
|
||||
new ColorPopup()
|
||||
.show()
|
||||
.then(function(color) Theme.setColor(color))
|
||||
.catchError(function(e) {});
|
||||
}
|
||||
}
|
||||
|
||||
class Demo extends App {
|
||||
|
||||
public static function main() {
|
||||
L.push(new TraceLogger());
|
||||
|
||||
var app = new App();
|
||||
app.resources.image.put("logo", HaxeLogo.resolve());
|
||||
Theme.setColor(0x33aa33);
|
||||
app.start(new DemoView());
|
||||
|
||||
new JsonLoader().GET("http://umix.tv/channel/data2/renova.json")
|
||||
.then(function(data:Array<Model>) {
|
||||
app.resources.any.put("data", data);
|
||||
app.resources.any.put("data50", Util.marray(data, 50));
|
||||
})
|
||||
.catchError(function(error) trace(error));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,19 +33,23 @@ views:
|
||||
+onPress: "$code:switcher.change('data_form')"
|
||||
- id: switcher
|
||||
$type: haxework.gui.frame.FrameSwitcher
|
||||
skin: $r:skin:border
|
||||
skin: $r:skin:panel
|
||||
animateFactory: { $class: haxework.animate.SlideAnimate }
|
||||
+onSwitch: $this:onFrameSwitch
|
||||
geometry.size.stretch: true
|
||||
geometry.padding: 5
|
||||
views:
|
||||
- id: list_form
|
||||
$type: demo.form.ListForm
|
||||
skin: $r:skin:background
|
||||
geometry.size.stretch: true
|
||||
- id: tail_form
|
||||
$type: demo.form.TailForm
|
||||
skin: $r:skin:background
|
||||
geometry.size.stretch: true
|
||||
- id: data_form
|
||||
$type: demo.form.DataForm
|
||||
skin: $r:skin:background
|
||||
geometry.size.stretch: true
|
||||
- $type: haxework.gui.HGroupView
|
||||
geometry.size.percent.width: 100
|
||||
@@ -55,23 +59,8 @@ views:
|
||||
- $type: haxework.gui.ButtonView
|
||||
geometry.padding: [25, 8]
|
||||
skin: $r:skin:button
|
||||
text: green
|
||||
+onPress: "$code:Theme.setColor(0x33AA33)"
|
||||
- $type: haxework.gui.ButtonView
|
||||
geometry.padding: [25, 8]
|
||||
skin: $r:skin:button
|
||||
text: red
|
||||
+onPress: "$code:Theme.setColor(0xAA3333)"
|
||||
- $type: haxework.gui.ButtonView
|
||||
geometry.padding: [25, 8]
|
||||
skin: $r:skin:button
|
||||
text: yellow
|
||||
+onPress: "$code:Theme.setColor(0xFFCC55, 0x555555)"
|
||||
- $type: haxework.gui.ButtonView
|
||||
geometry.padding: [25, 8]
|
||||
skin: $r:skin:button
|
||||
text: pink
|
||||
+onPress: "$code:Theme.setColor(0xCC33AA)"
|
||||
text: Color
|
||||
+onPress: "$code:choiceColor()"
|
||||
# separator
|
||||
- $type: haxework.gui.SpriteView
|
||||
geometry.size.stretch: true
|
||||
10
demo/src/demo/Model.hx
Normal file
10
demo/src/demo/Model.hx
Normal file
@@ -0,0 +1,10 @@
|
||||
package demo;
|
||||
|
||||
typedef Model = {
|
||||
var id:String;
|
||||
var created_at:Int;
|
||||
var maker:String;
|
||||
var title:String;
|
||||
var message:String;
|
||||
var image:{url:String, width:Int, height:Int};
|
||||
}
|
||||
@@ -13,9 +13,7 @@ class Theme {
|
||||
|
||||
public static function setColor(color:Int, textColor:Int = 0xffffff):Void {
|
||||
var text:ISkin<Dynamic> = new TextSkin(textColor, 16, "Courirer");
|
||||
var background:SkinSet = [
|
||||
Skin.color(0x00000),
|
||||
];
|
||||
var background = Skin.color(0x00000);
|
||||
var button:SkinSet = [
|
||||
Skin.buttonColor(color),
|
||||
text,
|
||||
@@ -32,18 +30,22 @@ class Theme {
|
||||
var scroll:SkinSet = [
|
||||
ScrollBarSkin.vertical(color, ColorUtils.diff(color, 128)),
|
||||
];
|
||||
var border:SkinSet = [
|
||||
Skin.border(ColorUtils.multiply(color, 1.5), 1, 2),
|
||||
];
|
||||
resources.skin.put("text", [
|
||||
var border = Skin.border(ColorUtils.multiply(color, 1.5), 1, 2);
|
||||
resources.skin.put("text0", [
|
||||
Skin.color(ColorUtils.diff(color, 128)),
|
||||
new TextSkin(ColorUtils.diff(color, -128), 16, "Courirer"),
|
||||
]);
|
||||
resources.skin.put("background", background);
|
||||
resources.skin.put("text1", [
|
||||
Skin.color(ColorUtils.diff(color, 64)),
|
||||
new TextSkin(ColorUtils.diff(color, -128), 16, "Courirer"),
|
||||
]);
|
||||
resources.skin.put("text", resources.skin.get("text0"));
|
||||
resources.skin.put("background", [background]);
|
||||
resources.skin.put("button", button);
|
||||
resources.skin.put("tab", tab);
|
||||
resources.skin.put("view", view);
|
||||
resources.skin.put("scroll", scroll);
|
||||
resources.skin.put("border", border);
|
||||
resources.skin.put("border", [border]);
|
||||
resources.skin.put("panel", [background, border]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,17 @@
|
||||
package demo.form;
|
||||
|
||||
import haxework.gui.DataView;
|
||||
import haxework.gui.TextView;
|
||||
import haxework.gui.VGroupView;
|
||||
import haxework.net.JsonLoader;
|
||||
import haxework.resources.IResources;
|
||||
|
||||
@:template class DataForm extends VGroupView {
|
||||
@:view var data:DataView<String>;
|
||||
@:provide var resources:IResources;
|
||||
|
||||
private function init() {
|
||||
new JsonLoader().GET("http://umix.tv/channel/data2/renova.json")
|
||||
.then(function(data:Array<Dynamic>) {
|
||||
var values = data.map(function(item) return '${item.id}: ${item.message}');
|
||||
this.data.data = Util.marray(values, 1);
|
||||
})
|
||||
.catchError(function(error) trace(error));
|
||||
}
|
||||
|
||||
private function factory(index:Int, value:String):TextView {
|
||||
private function factory(index:Int, value:Model):TextView {
|
||||
var label = new TextView();
|
||||
label.geometry.size.percent.width = 100;
|
||||
label.geometry.margin = 1;
|
||||
label.geometry.padding = 2;
|
||||
resources.skin.bind("text", label, "skin");
|
||||
label.text = value;
|
||||
label.skinId = "text";
|
||||
label.text = (value.title != null ? '${value.title}\n-\n' : '') + value.message;
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,12 @@ views:
|
||||
geometry.size.stretch: true
|
||||
view:
|
||||
id: data
|
||||
$type: haxework.gui.DataView<String>
|
||||
$type: haxework.gui.DataView<Model>
|
||||
layout:
|
||||
$type: haxework.gui.layout.VerticalLayout
|
||||
factory: $this:factory
|
||||
geometry.size.width: 100%
|
||||
data: $r:any:data
|
||||
scroll:
|
||||
$type: haxework.gui.list.VScrollBarView
|
||||
skin: $r:skin:scroll
|
||||
|
||||
@@ -1,23 +1,18 @@
|
||||
package demo.form;
|
||||
|
||||
import haxework.gui.list.LabelListItem;
|
||||
import haxework.gui.list.ListView.IListItemView;
|
||||
import haxework.gui.list.VListView;
|
||||
import haxework.gui.VGroupView;
|
||||
import haxework.net.JsonLoader;
|
||||
|
||||
@:template class ListForm extends VGroupView {
|
||||
@:view public var list(default, null):VListView<String>;
|
||||
@:view public var list(default, null):VListView<Model>;
|
||||
|
||||
private function init() {
|
||||
new JsonLoader().GET("http://umix.tv/channel/data2/renova.json")
|
||||
.then(function(data:Array<Dynamic>) {
|
||||
var values = data.map(function(item) return '${item.id}: ${item.message}');
|
||||
list.data = Util.marray(values, 50);
|
||||
})
|
||||
.catchError(function(error) trace(error));
|
||||
private function factory() {
|
||||
return new LabelListItem(function(index:Int, value:Model) return '${index}. ${value.id}: ${value.title}');
|
||||
}
|
||||
|
||||
private function onItemSelect(item:IListItemView<String>):Void {
|
||||
trace('onItemSelect: ${item.data}');
|
||||
private function onItemSelect(item:IListItemView<Model>):Void {
|
||||
trace('onItemSelect: ${item.data.id}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
views:
|
||||
- id: list
|
||||
$type: haxework.gui.list.VListView<String>
|
||||
$type: haxework.gui.list.VListView<Model>
|
||||
+onItemSelect: $this:onItemSelect
|
||||
factory: { $class: haxework.gui.list.LabelListItem }
|
||||
factory: $this:factory
|
||||
geometry.size.stretch: true
|
||||
scroll:
|
||||
$type: haxework.gui.list.VScrollBarView
|
||||
skin: $r:skin:scroll
|
||||
geometry.size.height: 100%
|
||||
geometry.size.width: 10
|
||||
data: $r:any:data50
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
package demo.form;
|
||||
|
||||
import haxework.gui.DataView;
|
||||
import haxework.gui.HGroupView;
|
||||
import haxework.gui.ImageView;
|
||||
import haxework.gui.IView;
|
||||
import haxework.gui.TextView;
|
||||
import haxework.resources.IResources;
|
||||
import haxework.gui.utils.DrawUtil.FillType;
|
||||
|
||||
@:template class TailForm extends HGroupView {
|
||||
@:view public var data:DataView<String>;
|
||||
@:provide var resources:IResources;
|
||||
|
||||
private function init() {
|
||||
data.data = [for (i in 0...100) '${i}'];
|
||||
private function factory(index:Int, value:Model):IView<Dynamic> {
|
||||
var view:IView<Dynamic>;
|
||||
if (value.image != null) {
|
||||
var imageView = new ImageView();
|
||||
imageView.skinId = "border";
|
||||
imageView.fillType = FillType.CONTAIN;
|
||||
imageView.imageUrl = value.image.url;
|
||||
view = imageView;
|
||||
} else {
|
||||
var textView = new TextView();
|
||||
textView.skinId = "view";
|
||||
textView.text = '${value.id}\n${value.maker}';
|
||||
view = textView;
|
||||
}
|
||||
|
||||
private function factory(index:Int, value:String):TextView {
|
||||
var view = new TextView();
|
||||
view.geometry.size.fixed.width = 100 + 100 * Math.random();
|
||||
view.geometry.size.fixed.height = 100 + 100 * Math.random();
|
||||
resources.skin.bind("view", view, "skin");
|
||||
view.text = 'View #${index}';
|
||||
view.geometry.size.fixed.width = 350;
|
||||
view.geometry.size.fixed.height = 200;
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ views:
|
||||
geometry.size.stretch: true
|
||||
view:
|
||||
id: data
|
||||
$type: haxework.gui.DataView<String>
|
||||
$type: haxework.gui.DataView<Model>
|
||||
layout:
|
||||
$type: haxework.gui.layout.TailLayout
|
||||
margin: 2
|
||||
factory: $this:factory
|
||||
geometry.size.width: 100%
|
||||
data: $r:any:data
|
||||
scroll:
|
||||
$type: haxework.gui.list.VScrollBarView
|
||||
skin: $r:skin:scroll
|
||||
|
||||
15
demo/src/demo/popup/ColorPopup.hx
Normal file
15
demo/src/demo/popup/ColorPopup.hx
Normal file
@@ -0,0 +1,15 @@
|
||||
package demo.popup;
|
||||
|
||||
import haxework.gui.ButtonView;
|
||||
import haxework.gui.popup.PopupView;
|
||||
import haxework.gui.skin.Skin;
|
||||
|
||||
@:template class ColorPopup extends PopupView<Int> {
|
||||
|
||||
private function colorViewFactory(index:Int, color:Int) {
|
||||
var view = new ButtonView();
|
||||
view.geometry.size.fixed = [48, 48];
|
||||
view.skin = [Skin.buttonColor(color)];
|
||||
return view;
|
||||
}
|
||||
}
|
||||
35
demo/src/demo/popup/ColorPopup.yaml
Normal file
35
demo/src/demo/popup/ColorPopup.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
view:
|
||||
$type: haxework.gui.VGroupView
|
||||
geometry.size.width: 400
|
||||
geometry.size.height: 200
|
||||
geometry.padding: 10
|
||||
geometry.hAlign: center
|
||||
geometry.vAlign: middle
|
||||
skinId: panel
|
||||
views:
|
||||
- id: colors
|
||||
$type: haxework.gui.DataView
|
||||
geometry.size.stretch: true
|
||||
layout:
|
||||
$type: haxework.gui.layout.TailLayout
|
||||
vAlign: middle
|
||||
margin: 5
|
||||
factory: $this:colorViewFactory
|
||||
data:
|
||||
- 0x33AA33
|
||||
- 0xAA3333
|
||||
- 0xFFCC55 # 0x555555
|
||||
- 0xCC33AA
|
||||
- 0x3333AA
|
||||
+onDataSelect: $this:close
|
||||
- $type: haxework.gui.HGroupView
|
||||
geometry.size.width: 100%
|
||||
layout.hAlign: right
|
||||
layout.margin: 10
|
||||
views:
|
||||
- $type: haxework.gui.ButtonView
|
||||
geometry.padding: [25, 8]
|
||||
skinId: button
|
||||
text: Cancel
|
||||
+onPress: $code:reject('cancel')
|
||||
35
src/main/haxework/App.hx
Normal file
35
src/main/haxework/App.hx
Normal file
@@ -0,0 +1,35 @@
|
||||
package haxework;
|
||||
|
||||
import haxework.gui.Root;
|
||||
import haxework.gui.IView;
|
||||
import flash.Lib;
|
||||
import haxework.animate.Animate;
|
||||
import haxework.animate.FadeAnimate;
|
||||
import haxework.animate.UnFadeAnimate;
|
||||
import haxework.gui.popup.PopupManager;
|
||||
import haxework.net.manage.ILoaderManager;
|
||||
import haxework.net.manage.LoaderManager;
|
||||
import haxework.resources.IResources;
|
||||
import haxework.resources.Resources;
|
||||
|
||||
class App {
|
||||
|
||||
@:provide var app:App;
|
||||
@:provide var resources:IResources;
|
||||
@:provide var loaderManager:ILoaderManager;
|
||||
@:provide var popupManager:PopupManager;
|
||||
|
||||
public function new() {
|
||||
resources = new Resources();
|
||||
loaderManager = new LoaderManager();
|
||||
popupManager = new PopupManager();
|
||||
popupManager.showAnimateFactory = UnFadeAnimate;
|
||||
popupManager.closeAnimateFactory = FadeAnimate;
|
||||
app = this;
|
||||
}
|
||||
|
||||
public function start(view:IView<Dynamic>) {
|
||||
Animate.bind(Lib.current.stage);
|
||||
Root.bind(view);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import flash.events.Event;
|
||||
import flash.display.Stage;
|
||||
|
||||
class Animate implements IAnimate {
|
||||
public static var defaultDuraion = 300;
|
||||
|
||||
private static var running:Array<IAnimate> = new Array<IAnimate>();
|
||||
|
||||
@@ -26,10 +27,10 @@ class Animate implements IAnimate {
|
||||
private var progress:Float;
|
||||
|
||||
public function new(duration:Int) {
|
||||
this.duration = duration;
|
||||
this.duration = duration > -1 ? duration : defaultDuraion;
|
||||
}
|
||||
|
||||
public function start(callback:IAnimate -> Void, ?custom:Bool = false):Void {
|
||||
public function start(callback:IAnimate -> Void, custom:Bool = false):Void {
|
||||
startTime = Date.now().getTime();
|
||||
this.callback = callback;
|
||||
if (!custom) running.push(this);
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
package haxework.animate;
|
||||
|
||||
import flash.display.DisplayObjectContainer;
|
||||
import haxework.animate.IAnimate;
|
||||
import flash.display.Sprite;
|
||||
import haxework.gui.IView;
|
||||
import haxework.animate.Animate;
|
||||
import haxework.animate.IAnimate;
|
||||
import haxework.gui.IView;
|
||||
|
||||
class CircleMaskAnimate extends Animate {
|
||||
|
||||
private var view:IView;
|
||||
private var view:IView<Dynamic>;
|
||||
private var mask:Sprite;
|
||||
private var cyrcle:Sprite;
|
||||
private var size:Float;
|
||||
|
||||
public function new(view:IView, ?duration:Int = 1000) {
|
||||
public function new(view:IView<Dynamic>, duration:Int = -1) {
|
||||
super(duration);
|
||||
this.view = view;
|
||||
this.mask = new Sprite();
|
||||
this.cyrcle = new Sprite();
|
||||
}
|
||||
|
||||
override public function start(callback:IAnimate -> Void, ?custom:Bool = false):Void {
|
||||
override public function start(callback:IAnimate -> Void, custom:Bool = false):Void {
|
||||
var width = view.parent.width;
|
||||
var height = view.parent.height;
|
||||
size = Math.sqrt(width * width + height * height);
|
||||
@@ -44,7 +43,7 @@ class CircleMaskAnimate extends Animate {
|
||||
mask.graphics.endFill();
|
||||
|
||||
cyrcle.graphics.clear();
|
||||
cyrcle.graphics.lineStyle(8, 0xffffff);
|
||||
cyrcle.graphics.lineStyle(4, 0xffffff);
|
||||
cyrcle.graphics.drawCircle(size + size / 2, size + size / 2, r / 2);
|
||||
cyrcle.graphics.lineStyle();
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package haxework.animate;
|
||||
|
||||
import flash.display.DisplayObject;
|
||||
import haxework.animate.IAnimate;
|
||||
import flash.display.Sprite;
|
||||
import haxework.gui.IView;
|
||||
import haxework.animate.Animate;
|
||||
|
||||
class FadeAnimate extends Animate {
|
||||
|
||||
private var view:IView;
|
||||
private var view:IView<DisplayObject>;
|
||||
|
||||
public function new(view:IView, ?duration = 500) {
|
||||
public function new(view:IView<DisplayObject>, duration:Int = -1) {
|
||||
super(duration);
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
override public function start(callback:IAnimate -> Void, ?custom:Bool = false):Void {
|
||||
override public function start(callback:IAnimate -> Void, custom:Bool = false):Void {
|
||||
view.content.alpha = 1.0;
|
||||
super.start(callback, custom);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ package haxework.animate;
|
||||
|
||||
interface IAnimate {
|
||||
|
||||
public function start(callback:IAnimate->Void, ?custom:Bool = false):Void;
|
||||
public function start(callback:IAnimate -> Void, custom:Bool = false):Void;
|
||||
|
||||
public function cancel():Void;
|
||||
|
||||
private function update(time:Float):Void;
|
||||
|
||||
24
src/main/haxework/animate/SlideAnimate.hx
Normal file
24
src/main/haxework/animate/SlideAnimate.hx
Normal file
@@ -0,0 +1,24 @@
|
||||
package haxework.animate;
|
||||
|
||||
import flash.display.DisplayObject;
|
||||
import haxework.gui.IView;
|
||||
|
||||
class SlideAnimate extends Animate {
|
||||
|
||||
private var view:IView<DisplayObject>;
|
||||
|
||||
public function new(view:IView<DisplayObject>, duration:Int = -1) {
|
||||
super(duration);
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
override public function start(callback:IAnimate -> Void, custom:Bool = false):Void {
|
||||
view.content.x = view.x - this.view.width + this.view.width / progress;
|
||||
super.start(callback, custom);
|
||||
}
|
||||
|
||||
override private function update(time:Float):Void {
|
||||
super.update(time);
|
||||
view.content.x = view.x - this.view.width + this.view.width / Math.min(1, progress);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,19 @@
|
||||
package haxework.animate;
|
||||
|
||||
import flash.display.Sprite;
|
||||
import flash.display.DisplayObject;
|
||||
import haxework.gui.IView;
|
||||
import haxework.animate.Animate;
|
||||
|
||||
class UnFadeAnimate extends Animate {
|
||||
|
||||
private var view:IView;
|
||||
private var view:IView<DisplayObject>;
|
||||
|
||||
public function new(view:IView, ?duration = 500) {
|
||||
public function new(view:IView<DisplayObject>, duration:Int = -1) {
|
||||
super(duration);
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
override public function start(callback:IAnimate -> Void, ?custom:Bool = false):Void {
|
||||
override public function start(callback:IAnimate -> Void, custom:Bool = false):Void {
|
||||
view.content.alpha = 0.0;
|
||||
super.start(callback, custom);
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package haxework.core;
|
||||
|
||||
interface IDisposable {
|
||||
public function dispose():Void;
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
package haxework.core;
|
||||
typedef Tuple2#if!H<T1, T2>#end = {
|
||||
var first(default, null):T1;
|
||||
var second(default, null):T2;
|
||||
}
|
||||
typedef Tuple3#if!H<T1, T2, T3>#end = {> Tuple2<T1, T2>,
|
||||
var third(default, null):T3;
|
||||
}
|
||||
typedef Tuple4#if!H<T1, T2, T3, T4>#end = {> Tuple3<T1, T2, T3>,
|
||||
var fourth(default, null):T4;
|
||||
}
|
||||
typedef Tuple5#if!H<T1, T2, T3, T4, T5>#end = {> Tuple4<T1, T2, T3, T4>,
|
||||
var fifth(default, null):T5;
|
||||
}
|
||||
|
||||
class Tuple {
|
||||
public static function five<T1, T2, T3, T4, T5>(first:T1, second:T2, third:T3, fourth:T4, fifth:T5):Tuple5<T1, T2, T3, T4, T5> {
|
||||
return new InternalTuple5(first, second, third, fourth, fifth);
|
||||
}
|
||||
|
||||
public static function four<T1, T2, T3, T4>(first:T1, second:T2, third:T3, fourth:T4):Tuple4<T1, T2, T3, T4> {
|
||||
return new InternalTuple4(first, second, third, fourth);
|
||||
}
|
||||
|
||||
public static function three<T1, T2, T3>(first:T1, second:T2, third:T3):Tuple3<T1, T2, T3> {
|
||||
return new InternalTuple3(first, second, third);
|
||||
}
|
||||
|
||||
public static function two<T1, T2>(first:T1, second:T2):Tuple2<T1, T2> {
|
||||
return new InternalTuple2(first, second);
|
||||
}
|
||||
|
||||
public static inline function asTuple2<T1, T2, T3>(tuple:Tuple3<T1, T2, T3>):Tuple2<T1, T2>
|
||||
return tuple;
|
||||
|
||||
public static inline function asTuple3<T1, T2, T3, T4>(tuple:Tuple4<T1, T2, T3, T4>):Tuple3<T1, T2, T3>
|
||||
return tuple;
|
||||
|
||||
public static inline function asTuple4<T1, T2, T3, T4, T5>(tuple:Tuple5<T1, T2, T3, T4, T5>):Tuple4<T1, T2, T3, T4>
|
||||
return tuple;
|
||||
}
|
||||
|
||||
private class InternalTuple2<T1, T2> {
|
||||
public var first(default, null):T1;
|
||||
public var second(default, null):T2;
|
||||
|
||||
/**
|
||||
* Creates a new tuple.
|
||||
* @param first The first value.
|
||||
* @param second The second value.
|
||||
*/
|
||||
|
||||
public function new(first:T1, second:T2) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public function toString():String {
|
||||
return "(" + first + ", " + second + ")";
|
||||
}
|
||||
}
|
||||
private class InternalTuple3<T1, T2, T3> extends InternalTuple2<T1, T2> {
|
||||
public var third(default, null):T3;
|
||||
|
||||
/**
|
||||
* Creates a new tuple.
|
||||
* @param first The first value.
|
||||
* @param second The second value.
|
||||
* @param third The third value.
|
||||
*/
|
||||
|
||||
public function new(first:T1, second:T2, third:T3) {
|
||||
super(first, second);
|
||||
this.third = third;
|
||||
}
|
||||
|
||||
public override function toString():String {
|
||||
return "("
|
||||
+ first + ", "
|
||||
+ second + ", "
|
||||
+ third + ")";
|
||||
}
|
||||
}
|
||||
private class InternalTuple4<T1, T2, T3, T4> extends InternalTuple3<T1, T2, T3> {
|
||||
public var fourth(default, null):T4;
|
||||
|
||||
/**
|
||||
* Creates a new tuple.
|
||||
* @param first The first value.
|
||||
* @param second The second value.
|
||||
* @param third The third value.
|
||||
* @param fourth The fourth value.
|
||||
*/
|
||||
|
||||
public function new(first:T1, second:T2, third:T3, fourth:T4) {
|
||||
super(first, second, third);
|
||||
this.fourth = fourth;
|
||||
}
|
||||
|
||||
public override function toString():String {
|
||||
return "("
|
||||
+ first + ", "
|
||||
+ second + ", "
|
||||
+ third + ", "
|
||||
+ fourth + ")";
|
||||
}
|
||||
}
|
||||
private class InternalTuple5<T1, T2, T3, T4, T5> extends InternalTuple4<T1, T2, T3, T4> {
|
||||
public var fifth(default, null):T5;
|
||||
|
||||
/**
|
||||
* Creates a new tuple.
|
||||
* @param first The first value.
|
||||
* @param second The second value.
|
||||
* @param third The third value.
|
||||
* @param fourth The fourth value.
|
||||
* @param fifth The fifth value.
|
||||
*/
|
||||
|
||||
public function new(first:T1, second:T2, third:T3, fourth:T4, fifth:T5) {
|
||||
super(first, second, third, fourth);
|
||||
this.fifth = fifth;
|
||||
}
|
||||
|
||||
public override function toString():String {
|
||||
return "("
|
||||
+ first + ", "
|
||||
+ second + ", "
|
||||
+ third + ", "
|
||||
+ fourth + ", "
|
||||
+ fifth + ")";
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package haxework.gui;
|
||||
|
||||
import haxe.Timer;
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.BitmapData;
|
||||
import haxework.gui.SpriteView;
|
||||
|
||||
class AnimateView extends SpriteView {
|
||||
|
||||
private var bitmap:Bitmap;
|
||||
public var frames(default, set):Array<BitmapData>;
|
||||
public var interval(default, set):Int;
|
||||
private var frame:Int;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
bitmap = new Bitmap();
|
||||
frames = [];
|
||||
frame = 0;
|
||||
interval = 200;
|
||||
content.addChild(bitmap);
|
||||
changeFrame();
|
||||
}
|
||||
|
||||
private function set_frames(value:Array<BitmapData>):Array<BitmapData> {
|
||||
if (frames != value) {
|
||||
frames = value;
|
||||
frame = 0;
|
||||
changeFrame(true);
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
|
||||
private function set_interval(value:Int):Int {
|
||||
if (interval != value) {
|
||||
interval = value;
|
||||
}
|
||||
return interval;
|
||||
}
|
||||
|
||||
private function changeFrame(?forse:Bool = false):Void {
|
||||
frame = ++frame % frames.length;
|
||||
bitmap.bitmapData = frames[frame];
|
||||
update();
|
||||
if (!forse) Timer.delay(function() changeFrame(false), interval);
|
||||
}
|
||||
|
||||
override public function update():Void {
|
||||
if (contentSize && bitmap.bitmapData != null) {
|
||||
width = bitmap.bitmapData.width;
|
||||
height = bitmap.bitmapData.height;
|
||||
}
|
||||
super.update();
|
||||
bitmap.x = (width - bitmap.width) / 2;
|
||||
bitmap.y = (height - bitmap.height) / 2;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import flash.display.DisplayObject;
|
||||
import flash.events.MouseEvent;
|
||||
import haxework.signal.Signal;
|
||||
|
||||
typedef Factory<D> = Int -> D -> IView<Dynamic>
|
||||
|
||||
class DataView<D> extends GroupView {
|
||||
|
||||
public var data(default, set):Array<D>;
|
||||
public var factory(default, default):Int -> D -> IView<Dynamic>;
|
||||
public var factory(default, set):Factory<D>;
|
||||
public var onItemSelect(default, null):Signal3<Int, D, IView<Dynamic>> = new Signal3();
|
||||
public var onDataSelect(default, null):Signal<D> = new Signal();
|
||||
|
||||
@@ -15,10 +17,16 @@ class DataView<D> extends GroupView {
|
||||
|
||||
private function set_data(value:Array<D>):Array<D> {
|
||||
data = value;
|
||||
rebuild();
|
||||
if (factory != null) rebuild();
|
||||
return data;
|
||||
}
|
||||
|
||||
private function set_factory(value:Factory<D>):Factory<D> {
|
||||
factory = value;
|
||||
if (data != null) rebuild();
|
||||
return factory;
|
||||
}
|
||||
|
||||
private function rebuild():Void {
|
||||
for (view in views) {
|
||||
view.content.removeEventListener(MouseEvent.CLICK, onItemClick);
|
||||
|
||||
@@ -17,6 +17,7 @@ interface IView<C:DisplayObject> {
|
||||
|
||||
public var content(default, null):C;
|
||||
public var skin(default, set):SkinSet;
|
||||
public var skinId(null, set):String;
|
||||
|
||||
public var parent(default, null):Null<IGroupView>;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package haxework.gui;
|
||||
|
||||
import flash.display.BitmapData;
|
||||
import haxework.gui.skin.BitmapSkin;
|
||||
import haxework.gui.skin.ISkin;
|
||||
import haxework.gui.utils.DrawUtil.FillType;
|
||||
import haxework.net.ImageLoader;
|
||||
|
||||
@@ -9,22 +10,29 @@ class ImageView extends SpriteView {
|
||||
|
||||
public var image(default, set):BitmapData;
|
||||
public var imageUrl(default, set):String;
|
||||
public var fillType(default, set):FillType;
|
||||
|
||||
public function new(?image:BitmapData) {
|
||||
private var bitmapSkin:BitmapSkin = new BitmapSkin();
|
||||
|
||||
public function new(image:BitmapData = null) {
|
||||
super();
|
||||
fillType = FillType.DEFAULT;
|
||||
if (image != null) {
|
||||
this.image = image;
|
||||
}
|
||||
}
|
||||
|
||||
override private function set_skin(value:SkinSet):SkinSet {
|
||||
value = value.slice(0);
|
||||
value.unshift(bitmapSkin);
|
||||
return super.set_skin(value);
|
||||
}
|
||||
|
||||
private function set_image(value:BitmapData):BitmapData {
|
||||
if (image != value) {
|
||||
image = value;
|
||||
skin = [new BitmapSkin(image, FillType.DEFAULT)];
|
||||
//geometry.size.content.width = value.width;
|
||||
//geometry.size.content.height = value.height;
|
||||
//toUpdate();
|
||||
//toRedraw();
|
||||
bitmapSkin.image = value;
|
||||
toRedraw();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
@@ -34,8 +42,15 @@ class ImageView extends SpriteView {
|
||||
imageUrl = value;
|
||||
new ImageLoader().GET(imageUrl).then(function(data) {
|
||||
image = data;
|
||||
});
|
||||
}).catchError(function(e) L.w("ImageView", "load", e));
|
||||
}
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
private function set_fillType(value:FillType):FillType {
|
||||
if (fillType != value) {
|
||||
bitmapSkin.fillType = fillType = value;
|
||||
}
|
||||
return fillType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,9 @@ import flash.errors.Error;
|
||||
import flash.events.Event;
|
||||
import flash.geom.Rectangle;
|
||||
import flash.Lib;
|
||||
import haxework.core.IDisposable;
|
||||
import haxework.signal.Signal;
|
||||
|
||||
class Root implements IDisposable {
|
||||
class Root {
|
||||
|
||||
public static function bind(view:IView<Dynamic>, autoSize:Bool = true) {
|
||||
new Root(view, autoSize);
|
||||
|
||||
@@ -144,7 +144,7 @@ class TextView extends SpriteView implements ITextView {
|
||||
|
||||
private function updateTextSize():Void {
|
||||
var size = TextUtil.getSize(textField);
|
||||
setContentSize(size.x, size.y);
|
||||
setContentSize(size.x, size.y, "text");
|
||||
}
|
||||
|
||||
override public function update():Void {
|
||||
@@ -168,7 +168,7 @@ class TextView extends SpriteView implements ITextView {
|
||||
|
||||
private function placeTextField(textField:TextField):Void {
|
||||
textField.width = width;
|
||||
textField.height = geometry.size.content.height;
|
||||
textField.height = geometry.size.content.exists("text") ? geometry.size.content.get("text").height : height;
|
||||
|
||||
textField.x = switch (layout.hAlign) {
|
||||
case LEFT | NONE: geometry.padding.left;
|
||||
@@ -178,8 +178,8 @@ class TextView extends SpriteView implements ITextView {
|
||||
}
|
||||
textField.y = switch (layout.vAlign) {
|
||||
case TOP | NONE: geometry.padding.top;
|
||||
case MIDDLE: (height - geometry.size.content.height) / 2 + geometry.padding.top - geometry.padding.bottom;
|
||||
case BOTTOM: height - geometry.size.content.height - geometry.padding.bottom;
|
||||
case MIDDLE: (height - textField.height) / 2 + geometry.padding.top - geometry.padding.bottom;
|
||||
case BOTTOM: height - textField.height - geometry.padding.bottom;
|
||||
default: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package haxework.gui;
|
||||
|
||||
import haxework.gui.skin.ISkin.ISizeSkin;
|
||||
import flash.display.DisplayObject;
|
||||
import flash.display.InteractiveObject;
|
||||
import haxework.gui.core.Geometry;
|
||||
import haxework.gui.skin.ISkin.ISizeSkin;
|
||||
import haxework.gui.skin.ISkin.SkinSet;
|
||||
import haxework.resources.IResources;
|
||||
|
||||
class View<C:DisplayObject> implements IView<C> {
|
||||
@:provide private var r:IResources;
|
||||
|
||||
private static var counter:Int = 0;
|
||||
public static var updater(default, null):ViewUpdater = new ViewUpdater();
|
||||
@@ -23,6 +25,7 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
|
||||
public var content(default, null):C;
|
||||
public var skin(default, set):SkinSet;
|
||||
public var skinId(null, set):String;
|
||||
|
||||
public var parent(default, null):Null<IGroupView>;
|
||||
|
||||
@@ -63,22 +66,16 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
for (skin in this.skin) {
|
||||
if (Std.is(skin, ISizeSkin)) {
|
||||
var sizeSkin:ISizeSkin = cast skin;
|
||||
setSize(sizeSkin.width, sizeSkin.height);
|
||||
setContentSize(sizeSkin.width, sizeSkin.height, "skin");
|
||||
}
|
||||
skin.draw(this);
|
||||
}
|
||||
}
|
||||
|
||||
private function setSize(width:Float, height:Float):Void {
|
||||
if (width != geometry.size.fixed.width || height != geometry.size.fixed.height) {
|
||||
geometry.size.fixed = [width, height];
|
||||
toUpdateParent();
|
||||
}
|
||||
}
|
||||
|
||||
private function setContentSize(width:Float, height:Float):Void {
|
||||
if (width != geometry.size.content.width || height != geometry.size.content.height) {
|
||||
geometry.size.content = [width, height];
|
||||
private function setContentSize(width:Float, height:Float, type:String="default"):Void {
|
||||
var contentSize = geometry.size.content.get(type);
|
||||
if (contentSize == null || width != contentSize.width || height != contentSize.height) {
|
||||
geometry.size.content.set(type, [width, height]);
|
||||
toUpdateParent();
|
||||
}
|
||||
}
|
||||
@@ -123,6 +120,11 @@ class View<C:DisplayObject> implements IView<C> {
|
||||
return this.skin;
|
||||
}
|
||||
|
||||
private function set_skinId(value:String):String {
|
||||
r.skin.bind(value, this, "skin");
|
||||
return value;
|
||||
}
|
||||
|
||||
private function set_visible(value:Bool):Bool {
|
||||
if (visible != value) {
|
||||
visible = value;
|
||||
|
||||
@@ -29,7 +29,7 @@ abstract ASizeValue(SizeValue) {
|
||||
}
|
||||
|
||||
class SizeSet {
|
||||
public var content(default, default):Size;
|
||||
public var content(default, default):Map<String, Size>;
|
||||
public var fixed(default, default):Size;
|
||||
public var percent(default, default):Size;
|
||||
public var stretch(null, set):Bool;
|
||||
@@ -38,7 +38,7 @@ class SizeSet {
|
||||
public var height(null, set):ASizeValue;
|
||||
|
||||
public function new() {
|
||||
this.content = [];
|
||||
this.content = new Map();
|
||||
this.fixed = [];
|
||||
this.percent = [];
|
||||
}
|
||||
@@ -96,7 +96,9 @@ class Geometry {
|
||||
}
|
||||
var result = size.fixed.width;
|
||||
if (result < 0) {
|
||||
result = size.content.width;
|
||||
for (s in size.content.iterator()) {
|
||||
result = Math.max(result, s.width);
|
||||
}
|
||||
}
|
||||
result += padding.horizontal;
|
||||
return FIXED(result);
|
||||
@@ -108,7 +110,9 @@ class Geometry {
|
||||
}
|
||||
var result = size.fixed.height;
|
||||
if (result < 0) {
|
||||
result = size.content.height;
|
||||
for (s in size.content.iterator()) {
|
||||
result = Math.max(result, s.height);
|
||||
}
|
||||
}
|
||||
result += padding.vertical;
|
||||
return FIXED(result);
|
||||
|
||||
@@ -5,7 +5,7 @@ import haxework.animate.IAnimate;
|
||||
import haxework.gui.IView;
|
||||
import haxework.gui.GroupView;
|
||||
|
||||
class FrameSwitcher extends GroupView implements IFrameSwitcher {
|
||||
class FrameSwitcher extends GroupView {
|
||||
|
||||
public var current(default, null):Null<IView<Dynamic>>;
|
||||
public var onSwitch:Signal<IView<Dynamic>> = new Signal();
|
||||
@@ -39,6 +39,7 @@ class FrameSwitcher extends GroupView implements IFrameSwitcher {
|
||||
throw 'frame "$id" not found';
|
||||
}
|
||||
addView(current);
|
||||
update();
|
||||
//ToDo:
|
||||
if (content.stage != null) content.stage.focus = cast(current, SpriteView).content;
|
||||
var onShowMethod:Dynamic = Reflect.field(current, "onShow");
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package haxework.gui.frame;
|
||||
|
||||
import haxework.gui.IView;
|
||||
|
||||
interface IFrameSwitcher extends IView<Dynamic> {
|
||||
public var current(default, null):Null<IView<Dynamic>>;
|
||||
public function change(id:String):IView<Dynamic>;
|
||||
}
|
||||
@@ -29,8 +29,7 @@ class HorizontalLayout extends DefaultLayout {
|
||||
maxSize = Math.max(maxSize, view.height);
|
||||
}
|
||||
|
||||
group.geometry.size.content.height = maxSize;
|
||||
group.geometry.size.content.width = fixedSize;
|
||||
group.geometry.size.content.set("group", [fixedSize, maxSize]);
|
||||
|
||||
leftSize -= fixedSize;
|
||||
for (view in views) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package haxework.gui.layout;
|
||||
|
||||
import haxework.gui.core.VAlign;
|
||||
typedef Row = {
|
||||
var width:Float;
|
||||
var height:Float;
|
||||
@@ -50,10 +51,18 @@ class TailLayout extends DefaultLayout {
|
||||
var y:Float = Math.max(group.geometry.padding.top, (group.height - h) / 2);
|
||||
|
||||
y = group.geometry.padding.top;
|
||||
if (h < group.height) {
|
||||
y = switch vAlign {
|
||||
case TOP | NONE: group.geometry.padding.top;
|
||||
case MIDDLE: (group.height - h) / 2;
|
||||
case BOTTOM: group.height - h - group.geometry.padding.bottom;
|
||||
}
|
||||
}
|
||||
for (row in rows) {
|
||||
placeRow(group, y, row);
|
||||
y += row.height + margin;
|
||||
}
|
||||
group.geometry.size.content.height = h;
|
||||
|
||||
group.geometry.size.content.set("group", [-1, h]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,7 @@ class VerticalLayout extends DefaultLayout {
|
||||
maxSize = Math.max(maxSize, view.width);
|
||||
}
|
||||
|
||||
group.geometry.size.content.width = maxSize;
|
||||
group.geometry.size.content.height = fixedSize;
|
||||
group.geometry.size.content.set("group", [maxSize, fixedSize]);
|
||||
|
||||
leftSize -= fixedSize;
|
||||
for (view in views) {
|
||||
|
||||
@@ -2,24 +2,32 @@ package haxework.gui.list;
|
||||
|
||||
import haxework.gui.core.HAlign;
|
||||
import haxework.gui.list.ListView.IListItemView;
|
||||
import haxework.gui.skin.ColorSkin;
|
||||
|
||||
private typedef Formatter<T> = Int -> T -> String;
|
||||
|
||||
class LabelListItem<T> extends LabelView implements IListItemView<T> {
|
||||
|
||||
public var item_index(default, default):Int;
|
||||
public var data(default, set):T;
|
||||
public var formatter(default, default):Formatter<T>;
|
||||
|
||||
public function new() {
|
||||
private static function defaultFormatter<T>(index:Int, value:T):String {
|
||||
return Std.string(value);
|
||||
}
|
||||
|
||||
public function new(formatter:Formatter<T> = null) {
|
||||
super();
|
||||
this.formatter = formatter == null ? defaultFormatter : formatter;
|
||||
geometry.size.percent.width = 100;
|
||||
geometry.size.fixed.height = 20;
|
||||
geometry.padding = 8;
|
||||
layout.hAlign = HAlign.LEFT;
|
||||
layout.hAlign = LEFT;
|
||||
}
|
||||
|
||||
private function set_data(value:T):T {
|
||||
data = value;
|
||||
text = Std.string(value);
|
||||
skin = item_index % 2 == 1 ? [new ColorSkin(0xdddddd)] : [new ColorSkin(0xcccccc)];
|
||||
text = formatter(item_index, value);
|
||||
skinId = 'text${item_index % 2}';
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import haxework.utils.NumberUtil;
|
||||
class ListView<D> extends GroupView {
|
||||
|
||||
public var data(default, set):Array<D>;
|
||||
public var factory(null, default):Class<IListItemView<D>>;
|
||||
public var factory(null, default):Void->IListItemView<D>;
|
||||
|
||||
public var offset(default, set):Int;
|
||||
private var offsetDiff(default, set):Float;
|
||||
@@ -183,7 +183,7 @@ class ListView<D> extends GroupView {
|
||||
|
||||
override public function update():Void {
|
||||
super.update();
|
||||
recalcSize(Type.createInstance(factory, []));
|
||||
recalcSize(factory());
|
||||
render();
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ class ListView<D> extends GroupView {
|
||||
var diff:Int = size - items.length;
|
||||
if (diff > 0) {
|
||||
for (i in 0...diff) {
|
||||
var item:IListItemView<D> = Type.createInstance(factory, []);
|
||||
var item:IListItemView<D> = factory();
|
||||
items.push(item);
|
||||
setClickListener(item);
|
||||
box.addView(item);
|
||||
|
||||
@@ -4,36 +4,35 @@ import haxework.animate.IAnimate;
|
||||
import haxework.gui.Root;
|
||||
import haxework.gui.IGroupView;
|
||||
|
||||
typedef P = PopupView<Dynamic>;
|
||||
|
||||
class PopupManager {
|
||||
|
||||
public var showAnimateFactory(default, default):Class<IAnimate>;
|
||||
public var closeAnimateFactory(default, default):Class<IAnimate>;
|
||||
|
||||
private var popups:Array<PopupView<Dynamic>>;
|
||||
private var popups:Array<P>;
|
||||
|
||||
public function new() {
|
||||
popups = new Array<PopupView<Dynamic>>();
|
||||
popups = new Array<P>();
|
||||
}
|
||||
|
||||
public function show(popup:PopupView<Dynamic>):Void {
|
||||
public function show(popup:P):Void {
|
||||
cast(Root.instance.view, IGroupView).addView(popup);
|
||||
if (showAnimateFactory != null) {
|
||||
Type.createInstance(showAnimateFactory, [popup]).start(null);
|
||||
}
|
||||
popups.push(popup);
|
||||
popup.onShow();
|
||||
}
|
||||
|
||||
public function close(popup:PopupView<Dynamic>):Void {
|
||||
public function close(popup:P):Void {
|
||||
popups.remove(popup);
|
||||
if (closeAnimateFactory != null) {
|
||||
Type.createInstance(closeAnimateFactory, [popup]).start(function(_) {
|
||||
cast(Root.instance.view, IGroupView).removeView(popup);
|
||||
popup.onClose();
|
||||
});
|
||||
} else {
|
||||
cast(Root.instance.view, IGroupView).removeView(popup);
|
||||
popup.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +1,48 @@
|
||||
package haxework.gui.popup;
|
||||
|
||||
import promhx.Deferred;
|
||||
import haxe.Timer;
|
||||
import haxework.provider.Provider;
|
||||
import haxework.dispath.Dispatcher;
|
||||
import haxework.dispath.IDispatcher;
|
||||
import haxework.gui.IGroupView;
|
||||
import haxework.gui.ButtonView;
|
||||
import haxework.gui.skin.ColorSkin;
|
||||
import haxework.gui.core.Geometry.Position;
|
||||
import haxework.gui.GroupView;
|
||||
import haxework.gui.skin.Skin;
|
||||
import promhx.Deferred;
|
||||
import promhx.Promise;
|
||||
|
||||
class PopupView<V:IView> extends GroupView {
|
||||
class PopupView<R> extends GroupView {
|
||||
@:provide var manager:PopupManager;
|
||||
|
||||
private var buttonId:String;
|
||||
private var contentView:V;
|
||||
private var deferred:Deferred<String>;
|
||||
public var view(default, set):IView<Dynamic>;
|
||||
private var deferred:Deferred<R>;
|
||||
|
||||
public function new(contentViewFactory:Class<V>) {
|
||||
public function new() {
|
||||
super();
|
||||
|
||||
pWidth = 100;
|
||||
pHeight = 100;
|
||||
inLayout = false;
|
||||
skin = new ColorSkin(0x000000, 0.6);
|
||||
|
||||
this.contentView = Type.createInstance(contentViewFactory, [{listener:this}]);
|
||||
addView(contentView);
|
||||
geometry.size.stretch = true;
|
||||
geometry.position = Position.ABSOLUTE;
|
||||
skin = [Skin.color(0x000000, 0.6)];
|
||||
}
|
||||
|
||||
public function onPress(button:ButtonView) {
|
||||
this.buttonId = button.id;
|
||||
close();
|
||||
private function set_view(value:IView<Dynamic>):IView<Dynamic> {
|
||||
this.view = value;
|
||||
this.views = [value];
|
||||
return this.view;
|
||||
}
|
||||
|
||||
public function show():Deferred<String> {
|
||||
Provider.get(PopupManager).show(this);
|
||||
deferred = new Deferred<String>();
|
||||
return deferred;
|
||||
public function show():Promise<R> {
|
||||
manager.show(this);
|
||||
deferred = new Deferred<R>();
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
public function close():Void {
|
||||
Provider.get(PopupManager).close(this);
|
||||
}
|
||||
|
||||
public function onShow():Void {
|
||||
buttonId = "close";
|
||||
}
|
||||
|
||||
public function onClose():Void {
|
||||
public function close(result:R):Void {
|
||||
manager.close(this);
|
||||
if (deferred != null) {
|
||||
deferred.resolve(buttonId);
|
||||
deferred.resolve(result);
|
||||
deferred = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function reject(reason:Dynamic):Void {
|
||||
manager.close(this);
|
||||
if (deferred != null) {
|
||||
deferred.throwError(reason);
|
||||
deferred = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,6 @@ class BitmapSkin implements ISkin<SpriteView> implements ISizeSkin {
|
||||
|
||||
public function draw(view:SpriteView):Void {
|
||||
if (image == null) return;
|
||||
DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color);
|
||||
DrawUtil.draw(view.content.graphics, image, new Rectangle(0, 0, view.width, view.height), fillType, color, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ class BorderSkin implements ISkin<SpriteView> {
|
||||
|
||||
public function draw(view:SpriteView):Void {
|
||||
view.content.graphics.lineStyle(tickness, color, alpha, true);
|
||||
view.content.graphics.drawRect(tickness, tickness, view.width - tickness * 2, view.height - tickness * 2);
|
||||
view.content.graphics.drawRect(tickness / 2, tickness / 2, view.width - tickness, view.height - tickness);
|
||||
view.content.graphics.lineStyle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package haxework.net.order;
|
||||
|
||||
import promhx.Promise;
|
||||
import promhx.Deferred;
|
||||
|
||||
typedef Order<T> = {
|
||||
var id:String;
|
||||
var data:Null<T>;
|
||||
var deferred:Deferred<T>;
|
||||
var clients:Int;
|
||||
}
|
||||
|
||||
interface IOrderSupplier {
|
||||
public var orders(default, null):Map<String, Order<Dynamic>>;
|
||||
|
||||
public function request<T>(url:String, clazz:Class<T>):Promise<T>;
|
||||
public function release(url:String, force:Bool = false):Void;
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
package haxework.net.order;
|
||||
|
||||
import promhx.Promise;
|
||||
import promhx.Deferred;
|
||||
import haxework.net.order.IOrderSupplier.Order;
|
||||
import flash.display.BitmapData;
|
||||
|
||||
class OrderSupplier implements IOrderSupplier {
|
||||
|
||||
private static inline var TAG:String = "OrderSupplier";
|
||||
|
||||
public var orders(default, null):Map<String, Order<Dynamic>>;
|
||||
|
||||
public function new() {
|
||||
orders = new Map<String, Order<Dynamic>>();
|
||||
}
|
||||
|
||||
public function request<T>(url:String, clazz:Class<T>):Promise<T> {
|
||||
if (orders.exists(url)) {
|
||||
var order:Order<T> = orders.get(url);
|
||||
order.clients++;
|
||||
//L.d(TAG, "Request(" + order.clients + "): " + url);
|
||||
return order.deferred.promise();
|
||||
} else {
|
||||
var deferred = new Deferred<T>();
|
||||
var order:Order<T> = {
|
||||
id:url,
|
||||
data:null,
|
||||
deferred:deferred,
|
||||
clients:1
|
||||
}
|
||||
//L.d(TAG, "Request(" + order.clients + "): " + url);
|
||||
orders.set(url, order);
|
||||
var loader:ILoader<T> = buildLoader(clazz);
|
||||
loader.GET(url)
|
||||
.then(function(data:T):Void {
|
||||
if (orders.exists(url)) {
|
||||
var order:Order<T> = orders.get(url);
|
||||
order.data = data;
|
||||
order.deferred.resolve(data);
|
||||
}
|
||||
})
|
||||
.catchError(function(error:Dynamic):Void {
|
||||
if (orders.exists(url)) orders.get(url).deferred.throwError(error);
|
||||
orders.remove(url);
|
||||
});
|
||||
return deferred.promise();
|
||||
}
|
||||
}
|
||||
|
||||
public function release(url:String, force:Bool = false):Void {
|
||||
if (orders.exists(url)) {
|
||||
var order:Order<Dynamic> = orders.get(url);
|
||||
if (--order.clients <= 0 || force) {
|
||||
var data:Dynamic = order.data;
|
||||
if (data != null && Std.is(data, BitmapData)) {
|
||||
cast(data, BitmapData).dispose();
|
||||
}
|
||||
orders.remove(url);
|
||||
}
|
||||
L.d(TAG, "Release(" + order.clients + "): " + url);
|
||||
//log();
|
||||
}
|
||||
}
|
||||
|
||||
private function buildLoader<T>(clazz:Class<T>):ILoader<T> {
|
||||
var c:Class<Dynamic> = clazz;
|
||||
return if (c == BitmapData) {
|
||||
var loader:ILoader<T> = cast new ImageLoader();
|
||||
loader.timeout = 7000; //ToDo: hardcode timeout for loading images
|
||||
loader;
|
||||
} else {
|
||||
throw "Unsupported order: " + c;
|
||||
}
|
||||
}
|
||||
|
||||
private function log():Void {
|
||||
L.d(TAG, "\n" + Lambda.map(orders, function(order:Order<Dynamic>):String {
|
||||
return "(" + order.clients + ") " + order.id;
|
||||
}).join("\n"));
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package haxework.resources;
|
||||
|
||||
import haxework.gui.skin.ISkin.SkinSet;
|
||||
import flash.display.MovieClip;
|
||||
import haxework.resources.Resources.ResMap;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.MovieClip;
|
||||
import haxework.gui.skin.ISkin.SkinSet;
|
||||
import haxework.resources.Resources.ResMap;
|
||||
|
||||
interface IResources {
|
||||
public var image(default, null):ResMap<BitmapData>;
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package haxework.resources;
|
||||
|
||||
import haxework.gui.skin.ISkin.SkinSet;
|
||||
import flash.display.BitmapData;
|
||||
import flash.display.MovieClip;
|
||||
import haxe.ds.StringMap;
|
||||
import haxework.core.Tuple;
|
||||
import haxework.gui.skin.ISkin;
|
||||
|
||||
private typedef F = Tuple2<Dynamic, String>
|
||||
private typedef Listener = {object:Dynamic, field:String};
|
||||
|
||||
class ResMap<T> extends StringMap<T> {
|
||||
|
||||
private var listeners:Map<String, Array<F>>;
|
||||
private var listeners:StringMap<Array<Listener>>;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
listeners = new Map<String, Array<F>>();
|
||||
listeners = new StringMap();
|
||||
}
|
||||
|
||||
public function put(key:String, value:T):Void {
|
||||
@@ -25,17 +24,18 @@ class ResMap<T> extends StringMap<T> {
|
||||
}
|
||||
|
||||
public function bind(key:String, object:Dynamic, field:String):Void {
|
||||
var f:F = Tuple.two(object, field);
|
||||
var listener:Listener = {object:object, field:field};
|
||||
if (listeners.exists(key)) {
|
||||
listeners.get(key).push(f);
|
||||
listeners.set(key, listeners.get(key).filter(function(l) return l.object != object || l.field != field));
|
||||
listeners.get(key).push(listener);
|
||||
} else {
|
||||
listeners.set(key, [f]);
|
||||
listeners.set(key, [listener]);
|
||||
}
|
||||
if (exists(key)) call(f, get(key));
|
||||
if (exists(key)) call(listener, get(key));
|
||||
}
|
||||
|
||||
private function call(field:F, value:T):Void {
|
||||
Reflect.setProperty(field.first, field.second, value);
|
||||
private function call(listener:Listener, value:T):Void {
|
||||
Reflect.setProperty(listener.object, listener.field, value);
|
||||
}
|
||||
|
||||
public function merge(value:Dynamic<T>):Void {
|
||||
|
||||
Reference in New Issue
Block a user