fixes
This commit is contained in:
@@ -35,6 +35,7 @@ class ButtonView extends LabelView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function onMouseClick(event:MouseEvent):Void {
|
private function onMouseClick(event:MouseEvent):Void {
|
||||||
|
event.stopImmediatePropagation();
|
||||||
dispatcher.dispatch(pressCaller);
|
dispatcher.dispatch(pressCaller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ typedef Content = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IView<C: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 x(default, set):Float;
|
||||||
public var y(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;
|
private static var counter:Int = 0;
|
||||||
public static var updater(default, null):Updater = new Updater();
|
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 x(default, set):Float;
|
||||||
public var y(default, set):Float;
|
public var y(default, set):Float;
|
||||||
@@ -279,7 +279,7 @@ class Updater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function invalidate(view:IView<Dynamic>):Void {
|
public function invalidate(view:IView<Dynamic>):Void {
|
||||||
invalidated.push(view);
|
if (Lambda.indexOf(invalidated, view) == -1) invalidated.push(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(?_):Void {
|
public function update(?_):Void {
|
||||||
|
|||||||
@@ -1,41 +1,58 @@
|
|||||||
package haxework.gui.list;
|
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 flash.events.MouseEvent;
|
||||||
import haxework.gui.core.HAlign;
|
import haxework.gui.core.HAlign;
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
import haxework.gui.skin.ISkin;
|
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 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 offset(default, set):Int;
|
||||||
|
|
||||||
|
public var dispatcher(default, null):IDispatcher<ListViewListener<V, D>>;
|
||||||
|
|
||||||
private var scroll:ScrollView;
|
private var scroll:ScrollView;
|
||||||
private var size(default, set):Int;
|
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() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
|
dispatcher = new Dispatcher<ListViewListener<V, D>>();
|
||||||
offset = 0;
|
offset = 0;
|
||||||
scroll = new ScrollView();
|
scroll = new ScrollView();
|
||||||
|
scroll.dispatcher.addListener(this);
|
||||||
scroll.inLayout = false;
|
scroll.inLayout = false;
|
||||||
scroll.pHeight = 100;
|
scroll.pHeight = 100;
|
||||||
scroll.width = 5;
|
scroll.width = 10;
|
||||||
scroll.hAlign = HAlign.RIGHT;
|
scroll.hAlign = HAlign.RIGHT;
|
||||||
scroll.position = 0;
|
scroll.position = 0;
|
||||||
scroll.ratio = 1;
|
scroll.ratio = 1;
|
||||||
|
scroll.rightMargin = -12;
|
||||||
|
rightPadding = 12;
|
||||||
addView(scroll);
|
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);
|
content.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onScroll(position:Float):Void {
|
||||||
|
offset = Math.round(data.length * position);
|
||||||
|
}
|
||||||
|
|
||||||
private function onMouseWheel(event:MouseEvent):Void {
|
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 {
|
private function set_offset(value:Int):Int {
|
||||||
|
value = NumberUtil.limitInt(value, 0, data == null ? 0 : data.length - size);
|
||||||
if (offset != value) {
|
if (offset != value) {
|
||||||
offset = value;
|
offset = value;
|
||||||
render();
|
render();
|
||||||
@@ -49,7 +66,7 @@ class ListView<V:View<Dynamic>, D> extends VGroupView {
|
|||||||
return data;
|
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;
|
renderer = value;
|
||||||
render();
|
render();
|
||||||
return renderer;
|
return renderer;
|
||||||
@@ -60,39 +77,68 @@ class ListView<V:View<Dynamic>, D> extends VGroupView {
|
|||||||
scroll.ratio = Math.min(1.0, size / data.length);
|
scroll.ratio = Math.min(1.0, size / data.length);
|
||||||
scroll.position = (offset / data.length);
|
scroll.position = (offset / data.length);
|
||||||
for (i in 0...size) {
|
for (i in 0...size) {
|
||||||
var view:V = items[i];
|
var item:ListItem<V, D> = items[i];
|
||||||
if (data[offset + i] == null) break;
|
item.index = offset + i;
|
||||||
renderer.render(view, data[offset + i]);
|
if (data[item.index] == null) break;
|
||||||
|
item.data = data[item.index];
|
||||||
|
renderer.render(this, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function update():Void {
|
override public function update():Void {
|
||||||
super.update();
|
super.update();
|
||||||
var item:V = renderer.factory();
|
var item:ListItem<V, D> = renderer.factory();
|
||||||
size = Math.round(height / item.height);
|
size = Math.round(Math.max(0, height / item.view.height));
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function set_size(value:Int):Int {
|
private function set_size(value:Int):Int {
|
||||||
if (size != value) {
|
if (size != value) {
|
||||||
size = value;
|
size = value;
|
||||||
for (item in items) removeView(item);
|
var diff:Int = size - items.length;
|
||||||
items = new Array<V>();
|
if (diff > 0) {
|
||||||
var item:V = renderer.factory();
|
for (i in 0...diff) {
|
||||||
var newSize = Math.round(height / item.height);
|
var item:ListItem<V, D> = renderer.factory();
|
||||||
for (i in 0...size) {
|
items.push(item);
|
||||||
item = renderer.factory();
|
setClickListener(item);
|
||||||
items.push(item);
|
addView(item.view);
|
||||||
addView(item);
|
}
|
||||||
|
} 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;
|
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> {
|
interface IRenderer<L, V, D> {
|
||||||
public function factory():V;
|
public function factory():ListItem<V, D>;
|
||||||
public function render(view:V, data:D):Void;
|
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;
|
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.Graphics;
|
||||||
import flash.display.Sprite;
|
import flash.display.Sprite;
|
||||||
import haxework.gui.skin.ISkin;
|
import haxework.gui.skin.ISkin;
|
||||||
@@ -10,12 +15,39 @@ class ScrollView extends SpriteView {
|
|||||||
public var position(default, set):Float;
|
public var position(default, set):Float;
|
||||||
public var ratio(default, set):Float;
|
public var ratio(default, set):Float;
|
||||||
|
|
||||||
|
public var dispatcher(default, null):IDispatcher<ScrollListener>;
|
||||||
|
|
||||||
|
private var mousePosition:Float;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
|
dispatcher = new Dispatcher<ScrollListener>();
|
||||||
skin = untyped new ScrollSkin();
|
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 {
|
private function set_position(value:Float):Float {
|
||||||
|
value = NumberUtil.limitFloat(value, 0, 1 - ratio);
|
||||||
if (position != value) {
|
if (position != value) {
|
||||||
position = value;
|
position = value;
|
||||||
invalidate();
|
invalidate();
|
||||||
@@ -52,3 +84,7 @@ class ScrollSkin implements ISkin<Sprite, ScrollView> {
|
|||||||
graphics.endFill();
|
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 {
|
public static function error2strign(error:Dynamic):String {
|
||||||
return if (Std.is(error, Error)) {
|
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)) {
|
} else if (Std.is(error, ErrorEvent)) {
|
||||||
var event:ErrorEvent = cast(error, ErrorEvent);
|
var event:ErrorEvent = cast(error, ErrorEvent);
|
||||||
event.type + " - " + event.text;
|
event.type + " - " + event.text;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class JsonLoader<T> extends BaseURLLoader<T> {
|
|||||||
str = Std.string(cast(e.currentTarget, URLLoader).data);
|
str = Std.string(cast(e.currentTarget, URLLoader).data);
|
||||||
data = Json.parse(str);
|
data = Json.parse(str);
|
||||||
} catch (error:Dynamic) {
|
} catch (error:Dynamic) {
|
||||||
throw new Error(error + ": " + str);
|
throw new Error(error + ": " + url);
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ class JsonLoader<T> extends BaseURLLoader<T> {
|
|||||||
str = bytes.readUTFBytes(bytes.length);
|
str = bytes.readUTFBytes(bytes.length);
|
||||||
data = Json.parse(str);
|
data = Json.parse(str);
|
||||||
} catch (error:Dynamic) {
|
} catch (error:Dynamic) {
|
||||||
throw new Error(error + ": " + str);
|
throw new Error(error + ": " + url);
|
||||||
}
|
}
|
||||||
return data;
|
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