real reactive ui
This commit is contained in:
parent
7b33667e04
commit
829484cb67
@ -1,3 +1,4 @@
|
||||
import lib.ui.Observable;
|
||||
import lib.ui.TextElement;
|
||||
import lib.ui.ReactiveUI;
|
||||
import kernel.Log;
|
||||
@ -36,13 +37,20 @@ class Startup {
|
||||
|
||||
static function exampleUI() {
|
||||
var context = WindowManager.instance.createNewContext();
|
||||
var ui = new ReactiveUI(context);
|
||||
|
||||
ui.render([
|
||||
new TextElement("Hello world"),
|
||||
new TextElement("Hello world",Green,Red),
|
||||
var text = new Observable("Hello world");
|
||||
|
||||
var ui = new ReactiveUI(context,[
|
||||
new TextElement(text),
|
||||
new TextElement(text,Green,Red),
|
||||
]);
|
||||
|
||||
ui.render();
|
||||
|
||||
context.clickSignal.on(data -> {
|
||||
text.set("Holla mundo");
|
||||
});
|
||||
|
||||
WindowManager.instance.focusContextToOutput(context,"main");
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package lib.ui;
|
||||
|
||||
using tink.CoreApi;
|
||||
import util.Vec.Vec2;
|
||||
|
||||
interface IElement {
|
||||
public function render(bounds: Vec2<Int>): Canvas;
|
||||
public var changed(default, null):Signal<Noise>;
|
||||
}
|
||||
|
28
src/lib/ui/Observable.hx
Normal file
28
src/lib/ui/Observable.hx
Normal file
@ -0,0 +1,28 @@
|
||||
package lib.ui;
|
||||
|
||||
using tink.CoreApi;
|
||||
|
||||
class Observable<T> {
|
||||
private var value: T;
|
||||
private var callbacks: CallbackList<T> = new CallbackList(true);
|
||||
|
||||
public function new(value: T) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public function set(value: T) {
|
||||
if (value != this.value){
|
||||
this.value = value;
|
||||
callbacks.invoke(value);
|
||||
}
|
||||
}
|
||||
|
||||
public function get(): T {
|
||||
return value;
|
||||
}
|
||||
|
||||
public function subscribe(callback: Callback<T>):CallbackLink {
|
||||
callback.invoke(value);
|
||||
return callbacks.add(callback);
|
||||
}
|
||||
}
|
@ -7,12 +7,20 @@ import kernel.ui.WindowContext;
|
||||
|
||||
class ReactiveUI {
|
||||
private final context:WindowContext;
|
||||
private final children:Array<IElement>;
|
||||
|
||||
public function new(context: WindowContext) {
|
||||
public function new(context: WindowContext,children: Array<IElement>) {
|
||||
this.context = context;
|
||||
this.children = children;
|
||||
|
||||
for(child in children){
|
||||
child.changed.handle(v -> {
|
||||
render();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function render(children: Array<IElement>) {
|
||||
public function render() {
|
||||
var size = context.getSize();
|
||||
|
||||
var screen = renderChildren(children,size);
|
||||
|
@ -1,26 +1,42 @@
|
||||
package lib.ui;
|
||||
|
||||
import kernel.Log;
|
||||
using tink.CoreApi;
|
||||
|
||||
import util.Color;
|
||||
import util.Vec.Vec2;
|
||||
import util.MathI;
|
||||
|
||||
class TextElement implements IElement {
|
||||
private final text:String;
|
||||
public var changed(default, null):Signal<Noise>;
|
||||
private var changedTrigger:SignalTrigger<Noise>;
|
||||
|
||||
private final text: Observable<String>;
|
||||
private final bg:Color;
|
||||
private final fg:Color;
|
||||
|
||||
public function new(text: String,?background: Color = Black,?textColor: Color = White) {
|
||||
public function new(text: Observable<String>,?background: Color = Black,?textColor: Color = White) {
|
||||
|
||||
setupTrigger();
|
||||
|
||||
this.text = text;
|
||||
this.bg = background;
|
||||
this.fg = textColor;
|
||||
|
||||
this.text.subscribe(value -> {
|
||||
this.changedTrigger.trigger(null);
|
||||
});
|
||||
}
|
||||
|
||||
private function setupTrigger() {
|
||||
changedTrigger = Signal.trigger();
|
||||
changed = changedTrigger.asSignal();
|
||||
}
|
||||
|
||||
public function render(bounds: Vec2<Int>):Canvas {
|
||||
var rtn = new Canvas();
|
||||
|
||||
for (i in 0...MathI.min(Math.floor(text.length / bounds.x) + 1,bounds.y)){
|
||||
var line = (text.substr(i * bounds.x,bounds.x));
|
||||
for (i in 0...MathI.min(Math.floor(text.get().length / bounds.x) + 1,bounds.y)){
|
||||
var line = (text.get().substr(i * bounds.x,bounds.x));
|
||||
for (char in 0...line.length) {
|
||||
rtn.set({x: char,y: i},{textColor: fg,char: line.charAt(char),bg: bg});
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
package lib.ui;
|
||||
|
||||
import util.Vec.Vec2;
|
||||
import kernel.ui.TermBuffer.Pixel;
|
||||
|
||||
class VSplitLayout implements IElement{
|
||||
|
||||
public function new(childrenLeft: Array<IElement>,childrenRight: Array<IElement>) {
|
||||
|
||||
}
|
||||
|
||||
public function render(bounds:Vec2<Int>):Canvas {
|
||||
var boundsLeft: Vec2<Int> = { x: Math.ceil(bounds.x / 2), y: bounds.y};
|
||||
var boundsRight: Vec2<Int> = { x: Math.floor(bounds.x / 2), y: bounds.y};
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user