Skip to content

Commit 0544aa3

Browse files
committed
feat(wip): start reworking Views
1 parent 38c259e commit 0544aa3

File tree

7 files changed

+69
-94
lines changed

7 files changed

+69
-94
lines changed

examples/demo.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ new Table({
348348
});
349349

350350
const view = new View({
351+
canvas: tui.canvas,
351352
rectangle: {
352353
column: 75,
353354
row: 3,
@@ -456,6 +457,8 @@ new Text({
456457
rectangle: {
457458
column: 2,
458459
row: 13,
460+
width: -1,
461+
height: -1,
459462
},
460463
theme: baseTheme,
461464
text: "wopa",
@@ -470,7 +473,7 @@ tui.canvas.on("render", () => {
470473
for (const component of tui.components) {
471474
if (
472475
// @ts-expect-error NOFRAME
473-
component.view.peek() || component.parent !== tui || component.NOFRAME ||
476+
component.view || component.parent !== tui || component.NOFRAME ||
474477
component === performanceStats
475478
) {
476479
continue;
@@ -501,7 +504,12 @@ let lastRender = 0;
501504

502505
const performanceStats = new Text({
503506
parent: tui,
504-
rectangle: { column: 0, row: 0 },
507+
rectangle: {
508+
column: 0,
509+
row: 0,
510+
width: -1,
511+
height: -1,
512+
},
505513
theme: baseTheme,
506514
text: new Computed(() =>
507515
`\

src/canvas/canvas.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export type CanvasEventMap = {
2626
render: EmitterEvent<[]>;
2727
};
2828

29-
interface Drawable {
29+
export interface Drawable {
3030
draw(row: number, column: number, data: string): void;
3131
}
3232

src/canvas/painter.ts

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ import { View } from "../view.ts";
88
import { Signal, SignalOfObject } from "../signals/mod.ts";
99
import { signalify } from "../utils/signals.ts";
1010
import { Subscription } from "../signals/types.ts";
11-
import { Effect } from "../signals/effect.ts";
1211

1312
export interface PainterOptions {
13+
view?: View;
1414
canvas: Canvas;
1515

1616
omitCells?: number[];
1717
omitCellsPointer?: number;
1818

19-
view?: View | Signal<View | undefined>;
2019
style: Style | SignalOfObject<Style>;
2120
zIndex: number | Signal<number>;
2221
}
@@ -36,8 +35,8 @@ export class Painter<Type extends string = string> {
3635
style: Signal<Style>;
3736
zIndex: Signal<number>;
3837

39-
view: Signal<View | undefined>;
40-
viewOffset: Offset;
38+
view?: View;
39+
viewOffset?: Offset;
4140

4241
rectangle!: Signal<Rectangle>;
4342
previousRectangle?: Rectangle;
@@ -73,7 +72,7 @@ export class Painter<Type extends string = string> {
7372
this.updated = true;
7473
this.moved = true;
7574

76-
this.view = signalify(options.view);
75+
this.view = options.view;
7776
this.zIndex = signalify(options.zIndex);
7877
this.style = signalify(options.style);
7978

@@ -91,38 +90,6 @@ export class Painter<Type extends string = string> {
9190
updateObjects.push(objectUnder);
9291
} */
9392
};
94-
95-
if (this.view.value) {
96-
queueMicrotask(() => {
97-
new Effect(() => {
98-
const view = this.view.value;
99-
// FIXME: they might not get watched if view wasnt set by default
100-
if (view) {
101-
const viewRectangle = view?.rectangle.value;
102-
const offset = view?.offset.value;
103-
const _maxOffset = view?.maxOffset.value;
104-
105-
const rectangle = this.rectangle?.peek();
106-
if (!rectangle) return;
107-
const { viewOffset } = this;
108-
109-
rectangle.column += viewRectangle.column - offset.columns - viewOffset.columns;
110-
rectangle.row += viewRectangle.row - offset.rows - viewOffset.rows;
111-
112-
viewOffset.columns = viewRectangle.column - offset.columns;
113-
viewOffset.rows = viewRectangle.row - offset.rows;
114-
}
115-
116-
this.updated = false;
117-
updateObjects.push(this);
118-
119-
for (const objectUnder of this.objectsUnder) {
120-
objectUnder.updated = false;
121-
updateObjects.push(objectUnder);
122-
}
123-
});
124-
});
125-
}
12693
}
12794

12895
draw(): void {
@@ -250,7 +217,7 @@ export class Painter<Type extends string = string> {
250217
column + width < 0 || row + height < 0;
251218

252219
if (!this.outOfBounds) {
253-
const viewRectangle = this.view.peek()?.rectangle?.peek();
220+
const viewRectangle = this.view?.rectangle?.peek();
254221
if (!viewRectangle) return;
255222

256223
if (

src/canvas/painters/box.ts

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -60,27 +60,12 @@ export class BoxPainter extends Painter<"box"> {
6060
new Effect(() => {
6161
const size = this.canvas.size.value;
6262
const rectangle = this.rectangle.value;
63-
const view = this.view.value;
64-
const viewRectangle = view?.rectangle.value;
6563

66-
let rowStart = rectangle.row;
67-
let rowRange = Math.min(rectangle.row + rectangle.height, size.rows);
64+
this.#rowStart = rectangle.row;
65+
this.#rowRange = Math.min(rectangle.row + rectangle.height, size.rows);
6866

69-
let columnStart = rectangle.column;
70-
let columnRange = Math.min(rectangle.column + rectangle.width, size.columns);
71-
72-
if (viewRectangle) {
73-
rowStart = Math.max(rowStart, viewRectangle.row);
74-
columnStart = Math.max(columnStart, viewRectangle.column);
75-
rowRange = Math.min(rowRange, viewRectangle.row + viewRectangle.height);
76-
columnRange = Math.min(columnRange, viewRectangle.column + viewRectangle.width);
77-
}
78-
79-
this.#rowStart = rowStart;
80-
this.#rowRange = rowRange;
81-
82-
this.#columnStart = columnStart;
83-
this.#columnRange = columnRange;
67+
this.#columnStart = rectangle.column;
68+
this.#columnRange = Math.min(rectangle.column + rectangle.width, size.columns);
8469
});
8570
}
8671

@@ -95,11 +80,13 @@ export class BoxPainter extends Painter<"box"> {
9580
}
9681

9782
paint(): void {
98-
const { canvas, rerenderCells, omitCells, painted } = this;
83+
const { rerenderCells, omitCells, painted } = this;
9984

10085
const rectangle = this.rectangle.peek();
10186
const filler = this.#filler;
10287

88+
const drawable = this.view ?? this.canvas;
89+
10390
const rowStart = this.#rowStart;
10491
const rowRange = this.#rowRange;
10592

@@ -123,7 +110,7 @@ export class BoxPainter extends Painter<"box"> {
123110
continue;
124111
}
125112

126-
canvas.draw(row, column, filler);
113+
drawable.draw(row, column, filler);
127114
}
128115

129116
rerenderColumns.clear();
@@ -133,7 +120,7 @@ export class BoxPainter extends Painter<"box"> {
133120
continue;
134121
}
135122

136-
canvas.draw(row, column, filler);
123+
drawable.draw(row, column, filler);
137124
}
138125
}
139126
}

src/canvas/painters/text.ts

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -156,27 +156,11 @@ export class TextPainter<TextType extends string | string[]> extends Painter<"bo
156156
this.text.value; // FIXME: this is temporary
157157
const size = this.canvas.size.value;
158158
const rectangle = this.rectangle.value;
159-
const view = this.view.value;
160-
const viewRectangle = view?.rectangle.value;
161159

162-
let rowStart = rectangle.row;
163-
let rowRange = Math.min(rectangle.row + rectangle.height, size.rows);
164-
165-
let columnStart = rectangle.column;
166-
let columnRange = Math.min(rectangle.column + rectangle.width, size.columns);
167-
168-
if (viewRectangle) {
169-
rowStart = Math.max(rowStart, viewRectangle.row);
170-
columnStart = Math.max(columnStart, viewRectangle.column);
171-
rowRange = Math.min(rowRange, viewRectangle.row + viewRectangle.height);
172-
columnRange = Math.min(columnRange, viewRectangle.column + viewRectangle.width);
173-
}
174-
175-
this.#rowStart = rowStart;
176-
this.#rowRange = rowRange;
177-
178-
this.#columnStart = columnStart;
179-
this.#columnRange = columnRange;
160+
this.#rowStart = rectangle.row;
161+
this.#rowRange = Math.min(rectangle.row + rectangle.height, size.rows);
162+
this.#columnStart = rectangle.column;
163+
this.#columnRange = Math.min(rectangle.column + rectangle.width, size.columns);
180164

181165
this.moved = true;
182166
this.updated = false;
@@ -247,10 +231,13 @@ export class TextPainter<TextType extends string | string[]> extends Painter<"bo
247231
}
248232

249233
paint(): void {
250-
const { canvas, rerenderCells, omitCells, painted } = this;
234+
const { rerenderCells, omitCells, painted } = this;
251235

252-
const rectangle = this.rectangle.peek();
253236
const style = this.style.peek();
237+
const rectangle = this.rectangle.peek();
238+
239+
const drawable = this.view ?? this.canvas;
240+
254241
const text = this.#text;
255242

256243
const rowStart = this.#rowStart;
@@ -279,7 +266,7 @@ export class TextPainter<TextType extends string | string[]> extends Painter<"bo
279266
const char = text[column - columnStart];
280267
if (!char) continue;
281268

282-
canvas.draw(row, column, style(char));
269+
drawable.draw(row, column, style(char));
283270
}
284271

285272
rerenderColumns.clear();
@@ -292,7 +279,7 @@ export class TextPainter<TextType extends string | string[]> extends Painter<"bo
292279
const char = text[column - columnStart];
293280
if (!char) continue;
294281

295-
canvas.draw(row, column, style(char));
282+
drawable.draw(row, column, style(char));
296283
}
297284
}
298285
} else {
@@ -319,7 +306,7 @@ export class TextPainter<TextType extends string | string[]> extends Painter<"bo
319306
const char = line[column - columnStart];
320307
if (!char) continue;
321308

322-
canvas.draw(row, column, style(char));
309+
drawable.draw(row, column, style(char));
323310
}
324311

325312
rerenderColumns.clear();
@@ -332,7 +319,7 @@ export class TextPainter<TextType extends string | string[]> extends Painter<"bo
332319
const char = line[column - columnStart];
333320
if (!char) continue;
334321

335-
canvas.draw(row, column, style(char));
322+
drawable.draw(row, column, style(char));
336323
}
337324
}
338325
}

src/component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export interface ComponentOptions {
1818
zIndex: number | Signal<number>;
1919
visible?: boolean | Signal<boolean>;
2020
rectangle: Rectangle | SignalOfObject<Rectangle>;
21-
view?: View | undefined | SignalOfObject<View | undefined>;
21+
view?: View;
2222
}
2323

2424
/** Type defining last interaction component experienced */
@@ -40,7 +40,7 @@ export class Component extends EventEmitter<
4040

4141
visible: Signal<boolean>;
4242
state: Signal<ComponentState>;
43-
view: Signal<View | undefined>;
43+
view?: View;
4444
zIndex: Signal<number>;
4545
rectangle: SignalOfObject<Rectangle>;
4646
style: Signal<Style>;
@@ -73,7 +73,7 @@ export class Component extends EventEmitter<
7373
method: undefined,
7474
};
7575

76-
this.view = signalify(options.view);
76+
this.view = options.view;
7777
this.zIndex = signalify(options.zIndex);
7878
this.visible = signalify(options.visible ?? true);
7979
this.rectangle = signalify(options.rectangle, { deepObserve: true, watchObjectIndex: true });

src/view.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,47 @@
11
// Copyright 2023 Im-Beast. All rights reserved. MIT license.
2-
import { Signal, signalify } from "../mod.ts";
2+
import { Canvas, Signal, signalify } from "../mod.ts";
33
import { Offset, Rectangle } from "./types.ts";
4+
import { Drawable } from "./canvas/canvas.ts";
45

56
interface ViewOptions {
7+
canvas: Canvas;
68
offset?: Offset;
79
maxOffset?: Offset;
810
rectangle: Rectangle;
911
}
1012

11-
export class View {
13+
export class View implements Drawable {
14+
canvas: Signal<Canvas>;
1215
offset: Signal<Offset>;
1316
maxOffset: Signal<Offset>;
1417
rectangle: Signal<Rectangle>;
1518

19+
#canvas: Canvas;
20+
#rectangle: Rectangle;
21+
1622
constructor(options: ViewOptions) {
23+
this.canvas = signalify(options.canvas);
1724
this.rectangle = signalify(options.rectangle, { deepObserve: true });
1825
this.offset = signalify(options.offset ?? { columns: 0, rows: 0 }, { deepObserve: true });
1926
this.maxOffset = signalify(options.maxOffset ?? { columns: 0, rows: 0 }, { deepObserve: true });
27+
28+
this.#canvas = this.canvas.peek();
29+
this.canvas.subscribe((canvas) => {
30+
this.#canvas = canvas;
31+
});
32+
33+
this.#rectangle = this.rectangle.peek();
34+
this.rectangle.subscribe((rectangle) => {
35+
this.#rectangle = rectangle;
36+
});
37+
}
38+
39+
draw(row: number, column: number, data: string): void {
40+
const canvas = this.#canvas;
41+
const rectangle = this.#rectangle;
42+
43+
if (row > rectangle.width || row > rectangle.height) return;
44+
45+
canvas.draw(row + rectangle.row, column + rectangle.column, data);
2046
}
2147
}

0 commit comments

Comments
 (0)