@elicdavis/node-flow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.github/workflows/deploy.yml +57 -0
  2. package/README.md +159 -0
  3. package/dev.tsconfig.json +18 -0
  4. package/docs/promotional-image.png +0 -0
  5. package/esbuild.ts +32 -0
  6. package/index.html +311 -0
  7. package/package.json +50 -0
  8. package/src/camera.ts +30 -0
  9. package/src/connection.ts +249 -0
  10. package/src/contextMenu.ts +367 -0
  11. package/src/draggable.ts +13 -0
  12. package/src/elements/base.ts +192 -0
  13. package/src/elements/container.ts +119 -0
  14. package/src/elements/interfaces.ts +50 -0
  15. package/src/elements/text.ts +86 -0
  16. package/src/graph.ts +535 -0
  17. package/src/graphSubsystem.ts +31 -0
  18. package/src/index.ts +28 -0
  19. package/src/input.ts +153 -0
  20. package/src/markdown/entry.ts +323 -0
  21. package/src/markdown/lexicalParser.ts +148 -0
  22. package/src/markdown/markdown.ts +14 -0
  23. package/src/markdown/syntaxParser.ts +344 -0
  24. package/src/markdown/token.ts +43 -0
  25. package/src/metadata.ts +3 -0
  26. package/src/node.ts +1130 -0
  27. package/src/nodes/factory.ts +87 -0
  28. package/src/nodes/publisher.ts +98 -0
  29. package/src/nodes/subsystem.ts +760 -0
  30. package/src/notes/note.ts +295 -0
  31. package/src/notes/subsystem.ts +262 -0
  32. package/src/organize.ts +181 -0
  33. package/src/pass/subsystem.ts +64 -0
  34. package/src/performance.ts +9 -0
  35. package/src/popup.ts +81 -0
  36. package/src/popups/form.ts +63 -0
  37. package/src/popups/string.ts +33 -0
  38. package/src/port.ts +223 -0
  39. package/src/quickMenu.ts +330 -0
  40. package/src/styles/box.ts +104 -0
  41. package/src/styles/canvasTextAlign.ts +8 -0
  42. package/src/styles/canvasTextBaseline.ts +9 -0
  43. package/src/styles/cursor.ts +18 -0
  44. package/src/styles/stroke.ts +39 -0
  45. package/src/styles/text.ts +90 -0
  46. package/src/styles/textBox.ts +82 -0
  47. package/src/theme.ts +78 -0
  48. package/src/types/box.ts +126 -0
  49. package/src/types/list.ts +41 -0
  50. package/src/types/pool.ts +66 -0
  51. package/src/types/text.ts +136 -0
  52. package/src/types/vector2.ts +34 -0
  53. package/src/utils/color.ts +136 -0
  54. package/src/utils/html.ts +21 -0
  55. package/src/utils/math.ts +8 -0
  56. package/src/utils/string.ts +98 -0
  57. package/src/widgets/button.ts +107 -0
  58. package/src/widgets/color.ts +151 -0
  59. package/src/widgets/factory.ts +46 -0
  60. package/src/widgets/image.ts +163 -0
  61. package/src/widgets/number.ts +153 -0
  62. package/src/widgets/slider.ts +216 -0
  63. package/src/widgets/string.ts +128 -0
  64. package/src/widgets/text.ts +92 -0
  65. package/src/widgets/toggle.ts +205 -0
  66. package/src/widgets/widget.ts +12 -0
  67. package/tsconfig.json +15 -0
  68. package/tsup.config.ts +10 -0
@@ -0,0 +1,192 @@
1
+ import { Vector2 } from "../types/vector2";
2
+ import { Border, BorderStyling, InstantiateRenderElementSidesStyling, IRenderElement, RenderElementSides, RenderElementSidesStyling } from "./interfaces";
3
+
4
+ export enum Display {
5
+ Flex = "flex",
6
+ None = "none"
7
+ }
8
+
9
+ export interface RenderElementBaseStyling {
10
+ Margin?: RenderElementSidesStyling | number;
11
+ Padding?: RenderElementSidesStyling | number;
12
+ Border?: BorderStyling;
13
+ BackgroundColor?: string;
14
+ MinWidth?: number;
15
+ MaxWidth?: number;
16
+ MaxHeight?: number;
17
+ MinHeight?: number;
18
+ Grow?: number;
19
+ Display?: Display;
20
+ }
21
+
22
+ export abstract class RenderElementBase implements IRenderElement {
23
+
24
+ #margin: RenderElementSides;
25
+
26
+ #padding: RenderElementSides;
27
+
28
+ #border: Border;
29
+
30
+ #backgroundColor?: string;
31
+
32
+ #minWidth?: number;
33
+
34
+ #maxWidth?: number;
35
+
36
+ #minHeight?: number;
37
+
38
+ #maxHeight?: number;
39
+
40
+ #grow?: number;
41
+
42
+ #display: Display;
43
+
44
+ constructor(config?: RenderElementBaseStyling) {
45
+ this.#margin = InstantiateRenderElementSidesStyling(config?.Margin);
46
+ this.#padding = InstantiateRenderElementSidesStyling(config?.Padding);
47
+ this.#backgroundColor = config?.BackgroundColor;
48
+ this.#border = {
49
+ Color: config?.Border?.Color ?? "black",
50
+ Thickness: config?.Border?.Thickness ?? 0,
51
+ Radius: config?.Border?.Radius ?? 0,
52
+ }
53
+ this.#minWidth = config?.MinWidth;
54
+ this.#maxWidth = config?.MaxWidth;
55
+ this.#minHeight = config?.MinHeight;
56
+ this.#maxHeight = config?.MaxHeight;
57
+ this.#grow = config?.Grow;
58
+ this.#display = config?.Display ?? Display.Flex;
59
+ }
60
+
61
+ setBackgroundColor(newColor: string): void {
62
+ this.#backgroundColor = newColor;
63
+ }
64
+
65
+ abstract doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void;
66
+
67
+ render(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {
68
+ if (this.#display === Display.None) {
69
+ return;
70
+ }
71
+
72
+ const scaledSize = { x: 0, y: 0 };
73
+ this.size(ctx, scaledSize);
74
+
75
+ scaledSize.x = scaledSize.x * graphScale;
76
+ scaledSize.y = scaledSize.y * graphScale;
77
+ scaledSize.x = Math.max(scaledSize.x, scaledFillableSpace.x);
78
+ scaledSize.y = Math.max(scaledSize.y, scaledFillableSpace.y);
79
+
80
+ if (this.#backgroundColor) {
81
+ ctx.fillStyle = this.#backgroundColor;
82
+ ctx.beginPath();
83
+ ctx.roundRect(
84
+ position.x + (this.#margin.Left * graphScale),
85
+ position.y + (this.#margin.Right * graphScale),
86
+ scaledSize.x - ((this.#margin.Left + this.#margin.Right) * graphScale),
87
+ scaledSize.y - ((this.#margin.Top + this.#margin.Bottom) * graphScale),
88
+ this.#border.Radius * graphScale
89
+ );
90
+ ctx.fill();
91
+ }
92
+
93
+ if (this.#border.Thickness > 0) {
94
+ ctx.lineWidth = this.#border.Thickness * graphScale;
95
+ ctx.strokeStyle = this.#border.Color;
96
+ ctx.stroke();
97
+ }
98
+
99
+ const offsetPosition = {
100
+ x: position.x + (this.#totalLeftOffset() * graphScale),
101
+ y: position.y + (this.#totalTopOffset() * graphScale),
102
+ };
103
+ const elementSize = {
104
+ x: scaledSize.x - (this.#horizontalOffset() * graphScale),
105
+ y: scaledSize.y - (this.#verticalOffset() * graphScale)
106
+ }
107
+ this.doRender(ctx, offsetPosition, graphScale, elementSize);
108
+ }
109
+
110
+ abstract calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void;
111
+
112
+ protected maxLimitations(out: Vector2): void {
113
+ out.x = -1;
114
+ out.y = -1;
115
+
116
+ if (this.#maxWidth) {
117
+ out.x = this.#maxWidth;
118
+ }
119
+
120
+ if (this.#maxHeight) {
121
+ out.y = this.#maxHeight;
122
+ }
123
+ }
124
+
125
+ setDisplay(display: Display): void {
126
+ this.#display = display;
127
+ }
128
+
129
+ getDisplay(): Display {
130
+ return this.#display;
131
+ }
132
+
133
+ size(ctx: CanvasRenderingContext2D, out: Vector2): void {
134
+ out.x = 0;
135
+ out.y = 0;
136
+ if (this.#display === Display.None) {
137
+ return;
138
+ }
139
+
140
+ const maxLimits = { x: -1, y: -1 }
141
+ this.maxLimitations(maxLimits);
142
+
143
+ this.calcSize(ctx, out, maxLimits);
144
+
145
+ out.x += this.#horizontalOffset();
146
+ out.y += this.#verticalOffset();
147
+
148
+ if (this.#minWidth) {
149
+ out.x = Math.max(out.x, this.#minWidth)
150
+ }
151
+
152
+ if (this.#maxWidth) {
153
+ out.x = Math.min(this.#maxWidth, out.x);
154
+ }
155
+
156
+ if (this.#maxHeight) {
157
+ out.y = Math.min(this.#maxHeight, out.y);
158
+ }
159
+
160
+ if (this.#minHeight) {
161
+ out.y = Math.max(this.#minHeight, out.y);
162
+ }
163
+ }
164
+
165
+ #horizontalOffset(): number {
166
+ return (this.#border.Thickness) +
167
+ this.#margin.Left +
168
+ this.#margin.Right +
169
+ this.#padding.Left +
170
+ this.#padding.Right;
171
+ }
172
+
173
+ #verticalOffset(): number {
174
+ return (this.#border.Thickness) +
175
+ this.#margin.Top +
176
+ this.#margin.Bottom +
177
+ this.#padding.Top +
178
+ this.#padding.Bottom;
179
+ }
180
+
181
+ #totalTopOffset(): number {
182
+ return (this.#border.Thickness / 2) +
183
+ this.#margin.Top +
184
+ this.#padding.Top;
185
+ }
186
+
187
+ #totalLeftOffset(): number {
188
+ return (this.#border.Thickness / 2) +
189
+ this.#margin.Left +
190
+ this.#padding.Left;
191
+ }
192
+ }
@@ -0,0 +1,119 @@
1
+ import { ScaleVector, Vector2 } from '../types/vector2';
2
+ import { RenderElementBase, RenderElementBaseStyling } from "./base";
3
+ import { IRenderElement } from "./interfaces";
4
+
5
+
6
+ interface ContainerRenderElementConfig extends RenderElementBaseStyling {
7
+
8
+ }
9
+
10
+ export enum LayoutDirection {
11
+ Column = "column",
12
+ Row = "row"
13
+ }
14
+
15
+ export enum AlignItems {
16
+ Stretch = "stretch",
17
+ Start = "start",
18
+ Center = "center",
19
+ End = "end"
20
+ }
21
+
22
+ export class ContainerRenderElement extends RenderElementBase {
23
+
24
+ #elements: Array<IRenderElement>;
25
+
26
+ #layout: LayoutDirection;
27
+
28
+ #alignment: AlignItems;
29
+
30
+ constructor(elements: Array<IRenderElement>, config?: ContainerRenderElementConfig) {
31
+ super(config);
32
+ this.#elements = elements;
33
+ this.#layout = LayoutDirection.Column;
34
+ this.#alignment = AlignItems.Stretch;
35
+ }
36
+
37
+ calcSize(ctx: CanvasRenderingContext2D, out: Vector2, limitations: Vector2): void {
38
+ out.x = 0;
39
+ out.y = 0;
40
+
41
+ const eleSize = { x: 0, y: 0 };
42
+
43
+ switch (this.#layout) {
44
+ case LayoutDirection.Column:
45
+ for (let i = 0; i < this.#elements.length; i++) {
46
+ this.#elements[i].size(ctx, eleSize);
47
+ out.x = Math.max(out.x, eleSize.x);
48
+ out.y += eleSize.y;
49
+ }
50
+ break;
51
+
52
+ case LayoutDirection.Row:
53
+ for (let i = 0; i < this.#elements.length; i++) {
54
+ this.#elements[i].size(ctx, eleSize);
55
+ out.y = Math.max(out.y, eleSize.y);
56
+ out.x += eleSize.x;
57
+ }
58
+ break;
59
+
60
+ default:
61
+ throw new Error("unknown layout: " + this.#layout);
62
+ }
63
+
64
+ }
65
+
66
+ doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {
67
+ // const size = { x: 0, y: 0 };
68
+ // const limitations = { x: 0, y: 0 };
69
+ // this.limitations(limitations)
70
+ // this.calcSize(ctx, size, limitations);
71
+ switch (this.#layout) {
72
+ case LayoutDirection.Column:
73
+ this.#renderColumn(ctx, position, graphScale, scaledFillableSpace);
74
+ break;
75
+
76
+ default:
77
+ throw new Error("unimplemented layout direction: " + this.#layout);
78
+ }
79
+ }
80
+
81
+ #renderColumn(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {
82
+ const currnetPos = { x: position.x, y: position.y };
83
+ const scaledEleSize = { x: 0, y: 0 };
84
+ for (let i = 0; i < this.#elements.length; i++) {
85
+ const ele = this.#elements[i];
86
+
87
+ ele.size(ctx, scaledEleSize);
88
+ ScaleVector(scaledEleSize, graphScale);
89
+
90
+ switch (this.#alignment) {
91
+
92
+ case AlignItems.Stretch:
93
+ currnetPos.x = position.x;
94
+ scaledEleSize.x = scaledFillableSpace.x;
95
+ break;
96
+
97
+ // I'm not sure if this is even needed, I feel like this should
98
+ // already be the case.
99
+ case AlignItems.Start: //garney flarney <---- silly goose steenky feet
100
+ currnetPos.x = position.x;
101
+ break
102
+
103
+ case AlignItems.End:
104
+ currnetPos.x = scaledFillableSpace.x - scaledEleSize.x
105
+ break;
106
+
107
+ case AlignItems.Center:
108
+ currnetPos.x = scaledFillableSpace.x - (scaledEleSize.x / 2)
109
+ break;
110
+
111
+ default:
112
+ throw new Error("unimplmeneted alignment: " + this.#alignment)
113
+ }
114
+
115
+ ele.render(ctx, currnetPos, graphScale, scaledEleSize);
116
+ currnetPos.y += scaledEleSize.y;
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,50 @@
1
+ import { Vector2 } from "../types/vector2"
2
+
3
+
4
+ export interface RenderElementSidesStyling {
5
+ Left?: number
6
+ Right?: number
7
+ Top?: number
8
+ Bottom?: number
9
+ }
10
+
11
+ export interface RenderElementSides {
12
+ Left: number
13
+ Right: number
14
+ Top: number
15
+ Bottom: number
16
+ }
17
+
18
+ export function InstantiateRenderElementSidesStyling(config?: RenderElementSidesStyling | number): RenderElementSides {
19
+ if (typeof config === 'number') {
20
+ return {
21
+ Bottom: config,
22
+ Right: config,
23
+ Top: config,
24
+ Left: config,
25
+ }
26
+ }
27
+ return {
28
+ Bottom: config?.Bottom === undefined ? 0 : config?.Bottom,
29
+ Right: config?.Right === undefined ? 0 : config?.Right,
30
+ Left: config?.Left === undefined ? 0 : config?.Left,
31
+ Top: config?.Top === undefined ? 0 : config?.Top,
32
+ }
33
+ }
34
+
35
+ export interface IRenderElement {
36
+ size(ctx: CanvasRenderingContext2D, out: Vector2): void;
37
+ render(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void;
38
+ }
39
+
40
+ export interface Border {
41
+ Color: string;
42
+ Thickness: number;
43
+ Radius: number;
44
+ }
45
+
46
+ export interface BorderStyling {
47
+ Color?: string;
48
+ Thickness?: number;
49
+ Radius?: number;
50
+ }
@@ -0,0 +1,86 @@
1
+ import { Text } from "../types/text";
2
+ import { CopyVector2, ScaleVector, Vector2, Zero } from "../types/vector2";
3
+ import { RenderElementBase, RenderElementBaseStyling } from "./base";
4
+
5
+ export enum TextAlign {
6
+ Left = "left",
7
+ Right = "right",
8
+ Center = "center",
9
+ }
10
+
11
+ export enum VerticalAlign {
12
+ Top = "top",
13
+ Center = "center",
14
+ Bottom = "bottom"
15
+ }
16
+
17
+ export interface TextElementStyling extends RenderElementBaseStyling {
18
+ Align?: TextAlign
19
+ VerticalAlign?: VerticalAlign
20
+ }
21
+
22
+ export class TextElement extends RenderElementBase {
23
+ #text: Text;
24
+
25
+ #align: TextAlign;
26
+
27
+ #verticalAlign: VerticalAlign;
28
+
29
+ constructor(text: Text, styling?: TextElementStyling) {
30
+ super(styling);
31
+ this.#text = text;
32
+ this.#align = styling?.Align ?? TextAlign.Left;
33
+ this.#verticalAlign = styling?.VerticalAlign ?? VerticalAlign.Top;
34
+ }
35
+
36
+ doRender(ctx: CanvasRenderingContext2D, position: Vector2, graphScale: number, scaledFillableSpace: Vector2): void {
37
+ const scale = Zero();
38
+ this.calcSize(ctx, scale);
39
+ ScaleVector(scale, graphScale);
40
+
41
+ const justifiedPosition = Zero();
42
+ CopyVector2(justifiedPosition, position)
43
+
44
+ ctx.textAlign = "left";
45
+ ctx.textBaseline = "top"
46
+
47
+ switch (this.#align) {
48
+ case TextAlign.Left:
49
+ // Do nothing. This is default
50
+ break;
51
+
52
+ case TextAlign.Right:
53
+ justifiedPosition.x += scaledFillableSpace.x - scale.x;
54
+ break;
55
+
56
+ case TextAlign.Center:
57
+ justifiedPosition.x += (scaledFillableSpace.x - scale.x) / 2;
58
+ break;
59
+
60
+ default:
61
+ throw new Error("unimplemented justification: " + this.#align);
62
+ }
63
+
64
+ switch (this.#verticalAlign) {
65
+ case VerticalAlign.Top:
66
+ // Do nothing. This is default
67
+ break;
68
+
69
+ case VerticalAlign.Bottom:
70
+ justifiedPosition.y += scaledFillableSpace.y - scale.y;
71
+ break;
72
+
73
+ case VerticalAlign.Center:
74
+ justifiedPosition.y += (scaledFillableSpace.y - scale.y) / 2;
75
+ break;
76
+
77
+ default:
78
+ throw new Error("unimplemented justification: " + this.#align);
79
+ }
80
+ this.#text.render(ctx, graphScale, justifiedPosition);
81
+ }
82
+
83
+ calcSize(ctx: CanvasRenderingContext2D, out: Vector2): void {
84
+ this.#text.size(ctx, 1, out);
85
+ }
86
+ }