pict-section-flow 1.0.0 → 1.0.1

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.
@@ -0,0 +1,259 @@
1
+ const libFableServiceProviderBase = require('fable-serviceproviderbase');
2
+
3
+ const _ProviderConfiguration =
4
+ {
5
+ ProviderIdentifier: 'PictProviderFlowStylePresets'
6
+ };
7
+
8
+ /**
9
+ * PictProvider-Flow-StylePresets
10
+ *
11
+ * The preset registry that the flow editor's primary "Style" picker
12
+ * surfaces. Each preset is a curated triple `(ColorTheme, Renderer,
13
+ * EdgeTheme)` that reproduces one of the legacy monolithic themes —
14
+ * but as a composition of the three new axes.
15
+ *
16
+ * A consumer app can:
17
+ * - Pick a preset by hash → `flowView.setStylePreset('sketch')`
18
+ * - Override any axis afterward → `flowView.setColorTheme('flow-cyberpunk')`
19
+ * leaves the renderer + edge theme alone.
20
+ * - Register their own preset → `pict.providers['PictProviderFlowStylePresets'].register({...})`
21
+ *
22
+ * ## Preset shape
23
+ *
24
+ * ```javascript
25
+ * {
26
+ * Hash: 'sketch',
27
+ * Label: 'Sketch',
28
+ * ColorTheme: 'flow-sketch', // a pict-section-theme catalog hash
29
+ * Renderer: 'sketch', // a PictProviderFlowRenderer key
30
+ * EdgeTheme: 'bezier', // a PictService-Flow-Layout edge theme name
31
+ * NoiseLevel: 0.4, // optional — overrides renderer default
32
+ * Description: 'Hand-drawn paper with jittery brackets'
33
+ * }
34
+ * ```
35
+ *
36
+ * ## API
37
+ *
38
+ * ```javascript
39
+ * pict.providers['PictProviderFlowStylePresets'].register(preset);
40
+ * pict.providers['PictProviderFlowStylePresets'].getPreset(hash);
41
+ * pict.providers['PictProviderFlowStylePresets'].getPresetHashes();
42
+ * pict.providers['PictProviderFlowStylePresets'].applyPreset(hash);
43
+ * pict.providers['PictProviderFlowStylePresets'].getActivePresetHash();
44
+ * ```
45
+ *
46
+ * Apply order on `applyPreset()`:
47
+ * 1. ColorTheme → delegated to pict.providers.Theme.applyTheme()
48
+ * (skipped if Theme provider isn't installed in the host)
49
+ * 2. Renderer → delegated to Flow-Renderer.setRenderer()
50
+ * 3. EdgeTheme → delegated to FlowView.setEdgeTheme()
51
+ * 4. NoiseLevel → Flow-Renderer.setNoiseLevel() if provided
52
+ *
53
+ * After any *individual* axis change via `flowView.setColorTheme()`,
54
+ * `setRenderer()`, or `setEdgeTheme()`, the active preset becomes `null`
55
+ * (we're in customized state — no single preset describes the combo).
56
+ */
57
+ class PictProviderFlowStylePresets extends libFableServiceProviderBase
58
+ {
59
+ constructor(pFable, pOptions, pServiceHash)
60
+ {
61
+ let tmpOptions = Object.assign({}, _ProviderConfiguration, pOptions);
62
+ super(pFable, tmpOptions, pServiceHash);
63
+
64
+ this.serviceType = 'PictProviderFlowStylePresets';
65
+
66
+ this._FlowView = (pOptions && pOptions.FlowView) ? pOptions.FlowView : null;
67
+
68
+ this._ActivePresetHash = null;
69
+ this._Presets = {};
70
+
71
+ this._registerBuiltInPresets();
72
+ }
73
+
74
+ _registerBuiltInPresets()
75
+ {
76
+ const _DEFAULTS =
77
+ [
78
+ {
79
+ Hash: 'modern',
80
+ Label: 'Modern',
81
+ Description: 'Clean modern look — rounded rectangles, soft shadows, bezier connections.',
82
+ ColorTheme: 'flow-modern',
83
+ Renderer: 'clean',
84
+ EdgeTheme: 'bezier'
85
+ },
86
+ {
87
+ Hash: 'sketch',
88
+ Label: 'Sketch',
89
+ Description: 'Hand-drawn paper — bracket nodes with jitter and Courier text.',
90
+ ColorTheme: 'flow-sketch',
91
+ Renderer: 'sketch',
92
+ EdgeTheme: 'bezier',
93
+ NoiseLevel: 0.4
94
+ },
95
+ {
96
+ Hash: 'blueprint',
97
+ Label: 'Blueprint',
98
+ Description: 'Technical drawing on navy — bracket nodes, dashed lines, orthogonal edges.',
99
+ ColorTheme: 'flow-blueprint',
100
+ Renderer: 'bracket',
101
+ EdgeTheme: 'orthogonal'
102
+ },
103
+ {
104
+ Hash: 'mono',
105
+ Label: 'Monochrome',
106
+ Description: 'Pure black on white — clean rectangles, straight lines, no noise.',
107
+ ColorTheme: 'flow-mono',
108
+ Renderer: 'clean',
109
+ EdgeTheme: 'straight'
110
+ },
111
+ {
112
+ Hash: 'retro-80s',
113
+ Label: '80s Retro',
114
+ Description: 'Neon synthwave glow — magenta + cyan with CRT shadow effects.',
115
+ ColorTheme: 'flow-retro-80s',
116
+ Renderer: 'crt',
117
+ EdgeTheme: 'orthogonal'
118
+ },
119
+ {
120
+ Hash: 'retro-90s',
121
+ Label: '90s Retro',
122
+ Description: 'Windows-95 chrome — gray panels with offset shadows on a teal desktop.',
123
+ ColorTheme: 'flow-retro-90s',
124
+ Renderer: 'workstation',
125
+ EdgeTheme: 'orthogonal'
126
+ },
127
+ {
128
+ Hash: 'whiteboard',
129
+ Label: 'Whiteboard',
130
+ Description: 'Minimal whiteboard — colored brackets per node type, gentle jitter.',
131
+ ColorTheme: 'flow-whiteboard',
132
+ Renderer: 'sketch',
133
+ EdgeTheme: 'bezier',
134
+ NoiseLevel: 0.3
135
+ }
136
+ ];
137
+
138
+ for (let i = 0; i < _DEFAULTS.length; i++)
139
+ {
140
+ this._Presets[_DEFAULTS[i].Hash] = _DEFAULTS[i];
141
+ }
142
+ }
143
+
144
+ // ── Public API ────────────────────────────────────────────────────────
145
+
146
+ /**
147
+ * Register a custom preset.
148
+ * @param {Object} pPreset - must include Hash, ColorTheme, Renderer, EdgeTheme
149
+ * @returns {boolean}
150
+ */
151
+ register(pPreset)
152
+ {
153
+ if (!pPreset || typeof pPreset !== 'object' || !pPreset.Hash)
154
+ {
155
+ this.log.warn('PictProviderFlowStylePresets: register requires a preset object with a Hash');
156
+ return false;
157
+ }
158
+ this._Presets[pPreset.Hash] = pPreset;
159
+ return true;
160
+ }
161
+
162
+ /**
163
+ * Look up a preset by hash.
164
+ * @param {string} pHash
165
+ * @returns {Object|null}
166
+ */
167
+ getPreset(pHash)
168
+ {
169
+ return this._Presets[pHash] || null;
170
+ }
171
+
172
+ /**
173
+ * All registered preset hashes (insertion order).
174
+ * @returns {Array<string>}
175
+ */
176
+ getPresetHashes()
177
+ {
178
+ return Object.keys(this._Presets);
179
+ }
180
+
181
+ /**
182
+ * All registered presets as an ordered array (useful for picker UIs).
183
+ * @returns {Array<Object>}
184
+ */
185
+ listPresets()
186
+ {
187
+ return Object.values(this._Presets);
188
+ }
189
+
190
+ /**
191
+ * Hash of the currently-active preset, or null when in customized state
192
+ * (any individual axis was changed since the last setStylePreset call).
193
+ * @returns {string|null}
194
+ */
195
+ getActivePresetHash()
196
+ {
197
+ return this._ActivePresetHash;
198
+ }
199
+
200
+ /**
201
+ * Apply a preset by hash. Applies color theme, renderer, edge theme,
202
+ * and optional noise level in that order.
203
+ *
204
+ * @param {string} pHash
205
+ * @returns {boolean}
206
+ */
207
+ applyPreset(pHash)
208
+ {
209
+ let tmpPreset = this._Presets[pHash];
210
+ if (!tmpPreset)
211
+ {
212
+ this.log.warn(`PictProviderFlowStylePresets: preset '${pHash}' not found`);
213
+ return false;
214
+ }
215
+
216
+ // 1. Color theme — go through the host's pict-provider-theme if installed.
217
+ if (tmpPreset.ColorTheme && this.fable.providers && this.fable.providers.Theme)
218
+ {
219
+ try { this.fable.providers.Theme.applyTheme(tmpPreset.ColorTheme); }
220
+ catch (pErr) { this.log.warn(`PictProviderFlowStylePresets: Theme.applyTheme failed for '${tmpPreset.ColorTheme}' — ${pErr.message}`); }
221
+ }
222
+
223
+ // 2. Renderer — go through Flow-Renderer (must be present).
224
+ if (tmpPreset.Renderer && this._FlowView && this._FlowView._RendererProvider)
225
+ {
226
+ this._FlowView._RendererProvider.setRenderer(tmpPreset.Renderer);
227
+ }
228
+
229
+ // 3. Edge theme — go through FlowView's existing setEdgeTheme().
230
+ if (tmpPreset.EdgeTheme && this._FlowView && typeof this._FlowView.setEdgeTheme === 'function')
231
+ {
232
+ try { this._FlowView.setEdgeTheme(tmpPreset.EdgeTheme); }
233
+ catch (pErr) { this.log.warn(`PictProviderFlowStylePresets: setEdgeTheme failed for '${tmpPreset.EdgeTheme}' — ${pErr.message}`); }
234
+ }
235
+
236
+ // 4. Optional noise override.
237
+ if (typeof tmpPreset.NoiseLevel === 'number' && this._FlowView && this._FlowView._RendererProvider)
238
+ {
239
+ this._FlowView._RendererProvider.setNoiseLevel(tmpPreset.NoiseLevel);
240
+ }
241
+
242
+ this._ActivePresetHash = pHash;
243
+ this.log.trace(`PictProviderFlowStylePresets: applied preset '${pHash}'`);
244
+ return true;
245
+ }
246
+
247
+ /**
248
+ * Called by FlowView when a single axis is overridden by the user — this
249
+ * clears the active-preset tracker so getActivePresetHash() returns null.
250
+ */
251
+ markCustomized()
252
+ {
253
+ this._ActivePresetHash = null;
254
+ }
255
+ }
256
+
257
+ module.exports = PictProviderFlowStylePresets;
258
+
259
+ module.exports.default_configuration = _ProviderConfiguration;