pict-section-flow 0.0.18 → 0.0.19

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.
@@ -85,10 +85,13 @@ const _DefaultConfiguration =
85
85
  [
86
86
  {
87
87
  Hash: 'Flow-PanelChrome-Template',
88
- Template: /*html*/`<div class="pict-flow-panel" xmlns="http://www.w3.org/1999/xhtml"><div class="pict-flow-panel-titlebar" data-element-type="panel-titlebar" data-panel-hash="{~D:Record.Hash~}"><span class="pict-flow-panel-title-text">{~D:Record.Title~}</span><span class="pict-flow-panel-close-btn" data-element-type="panel-close" data-panel-hash="{~D:Record.Hash~}"><span class="pict-flow-panel-close-icon"></span></span></div><div class="pict-flow-panel-content" data-panel-hash="{~D:Record.Hash~}"><div class="pict-flow-panel-tab-pane active" data-tab="properties" data-panel-hash="{~D:Record.Hash~}"></div><div class="pict-flow-panel-tab-pane" data-tab="help" data-panel-hash="{~D:Record.Hash~}" style="display:none;"></div><div class="pict-flow-panel-tab-pane" data-tab="appearance" data-panel-hash="{~D:Record.Hash~}" style="display:none;"></div></div><div class="pict-flow-panel-resize-handle" data-element-type="panel-resize" data-panel-hash="{~D:Record.Hash~}"></div><div class="pict-flow-panel-tabbar" data-panel-hash="{~D:Record.Hash~}"><div class="pict-flow-panel-tab active" data-tab-target="properties" data-panel-hash="{~D:Record.Hash~}">Properties</div><div class="pict-flow-panel-tab" data-tab-target="help" data-panel-hash="{~D:Record.Hash~}" style="display:none;">Help</div><div class="pict-flow-panel-tab" data-tab-target="appearance" data-panel-hash="{~D:Record.Hash~}">Appearance</div></div></div>`
88
+ Template: /*html*/`<div class="pict-flow-panel" xmlns="http://www.w3.org/1999/xhtml"><div class="pict-flow-panel-titlebar" data-element-type="panel-titlebar" data-panel-hash="{~D:Record.Hash~}"><span class="pict-flow-panel-title-text">{~D:Record.Title~}</span><span class="pict-flow-panel-close-btn" data-element-type="panel-close" data-panel-hash="{~D:Record.Hash~}"><span class="pict-flow-panel-close-icon"></span></span></div><div class="pict-flow-panel-content" data-panel-hash="{~D:Record.Hash~}" onpointerdown="event.stopPropagation()" onwheel="event.stopPropagation()"><div class="pict-flow-panel-tab-pane active" data-tab="properties" data-panel-hash="{~D:Record.Hash~}"></div><div class="pict-flow-panel-tab-pane" data-tab="help" data-panel-hash="{~D:Record.Hash~}" style="display:none;"></div><div class="pict-flow-panel-tab-pane" data-tab="appearance" data-panel-hash="{~D:Record.Hash~}" style="display:none;"></div></div><div class="pict-flow-panel-resize-handle" data-element-type="panel-resize" data-panel-hash="{~D:Record.Hash~}"></div><div class="pict-flow-panel-tabbar" data-panel-hash="{~D:Record.Hash~}" onpointerdown="event.stopPropagation()" onwheel="event.stopPropagation()"><div class="pict-flow-panel-tab active" data-tab-target="properties" data-panel-hash="{~D:Record.Hash~}" onclick="_Pict.views['{~D:Record.FlowViewIdentifier~}']._handlePanelTabClick(this, event)">Properties</div><div class="pict-flow-panel-tab" data-tab-target="help" data-panel-hash="{~D:Record.Hash~}" style="display:none;" onclick="_Pict.views['{~D:Record.FlowViewIdentifier~}']._handlePanelTabClick(this, event)">Help</div><div class="pict-flow-panel-tab" data-tab-target="appearance" data-panel-hash="{~D:Record.Hash~}" onclick="_Pict.views['{~D:Record.FlowViewIdentifier~}']._handlePanelTabClick(this, event)">Appearance</div></div></div>`
89
89
  },
90
90
  {
91
91
  Hash: 'Flow-Container-Template',
92
+ // Inline pointer/wheel/contextmenu handlers route to the
93
+ // InteractionManager via the FlowView. Keyboard events stay
94
+ // document-level (no element-level inline equivalent).
92
95
  Template: /*html*/`
93
96
  <div class="pict-flow-container" id="Flow-Wrapper-{~D:Record.ViewIdentifier~}">
94
97
  <div id="Flow-Toolbar-{~D:Record.ViewIdentifier~}"></div>
@@ -96,7 +99,13 @@ const _DefaultConfiguration =
96
99
  <div class="pict-flow-svg-container" id="Flow-SVG-Container-{~D:Record.ViewIdentifier~}">
97
100
  <svg class="pict-flow-svg"
98
101
  id="Flow-SVG-{~D:Record.ViewIdentifier~}"
99
- xmlns="http://www.w3.org/2000/svg">
102
+ xmlns="http://www.w3.org/2000/svg"
103
+ onpointerdown="_Pict.views['{~D:Record.ViewIdentifier~}']._handleSVGPointerDown(event)"
104
+ onpointermove="_Pict.views['{~D:Record.ViewIdentifier~}']._handleSVGPointerMove(event)"
105
+ onpointerup="_Pict.views['{~D:Record.ViewIdentifier~}']._handleSVGPointerUp(event)"
106
+ onpointerleave="_Pict.views['{~D:Record.ViewIdentifier~}']._handleSVGPointerUp(event)"
107
+ onwheel="_Pict.views['{~D:Record.ViewIdentifier~}']._handleSVGWheel(event)"
108
+ oncontextmenu="_Pict.views['{~D:Record.ViewIdentifier~}']._handleSVGContextMenu(event)">
100
109
  <defs>
101
110
  <pattern id="flow-grid-{~D:Record.ViewIdentifier~}"
102
111
  width="20" height="20" patternUnits="userSpaceOnUse">
@@ -351,9 +360,65 @@ class PictViewFlow extends libPictView
351
360
  // Instantiate all remaining services (skips Theme + Noise since already set)
352
361
  this._instantiateServices();
353
362
 
363
+ // Subscribe to the host application's pict-provider-theme so the flow
364
+ // editor's marker arrowhead colors and shape overrides update when the
365
+ // host swaps light/dark or palette themes. CSS variables (--theme-*)
366
+ // re-resolve automatically — only the SVG <marker> defs (which inline
367
+ // fill colors at build time) and ConnectorShapesProvider state need a
368
+ // manual refresh.
369
+ this._subscribeToHostTheme();
370
+
354
371
  return super.onBeforeInitialize();
355
372
  }
356
373
 
374
+ /**
375
+ * If the host application has registered pict-provider-theme, subscribe
376
+ * to its onApply hook so we can refresh anything that doesn't pick up
377
+ * the new --theme-* CSS variables automatically (SVG marker fills,
378
+ * connector shape overrides). No-op when no host theme provider is
379
+ * available — the flow editor still functions with its built-in themes.
380
+ */
381
+ _subscribeToHostTheme()
382
+ {
383
+ let tmpHostTheme = this._resolveHostThemeProvider();
384
+ if (!tmpHostTheme || typeof tmpHostTheme.onApply !== 'function') return;
385
+
386
+ this._HostThemeUnsubscribe = tmpHostTheme.onApply(() =>
387
+ {
388
+ if (this._CSSProvider) this._CSSProvider.registerCSS();
389
+ this._reinjectMarkerDefs();
390
+ if (this.initialRenderComplete) this.renderFlow();
391
+ });
392
+ }
393
+
394
+ /**
395
+ * Locate the host's pict-provider-theme instance. It is normally
396
+ * registered under a stable service hash by the host app; we check
397
+ * common locations so consumers don't have to wire it manually.
398
+ * @returns {Object|null}
399
+ */
400
+ _resolveHostThemeProvider()
401
+ {
402
+ let tmpPict = this.pict;
403
+ if (!tmpPict) return null;
404
+ if (tmpPict.providers)
405
+ {
406
+ let tmpKeys = Object.keys(tmpPict.providers);
407
+ for (let i = 0; i < tmpKeys.length; i++)
408
+ {
409
+ let tmpProvider = tmpPict.providers[tmpKeys[i]];
410
+ if (tmpProvider
411
+ && typeof tmpProvider.onApply === 'function'
412
+ && typeof tmpProvider.applyTheme === 'function'
413
+ && typeof tmpProvider.listThemes === 'function')
414
+ {
415
+ return tmpProvider;
416
+ }
417
+ }
418
+ }
419
+ return null;
420
+ }
421
+
357
422
  onAfterRender(pRenderable, pRenderDestinationAddress, pRecord, pContent)
358
423
  {
359
424
  if (!this.initialRenderComplete)
@@ -1148,6 +1213,122 @@ class PictViewFlow extends libPictView
1148
1213
  {
1149
1214
  return this._PanelManager.updatePanelPosition(pPanelHash, pX, pY);
1150
1215
  }
1216
+
1217
+ // ── Inline-handler bridges (called from template onclick/oninput attrs)
1218
+
1219
+ /**
1220
+ * Handle a click on a panel tab button. Stops propagation so the
1221
+ * underlying SVG doesn't see it, then delegates to the properties
1222
+ * panel view for the actual visibility toggle.
1223
+ *
1224
+ * @param {Element} pTabElement
1225
+ * @param {Event} pEvent
1226
+ */
1227
+ _handlePanelTabClick(pTabElement, pEvent)
1228
+ {
1229
+ if (pEvent && typeof pEvent.stopPropagation === 'function')
1230
+ {
1231
+ pEvent.stopPropagation();
1232
+ }
1233
+ if (this._PropertiesPanelView)
1234
+ {
1235
+ this._PropertiesPanelView.switchPanelTab(pTabElement);
1236
+ }
1237
+ }
1238
+
1239
+ /**
1240
+ * Apply a node property change driven from the appearance editor's
1241
+ * inline `oninput` handler. Stops propagation, then delegates to the
1242
+ * properties panel view.
1243
+ *
1244
+ * @param {string} pNodeHash
1245
+ * @param {string} pPropPath
1246
+ * @param {string} pValue
1247
+ * @param {string} pInputType - 'text' | 'number' | 'color'
1248
+ * @param {Event} [pEvent]
1249
+ */
1250
+ _applyNodePropChange(pNodeHash, pPropPath, pValue, pInputType, pEvent)
1251
+ {
1252
+ if (pEvent && typeof pEvent.stopPropagation === 'function')
1253
+ {
1254
+ pEvent.stopPropagation();
1255
+ }
1256
+ if (this._PropertiesPanelView)
1257
+ {
1258
+ this._PropertiesPanelView._applyNodePropChange(pNodeHash, pPropPath, pValue, pInputType);
1259
+ }
1260
+ }
1261
+
1262
+ /**
1263
+ * Inline-handler bridge — light up port-hint paths matching the given
1264
+ * port (and optionally node) hash. Called from inline `onmouseenter`
1265
+ * on port badges; see PictService-Flow-PortRenderer._wirePortHintHover.
1266
+ *
1267
+ * @param {string|null} pPortHash
1268
+ * @param {string|null} pNodeHash
1269
+ */
1270
+ _activatePortHints(pPortHash, pNodeHash)
1271
+ {
1272
+ this._togglePortHints(pPortHash, pNodeHash, true);
1273
+ }
1274
+
1275
+ /**
1276
+ * Inline-handler bridge — clear port-hint highlights.
1277
+ *
1278
+ * @param {string|null} pPortHash
1279
+ * @param {string|null} pNodeHash
1280
+ */
1281
+ _deactivatePortHints(pPortHash, pNodeHash)
1282
+ {
1283
+ this._togglePortHints(pPortHash, pNodeHash, false);
1284
+ }
1285
+
1286
+ _togglePortHints(pPortHash, pNodeHash, pActive)
1287
+ {
1288
+ let tmpScope = this._SVGElement || document;
1289
+ let tmpSelector = pPortHash
1290
+ ? '.pict-flow-port-hint[data-port-hash="' + pPortHash + '"]'
1291
+ : '.pict-flow-port-hint[data-node-hash="' + pNodeHash + '"]';
1292
+ let tmpHints = tmpScope.querySelectorAll(tmpSelector);
1293
+ for (let i = 0; i < tmpHints.length; i++)
1294
+ {
1295
+ if (pActive)
1296
+ {
1297
+ tmpHints[i].setAttribute('data-active', 'true');
1298
+ }
1299
+ else
1300
+ {
1301
+ tmpHints[i].removeAttribute('data-active');
1302
+ }
1303
+ }
1304
+ }
1305
+
1306
+ // ── SVG inline pointer/wheel bridges ─────────────────────────────────
1307
+
1308
+ _handleSVGPointerDown(pEvent)
1309
+ {
1310
+ if (this._InteractionManager) this._InteractionManager._onPointerDown(pEvent);
1311
+ }
1312
+
1313
+ _handleSVGPointerMove(pEvent)
1314
+ {
1315
+ if (this._InteractionManager) this._InteractionManager._onPointerMove(pEvent);
1316
+ }
1317
+
1318
+ _handleSVGPointerUp(pEvent)
1319
+ {
1320
+ if (this._InteractionManager) this._InteractionManager._onPointerUp(pEvent);
1321
+ }
1322
+
1323
+ _handleSVGWheel(pEvent)
1324
+ {
1325
+ if (this._InteractionManager) this._InteractionManager._onWheel(pEvent);
1326
+ }
1327
+
1328
+ _handleSVGContextMenu(pEvent)
1329
+ {
1330
+ if (this._InteractionManager) this._InteractionManager.handleContextMenu(pEvent);
1331
+ }
1151
1332
  }
1152
1333
 
1153
1334
  module.exports = PictViewFlow;