From af22b3e4d0aa75c9d1bfd20638a07efaa9be0a68 Mon Sep 17 00:00:00 2001 From: shmyga Date: Mon, 27 Jan 2014 16:52:58 +0400 Subject: [PATCH] fixes --- haxework/gui/ButtonView.hx | 1 + haxework/gui/IView.hx | 2 +- haxework/gui/View.hx | 4 +- haxework/gui/list/ListView.hx | 92 ++++++++++++++++++++++++--------- haxework/gui/list/ScrollView.hx | 36 +++++++++++++ haxework/log/BaseLogger.hx | 3 +- haxework/net/JsonLoader.hx | 4 +- haxework/utils/NumberUtil.hx | 12 +++++ 8 files changed, 125 insertions(+), 29 deletions(-) create mode 100755 haxework/utils/NumberUtil.hx diff --git a/haxework/gui/ButtonView.hx b/haxework/gui/ButtonView.hx index 290f218..83d13ca 100755 --- a/haxework/gui/ButtonView.hx +++ b/haxework/gui/ButtonView.hx @@ -35,6 +35,7 @@ class ButtonView extends LabelView { } private function onMouseClick(event:MouseEvent):Void { + event.stopImmediatePropagation(); dispatcher.dispatch(pressCaller); } diff --git a/haxework/gui/IView.hx b/haxework/gui/IView.hx index 0ada5fa..31f3086 100755 --- a/haxework/gui/IView.hx +++ b/haxework/gui/IView.hx @@ -12,7 +12,7 @@ typedef Content = { } interface IView { - public var id(default, null):String; + public var id(default, default):String; public var x(default, set):Float; public var y(default, set):Float; diff --git a/haxework/gui/View.hx b/haxework/gui/View.hx index c142f42..a65f130 100755 --- a/haxework/gui/View.hx +++ b/haxework/gui/View.hx @@ -17,7 +17,7 @@ class View implements IView { private static var counter:Int = 0; public static var updater(default, null):Updater = new Updater(); - public var id(default, null):String; + public var id(default, default):String; public var x(default, set):Float; public var y(default, set):Float; @@ -279,7 +279,7 @@ class Updater { } public function invalidate(view:IView):Void { - invalidated.push(view); + if (Lambda.indexOf(invalidated, view) == -1) invalidated.push(view); } public function update(?_):Void { diff --git a/haxework/gui/list/ListView.hx b/haxework/gui/list/ListView.hx index 41cc149..c721fbd 100755 --- a/haxework/gui/list/ListView.hx +++ b/haxework/gui/list/ListView.hx @@ -1,41 +1,58 @@ package haxework.gui.list; +import haxework.utils.NumberUtil; +import haxework.dispath.Dispatcher; +import haxework.dispath.IDispatcher; +import haxework.gui.list.ScrollView.ScrollListener; import flash.events.MouseEvent; import haxework.gui.core.HAlign; import flash.display.Sprite; import haxework.gui.skin.ISkin; -class ListView, D> extends VGroupView { +class ListView, D> extends VGroupView implements ScrollListener { public var data(default, set):Array; - public var renderer(null, set):IRenderer; + public var renderer(null, set):IRenderer; public var offset(default, set):Int; + public var dispatcher(default, null):IDispatcher>; + private var scroll:ScrollView; private var size(default, set):Int; - private var items:Array; + private var items:Array>; + private var itemsListeners:Map, MouseEvent->Void>; public function new() { super(); + dispatcher = new Dispatcher>(); offset = 0; scroll = new ScrollView(); + scroll.dispatcher.addListener(this); scroll.inLayout = false; scroll.pHeight = 100; - scroll.width = 5; + scroll.width = 10; scroll.hAlign = HAlign.RIGHT; scroll.position = 0; scroll.ratio = 1; + scroll.rightMargin = -12; + rightPadding = 12; addView(scroll); - items = new Array(); + items = new Array>(); + itemsListeners = new Map, MouseEvent->Void>(); content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel); } + public function onScroll(position:Float):Void { + offset = Math.round(data.length * position); + } + private function onMouseWheel(event:MouseEvent):Void { - offset = Math.round(Math.min(Math.max(0, offset -= event.delta*3), data.length - size)); + offset = offset - event.delta * 3; } private function set_offset(value:Int):Int { + value = NumberUtil.limitInt(value, 0, data == null ? 0 : data.length - size); if (offset != value) { offset = value; render(); @@ -49,7 +66,7 @@ class ListView, D> extends VGroupView { return data; } - private function set_renderer(value:IRenderer):IRenderer { + private function set_renderer(value:IRenderer):IRenderer { renderer = value; render(); return renderer; @@ -60,39 +77,68 @@ class ListView, D> extends VGroupView { scroll.ratio = Math.min(1.0, size / data.length); scroll.position = (offset / data.length); for (i in 0...size) { - var view:V = items[i]; - if (data[offset + i] == null) break; - renderer.render(view, data[offset + i]); + var item:ListItem = items[i]; + item.index = offset + i; + if (data[item.index] == null) break; + item.data = data[item.index]; + renderer.render(this, item); } } } override public function update():Void { super.update(); - var item:V = renderer.factory(); - size = Math.round(height / item.height); + var item:ListItem = renderer.factory(); + size = Math.round(Math.max(0, height / item.view.height)); render(); } private function set_size(value:Int):Int { if (size != value) { size = value; - for (item in items) removeView(item); - items = new Array(); - var item:V = renderer.factory(); - var newSize = Math.round(height / item.height); - for (i in 0...size) { - item = renderer.factory(); - items.push(item); - addView(item); + var diff:Int = size - items.length; + if (diff > 0) { + for (i in 0...diff) { + var item:ListItem = renderer.factory(); + items.push(item); + setClickListener(item); + addView(item.view); + } + } else if (diff < 0) { + for (i in 0...-diff) { + var item:ListItem = items.pop(); + item.view.content.removeEventListener(MouseEvent.CLICK, itemsListeners.get(item)); + itemsListeners.remove(item); + removeView(item.view); + } } } return size; } + + private function setClickListener(item:ListItem):Void { + var listener:MouseEvent->Void = function(event:MouseEvent):Void { + dispatcher.dispatch(function(listener:ListViewListener):Void { + listener.onListItemClick(item); + }); + } + item.view.content.addEventListener(MouseEvent.CLICK, listener); + itemsListeners.set(item, listener); + } } -interface IRenderer { - public function factory():V; - public function render(view:V, data:D):Void; +interface IRenderer { + public function factory():ListItem; + public function render(list:L, item:ListItem):Void; +} + +interface ListViewListener { + public function onListItemClick(item:ListItem):Void; +} + +typedef ListItem = { + var view:V; + @:optional var index:Int; + @:optional var data:D; } diff --git a/haxework/gui/list/ScrollView.hx b/haxework/gui/list/ScrollView.hx index e7fe4c6..71bd00d 100755 --- a/haxework/gui/list/ScrollView.hx +++ b/haxework/gui/list/ScrollView.hx @@ -1,5 +1,10 @@ package haxework.gui.list; +import haxework.utils.NumberUtil; +import flash.geom.Point; +import haxework.dispath.Dispatcher; +import haxework.dispath.IDispatcher; +import flash.events.MouseEvent; import flash.display.Graphics; import flash.display.Sprite; import haxework.gui.skin.ISkin; @@ -10,12 +15,39 @@ class ScrollView extends SpriteView { public var position(default, set):Float; public var ratio(default, set):Float; + public var dispatcher(default, null):IDispatcher; + + private var mousePosition:Float; + public function new() { super(); + dispatcher = new Dispatcher(); skin = untyped new ScrollSkin(); + content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); + } + + private function onMouseDown(event:MouseEvent):Void { + content.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); + content.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); + var p:Point = content.globalToLocal(new Point(event.stageX, event.stageY)); + mousePosition = p.y - height * position; + } + + private function onMouseMove(event:MouseEvent):Void { + var p:Point = content.globalToLocal(new Point(event.stageX, event.stageY)); + position = (p.y - mousePosition) / height; + dispatcher.dispatch(function(listener:ScrollListener):Void { + listener.onScroll(position); + }); + } + + private function onMouseUp(event:MouseEvent):Void { + content.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); + content.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); } private function set_position(value:Float):Float { + value = NumberUtil.limitFloat(value, 0, 1 - ratio); if (position != value) { position = value; invalidate(); @@ -51,4 +83,8 @@ class ScrollSkin implements ISkin { graphics.drawRect(0, view.height * view.position, view.width, view.height * view.ratio); graphics.endFill(); } +} + +interface ScrollListener { + public function onScroll(position:Float):Void; } \ No newline at end of file diff --git a/haxework/log/BaseLogger.hx b/haxework/log/BaseLogger.hx index 2d9782e..ce50605 100755 --- a/haxework/log/BaseLogger.hx +++ b/haxework/log/BaseLogger.hx @@ -18,7 +18,8 @@ class BaseLogger implements ILogger { public static function error2strign(error:Dynamic):String { return if (Std.is(error, Error)) { - cast(error, Error).getStackTrace(); + var stack:String = error.getStackTrace(); + stack == null ? Std.string(error) : stack; } else if (Std.is(error, ErrorEvent)) { var event:ErrorEvent = cast(error, ErrorEvent); event.type + " - " + event.text; diff --git a/haxework/net/JsonLoader.hx b/haxework/net/JsonLoader.hx index a272afe..c34d78f 100755 --- a/haxework/net/JsonLoader.hx +++ b/haxework/net/JsonLoader.hx @@ -15,7 +15,7 @@ class JsonLoader extends BaseURLLoader { str = Std.string(cast(e.currentTarget, URLLoader).data); data = Json.parse(str); } catch (error:Dynamic) { - throw new Error(error + ": " + str); + throw new Error(error + ": " + url); } return data; } @@ -27,7 +27,7 @@ class JsonLoader extends BaseURLLoader { str = bytes.readUTFBytes(bytes.length); data = Json.parse(str); } catch (error:Dynamic) { - throw new Error(error + ": " + str); + throw new Error(error + ": " + url); } return data; } diff --git a/haxework/utils/NumberUtil.hx b/haxework/utils/NumberUtil.hx new file mode 100755 index 0000000..c19e618 --- /dev/null +++ b/haxework/utils/NumberUtil.hx @@ -0,0 +1,12 @@ +package haxework.utils; + +class NumberUtil { + + public static inline function limitInt(value:Int, min:Int, max:Int):Int { + return Math.round(Math.min(Math.max(min, value), max)); + } + + public static inline function limitFloat(value:Float, min:Float, max:Float):Float { + return Math.min(Math.max(min, value), max); + } +} \ No newline at end of file