Compare commits

...

4 Commits

Author SHA1 Message Date
1881d8f488 minor ui stuff 2022-03-04 00:59:32 +01:00
3b6bc85271 pass events to ui element 2022-03-04 00:59:02 +01:00
bddb80c42d added Rect 2022-03-04 00:58:35 +01:00
1aa3b43d8c added debug target 2022-03-03 15:47:11 +01:00
9 changed files with 102 additions and 39 deletions

View File

@@ -2,7 +2,7 @@ BUNDLE_NAME = bundle.lua
HAXE_NAME = haxe.lua
MINIFYD_NAME = bundle.min.lua
BUILD_DIR = build
HAXE_FLAGS =
HAXE_FLAGS =
POLYFILLED_NAME = bundle.polyfill.lua
POLYFILL_SRC = src/polyfill.lua
@@ -14,6 +14,9 @@ all: clean build
build: $(MIN_PATH)
debug: HAXE_FLAGS += -D webconsole --debug
debug: build
$(HAXE_PATH): $(shell find src -name '*.hx')
haxe build.hxml $(HAXE_FLAGS)
@@ -30,7 +33,7 @@ clean:
rm -rf $(BUILD_DIR)
watch:
find src -name "*.hx" | entr make build
find src -name "*.hx" | entr make debug
emulator:
craftos --mount-ro /=build

View File

@@ -7,6 +7,9 @@ import kernel.ButtonType;
import util.Vec.Vec2;
import lib.TermWriteable;
/**
The main object you interact with when writing anything to the screen.
**/
class WindowContext implements TermWriteable {
private final writer:VirtualTermWriter;
@@ -26,7 +29,8 @@ class WindowContext implements TermWriteable {
@:allow(kernel.ui.WindowManager) private final mouseUpTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}>;
@:allow(kernel.ui.WindowManager) private final pasteTrigger:SignalTrigger<String>;
public function new(writer:VirtualTermWriter) {
@:allow(kernel.ui.WindowManager)
private function new(writer:VirtualTermWriter) {
this.writer = writer;
this.onResize = writer.onResize;

View File

@@ -67,10 +67,6 @@ class WindowManager {
allContexts.push(newContext);
// newContext.setTarget(MainTerm.instance);
newContext.enable();
currentMainContext = newContext;
return newContext;
}
@@ -84,6 +80,7 @@ class WindowManager {
var target:TermWriteable;
if (output == "main") {
target = MainTerm.instance;
currentMainContext = context;
} else {
target = Peripheral.instance.getScreen(output);

View File

@@ -12,7 +12,7 @@ class TermIO {
public function new(output:TermWriteable) {
this.output = output;
output.clear();
output.reset();
output.setCursorPos(0, 0);
}

View File

@@ -1,10 +0,0 @@
package lib.ui.reactive;
using tink.CoreApi;
import util.Vec.Vec2;
interface IElement {
public function render(bounds:Vec2<Int>):Canvas;
public var changed(default, null):Signal<Noise>;
}

View File

@@ -1,31 +1,48 @@
package lib.ui.reactive;
import util.Rect;
import kernel.Log;
import util.Color;
import util.Vec.Vec2;
import kernel.ui.WindowContext;
using tink.CoreApi;
class ReactiveUI {
private final context:WindowContext;
private final children:Array<IElement>;
private final children:Array<UIElement>;
private var elementMap: Map<Rect,UIElement> = new Map();
public function new(context:WindowContext, children:Array<IElement>) {
public function new(context:WindowContext, children:Array<UIElement>) {
this.context = context;
this.children = children;
for (child in children) {
child.changed.handle(v -> {
child.changed.handle(_ -> {
context.reset();
render();
});
}
setupEvents();
}
private function setupEvents() {
context.clickSignal.handle(params ->{
for (k => v in this.elementMap){
if (k.isInside(params.pos)){
v.handleClickEvent(params.pos,params.button);
}
}
});
}
public function render() {
var size = context.getSize();
var result = renderChildren(children, size);
this.elementMap = result.map;
var screen = renderChildren(children, size);
writeToContext(screen);
writeToContext(result.canvas);
}
private function writeToContext(screen:Canvas) {
@@ -62,8 +79,9 @@ class ReactiveUI {
}
}
public static function renderChildren(children:Array<IElement>, bounds:Vec2<Int>):Canvas {
var rtn:Canvas = new Canvas();
public static function renderChildren(children:Array<UIElement>, bounds:Vec2<Int>):{canvas: Canvas, map: Map<Rect,UIElement>} {
var canvas:Canvas = new Canvas();
var elementMap: Map<Rect,UIElement> = new Map();
var writePoint:Vec2<Int> = {x: 0, y: 0};
@@ -79,11 +97,12 @@ class ReactiveUI {
y: bounds.y - writePoint.y
});
rtn.combine(childRender, writePoint);
canvas.combine(childRender, writePoint);
elementMap.set(new Rect(writePoint,{x: childRender.maxWidth(), y: writePoint.y + childRender.hight()}),child);
writePoint = {x: 0, y: writePoint.y + childRender.hight()};
}
return rtn;
return {canvas: canvas,map: elementMap};
}
}

View File

@@ -1,5 +1,7 @@
package lib.ui.reactive;
import kernel.Log;
import kernel.ButtonType;
import util.Observable;
using tink.CoreApi;
@@ -7,17 +9,13 @@ import util.Color;
import util.Vec.Vec2;
import util.MathI;
class TextElement implements IElement {
public var changed(default, null):Signal<Noise>;
private var changedTrigger:SignalTrigger<Noise>;
class TextElement extends UIElement {
private final text:Observable<String>;
private final bg:Color;
private final fg:Color;
public function new(text:Observable<String>, ?background:Color = Black, ?textColor:Color = White) {
setupTrigger();
super();
this.text = text;
this.bg = background;
@@ -28,11 +26,6 @@ class TextElement implements IElement {
});
}
private function setupTrigger() {
changedTrigger = Signal.trigger();
changed = changedTrigger.asSignal();
}
public function render(bounds:Vec2<Int>):Canvas {
var rtn = new Canvas();
@@ -45,4 +38,8 @@ class TextElement implements IElement {
return rtn;
}
public override function handleClickEvent(pos: Vec2<Int>,button: ButtonType):Void {
Log.debug('Click: ${this.text.get()}');
}
}

View File

@@ -0,0 +1,20 @@
package lib.ui.reactive;
import kernel.Log;
import kernel.ButtonType;
import util.Vec.Vec2;
using tink.CoreApi;
abstract class UIElement {
abstract public function render(bounds:Vec2<Int>):Canvas;
public var changed(default, null):Signal<Noise>;
private final changedTrigger:SignalTrigger<Noise> = Signal.trigger();
public function new() {
changed = changedTrigger.asSignal();
}
public function handleClickEvent(pos: Vec2<Int>,button: ButtonType):Void {
}
}

33
src/util/Rect.hx Normal file
View File

@@ -0,0 +1,33 @@
package util;
import util.Vec.Vec2;
class Rect {
private final tr:Vec2<Int>;
private final bl:Vec2<Int>;
public function new(p1: Vec2<Int>,p2:Vec2<Int>) {
this.tr = {
x: MathI.max(p1.x,p2.x),
y: MathI.max(p1.y,p2.y)
};
this.bl = {
x: MathI.min(p1.x,p2.x),
y: MathI.min(p1.y,p2.y)
};
}
public function getSize(): Int {
return (tr.x - bl.x) * (tr.y - bl.y);
}
public function isInside(p: Vec2<Int>): Bool {
return (p.x >= bl.x && p.x <= tr.x) && (p.y >= bl.y && p.y <= tr.y);
}
public function isOutside(p: Vec2<Int>): Bool {
return !this.isInside(p);
}
}