diff --git a/src/lib/ui/Canvas.hx b/src/lib/ui/Canvas.hx index 18500b4..a0247c2 100644 --- a/src/lib/ui/Canvas.hx +++ b/src/lib/ui/Canvas.hx @@ -1,5 +1,6 @@ package lib.ui; +import util.Rect; import util.Vec.Vec2; import kernel.ui.Pixel; @@ -55,6 +56,13 @@ abstract Canvas(Array>) to Array> { return max; } + + public function getBounds(): Rect { + return new Rect({x:0,y:0},{ + x: maxWidth(), + y: hight() + }); + } } class CanvasKeyValueIterator { diff --git a/src/lib/ui/reactive/ListElement.hx b/src/lib/ui/reactive/ListElement.hx index 2b367e8..1aff4da 100644 --- a/src/lib/ui/reactive/ListElement.hx +++ b/src/lib/ui/reactive/ListElement.hx @@ -1,14 +1,39 @@ package lib.ui.reactive; +import util.Pos; +import util.Rect; import util.ObservableArray; import util.Vec.Vec2; class ListElement extends UIElement { private final content:ObservableArray; + private var elementMap: Map = new Map(); // Position in the map is relative. + private var offset:Pos; public function new(content: ObservableArray) { - super(); + var events: UIEvents = { + onClick: (p)->{ + var element = UIElement.getElementInMap((p.pos:Pos) - offset,elementMap); + if (element != null) + if (element.eventListner.onClick != null) + element.eventListner.onClick.invoke(p); + }, + onMouseUp: (p)->{ + var element = UIElement.getElementInMap((p.pos:Pos) - offset,elementMap); + if (element != null) + if (element.eventListner.onMouseUp != null) + element.eventListner.onMouseUp.invoke(p); + }, + onMouseScroll: (p)->{ + var element = UIElement.getElementInMap((p.pos:Pos) - offset,elementMap); + if (element != null) + if (element.eventListner.onMouseScroll != null) + element.eventListner.onMouseScroll.invoke(p); + }, + }; + + super(events); this.content = content; this.content.subscribe(value -> { @@ -17,9 +42,10 @@ class ListElement extends UIElement { }); } - public function render(bounds:Vec2):Canvas { + public function render(bounds:Vec2,offset: Pos):Canvas { var canvas: Canvas = new Canvas(); var writePoint:Vec2 = {x: 0, y: 0}; + this.offset = offset; for(element in this.content.get()){ if (bounds.y - writePoint.y <= 0) { @@ -30,9 +56,15 @@ class ListElement extends UIElement { var childRender = element.render({ x: bounds.x, y: bounds.y - writePoint.y - }); + }, offset + writePoint); canvas.combine(childRender, writePoint); + elementMap.set(new Rect(writePoint, + { + x: childRender.maxWidth() + writePoint.x, + y: writePoint.y + (childRender.hight() - 1), + } + ),element); writePoint = {x: 0, y: writePoint.y + childRender.hight()}; } diff --git a/src/lib/ui/reactive/ReactiveUI.hx b/src/lib/ui/reactive/ReactiveUI.hx index ebbb904..a86e690 100644 --- a/src/lib/ui/reactive/ReactiveUI.hx +++ b/src/lib/ui/reactive/ReactiveUI.hx @@ -1,7 +1,6 @@ package lib.ui.reactive; import util.Rect; -import kernel.Log; import util.Color; import util.Vec.Vec2; import kernel.ui.WindowContext; @@ -157,7 +156,7 @@ class ReactiveUI { var childRender = child.render({ x: bounds.x, y: bounds.y - writePoint.y - }); + },writePoint); canvas.combine(childRender, writePoint); elementMap.set(new Rect(writePoint,{x: childRender.maxWidth() + writePoint.x, y: writePoint.y + (childRender.hight() - 1)}),child); diff --git a/src/lib/ui/reactive/TextElement.hx b/src/lib/ui/reactive/TextElement.hx index 85c1150..d344628 100644 --- a/src/lib/ui/reactive/TextElement.hx +++ b/src/lib/ui/reactive/TextElement.hx @@ -1,7 +1,6 @@ package lib.ui.reactive; -import kernel.Log; -import kernel.ButtonType; +import util.Pos; import util.Observable; using tink.CoreApi; @@ -26,7 +25,7 @@ class TextElement extends UIElement { }); } - public function render(bounds:Vec2):Canvas { + public function render(bounds:Vec2,offset: Pos):Canvas { var rtn = new Canvas(); for (i in 0...MathI.min(Math.floor(text.get().length / bounds.x) + 1, bounds.y)) { diff --git a/src/lib/ui/reactive/UIElement.hx b/src/lib/ui/reactive/UIElement.hx index 339aa63..dc43ed0 100644 --- a/src/lib/ui/reactive/UIElement.hx +++ b/src/lib/ui/reactive/UIElement.hx @@ -1,11 +1,18 @@ package lib.ui.reactive; +import util.Pos; +import util.Rect; import util.Vec.Vec2; using tink.CoreApi; abstract class UIElement { - abstract public function render(bounds:Vec2):Canvas; + /** + Render the element inside the bounds. `offset` is the offset to the parents position + and can be used to calculate the absolute position of element. + Just save `offset` and pass it to the children. + **/ + abstract public function render(bounds:Vec2, offset: Pos):Canvas; public var changed(default, null):Signal; private final changedTrigger:SignalTrigger = Signal.trigger(); public final eventListner:UIEvents = {}; @@ -16,4 +23,14 @@ abstract class UIElement { this.eventListner = events; } } + + public static function getElementInMap(pos: Pos,elementMap: Map):Null{ + for (k => v in elementMap){ + if (k.isInside(pos)){ + return v; + } + } + + return null; + }; }