Compare commits
4 Commits
daff654867
...
1881d8f488
| Author | SHA1 | Date | |
|---|---|---|---|
| 1881d8f488 | |||
| 3b6bc85271 | |||
| bddb80c42d | |||
| 1aa3b43d8c |
5
Makefile
5
Makefile
@@ -14,6 +14,9 @@ all: clean build
|
|||||||
|
|
||||||
build: $(MIN_PATH)
|
build: $(MIN_PATH)
|
||||||
|
|
||||||
|
debug: HAXE_FLAGS += -D webconsole --debug
|
||||||
|
debug: build
|
||||||
|
|
||||||
$(HAXE_PATH): $(shell find src -name '*.hx')
|
$(HAXE_PATH): $(shell find src -name '*.hx')
|
||||||
haxe build.hxml $(HAXE_FLAGS)
|
haxe build.hxml $(HAXE_FLAGS)
|
||||||
|
|
||||||
@@ -30,7 +33,7 @@ clean:
|
|||||||
rm -rf $(BUILD_DIR)
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
find src -name "*.hx" | entr make build
|
find src -name "*.hx" | entr make debug
|
||||||
|
|
||||||
emulator:
|
emulator:
|
||||||
craftos --mount-ro /=build
|
craftos --mount-ro /=build
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import kernel.ButtonType;
|
|||||||
import util.Vec.Vec2;
|
import util.Vec.Vec2;
|
||||||
import lib.TermWriteable;
|
import lib.TermWriteable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
The main object you interact with when writing anything to the screen.
|
||||||
|
**/
|
||||||
class WindowContext implements TermWriteable {
|
class WindowContext implements TermWriteable {
|
||||||
private final writer:VirtualTermWriter;
|
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 mouseUpTrigger:SignalTrigger<{button:ButtonType, pos:Vec2<Int>}>;
|
||||||
@:allow(kernel.ui.WindowManager) private final pasteTrigger:SignalTrigger<String>;
|
@: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.writer = writer;
|
||||||
this.onResize = writer.onResize;
|
this.onResize = writer.onResize;
|
||||||
|
|
||||||
|
|||||||
@@ -67,10 +67,6 @@ class WindowManager {
|
|||||||
|
|
||||||
allContexts.push(newContext);
|
allContexts.push(newContext);
|
||||||
|
|
||||||
// newContext.setTarget(MainTerm.instance);
|
|
||||||
newContext.enable();
|
|
||||||
currentMainContext = newContext;
|
|
||||||
|
|
||||||
return newContext;
|
return newContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +80,7 @@ class WindowManager {
|
|||||||
var target:TermWriteable;
|
var target:TermWriteable;
|
||||||
if (output == "main") {
|
if (output == "main") {
|
||||||
target = MainTerm.instance;
|
target = MainTerm.instance;
|
||||||
|
currentMainContext = context;
|
||||||
} else {
|
} else {
|
||||||
target = Peripheral.instance.getScreen(output);
|
target = Peripheral.instance.getScreen(output);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class TermIO {
|
|||||||
public function new(output:TermWriteable) {
|
public function new(output:TermWriteable) {
|
||||||
this.output = output;
|
this.output = output;
|
||||||
|
|
||||||
output.clear();
|
output.reset();
|
||||||
output.setCursorPos(0, 0);
|
output.setCursorPos(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>;
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,48 @@
|
|||||||
package lib.ui.reactive;
|
package lib.ui.reactive;
|
||||||
|
|
||||||
|
import util.Rect;
|
||||||
import kernel.Log;
|
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;
|
||||||
|
|
||||||
|
using tink.CoreApi;
|
||||||
|
|
||||||
class ReactiveUI {
|
class ReactiveUI {
|
||||||
private final context:WindowContext;
|
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.context = context;
|
||||||
this.children = children;
|
this.children = children;
|
||||||
|
|
||||||
for (child in children) {
|
for (child in children) {
|
||||||
child.changed.handle(v -> {
|
child.changed.handle(_ -> {
|
||||||
|
context.reset();
|
||||||
render();
|
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() {
|
public function render() {
|
||||||
var size = context.getSize();
|
var size = context.getSize();
|
||||||
|
var result = renderChildren(children, size);
|
||||||
|
this.elementMap = result.map;
|
||||||
|
|
||||||
var screen = renderChildren(children, size);
|
writeToContext(result.canvas);
|
||||||
|
|
||||||
writeToContext(screen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function writeToContext(screen:Canvas) {
|
private function writeToContext(screen:Canvas) {
|
||||||
@@ -62,8 +79,9 @@ class ReactiveUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function renderChildren(children:Array<IElement>, bounds:Vec2<Int>):Canvas {
|
public static function renderChildren(children:Array<UIElement>, bounds:Vec2<Int>):{canvas: Canvas, map: Map<Rect,UIElement>} {
|
||||||
var rtn:Canvas = new Canvas();
|
var canvas:Canvas = new Canvas();
|
||||||
|
var elementMap: Map<Rect,UIElement> = new Map();
|
||||||
|
|
||||||
var writePoint:Vec2<Int> = {x: 0, y: 0};
|
var writePoint:Vec2<Int> = {x: 0, y: 0};
|
||||||
|
|
||||||
@@ -79,11 +97,12 @@ class ReactiveUI {
|
|||||||
y: bounds.y - writePoint.y
|
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()};
|
writePoint = {x: 0, y: writePoint.y + childRender.hight()};
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtn;
|
return {canvas: canvas,map: elementMap};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package lib.ui.reactive;
|
package lib.ui.reactive;
|
||||||
|
|
||||||
|
import kernel.Log;
|
||||||
|
import kernel.ButtonType;
|
||||||
import util.Observable;
|
import util.Observable;
|
||||||
using tink.CoreApi;
|
using tink.CoreApi;
|
||||||
|
|
||||||
@@ -7,17 +9,13 @@ import util.Color;
|
|||||||
import util.Vec.Vec2;
|
import util.Vec.Vec2;
|
||||||
import util.MathI;
|
import util.MathI;
|
||||||
|
|
||||||
class TextElement implements IElement {
|
class TextElement extends UIElement {
|
||||||
public var changed(default, null):Signal<Noise>;
|
|
||||||
|
|
||||||
private var changedTrigger:SignalTrigger<Noise>;
|
|
||||||
|
|
||||||
private final text:Observable<String>;
|
private final text:Observable<String>;
|
||||||
private final bg:Color;
|
private final bg:Color;
|
||||||
private final fg:Color;
|
private final fg:Color;
|
||||||
|
|
||||||
public function new(text:Observable<String>, ?background:Color = Black, ?textColor:Color = White) {
|
public function new(text:Observable<String>, ?background:Color = Black, ?textColor:Color = White) {
|
||||||
setupTrigger();
|
super();
|
||||||
|
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.bg = background;
|
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 {
|
public function render(bounds:Vec2<Int>):Canvas {
|
||||||
var rtn = new Canvas();
|
var rtn = new Canvas();
|
||||||
|
|
||||||
@@ -45,4 +38,8 @@ class TextElement implements IElement {
|
|||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override function handleClickEvent(pos: Vec2<Int>,button: ButtonType):Void {
|
||||||
|
Log.debug('Click: ${this.text.get()}');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/lib/ui/reactive/UIElement.hx
Normal file
20
src/lib/ui/reactive/UIElement.hx
Normal 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
33
src/util/Rect.hx
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user