diff --git a/src/lib/Rect.hx b/src/lib/Rect.hx index 0047167..b13c070 100644 --- a/src/lib/Rect.hx +++ b/src/lib/Rect.hx @@ -2,27 +2,27 @@ package lib; class Rect { - private final tr:Pos; - private final bl:Pos; + private final tl:Pos; + private final br:Pos; public function new(p1: Pos,p2:Pos) { - this.tr = { - x: MathI.max(p1.x,p2.x), - y: MathI.max(p1.y,p2.y) - }; - - this.bl = { + this.tl = { x: MathI.min(p1.x,p2.x), y: MathI.min(p1.y,p2.y) }; + + this.br = { + x: MathI.max(p1.x,p2.x), + y: MathI.max(p1.y,p2.y) + }; } public function getSize(): Int { - return (tr.x - bl.x) * (tr.y - bl.y); + return getWidth() * getHight(); } public function isInside(p: Pos): Bool { - return (p.x >= bl.x && p.x <= tr.x) && (p.y >= bl.y && p.y <= tr.y); + return (p.x >= tl.x && p.x <= br.x) && (p.y >= tl.y && p.y <= br.y); } public function isOutside(p: Pos): Bool { @@ -30,10 +30,17 @@ class Rect { } public function getHight(): Int { - return tr.y - bl.y; + return br.y - tl.y; } public function getWidth(): Int { - return tr.x - bl.x; + return br.x - tl.x; + } + + public function offset(pos: Pos) { + tl.x += pos.x; + tl.y += pos.y; + br.x += pos.x; + br.y += pos.y; } } diff --git a/src/lib/Vec.hx b/src/lib/Vec.hx index b67d079..12472e8 100644 --- a/src/lib/Vec.hx +++ b/src/lib/Vec.hx @@ -1,12 +1,12 @@ package lib; @:structInit class Vec2 { - public final x:T; - public final y:T; + public var x:T; + public var y:T; } @:structInit class Vec3 { - public final x:T; - public final y:T; - public final z:T; + public var x:T; + public var y:T; + public var z:T; } diff --git a/src/lib/ui/Canvas.hx b/src/lib/ui/Canvas.hx index e9f4d56..10885c9 100644 --- a/src/lib/ui/Canvas.hx +++ b/src/lib/ui/Canvas.hx @@ -64,8 +64,8 @@ abstract Canvas(Array>) to Array> from Array) { + inline public function new(?i:List<{bound:Rect, delegate:UIEventDelegate}>) { + if (i == null) { + this = new List<{bound:Rect, delegate:UIEventDelegate}>(); + } else { + this = i; + } + } + + public function findResponseableDelegate(pos:Pos):UIEventDelegate { + for (i in this) { + if (i.bound.isInside(pos)) { + return i.delegate; + } + } + return null; + } + + public function addElement(element:UIEventDelegate, bound:Rect) { + this.add({bound: bound, delegate: element}); + } +} diff --git a/src/lib/ui/elements/RootElement.hx b/src/lib/ui/elements/RootElement.hx new file mode 100644 index 0000000..a6f66a0 --- /dev/null +++ b/src/lib/ui/elements/RootElement.hx @@ -0,0 +1,42 @@ +package lib.ui.elements; + +class RootElement implements UIElement { + private var children:Array; + private final eventManager:UIEventManager = new UIEventManager(); + + public function new(?children:Array) { + if (children == null) { + children = []; + } else { + this.children = children; + } + } + + public function getEventHandlers():UIEvents { + return eventManager.getEventHandlers(); + } + + public function setChildren(children:Array) { + this.children = children; + } + + public function render():Canvas { + var canvas = new Canvas(); + var offset = new Pos({x: 0, y: 0}); + + this.eventManager.clearMap(); + + for (child in children) { + var childCanvas = child.render(); + var bounds = childCanvas.getBounds(); + bounds.offset(offset); + + this.eventManager.addMapElement(child, bounds); + canvas.combine(childCanvas, offset); + + offset = new Pos({x: 0, y: offset.y + bounds.getHight() + 1}); + } + + return canvas; + } +} diff --git a/src/lib/ui/elements/TextElement.hx b/src/lib/ui/elements/TextElement.hx new file mode 100644 index 0000000..c4db0f5 --- /dev/null +++ b/src/lib/ui/elements/TextElement.hx @@ -0,0 +1,36 @@ +package lib.ui.elements; + +import lib.ui.elements.UIElement; + +class TextElement implements UIElement { + public var text:String; + + private final uiEvents:UIEvents; + + public function new(text:String, ?uiEvents:UIEvents) { + this.text = text; + this.uiEvents = uiEvents; + } + + public function set(text:String) { + this.text = text; + } + + public function get():String { + return this.text; + } + + public function getEventHandlers():UIEvents { + return uiEvents; + } + + public function render():Canvas { + var canvas = new Canvas(); + for (i in 0...this.text.length) { + var c = this.text.charAt(i); + canvas.set({x: i, y: 0}, {bg: Black, textColor: White, char: c}); + } + + return canvas; + } +} diff --git a/src/lib/ui/elements/UIElement.hx b/src/lib/ui/elements/UIElement.hx new file mode 100644 index 0000000..a5c73d9 --- /dev/null +++ b/src/lib/ui/elements/UIElement.hx @@ -0,0 +1,7 @@ +package lib.ui.elements; + +import lib.ui.rendere.UIEventDelegate; + +interface UIElement extends UIEventDelegate { + public function render():Canvas; +} diff --git a/src/lib/ui/elements/UIEventManager.hx b/src/lib/ui/elements/UIEventManager.hx new file mode 100644 index 0000000..69747bc --- /dev/null +++ b/src/lib/ui/elements/UIEventManager.hx @@ -0,0 +1,60 @@ +package lib.ui.elements; + +import kernel.log.Log; +import kernel.ButtonType; +import lib.ui.rendere.UIEventDelegate; + +class UIEventManager implements UIEventDelegate { + private var map:EventMap = new EventMap(); + + public function new() {} + + public function clearMap() { + this.map = new EventMap(); + } + + public function addMapElement(element:UIEventDelegate, bound:Rect) { + this.map.addElement(element, bound); + } + + public function getEventHandlers():UIEvents { + return { + onClick: handleClickEvent, + onKey: handleKeyEvent, + onKeyUp: handleKeyUpEvent, + onMouseDrag: handleMouseDragEvent, + onMouseScroll: handleMouseScrollEvent, + onMouseUp: handleMouseUpEvent, + onPaste: handlePasteEvent, + onChar: handleCharEvent, + }; + } + + private function handleClickEvent(params:{button:ButtonType, pos:Pos}) { + var element = this.map.findResponseableDelegate(params.pos); + if (element == null) { + return; + } + + var handlers = element.getEventHandlers(); + if (handlers == null || handlers.onClick == null) { + return; + } + + handlers.onClick.invoke(params); + } + + private function handleCharEvent(char:String) {} + + private function handlePasteEvent(text:String) {} + + private function handleMouseUpEvent(params:{button:ButtonType, pos:Pos}) {} + + private function handleMouseScrollEvent(params:{dir:Int, pos:Pos}) {} + + private function handleMouseDragEvent(params:{button:ButtonType, pos:Pos}) {} + + private function handleKeyEvent(params:{keyCode:Int, isHeld:Bool}) {} + + private function handleKeyUpEvent(key:Int) {} +}