[gui] update
This commit is contained in:
@@ -1,38 +1,50 @@
|
|||||||
package demo;
|
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.IGroupView;
|
||||||
import haxework.gui.IView;
|
import haxework.gui.IView;
|
||||||
import haxework.gui.Root;
|
|
||||||
import haxework.gui.ToggleButtonView;
|
import haxework.gui.ToggleButtonView;
|
||||||
import haxework.gui.VGroupView;
|
import haxework.gui.VGroupView;
|
||||||
import haxework.log.TraceLogger;
|
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 {
|
@:template class DemoView extends VGroupView {
|
||||||
|
@:view var switcher:FrameSwitcher;
|
||||||
@: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;
|
|
||||||
@:view var tabs:IGroupView;
|
@:view var tabs:IGroupView;
|
||||||
|
|
||||||
|
private function init():Void {
|
||||||
|
switcher.change("list_form");
|
||||||
|
}
|
||||||
|
|
||||||
private function onFrameSwitch(frame:IView<Dynamic>):Void {
|
private function onFrameSwitch(frame:IView<Dynamic>):Void {
|
||||||
for (view in tabs.views) cast(view, ToggleButtonView).on = view.id == frame.id;
|
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')"
|
+onPress: "$code:switcher.change('data_form')"
|
||||||
- id: switcher
|
- id: switcher
|
||||||
$type: haxework.gui.frame.FrameSwitcher
|
$type: haxework.gui.frame.FrameSwitcher
|
||||||
skin: $r:skin:border
|
skin: $r:skin:panel
|
||||||
|
animateFactory: { $class: haxework.animate.SlideAnimate }
|
||||||
+onSwitch: $this:onFrameSwitch
|
+onSwitch: $this:onFrameSwitch
|
||||||
geometry.size.stretch: true
|
geometry.size.stretch: true
|
||||||
geometry.padding: 5
|
geometry.padding: 5
|
||||||
views:
|
views:
|
||||||
- id: list_form
|
- id: list_form
|
||||||
$type: demo.form.ListForm
|
$type: demo.form.ListForm
|
||||||
|
skin: $r:skin:background
|
||||||
geometry.size.stretch: true
|
geometry.size.stretch: true
|
||||||
- id: tail_form
|
- id: tail_form
|
||||||
$type: demo.form.TailForm
|
$type: demo.form.TailForm
|
||||||
|
skin: $r:skin:background
|
||||||
geometry.size.stretch: true
|
geometry.size.stretch: true
|
||||||
- id: data_form
|
- id: data_form
|
||||||
$type: demo.form.DataForm
|
$type: demo.form.DataForm
|
||||||
|
skin: $r:skin:background
|
||||||
geometry.size.stretch: true
|
geometry.size.stretch: true
|
||||||
- $type: haxework.gui.HGroupView
|
- $type: haxework.gui.HGroupView
|
||||||
geometry.size.percent.width: 100
|
geometry.size.percent.width: 100
|
||||||
@@ -55,23 +59,8 @@ views:
|
|||||||
- $type: haxework.gui.ButtonView
|
- $type: haxework.gui.ButtonView
|
||||||
geometry.padding: [25, 8]
|
geometry.padding: [25, 8]
|
||||||
skin: $r:skin:button
|
skin: $r:skin:button
|
||||||
text: green
|
text: Color
|
||||||
+onPress: "$code:Theme.setColor(0x33AA33)"
|
+onPress: "$code:choiceColor()"
|
||||||
- $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)"
|
|
||||||
# separator
|
# separator
|
||||||
- $type: haxework.gui.SpriteView
|
- $type: haxework.gui.SpriteView
|
||||||
geometry.size.stretch: true
|
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 {
|
public static function setColor(color:Int, textColor:Int = 0xffffff):Void {
|
||||||
var text:ISkin<Dynamic> = new TextSkin(textColor, 16, "Courirer");
|
var text:ISkin<Dynamic> = new TextSkin(textColor, 16, "Courirer");
|
||||||
var background:SkinSet = [
|
var background = Skin.color(0x00000);
|
||||||
Skin.color(0x00000),
|
|
||||||
];
|
|
||||||
var button:SkinSet = [
|
var button:SkinSet = [
|
||||||
Skin.buttonColor(color),
|
Skin.buttonColor(color),
|
||||||
text,
|
text,
|
||||||
@@ -32,18 +30,22 @@ class Theme {
|
|||||||
var scroll:SkinSet = [
|
var scroll:SkinSet = [
|
||||||
ScrollBarSkin.vertical(color, ColorUtils.diff(color, 128)),
|
ScrollBarSkin.vertical(color, ColorUtils.diff(color, 128)),
|
||||||
];
|
];
|
||||||
var border:SkinSet = [
|
var border = Skin.border(ColorUtils.multiply(color, 1.5), 1, 2);
|
||||||
Skin.border(ColorUtils.multiply(color, 1.5), 1, 2),
|
resources.skin.put("text0", [
|
||||||
];
|
|
||||||
resources.skin.put("text", [
|
|
||||||
Skin.color(ColorUtils.diff(color, 128)),
|
Skin.color(ColorUtils.diff(color, 128)),
|
||||||
new TextSkin(ColorUtils.diff(color, -128), 16, "Courirer"),
|
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("button", button);
|
||||||
resources.skin.put("tab", tab);
|
resources.skin.put("tab", tab);
|
||||||
resources.skin.put("view", view);
|
resources.skin.put("view", view);
|
||||||
resources.skin.put("scroll", scroll);
|
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;
|
package demo.form;
|
||||||
|
|
||||||
import haxework.gui.DataView;
|
|
||||||
import haxework.gui.TextView;
|
import haxework.gui.TextView;
|
||||||
import haxework.gui.VGroupView;
|
import haxework.gui.VGroupView;
|
||||||
import haxework.net.JsonLoader;
|
|
||||||
import haxework.resources.IResources;
|
|
||||||
|
|
||||||
@:template class DataForm extends VGroupView {
|
@:template class DataForm extends VGroupView {
|
||||||
@:view var data:DataView<String>;
|
|
||||||
@:provide var resources:IResources;
|
|
||||||
|
|
||||||
private function init() {
|
private function factory(index:Int, value:Model):TextView {
|
||||||
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 {
|
|
||||||
var label = new TextView();
|
var label = new TextView();
|
||||||
label.geometry.size.percent.width = 100;
|
label.geometry.size.percent.width = 100;
|
||||||
label.geometry.margin = 1;
|
label.geometry.margin = 1;
|
||||||
label.geometry.padding = 2;
|
label.geometry.padding = 2;
|
||||||
resources.skin.bind("text", label, "skin");
|
label.skinId = "text";
|
||||||
label.text = value;
|
label.text = (value.title != null ? '${value.title}\n-\n' : '') + value.message;
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ views:
|
|||||||
geometry.size.stretch: true
|
geometry.size.stretch: true
|
||||||
view:
|
view:
|
||||||
id: data
|
id: data
|
||||||
$type: haxework.gui.DataView<String>
|
$type: haxework.gui.DataView<Model>
|
||||||
layout:
|
layout:
|
||||||
$type: haxework.gui.layout.VerticalLayout
|
$type: haxework.gui.layout.VerticalLayout
|
||||||
factory: $this:factory
|
factory: $this:factory
|
||||||
geometry.size.width: 100%
|
geometry.size.width: 100%
|
||||||
|
data: $r:any:data
|
||||||
scroll:
|
scroll:
|
||||||
$type: haxework.gui.list.VScrollBarView
|
$type: haxework.gui.list.VScrollBarView
|
||||||
skin: $r:skin:scroll
|
skin: $r:skin:scroll
|
||||||
|
|||||||
@@ -1,23 +1,18 @@
|
|||||||
package demo.form;
|
package demo.form;
|
||||||
|
|
||||||
|
import haxework.gui.list.LabelListItem;
|
||||||
import haxework.gui.list.ListView.IListItemView;
|
import haxework.gui.list.ListView.IListItemView;
|
||||||
import haxework.gui.list.VListView;
|
import haxework.gui.list.VListView;
|
||||||
import haxework.gui.VGroupView;
|
import haxework.gui.VGroupView;
|
||||||
import haxework.net.JsonLoader;
|
|
||||||
|
|
||||||
@:template class ListForm extends VGroupView {
|
@:template class ListForm extends VGroupView {
|
||||||
@:view public var list(default, null):VListView<String>;
|
@:view public var list(default, null):VListView<Model>;
|
||||||
|
|
||||||
private function init() {
|
private function factory() {
|
||||||
new JsonLoader().GET("http://umix.tv/channel/data2/renova.json")
|
return new LabelListItem(function(index:Int, value:Model) return '${index}. ${value.id}: ${value.title}');
|
||||||
.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 onItemSelect(item:IListItemView<String>):Void {
|
private function onItemSelect(item:IListItemView<Model>):Void {
|
||||||
trace('onItemSelect: ${item.data}');
|
trace('onItemSelect: ${item.data.id}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
---
|
---
|
||||||
views:
|
views:
|
||||||
- id: list
|
- id: list
|
||||||
$type: haxework.gui.list.VListView<String>
|
$type: haxework.gui.list.VListView<Model>
|
||||||
+onItemSelect: $this:onItemSelect
|
+onItemSelect: $this:onItemSelect
|
||||||
factory: { $class: haxework.gui.list.LabelListItem }
|
factory: $this:factory
|
||||||
geometry.size.stretch: true
|
geometry.size.stretch: true
|
||||||
scroll:
|
scroll:
|
||||||
$type: haxework.gui.list.VScrollBarView
|
$type: haxework.gui.list.VScrollBarView
|
||||||
skin: $r:skin:scroll
|
skin: $r:skin:scroll
|
||||||
geometry.size.height: 100%
|
geometry.size.height: 100%
|
||||||
geometry.size.width: 10
|
geometry.size.width: 10
|
||||||
|
data: $r:any:data50
|
||||||
|
|||||||
@@ -1,24 +1,29 @@
|
|||||||
package demo.form;
|
package demo.form;
|
||||||
|
|
||||||
import haxework.gui.DataView;
|
|
||||||
import haxework.gui.HGroupView;
|
import haxework.gui.HGroupView;
|
||||||
|
import haxework.gui.ImageView;
|
||||||
|
import haxework.gui.IView;
|
||||||
import haxework.gui.TextView;
|
import haxework.gui.TextView;
|
||||||
import haxework.resources.IResources;
|
import haxework.gui.utils.DrawUtil.FillType;
|
||||||
|
|
||||||
@:template class TailForm extends HGroupView {
|
@:template class TailForm extends HGroupView {
|
||||||
@:view public var data:DataView<String>;
|
|
||||||
@:provide var resources:IResources;
|
|
||||||
|
|
||||||
private function init() {
|
private function factory(index:Int, value:Model):IView<Dynamic> {
|
||||||
data.data = [for (i in 0...100) '${i}'];
|
var view:IView<Dynamic>;
|
||||||
}
|
if (value.image != null) {
|
||||||
|
var imageView = new ImageView();
|
||||||
private function factory(index:Int, value:String):TextView {
|
imageView.skinId = "border";
|
||||||
var view = new TextView();
|
imageView.fillType = FillType.CONTAIN;
|
||||||
view.geometry.size.fixed.width = 100 + 100 * Math.random();
|
imageView.imageUrl = value.image.url;
|
||||||
view.geometry.size.fixed.height = 100 + 100 * Math.random();
|
view = imageView;
|
||||||
resources.skin.bind("view", view, "skin");
|
} else {
|
||||||
view.text = 'View #${index}';
|
var textView = new TextView();
|
||||||
|
textView.skinId = "view";
|
||||||
|
textView.text = '${value.id}\n${value.maker}';
|
||||||
|
view = textView;
|
||||||
|
}
|
||||||
|
view.geometry.size.fixed.width = 350;
|
||||||
|
view.geometry.size.fixed.height = 200;
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ views:
|
|||||||
geometry.size.stretch: true
|
geometry.size.stretch: true
|
||||||
view:
|
view:
|
||||||
id: data
|
id: data
|
||||||
$type: haxework.gui.DataView<String>
|
$type: haxework.gui.DataView<Model>
|
||||||
layout:
|
layout:
|
||||||
$type: haxework.gui.layout.TailLayout
|
$type: haxework.gui.layout.TailLayout
|
||||||
margin: 2
|
margin: 2
|
||||||
factory: $this:factory
|
factory: $this:factory
|
||||||
geometry.size.width: 100%
|
geometry.size.width: 100%
|
||||||
|
data: $r:any:data
|
||||||
scroll:
|
scroll:
|
||||||
$type: haxework.gui.list.VScrollBarView
|
$type: haxework.gui.list.VScrollBarView
|
||||||
skin: $r:skin:scroll
|
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,50 +4,51 @@ import flash.events.Event;
|
|||||||
import flash.display.Stage;
|
import flash.display.Stage;
|
||||||
|
|
||||||
class Animate implements IAnimate {
|
class Animate implements IAnimate {
|
||||||
|
public static var defaultDuraion = 300;
|
||||||
|
|
||||||
private static var running:Array<IAnimate> = new Array<IAnimate>();
|
private static var running:Array<IAnimate> = new Array<IAnimate>();
|
||||||
|
|
||||||
public static function bind(stage:Stage):Void {
|
public static function bind(stage:Stage):Void {
|
||||||
stage.addEventListener(Event.ENTER_FRAME, function(_) {
|
stage.addEventListener(Event.ENTER_FRAME, function(_) {
|
||||||
Animate.updateAll();
|
Animate.updateAll();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
public static function updateAll():Void {
|
|
||||||
if (running.length > 0) {
|
|
||||||
var time = Date.now().getTime();
|
|
||||||
for (animate in running) animate.update(time);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private var callback:Animate -> Void;
|
public static function updateAll():Void {
|
||||||
private var duration:Int;
|
if (running.length > 0) {
|
||||||
private var startTime:Float;
|
var time = Date.now().getTime();
|
||||||
private var progress:Float;
|
for (animate in running) animate.update(time);
|
||||||
|
}
|
||||||
public function new(duration:Int) {
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function start(callback:IAnimate -> Void, ?custom:Bool = false):Void {
|
|
||||||
startTime = Date.now().getTime();
|
|
||||||
this.callback = callback;
|
|
||||||
if (!custom) running.push(this);
|
|
||||||
update(startTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function update(time:Float):Void {
|
|
||||||
progress = (time - startTime) / duration;
|
|
||||||
if (progress >= 1) {
|
|
||||||
running.remove(this);
|
|
||||||
if (callback != null) {
|
|
||||||
callback(this);
|
|
||||||
callback = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function cancel():Void {
|
private var callback:Animate -> Void;
|
||||||
if (!Math.isNaN(startTime)) update(startTime + duration);
|
private var duration:Int;
|
||||||
}
|
private var startTime:Float;
|
||||||
|
private var progress:Float;
|
||||||
|
|
||||||
|
public function new(duration:Int) {
|
||||||
|
this.duration = duration > -1 ? duration : defaultDuraion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function start(callback:IAnimate -> Void, custom:Bool = false):Void {
|
||||||
|
startTime = Date.now().getTime();
|
||||||
|
this.callback = callback;
|
||||||
|
if (!custom) running.push(this);
|
||||||
|
update(startTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function update(time:Float):Void {
|
||||||
|
progress = (time - startTime) / duration;
|
||||||
|
if (progress >= 1) {
|
||||||
|
running.remove(this);
|
||||||
|
if (callback != null) {
|
||||||
|
callback(this);
|
||||||
|
callback = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cancel():Void {
|
||||||
|
if (!Math.isNaN(startTime)) update(startTime + duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +1,62 @@
|
|||||||
package haxework.animate;
|
package haxework.animate;
|
||||||
|
|
||||||
import flash.display.DisplayObjectContainer;
|
|
||||||
import haxework.animate.IAnimate;
|
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
import haxework.gui.IView;
|
|
||||||
import haxework.animate.Animate;
|
import haxework.animate.Animate;
|
||||||
|
import haxework.animate.IAnimate;
|
||||||
|
import haxework.gui.IView;
|
||||||
|
|
||||||
class CircleMaskAnimate extends Animate {
|
class CircleMaskAnimate extends Animate {
|
||||||
|
|
||||||
private var view:IView;
|
private var view:IView<Dynamic>;
|
||||||
private var mask:Sprite;
|
private var mask:Sprite;
|
||||||
private var cyrcle:Sprite;
|
private var cyrcle:Sprite;
|
||||||
private var size:Float;
|
private var size:Float;
|
||||||
|
|
||||||
public function new(view:IView, ?duration:Int = 1000) {
|
public function new(view:IView<Dynamic>, duration:Int = -1) {
|
||||||
super(duration);
|
super(duration);
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.mask = new Sprite();
|
this.mask = new Sprite();
|
||||||
this.cyrcle = 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 width = view.parent.width;
|
||||||
var height = view.parent.height;
|
var height = view.parent.height;
|
||||||
size = Math.sqrt(width * width + height * height);
|
size = Math.sqrt(width * width + height * height);
|
||||||
//size = Math.max(width, height);
|
//size = Math.max(width, height);
|
||||||
cyrcle.x = mask.x = -(size - width) / 2 - size;
|
cyrcle.x = mask.x = -(size - width) / 2 - size;
|
||||||
cyrcle.y = mask.y = -(size - height) / 2 - size;
|
cyrcle.y = mask.y = -(size - height) / 2 - size;
|
||||||
|
|
||||||
redraw(size, size);
|
redraw(size, size);
|
||||||
|
|
||||||
view.parent.container.addChild(mask);
|
view.parent.container.addChild(mask);
|
||||||
view.content.mask = mask;
|
view.content.mask = mask;
|
||||||
view.parent.container.addChild(cyrcle);
|
view.parent.container.addChild(cyrcle);
|
||||||
|
|
||||||
super.start(callback, custom);
|
super.start(callback, custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function redraw(size:Float, r:Float):Void {
|
private function redraw(size:Float, r:Float):Void {
|
||||||
mask.graphics.clear();
|
mask.graphics.clear();
|
||||||
mask.graphics.beginFill(0xffffff);
|
mask.graphics.beginFill(0xffffff);
|
||||||
mask.graphics.drawCircle(size + size / 2, size + size / 2, r / 2);
|
mask.graphics.drawCircle(size + size / 2, size + size / 2, r / 2);
|
||||||
mask.graphics.endFill();
|
mask.graphics.endFill();
|
||||||
|
|
||||||
cyrcle.graphics.clear();
|
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.drawCircle(size + size / 2, size + size / 2, r / 2);
|
||||||
cyrcle.graphics.lineStyle();
|
cyrcle.graphics.lineStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
override private function update(time:Float):Void {
|
override private function update(time:Float):Void {
|
||||||
super.update(time);
|
super.update(time);
|
||||||
|
|
||||||
redraw(size, size * progress);
|
redraw(size, size * progress);
|
||||||
|
|
||||||
if (progress >= 1 && view.content.parent != null) {
|
if (progress >= 1 && view.content.parent != null) {
|
||||||
if (view.content.parent.contains(mask)) view.content.parent.removeChild(mask);
|
if (view.content.parent.contains(mask)) view.content.parent.removeChild(mask);
|
||||||
view.content.mask = null;
|
view.content.mask = null;
|
||||||
if (view.content.parent.contains(cyrcle)) view.parent.container.removeChild(cyrcle);
|
if (view.content.parent.contains(cyrcle)) view.parent.container.removeChild(cyrcle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
package haxework.animate;
|
package haxework.animate;
|
||||||
|
|
||||||
|
import flash.display.DisplayObject;
|
||||||
import haxework.animate.IAnimate;
|
import haxework.animate.IAnimate;
|
||||||
import flash.display.Sprite;
|
|
||||||
import haxework.gui.IView;
|
import haxework.gui.IView;
|
||||||
import haxework.animate.Animate;
|
import haxework.animate.Animate;
|
||||||
|
|
||||||
class FadeAnimate extends 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);
|
super(duration);
|
||||||
this.view = view;
|
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;
|
view.content.alpha = 1.0;
|
||||||
super.start(callback, custom);
|
super.start(callback, custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
override private function update(time:Float):Void {
|
override private function update(time:Float):Void {
|
||||||
super.update(time);
|
super.update(time);
|
||||||
view.content.alpha = 1 - (progress * 1.0);
|
view.content.alpha = 1 - (progress * 1.0);
|
||||||
if (progress >= 1) {
|
if (progress >= 1) {
|
||||||
view.content.alpha = 0.0;
|
view.content.alpha = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ package haxework.animate;
|
|||||||
|
|
||||||
interface IAnimate {
|
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;
|
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,28 +1,28 @@
|
|||||||
package haxework.animate;
|
package haxework.animate;
|
||||||
|
|
||||||
import flash.display.Sprite;
|
import flash.display.DisplayObject;
|
||||||
import haxework.gui.IView;
|
import haxework.gui.IView;
|
||||||
import haxework.animate.Animate;
|
import haxework.animate.Animate;
|
||||||
|
|
||||||
class UnFadeAnimate extends 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);
|
super(duration);
|
||||||
this.view = view;
|
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;
|
view.content.alpha = 0.0;
|
||||||
super.start(callback, custom);
|
super.start(callback, custom);
|
||||||
}
|
}
|
||||||
|
|
||||||
override private function update(time:Float):Void {
|
override private function update(time:Float):Void {
|
||||||
super.update(time);
|
super.update(time);
|
||||||
view.content.alpha = progress * 1.0;
|
view.content.alpha = progress * 1.0;
|
||||||
if (progress >= 1) {
|
if (progress >= 1) {
|
||||||
view.content.alpha = 1.0;
|
view.content.alpha = 1.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 flash.events.MouseEvent;
|
||||||
import haxework.signal.Signal;
|
import haxework.signal.Signal;
|
||||||
|
|
||||||
|
typedef Factory<D> = Int -> D -> IView<Dynamic>
|
||||||
|
|
||||||
class DataView<D> extends GroupView {
|
class DataView<D> extends GroupView {
|
||||||
|
|
||||||
public var data(default, set):Array<D>;
|
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 onItemSelect(default, null):Signal3<Int, D, IView<Dynamic>> = new Signal3();
|
||||||
public var onDataSelect(default, null):Signal<D> = new Signal();
|
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> {
|
private function set_data(value:Array<D>):Array<D> {
|
||||||
data = value;
|
data = value;
|
||||||
rebuild();
|
if (factory != null) rebuild();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function set_factory(value:Factory<D>):Factory<D> {
|
||||||
|
factory = value;
|
||||||
|
if (data != null) rebuild();
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
private function rebuild():Void {
|
private function rebuild():Void {
|
||||||
for (view in views) {
|
for (view in views) {
|
||||||
view.content.removeEventListener(MouseEvent.CLICK, onItemClick);
|
view.content.removeEventListener(MouseEvent.CLICK, onItemClick);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ interface IView<C:DisplayObject> {
|
|||||||
|
|
||||||
public var content(default, null):C;
|
public var content(default, null):C;
|
||||||
public var skin(default, set):SkinSet;
|
public var skin(default, set):SkinSet;
|
||||||
|
public var skinId(null, set):String;
|
||||||
|
|
||||||
public var parent(default, null):Null<IGroupView>;
|
public var parent(default, null):Null<IGroupView>;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package haxework.gui;
|
|||||||
|
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import haxework.gui.skin.BitmapSkin;
|
import haxework.gui.skin.BitmapSkin;
|
||||||
|
import haxework.gui.skin.ISkin;
|
||||||
import haxework.gui.utils.DrawUtil.FillType;
|
import haxework.gui.utils.DrawUtil.FillType;
|
||||||
import haxework.net.ImageLoader;
|
import haxework.net.ImageLoader;
|
||||||
|
|
||||||
@@ -9,22 +10,29 @@ class ImageView extends SpriteView {
|
|||||||
|
|
||||||
public var image(default, set):BitmapData;
|
public var image(default, set):BitmapData;
|
||||||
public var imageUrl(default, set):String;
|
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();
|
super();
|
||||||
|
fillType = FillType.DEFAULT;
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
this.image = image;
|
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 {
|
private function set_image(value:BitmapData):BitmapData {
|
||||||
if (image != value) {
|
if (image != value) {
|
||||||
image = value;
|
image = value;
|
||||||
skin = [new BitmapSkin(image, FillType.DEFAULT)];
|
bitmapSkin.image = value;
|
||||||
//geometry.size.content.width = value.width;
|
toRedraw();
|
||||||
//geometry.size.content.height = value.height;
|
|
||||||
//toUpdate();
|
|
||||||
//toRedraw();
|
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@@ -34,8 +42,15 @@ class ImageView extends SpriteView {
|
|||||||
imageUrl = value;
|
imageUrl = value;
|
||||||
new ImageLoader().GET(imageUrl).then(function(data) {
|
new ImageLoader().GET(imageUrl).then(function(data) {
|
||||||
image = data;
|
image = data;
|
||||||
});
|
}).catchError(function(e) L.w("ImageView", "load", e));
|
||||||
}
|
}
|
||||||
return imageUrl;
|
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.events.Event;
|
||||||
import flash.geom.Rectangle;
|
import flash.geom.Rectangle;
|
||||||
import flash.Lib;
|
import flash.Lib;
|
||||||
import haxework.core.IDisposable;
|
|
||||||
import haxework.signal.Signal;
|
import haxework.signal.Signal;
|
||||||
|
|
||||||
class Root implements IDisposable {
|
class Root {
|
||||||
|
|
||||||
public static function bind(view:IView<Dynamic>, autoSize:Bool = true) {
|
public static function bind(view:IView<Dynamic>, autoSize:Bool = true) {
|
||||||
new Root(view, autoSize);
|
new Root(view, autoSize);
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ class TextView extends SpriteView implements ITextView {
|
|||||||
|
|
||||||
private function updateTextSize():Void {
|
private function updateTextSize():Void {
|
||||||
var size = TextUtil.getSize(textField);
|
var size = TextUtil.getSize(textField);
|
||||||
setContentSize(size.x, size.y);
|
setContentSize(size.x, size.y, "text");
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function update():Void {
|
override public function update():Void {
|
||||||
@@ -168,7 +168,7 @@ class TextView extends SpriteView implements ITextView {
|
|||||||
|
|
||||||
private function placeTextField(textField:TextField):Void {
|
private function placeTextField(textField:TextField):Void {
|
||||||
textField.width = width;
|
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) {
|
textField.x = switch (layout.hAlign) {
|
||||||
case LEFT | NONE: geometry.padding.left;
|
case LEFT | NONE: geometry.padding.left;
|
||||||
@@ -178,8 +178,8 @@ class TextView extends SpriteView implements ITextView {
|
|||||||
}
|
}
|
||||||
textField.y = switch (layout.vAlign) {
|
textField.y = switch (layout.vAlign) {
|
||||||
case TOP | NONE: geometry.padding.top;
|
case TOP | NONE: geometry.padding.top;
|
||||||
case MIDDLE: (height - geometry.size.content.height) / 2 + geometry.padding.top - geometry.padding.bottom;
|
case MIDDLE: (height - textField.height) / 2 + geometry.padding.top - geometry.padding.bottom;
|
||||||
case BOTTOM: height - geometry.size.content.height - geometry.padding.bottom;
|
case BOTTOM: height - textField.height - geometry.padding.bottom;
|
||||||
default: 0;
|
default: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
package haxework.gui;
|
package haxework.gui;
|
||||||
|
|
||||||
import haxework.gui.skin.ISkin.ISizeSkin;
|
|
||||||
import flash.display.DisplayObject;
|
import flash.display.DisplayObject;
|
||||||
import flash.display.InteractiveObject;
|
import flash.display.InteractiveObject;
|
||||||
import haxework.gui.core.Geometry;
|
import haxework.gui.core.Geometry;
|
||||||
|
import haxework.gui.skin.ISkin.ISizeSkin;
|
||||||
import haxework.gui.skin.ISkin.SkinSet;
|
import haxework.gui.skin.ISkin.SkinSet;
|
||||||
|
import haxework.resources.IResources;
|
||||||
|
|
||||||
class View<C:DisplayObject> implements IView<C> {
|
class View<C:DisplayObject> implements IView<C> {
|
||||||
|
@:provide private var r:IResources;
|
||||||
|
|
||||||
private static var counter:Int = 0;
|
private static var counter:Int = 0;
|
||||||
public static var updater(default, null):ViewUpdater = new ViewUpdater();
|
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 content(default, null):C;
|
||||||
public var skin(default, set):SkinSet;
|
public var skin(default, set):SkinSet;
|
||||||
|
public var skinId(null, set):String;
|
||||||
|
|
||||||
public var parent(default, null):Null<IGroupView>;
|
public var parent(default, null):Null<IGroupView>;
|
||||||
|
|
||||||
@@ -63,22 +66,16 @@ class View<C:DisplayObject> implements IView<C> {
|
|||||||
for (skin in this.skin) {
|
for (skin in this.skin) {
|
||||||
if (Std.is(skin, ISizeSkin)) {
|
if (Std.is(skin, ISizeSkin)) {
|
||||||
var sizeSkin:ISizeSkin = cast skin;
|
var sizeSkin:ISizeSkin = cast skin;
|
||||||
setSize(sizeSkin.width, sizeSkin.height);
|
setContentSize(sizeSkin.width, sizeSkin.height, "skin");
|
||||||
}
|
}
|
||||||
skin.draw(this);
|
skin.draw(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setSize(width:Float, height:Float):Void {
|
private function setContentSize(width:Float, height:Float, type:String="default"):Void {
|
||||||
if (width != geometry.size.fixed.width || height != geometry.size.fixed.height) {
|
var contentSize = geometry.size.content.get(type);
|
||||||
geometry.size.fixed = [width, height];
|
if (contentSize == null || width != contentSize.width || height != contentSize.height) {
|
||||||
toUpdateParent();
|
geometry.size.content.set(type, [width, height]);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setContentSize(width:Float, height:Float):Void {
|
|
||||||
if (width != geometry.size.content.width || height != geometry.size.content.height) {
|
|
||||||
geometry.size.content = [width, height];
|
|
||||||
toUpdateParent();
|
toUpdateParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,6 +120,11 @@ class View<C:DisplayObject> implements IView<C> {
|
|||||||
return this.skin;
|
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 {
|
private function set_visible(value:Bool):Bool {
|
||||||
if (visible != value) {
|
if (visible != value) {
|
||||||
visible = value;
|
visible = value;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ abstract ASizeValue(SizeValue) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SizeSet {
|
class SizeSet {
|
||||||
public var content(default, default):Size;
|
public var content(default, default):Map<String, Size>;
|
||||||
public var fixed(default, default):Size;
|
public var fixed(default, default):Size;
|
||||||
public var percent(default, default):Size;
|
public var percent(default, default):Size;
|
||||||
public var stretch(null, set):Bool;
|
public var stretch(null, set):Bool;
|
||||||
@@ -38,7 +38,7 @@ class SizeSet {
|
|||||||
public var height(null, set):ASizeValue;
|
public var height(null, set):ASizeValue;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
this.content = [];
|
this.content = new Map();
|
||||||
this.fixed = [];
|
this.fixed = [];
|
||||||
this.percent = [];
|
this.percent = [];
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,9 @@ class Geometry {
|
|||||||
}
|
}
|
||||||
var result = size.fixed.width;
|
var result = size.fixed.width;
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
result = size.content.width;
|
for (s in size.content.iterator()) {
|
||||||
|
result = Math.max(result, s.width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result += padding.horizontal;
|
result += padding.horizontal;
|
||||||
return FIXED(result);
|
return FIXED(result);
|
||||||
@@ -108,7 +110,9 @@ class Geometry {
|
|||||||
}
|
}
|
||||||
var result = size.fixed.height;
|
var result = size.fixed.height;
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
result = size.content.height;
|
for (s in size.content.iterator()) {
|
||||||
|
result = Math.max(result, s.height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result += padding.vertical;
|
result += padding.vertical;
|
||||||
return FIXED(result);
|
return FIXED(result);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import haxework.animate.IAnimate;
|
|||||||
import haxework.gui.IView;
|
import haxework.gui.IView;
|
||||||
import haxework.gui.GroupView;
|
import haxework.gui.GroupView;
|
||||||
|
|
||||||
class FrameSwitcher extends GroupView implements IFrameSwitcher {
|
class FrameSwitcher extends GroupView {
|
||||||
|
|
||||||
public var current(default, null):Null<IView<Dynamic>>;
|
public var current(default, null):Null<IView<Dynamic>>;
|
||||||
public var onSwitch:Signal<IView<Dynamic>> = new Signal();
|
public var onSwitch:Signal<IView<Dynamic>> = new Signal();
|
||||||
@@ -39,6 +39,7 @@ class FrameSwitcher extends GroupView implements IFrameSwitcher {
|
|||||||
throw 'frame "$id" not found';
|
throw 'frame "$id" not found';
|
||||||
}
|
}
|
||||||
addView(current);
|
addView(current);
|
||||||
|
update();
|
||||||
//ToDo:
|
//ToDo:
|
||||||
if (content.stage != null) content.stage.focus = cast(current, SpriteView).content;
|
if (content.stage != null) content.stage.focus = cast(current, SpriteView).content;
|
||||||
var onShowMethod:Dynamic = Reflect.field(current, "onShow");
|
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);
|
maxSize = Math.max(maxSize, view.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
group.geometry.size.content.height = maxSize;
|
group.geometry.size.content.set("group", [fixedSize, maxSize]);
|
||||||
group.geometry.size.content.width = fixedSize;
|
|
||||||
|
|
||||||
leftSize -= fixedSize;
|
leftSize -= fixedSize;
|
||||||
for (view in views) {
|
for (view in views) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package haxework.gui.layout;
|
package haxework.gui.layout;
|
||||||
|
|
||||||
|
import haxework.gui.core.VAlign;
|
||||||
typedef Row = {
|
typedef Row = {
|
||||||
var width:Float;
|
var width:Float;
|
||||||
var height: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);
|
var y:Float = Math.max(group.geometry.padding.top, (group.height - h) / 2);
|
||||||
|
|
||||||
y = group.geometry.padding.top;
|
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) {
|
for (row in rows) {
|
||||||
placeRow(group, y, row);
|
placeRow(group, y, row);
|
||||||
y += row.height + margin;
|
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);
|
maxSize = Math.max(maxSize, view.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
group.geometry.size.content.width = maxSize;
|
group.geometry.size.content.set("group", [maxSize, fixedSize]);
|
||||||
group.geometry.size.content.height = fixedSize;
|
|
||||||
|
|
||||||
leftSize -= fixedSize;
|
leftSize -= fixedSize;
|
||||||
for (view in views) {
|
for (view in views) {
|
||||||
|
|||||||
@@ -2,24 +2,32 @@ package haxework.gui.list;
|
|||||||
|
|
||||||
import haxework.gui.core.HAlign;
|
import haxework.gui.core.HAlign;
|
||||||
import haxework.gui.list.ListView.IListItemView;
|
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> {
|
class LabelListItem<T> extends LabelView implements IListItemView<T> {
|
||||||
|
|
||||||
public var item_index(default, default):Int;
|
public var item_index(default, default):Int;
|
||||||
public var data(default, set):T;
|
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();
|
super();
|
||||||
|
this.formatter = formatter == null ? defaultFormatter : formatter;
|
||||||
geometry.size.percent.width = 100;
|
geometry.size.percent.width = 100;
|
||||||
geometry.size.fixed.height = 20;
|
geometry.size.fixed.height = 20;
|
||||||
geometry.padding = 8;
|
geometry.padding = 8;
|
||||||
layout.hAlign = HAlign.LEFT;
|
layout.hAlign = LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function set_data(value:T):T {
|
private function set_data(value:T):T {
|
||||||
data = value;
|
data = value;
|
||||||
text = Std.string(value);
|
text = formatter(item_index, value);
|
||||||
skin = item_index % 2 == 1 ? [new ColorSkin(0xdddddd)] : [new ColorSkin(0xcccccc)];
|
skinId = 'text${item_index % 2}';
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import haxework.utils.NumberUtil;
|
|||||||
class ListView<D> extends GroupView {
|
class ListView<D> extends GroupView {
|
||||||
|
|
||||||
public var data(default, set):Array<D>;
|
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;
|
public var offset(default, set):Int;
|
||||||
private var offsetDiff(default, set):Float;
|
private var offsetDiff(default, set):Float;
|
||||||
@@ -183,7 +183,7 @@ class ListView<D> extends GroupView {
|
|||||||
|
|
||||||
override public function update():Void {
|
override public function update():Void {
|
||||||
super.update();
|
super.update();
|
||||||
recalcSize(Type.createInstance(factory, []));
|
recalcSize(factory());
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ class ListView<D> extends GroupView {
|
|||||||
var diff:Int = size - items.length;
|
var diff:Int = size - items.length;
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
for (i in 0...diff) {
|
for (i in 0...diff) {
|
||||||
var item:IListItemView<D> = Type.createInstance(factory, []);
|
var item:IListItemView<D> = factory();
|
||||||
items.push(item);
|
items.push(item);
|
||||||
setClickListener(item);
|
setClickListener(item);
|
||||||
box.addView(item);
|
box.addView(item);
|
||||||
|
|||||||
@@ -4,44 +4,43 @@ import haxework.animate.IAnimate;
|
|||||||
import haxework.gui.Root;
|
import haxework.gui.Root;
|
||||||
import haxework.gui.IGroupView;
|
import haxework.gui.IGroupView;
|
||||||
|
|
||||||
|
typedef P = PopupView<Dynamic>;
|
||||||
|
|
||||||
class PopupManager {
|
class PopupManager {
|
||||||
|
|
||||||
public var showAnimateFactory(default, default):Class<IAnimate>;
|
public var showAnimateFactory(default, default):Class<IAnimate>;
|
||||||
public var closeAnimateFactory(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() {
|
public function new() {
|
||||||
popups = new Array<PopupView<Dynamic>>();
|
popups = new Array<P>();
|
||||||
}
|
|
||||||
|
|
||||||
public function show(popup:PopupView<Dynamic>):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 show(popup:P):Void {
|
||||||
popups.remove(popup);
|
cast(Root.instance.view, IGroupView).addView(popup);
|
||||||
if (closeAnimateFactory != null) {
|
if (showAnimateFactory != null) {
|
||||||
Type.createInstance(closeAnimateFactory, [popup]).start(function(_) {
|
Type.createInstance(showAnimateFactory, [popup]).start(null);
|
||||||
cast(Root.instance.view, IGroupView).removeView(popup);
|
}
|
||||||
popup.onClose();
|
popups.push(popup);
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cast(Root.instance.view, IGroupView).removeView(popup);
|
|
||||||
popup.onClose();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function closeTop():Bool {
|
public function close(popup:P):Void {
|
||||||
if (popups.length > 0) {
|
popups.remove(popup);
|
||||||
close(popups[popups.length - 1]);
|
if (closeAnimateFactory != null) {
|
||||||
return true;
|
Type.createInstance(closeAnimateFactory, [popup]).start(function(_) {
|
||||||
|
cast(Root.instance.view, IGroupView).removeView(popup);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cast(Root.instance.view, IGroupView).removeView(popup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function closeTop():Bool {
|
||||||
|
if (popups.length > 0) {
|
||||||
|
close(popups[popups.length - 1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,49 @@
|
|||||||
package haxework.gui.popup;
|
package haxework.gui.popup;
|
||||||
|
|
||||||
import promhx.Deferred;
|
import haxework.gui.core.Geometry.Position;
|
||||||
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.GroupView;
|
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;
|
public var view(default, set):IView<Dynamic>;
|
||||||
private var contentView:V;
|
private var deferred:Deferred<R>;
|
||||||
private var deferred:Deferred<String>;
|
|
||||||
|
|
||||||
public function new(contentViewFactory:Class<V>) {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
|
geometry.size.stretch = true;
|
||||||
pWidth = 100;
|
geometry.position = Position.ABSOLUTE;
|
||||||
pHeight = 100;
|
skin = [Skin.color(0x000000, 0.6)];
|
||||||
inLayout = false;
|
}
|
||||||
skin = new ColorSkin(0x000000, 0.6);
|
|
||||||
|
private function set_view(value:IView<Dynamic>):IView<Dynamic> {
|
||||||
this.contentView = Type.createInstance(contentViewFactory, [{listener:this}]);
|
this.view = value;
|
||||||
addView(contentView);
|
this.views = [value];
|
||||||
}
|
return this.view;
|
||||||
|
}
|
||||||
public function onPress(button:ButtonView) {
|
|
||||||
this.buttonId = button.id;
|
public function show():Promise<R> {
|
||||||
close();
|
manager.show(this);
|
||||||
}
|
deferred = new Deferred<R>();
|
||||||
|
return deferred.promise();
|
||||||
public function show():Deferred<String> {
|
}
|
||||||
Provider.get(PopupManager).show(this);
|
|
||||||
deferred = new Deferred<String>();
|
public function close(result:R):Void {
|
||||||
return deferred;
|
manager.close(this);
|
||||||
}
|
if (deferred != null) {
|
||||||
|
deferred.resolve(result);
|
||||||
public function close():Void {
|
deferred = null;
|
||||||
Provider.get(PopupManager).close(this);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onShow():Void {
|
public function reject(reason:Dynamic):Void {
|
||||||
buttonId = "close";
|
manager.close(this);
|
||||||
}
|
if (deferred != null) {
|
||||||
|
deferred.throwError(reason);
|
||||||
public function onClose():Void {
|
deferred = null;
|
||||||
if (deferred != null) {
|
}
|
||||||
deferred.resolve(buttonId);
|
|
||||||
deferred = null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ class BitmapSkin implements ISkin<SpriteView> implements ISizeSkin {
|
|||||||
|
|
||||||
public function draw(view:SpriteView):Void {
|
public function draw(view:SpriteView):Void {
|
||||||
if (image == null) return;
|
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 {
|
public function draw(view:SpriteView):Void {
|
||||||
view.content.graphics.lineStyle(tickness, color, alpha, true);
|
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();
|
view.content.graphics.lineStyle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,40 +7,40 @@ import flash.display.BitmapData;
|
|||||||
|
|
||||||
class BitmapUtil {
|
class BitmapUtil {
|
||||||
|
|
||||||
private static var cache:Map<BitmapData, Map<String, BitmapData>> = new Map<BitmapData, Map<String, BitmapData>>();
|
private static var cache:Map<BitmapData, Map<String, BitmapData>> = new Map<BitmapData, Map<String, BitmapData>>();
|
||||||
|
|
||||||
private static function fromCache(image:BitmapData, key:String):Null<BitmapData> {
|
private static function fromCache(image:BitmapData, key:String):Null<BitmapData> {
|
||||||
return cache.exists(image) && cache.get(image).exists(key) ? cache.get(image).get(key) : null;
|
return cache.exists(image) && cache.get(image).exists(key) ? cache.get(image).get(key) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function toCache(image:BitmapData, key:String, value:BitmapData):Void {
|
private static function toCache(image:BitmapData, key:String, value:BitmapData):Void {
|
||||||
if (!cache.exists(image)) cache.set(image, new Map<String, BitmapData>());
|
if (!cache.exists(image)) cache.set(image, new Map<String, BitmapData>());
|
||||||
cache.get(image).set(key, value);
|
cache.get(image).set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function multiply(image:BitmapData, m:Float):BitmapData {
|
public static function multiply(image:BitmapData, m:Float):BitmapData {
|
||||||
var result = fromCache(image, "multiply:" + m);
|
var result = fromCache(image, "multiply:" + m);
|
||||||
if (result != null) return result;
|
if (result != null) return result;
|
||||||
var ct:ColorTransform = new ColorTransform(m, m, m, 1.0, 0, 0, 0);
|
var ct:ColorTransform = new ColorTransform(m, m, m, 1.0, 0, 0, 0);
|
||||||
var out:BitmapData = image.clone();
|
var out:BitmapData = image.clone();
|
||||||
out.colorTransform(out.rect, ct);
|
out.colorTransform(out.rect, ct);
|
||||||
toCache(image, "multiply:" + m, out);
|
toCache(image, "multiply:" + m, out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function grayscale(image:BitmapData, m:Float):BitmapData {
|
public static function grayscale(image:BitmapData, m:Float):BitmapData {
|
||||||
var result = fromCache(image, "grayscale:" + m);
|
var result = fromCache(image, "grayscale:" + m);
|
||||||
if (result != null) return result;
|
if (result != null) return result;
|
||||||
var matrix:Array<Float> = [];
|
var matrix:Array<Float> = [];
|
||||||
matrix = matrix.concat([m, m, m, 0, 0]);
|
matrix = matrix.concat([m, m, m, 0, 0]);
|
||||||
matrix = matrix.concat([m, m, m, 0, 0]);
|
matrix = matrix.concat([m, m, m, 0, 0]);
|
||||||
matrix = matrix.concat([m, m, m, 0, 0]);
|
matrix = matrix.concat([m, m, m, 0, 0]);
|
||||||
matrix = matrix.concat([0, 0, 0, 1, 0]);
|
matrix = matrix.concat([0, 0, 0, 1, 0]);
|
||||||
var cmf:ColorMatrixFilter = new ColorMatrixFilter(matrix);
|
var cmf:ColorMatrixFilter = new ColorMatrixFilter(matrix);
|
||||||
var out:BitmapData = image.clone();
|
var out:BitmapData = image.clone();
|
||||||
out.applyFilter(out, out.rect, new Point(0,0), cmf);
|
out.applyFilter(out, out.rect, new Point(0, 0), cmf);
|
||||||
toCache(image, "grayscale:" + m, out);
|
toCache(image, "grayscale:" + m, out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,30 +2,30 @@ package haxework.gui.utils;
|
|||||||
|
|
||||||
class ColorUtils {
|
class ColorUtils {
|
||||||
|
|
||||||
public static function multiply(color:Int, m:Float):Int {
|
public static function multiply(color:Int, m:Float):Int {
|
||||||
var rgb:Array<Int> = color2rgb(color);
|
var rgb:Array<Int> = color2rgb(color);
|
||||||
var red:Int = cast Math.min(255, Math.round(rgb[0] * m));
|
var red:Int = cast Math.min(255, Math.round(rgb[0] * m));
|
||||||
var green:Int = cast Math.min(255, Math.round(rgb[1] * m));
|
var green:Int = cast Math.min(255, Math.round(rgb[1] * m));
|
||||||
var blue:Int = cast Math.min(255, Math.round(rgb[2] * m));
|
var blue:Int = cast Math.min(255, Math.round(rgb[2] * m));
|
||||||
return rgb2color(red, green, blue);
|
return rgb2color(red, green, blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function diff(color:Int, d:Int):Int {
|
public static function diff(color:Int, d:Int):Int {
|
||||||
var rgb:Array<Int> = color2rgb(color);
|
var rgb:Array<Int> = color2rgb(color);
|
||||||
var red:Int = cast Math.max(0, Math.min(255, rgb[0] + d));
|
var red:Int = cast Math.max(0, Math.min(255, rgb[0] + d));
|
||||||
var green:Int = cast Math.max(0, Math.min(255, rgb[1] + d));
|
var green:Int = cast Math.max(0, Math.min(255, rgb[1] + d));
|
||||||
var blue:Int = cast Math.max(0, Math.min(255, rgb[2] + d));
|
var blue:Int = cast Math.max(0, Math.min(255, rgb[2] + d));
|
||||||
return rgb2color(red, green, blue);
|
return rgb2color(red, green, blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function rgb2color(red:Int, green:Int, blue:Int):Int {
|
public static function rgb2color(red:Int, green:Int, blue:Int):Int {
|
||||||
return (red << 16) + (green << 8) + blue;
|
return (red << 16) + (green << 8) + blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function color2rgb(color:Int):Array<Int> {
|
public static function color2rgb(color:Int):Array<Int> {
|
||||||
var red:Int = ((color & 0xFF0000) >>> 16);
|
var red:Int = ((color & 0xFF0000) >>> 16);
|
||||||
var green:Int = ((color & 0x00FF00) >> 8);
|
var green:Int = ((color & 0x00FF00) >> 8);
|
||||||
var blue:Int = (color & 0x0000FF);
|
var blue:Int = (color & 0x0000FF);
|
||||||
return [red, green, blue];
|
return [red, green, blue];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,17 +1,17 @@
|
|||||||
package haxework.resources;
|
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.BitmapData;
|
||||||
|
import flash.display.MovieClip;
|
||||||
|
import haxework.gui.skin.ISkin.SkinSet;
|
||||||
|
import haxework.resources.Resources.ResMap;
|
||||||
|
|
||||||
interface IResources {
|
interface IResources {
|
||||||
public var image(default, null):ResMap<BitmapData>;
|
public var image(default, null):ResMap<BitmapData>;
|
||||||
public var color(default, null):ResMap<Int>;
|
public var color(default, null):ResMap<Int>;
|
||||||
public var movie(default, null):ResMap<MovieClip>;
|
public var movie(default, null):ResMap<MovieClip>;
|
||||||
public var text(default, null):ResMap<String>;
|
public var text(default, null):ResMap<String>;
|
||||||
public var float(default, null):ResMap<Float>;
|
public var float(default, null):ResMap<Float>;
|
||||||
public var int(default, null):ResMap<Int>;
|
public var int(default, null):ResMap<Int>;
|
||||||
public var any(default, null):ResMap<Dynamic>;
|
public var any(default, null):ResMap<Dynamic>;
|
||||||
public var skin(default, null):ResMap<SkinSet>;
|
public var skin(default, null):ResMap<SkinSet>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
package haxework.resources;
|
package haxework.resources;
|
||||||
|
|
||||||
import haxework.gui.skin.ISkin.SkinSet;
|
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flash.display.MovieClip;
|
import flash.display.MovieClip;
|
||||||
import haxe.ds.StringMap;
|
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> {
|
class ResMap<T> extends StringMap<T> {
|
||||||
|
|
||||||
private var listeners:Map<String, Array<F>>;
|
private var listeners:StringMap<Array<Listener>>;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
listeners = new Map<String, Array<F>>();
|
listeners = new StringMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function put(key:String, value:T):Void {
|
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 {
|
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)) {
|
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 {
|
} 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 {
|
private function call(listener:Listener, value:T):Void {
|
||||||
Reflect.setProperty(field.first, field.second, value);
|
Reflect.setProperty(listener.object, listener.field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function merge(value:Dynamic<T>):Void {
|
public function merge(value:Dynamic<T>):Void {
|
||||||
|
|||||||
Reference in New Issue
Block a user