added ui elements with children

This commit is contained in:
Djeeberjr 2022-03-08 13:25:27 +01:00
parent 47c38ac731
commit edc3195192
5 changed files with 64 additions and 9 deletions

View File

@ -1,5 +1,6 @@
package lib.ui; package lib.ui;
import util.Rect;
import util.Vec.Vec2; import util.Vec.Vec2;
import kernel.ui.Pixel; import kernel.ui.Pixel;
@ -55,6 +56,13 @@ abstract Canvas(Array<Array<Pixel>>) to Array<Array<Pixel>> {
return max; return max;
} }
public function getBounds(): Rect {
return new Rect({x:0,y:0},{
x: maxWidth(),
y: hight()
});
}
} }
class CanvasKeyValueIterator { class CanvasKeyValueIterator {

View File

@ -1,14 +1,39 @@
package lib.ui.reactive; package lib.ui.reactive;
import util.Pos;
import util.Rect;
import util.ObservableArray; import util.ObservableArray;
import util.Vec.Vec2; import util.Vec.Vec2;
class ListElement extends UIElement { class ListElement extends UIElement {
private final content:ObservableArray<UIElement>; private final content:ObservableArray<UIElement>;
private var elementMap: Map<Rect,UIElement> = new Map(); // Position in the map is relative.
private var offset:Pos;
public function new(content: ObservableArray<UIElement>) { public function new(content: ObservableArray<UIElement>) {
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 = content;
this.content.subscribe(value -> { this.content.subscribe(value -> {
@ -17,9 +42,10 @@ class ListElement extends UIElement {
}); });
} }
public function render(bounds:Vec2<Int>):Canvas { public function render(bounds:Vec2<Int>,offset: Pos):Canvas {
var canvas: Canvas = new Canvas(); var canvas: Canvas = new Canvas();
var writePoint:Vec2<Int> = {x: 0, y: 0}; var writePoint:Vec2<Int> = {x: 0, y: 0};
this.offset = offset;
for(element in this.content.get()){ for(element in this.content.get()){
if (bounds.y - writePoint.y <= 0) { if (bounds.y - writePoint.y <= 0) {
@ -30,9 +56,15 @@ class ListElement extends UIElement {
var childRender = element.render({ var childRender = element.render({
x: bounds.x, x: bounds.x,
y: bounds.y - writePoint.y y: bounds.y - writePoint.y
}); }, offset + writePoint);
canvas.combine(childRender, 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()}; writePoint = {x: 0, y: writePoint.y + childRender.hight()};
} }

View File

@ -1,7 +1,6 @@
package lib.ui.reactive; package lib.ui.reactive;
import util.Rect; import util.Rect;
import kernel.Log;
import util.Color; import util.Color;
import util.Vec.Vec2; import util.Vec.Vec2;
import kernel.ui.WindowContext; import kernel.ui.WindowContext;
@ -157,7 +156,7 @@ class ReactiveUI {
var childRender = child.render({ var childRender = child.render({
x: bounds.x, x: bounds.x,
y: bounds.y - writePoint.y y: bounds.y - writePoint.y
}); },writePoint);
canvas.combine(childRender, writePoint); canvas.combine(childRender, writePoint);
elementMap.set(new Rect(writePoint,{x: childRender.maxWidth() + writePoint.x, y: writePoint.y + (childRender.hight() - 1)}),child); elementMap.set(new Rect(writePoint,{x: childRender.maxWidth() + writePoint.x, y: writePoint.y + (childRender.hight() - 1)}),child);

View File

@ -1,7 +1,6 @@
package lib.ui.reactive; package lib.ui.reactive;
import kernel.Log; import util.Pos;
import kernel.ButtonType;
import util.Observable; import util.Observable;
using tink.CoreApi; using tink.CoreApi;
@ -26,7 +25,7 @@ class TextElement extends UIElement {
}); });
} }
public function render(bounds:Vec2<Int>):Canvas { public function render(bounds:Vec2<Int>,offset: Pos):Canvas {
var rtn = new Canvas(); var rtn = new Canvas();
for (i in 0...MathI.min(Math.floor(text.get().length / bounds.x) + 1, bounds.y)) { for (i in 0...MathI.min(Math.floor(text.get().length / bounds.x) + 1, bounds.y)) {

View File

@ -1,11 +1,18 @@
package lib.ui.reactive; package lib.ui.reactive;
import util.Pos;
import util.Rect;
import util.Vec.Vec2; import util.Vec.Vec2;
using tink.CoreApi; using tink.CoreApi;
abstract class UIElement { abstract class UIElement {
abstract public function render(bounds:Vec2<Int>):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<Int>, offset: Pos):Canvas;
public var changed(default, null):Signal<Noise>; public var changed(default, null):Signal<Noise>;
private final changedTrigger:SignalTrigger<Noise> = Signal.trigger(); private final changedTrigger:SignalTrigger<Noise> = Signal.trigger();
public final eventListner:UIEvents = {}; public final eventListner:UIEvents = {};
@ -16,4 +23,14 @@ abstract class UIElement {
this.eventListner = events; this.eventListner = events;
} }
} }
public static function getElementInMap(pos: Pos,elementMap: Map<Rect,UIElement>):Null<UIElement>{
for (k => v in elementMap){
if (k.isInside(pos)){
return v;
}
}
return null;
};
} }