fixes
This commit is contained in:
@@ -35,6 +35,7 @@ class ButtonView extends LabelView {
|
||||
}
|
||||
|
||||
private function onMouseClick(event:MouseEvent):Void {
|
||||
event.stopImmediatePropagation();
|
||||
dispatcher.dispatch(pressCaller);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ typedef Content = {
|
||||
}
|
||||
|
||||
interface IView<C:Content> {
|
||||
public var id(default, null):String;
|
||||
public var id(default, default):String;
|
||||
|
||||
public var x(default, set):Float;
|
||||
public var y(default, set):Float;
|
||||
|
||||
@@ -17,7 +17,7 @@ class View<C:Content> implements IView<C> {
|
||||
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<Dynamic>):Void {
|
||||
invalidated.push(view);
|
||||
if (Lambda.indexOf(invalidated, view) == -1) invalidated.push(view);
|
||||
}
|
||||
|
||||
public function update(?_):Void {
|
||||
|
||||
@@ -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<V:View<Dynamic>, D> extends VGroupView {
|
||||
class ListView<V:View<Dynamic>, D> extends VGroupView implements ScrollListener {
|
||||
|
||||
public var data(default, set):Array<D>;
|
||||
public var renderer(null, set):IRenderer<V, D>;
|
||||
public var renderer(null, set):IRenderer<Dynamic, V, D>;
|
||||
public var offset(default, set):Int;
|
||||
|
||||
public var dispatcher(default, null):IDispatcher<ListViewListener<V, D>>;
|
||||
|
||||
private var scroll:ScrollView;
|
||||
private var size(default, set):Int;
|
||||
|
||||
private var items:Array<V>;
|
||||
private var items:Array<ListItem<V, D>>;
|
||||
private var itemsListeners:Map<ListItem<V, D>, MouseEvent->Void>;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
dispatcher = new Dispatcher<ListViewListener<V, D>>();
|
||||
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<V>();
|
||||
items = new Array<ListItem<V, D>>();
|
||||
itemsListeners = new Map<ListItem<V, D>, 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<V:View<Dynamic>, D> extends VGroupView {
|
||||
return data;
|
||||
}
|
||||
|
||||
private function set_renderer(value:IRenderer<V, D>):IRenderer<V, D> {
|
||||
private function set_renderer(value:IRenderer<Dynamic, V, D>):IRenderer<Dynamic, V, D> {
|
||||
renderer = value;
|
||||
render();
|
||||
return renderer;
|
||||
@@ -60,39 +77,68 @@ class ListView<V:View<Dynamic>, 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<V, D> = 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<V, D> = 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<V>();
|
||||
var item:V = renderer.factory();
|
||||
var newSize = Math.round(height / item.height);
|
||||
for (i in 0...size) {
|
||||
item = renderer.factory();
|
||||
var diff:Int = size - items.length;
|
||||
if (diff > 0) {
|
||||
for (i in 0...diff) {
|
||||
var item:ListItem<V, D> = renderer.factory();
|
||||
items.push(item);
|
||||
addView(item);
|
||||
setClickListener(item);
|
||||
addView(item.view);
|
||||
}
|
||||
} else if (diff < 0) {
|
||||
for (i in 0...-diff) {
|
||||
var item:ListItem<V, D> = items.pop();
|
||||
item.view.content.removeEventListener(MouseEvent.CLICK, itemsListeners.get(item));
|
||||
itemsListeners.remove(item);
|
||||
removeView(item.view);
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private function setClickListener(item:ListItem<V, D>):Void {
|
||||
var listener:MouseEvent->Void = function(event:MouseEvent):Void {
|
||||
dispatcher.dispatch(function(listener:ListViewListener<V, D>):Void {
|
||||
listener.onListItemClick(item);
|
||||
});
|
||||
}
|
||||
item.view.content.addEventListener(MouseEvent.CLICK, listener);
|
||||
itemsListeners.set(item, listener);
|
||||
}
|
||||
}
|
||||
|
||||
interface IRenderer<V, D> {
|
||||
public function factory():V;
|
||||
public function render(view:V, data:D):Void;
|
||||
interface IRenderer<L, V, D> {
|
||||
public function factory():ListItem<V, D>;
|
||||
public function render(list:L, item:ListItem<V, D>):Void;
|
||||
}
|
||||
|
||||
interface ListViewListener<V, D> {
|
||||
public function onListItemClick(item:ListItem<V, D>):Void;
|
||||
}
|
||||
|
||||
typedef ListItem<V, D> = {
|
||||
var view:V;
|
||||
@:optional var index:Int;
|
||||
@:optional var data:D;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ScrollListener>;
|
||||
|
||||
private var mousePosition:Float;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
dispatcher = new Dispatcher<ScrollListener>();
|
||||
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();
|
||||
@@ -52,3 +84,7 @@ class ScrollSkin implements ISkin<Sprite, ScrollView> {
|
||||
graphics.endFill();
|
||||
}
|
||||
}
|
||||
|
||||
interface ScrollListener {
|
||||
public function onScroll(position:Float):Void;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -15,7 +15,7 @@ class JsonLoader<T> extends BaseURLLoader<T> {
|
||||
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<T> extends BaseURLLoader<T> {
|
||||
str = bytes.readUTFBytes(bytes.length);
|
||||
data = Json.parse(str);
|
||||
} catch (error:Dynamic) {
|
||||
throw new Error(error + ": " + str);
|
||||
throw new Error(error + ": " + url);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
12
haxework/utils/NumberUtil.hx
Executable file
12
haxework/utils/NumberUtil.hx
Executable file
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user