pict-section-flow 1.4.0 → 2.0.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.
- package/package.json +7 -2
- package/source/Pict-Section-Flow.js +20 -14
- package/source/providers/PictProvider-Flow-Background.js +303 -0
- package/source/providers/PictProvider-Flow-CSS.js +73 -7
- package/source/providers/PictProvider-Flow-Geometry.js +11 -421
- package/source/providers/PictProvider-Flow-Icons.js +12 -0
- package/source/providers/PictProvider-Flow-Layouts.js +107 -0
- package/source/services/PictService-Flow-ConnectionRenderer.js +1 -1
- package/source/services/PictService-Flow-CursorManager.js +113 -0
- package/source/services/PictService-Flow-InteractionManager.js +439 -59
- package/source/services/PictService-Flow-Layout.js +21 -16
- package/source/services/PictService-Flow-PathGenerator.js +30 -417
- package/source/services/PictService-Flow-RenderManager.js +9 -1
- package/source/services/PictService-Flow-ViewportManager.js +102 -0
- package/source/views/PictView-Flow-FloatingToolbar.js +5 -1
- package/source/views/PictView-Flow-Node.js +29 -0
- package/source/views/PictView-Flow-Toolbar.js +50 -3
- package/source/views/PictView-Flow.js +591 -2
- package/.claude/launch.json +0 -11
- package/docs/.nojekyll +0 -0
- package/docs/Architecture.md +0 -163
- package/docs/Custom-Styling.md +0 -275
- package/docs/Data_Model.md +0 -149
- package/docs/Event_System.md +0 -156
- package/docs/Getting_Started.md +0 -237
- package/docs/Implementation_Reference.md +0 -528
- package/docs/Layout_Persistence.md +0 -117
- package/docs/README.md +0 -103
- package/docs/Theme_Integration.md +0 -150
- package/docs/_brand.json +0 -18
- package/docs/_cover.md +0 -17
- package/docs/_playground.json +0 -24
- package/docs/_sidebar.md +0 -57
- package/docs/_topbar.md +0 -8
- package/docs/_version.json +0 -7
- package/docs/api/PictFlowCard.md +0 -216
- package/docs/api/PictFlowCardPropertiesPanel.md +0 -235
- package/docs/api/addConnection.md +0 -101
- package/docs/api/addNode.md +0 -137
- package/docs/api/autoLayout.md +0 -77
- package/docs/api/getFlowData.md +0 -112
- package/docs/api/marshalToView.md +0 -95
- package/docs/api/openPanel.md +0 -128
- package/docs/api/registerHandler.md +0 -174
- package/docs/api/registerNodeType.md +0 -142
- package/docs/api/removeConnection.md +0 -57
- package/docs/api/removeNode.md +0 -80
- package/docs/api/saveLayout.md +0 -152
- package/docs/api/screenToSVGCoords.md +0 -68
- package/docs/api/selectNode.md +0 -116
- package/docs/api/setTheme.md +0 -168
- package/docs/api/setZoom.md +0 -97
- package/docs/api/toggleFullscreen.md +0 -68
- package/docs/card-help/EACH.md +0 -19
- package/docs/card-help/FREAD.md +0 -24
- package/docs/card-help/FWRITE.md +0 -24
- package/docs/card-help/GET.md +0 -22
- package/docs/card-help/ITE.md +0 -23
- package/docs/card-help/LOG.md +0 -23
- package/docs/card-help/NOTE.md +0 -17
- package/docs/card-help/PREV.md +0 -18
- package/docs/card-help/SET.md +0 -27
- package/docs/card-help/SPKL.md +0 -22
- package/docs/card-help/STAT.md +0 -23
- package/docs/card-help/SW.md +0 -25
- package/docs/diagrams/architecture-at-a-glance.excalidraw +0 -4270
- package/docs/diagrams/architecture-at-a-glance.mmd +0 -30
- package/docs/diagrams/architecture-at-a-glance.svg +0 -2
- package/docs/diagrams/data-flow.excalidraw +0 -1451
- package/docs/diagrams/data-flow.mmd +0 -17
- package/docs/diagrams/data-flow.svg +0 -2
- package/docs/diagrams/high-level-design.excalidraw +0 -5767
- package/docs/diagrams/high-level-design.mmd +0 -86
- package/docs/diagrams/high-level-design.svg +0 -2
- package/docs/diagrams/relationships.excalidraw +0 -3852
- package/docs/diagrams/relationships.mmd +0 -9
- package/docs/diagrams/relationships.svg +0 -2
- package/docs/diagrams/service-initialization-sequence.excalidraw +0 -1466
- package/docs/diagrams/service-initialization-sequence.mmd +0 -19
- package/docs/diagrams/service-initialization-sequence.svg +0 -2
- package/docs/diagrams/svg-layer-structure.excalidraw +0 -1060
- package/docs/diagrams/svg-layer-structure.mmd +0 -18
- package/docs/diagrams/svg-layer-structure.svg +0 -2
- package/docs/examples/README.md +0 -9
- package/docs/examples/simple_cards/README.md +0 -677
- package/docs/examples/simple_cards/css/flowexample.css +0 -65
- package/docs/examples/simple_cards/index.html +0 -32
- package/docs/examples/simple_cards/js/pict.min.js +0 -12
- package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +0 -1
- package/docs/index.html +0 -38
- package/docs/playground/app.json +0 -6
- package/docs/playground/appdata.json +0 -85
- package/docs/playground/application.js +0 -23
- package/docs/playground/pict.json +0 -17
- package/docs/playground/runtime/pict-application.min.js +0 -2
- package/docs/playground/runtime/pict-section-flow.min.js +0 -2
- package/docs/playground/runtime/pict-section-modal.min.js +0 -2
- package/docs/playground/runtime/pict.min.js +0 -12
- package/docs/retold-catalog.json +0 -244
- package/docs/retold-keyword-index.json +0 -26028
- package/example_applications/simple_cards/css/flowexample.css +0 -65
- package/example_applications/simple_cards/html/index.html +0 -32
- package/example_applications/simple_cards/package.json +0 -52
- package/example_applications/simple_cards/source/Pict-Application-FlowExample-Configuration.json +0 -15
- package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +0 -539
- package/example_applications/simple_cards/source/card-help-content.js +0 -16
- package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +0 -38
- package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +0 -44
- package/example_applications/simple_cards/source/cards/FlowCard-Each.js +0 -38
- package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +0 -56
- package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +0 -50
- package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +0 -37
- package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +0 -49
- package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +0 -55
- package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +0 -97
- package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +0 -100
- package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +0 -46
- package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +0 -39
- package/example_applications/simple_cards/source/providers/PictRouter-FlowExample-Configuration.json +0 -22
- package/example_applications/simple_cards/source/sample-flows.js +0 -410
- package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +0 -184
- package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +0 -77
- package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +0 -325
- package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +0 -59
- package/example_applications/simple_cards/source/views/PictView-FlowExample-Layout.js +0 -90
- package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +0 -453
- package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +0 -95
- package/scripts/generate-card-help.js +0 -214
- package/source/providers/edges/Edge-Bezier.js +0 -41
- package/source/providers/edges/Edge-Orthogonal.js +0 -37
- package/source/providers/edges/Edge-OrthogonalSnap.js +0 -72
- package/source/providers/edges/Edge-Perimeter-Linear.js +0 -31
- package/source/providers/edges/Edge-Perimeter-Orthogonal.js +0 -39
- package/source/providers/edges/Edge-Perimeter.js +0 -48
- package/source/providers/edges/Edge-PerimeterMath.js +0 -92
- package/source/providers/edges/Edge-Straight.js +0 -24
- package/source/providers/layouts/Layout-Circular.js +0 -203
- package/source/providers/layouts/Layout-Coerce.js +0 -40
- package/source/providers/layouts/Layout-Columnar.js +0 -134
- package/source/providers/layouts/Layout-Custom.js +0 -27
- package/source/providers/layouts/Layout-ForcedFromCenter.js +0 -256
- package/source/providers/layouts/Layout-Grid.js +0 -134
- package/source/providers/layouts/Layout-Layered.js +0 -155
- package/source/providers/layouts/Layout-Rank.js +0 -141
- package/source/providers/layouts/Layout-Staggered.js +0 -131
- package/source/providers/layouts/Layout-Tabular.js +0 -94
- package/test/CardPalette_tests.js +0 -43
- package/test/ConnectionHandleManager_tests.js +0 -717
- package/test/ConnectionRenderer_tests.js +0 -591
- package/test/ConnectionStyle_tests.js +0 -90
- package/test/DataManager_tests.js +0 -859
- package/test/Geometry_tests.js +0 -767
- package/test/InteractionManager_tests.js +0 -279
- package/test/Layout_tests.js +0 -1604
- package/test/NodeView_tests.js +0 -66
- package/test/PanelManager_tests.js +0 -172
- package/test/PathGenerator_tests.js +0 -978
- package/test/PortRenderer_tests.js +0 -376
- package/test/RenderManager_tests.js +0 -756
- package/test/Renderer_tests.js +0 -133
- package/test/SelectionManager_tests.js +0 -185
- package/test/StylePresets_tests.js +0 -153
- package/test/ToolbarExtraButtons_tests.js +0 -138
- package/test/UndirectedConnections_tests.js +0 -70
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pict-section-flow",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Pict Section Flow Diagram",
|
|
5
5
|
"main": "source/Pict-Section-Flow.js",
|
|
6
6
|
"scripts": {
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"fable-serviceproviderbase": "^3.0.19",
|
|
17
17
|
"pict-provider": "^1.0.13",
|
|
18
|
+
"pict-provider-graphgeometry": "^1.0.0",
|
|
19
|
+
"pict-provider-graphlayout": "^1.0.0",
|
|
18
20
|
"pict-section-form": "^1.0.199",
|
|
19
21
|
"pict-view": "^1.0.68"
|
|
20
22
|
},
|
|
@@ -25,5 +27,8 @@
|
|
|
25
27
|
"pict-docuserve": "^1.4.4",
|
|
26
28
|
"pict-router": "^1.0.10",
|
|
27
29
|
"quackage": "^1.3.0"
|
|
28
|
-
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"source"
|
|
33
|
+
]
|
|
29
34
|
}
|
|
@@ -35,30 +35,36 @@ module.exports.PictProviderFlowCSS = require('./providers/PictProvider-Flow-CSS.
|
|
|
35
35
|
module.exports.PictProviderFlowIcons = require('./providers/PictProvider-Flow-Icons.js');
|
|
36
36
|
module.exports.PictProviderFlowConnectorShapes = require('./providers/PictProvider-Flow-ConnectorShapes.js');
|
|
37
37
|
|
|
38
|
+
// Layout algorithm and edge-theme descriptors now live in the standalone
|
|
39
|
+
// pict-provider-graphlayout module. They are re-exported here unchanged so the
|
|
40
|
+
// historical pict-section-flow export surface (LayoutAlgorithms / EdgeThemes) is
|
|
41
|
+
// preserved for consumers.
|
|
42
|
+
const libPictProviderGraphLayout = require('pict-provider-graphlayout');
|
|
43
|
+
|
|
38
44
|
// Layout algorithm descriptors (consumers can register custom algorithms via
|
|
39
45
|
// _LayoutService.registerAlgorithm({ Name, Apply, DefaultParameters, ParameterSchema }))
|
|
40
46
|
module.exports.LayoutAlgorithms =
|
|
41
47
|
{
|
|
42
|
-
Custom:
|
|
43
|
-
Layered:
|
|
44
|
-
ForcedFromCenter:
|
|
45
|
-
Grid:
|
|
46
|
-
Circular:
|
|
47
|
-
Tabular:
|
|
48
|
-
Columnar:
|
|
48
|
+
Custom: libPictProviderGraphLayout.Layouts.Custom,
|
|
49
|
+
Layered: libPictProviderGraphLayout.Layouts.Layered,
|
|
50
|
+
ForcedFromCenter: libPictProviderGraphLayout.Layouts.ForcedFromCenter,
|
|
51
|
+
Grid: libPictProviderGraphLayout.Layouts.Grid,
|
|
52
|
+
Circular: libPictProviderGraphLayout.Layouts.Circular,
|
|
53
|
+
Tabular: libPictProviderGraphLayout.Layouts.Tabular,
|
|
54
|
+
Columnar: libPictProviderGraphLayout.Layouts.Columnar
|
|
49
55
|
};
|
|
50
56
|
|
|
51
57
|
// Edge-theme descriptors (consumers can register custom edge themes via
|
|
52
58
|
// _LayoutService.registerEdgeTheme({ Name, GeneratePath, AdjustLayout?, ResolveAttachment?, ... }))
|
|
53
59
|
module.exports.EdgeThemes =
|
|
54
60
|
{
|
|
55
|
-
Bezier:
|
|
56
|
-
Orthogonal:
|
|
57
|
-
Straight:
|
|
58
|
-
OrthogonalSnap:
|
|
59
|
-
Perimeter:
|
|
60
|
-
PerimeterLinear:
|
|
61
|
-
PerimeterOrthogonal:
|
|
61
|
+
Bezier: libPictProviderGraphLayout.Edges.Bezier,
|
|
62
|
+
Orthogonal: libPictProviderGraphLayout.Edges.Orthogonal,
|
|
63
|
+
Straight: libPictProviderGraphLayout.Edges.Straight,
|
|
64
|
+
OrthogonalSnap: libPictProviderGraphLayout.Edges.OrthogonalSnap,
|
|
65
|
+
Perimeter: libPictProviderGraphLayout.Edges.Perimeter,
|
|
66
|
+
PerimeterLinear: libPictProviderGraphLayout.Edges.PerimeterLinear,
|
|
67
|
+
PerimeterOrthogonal: libPictProviderGraphLayout.Edges.PerimeterOrthogonal
|
|
62
68
|
};
|
|
63
69
|
|
|
64
70
|
// FlowCard base class
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
const libPictProvider = require('pict-provider');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PictProvider-Flow-Background
|
|
5
|
+
*
|
|
6
|
+
* Native canvas background for the flow diagram. The container template ships a
|
|
7
|
+
* default grid; this provider lets a host pick a background through config or
|
|
8
|
+
* ViewState instead of hand-painting the SVG from outside (which moodboard used
|
|
9
|
+
* to do). When no background is configured the provider is a no-op and the
|
|
10
|
+
* template grid stands, so existing diagrams are unchanged.
|
|
11
|
+
*
|
|
12
|
+
* Background shape:
|
|
13
|
+
* { Style: 'grid' | 'dots' | 'graph' | 'solid' | 'image' | 'none',
|
|
14
|
+
* Color?: string, // line / dot color (minor lines for 'graph')
|
|
15
|
+
* MajorColor?: string, // 'graph' only: the heavier every-Nth line color
|
|
16
|
+
* Paper?: string, // grid/dots/graph: solid fill painted behind the pattern
|
|
17
|
+
* Image?: string,
|
|
18
|
+
* GridSize?: number, // cell spacing (minor cell for 'graph')
|
|
19
|
+
* MajorEvery?: number, // 'graph' only: heavier line every N cells (default 10)
|
|
20
|
+
* DotSize?: number,
|
|
21
|
+
* LineWidth?: number, // grid/graph minor line width
|
|
22
|
+
* MajorLineWidth?: number } // 'graph' major line width
|
|
23
|
+
*
|
|
24
|
+
* Named presets (smaller / lighter / darker dots, grids, blue graph paper,
|
|
25
|
+
* blueprint, ...) live in PRESETS and are fetched with preset(name).
|
|
26
|
+
*
|
|
27
|
+
* The markup generators are pure (string in, string out) and unit tested; only
|
|
28
|
+
* apply() touches the DOM.
|
|
29
|
+
*/
|
|
30
|
+
const _ProviderConfiguration =
|
|
31
|
+
{
|
|
32
|
+
ProviderIdentifier: 'PictProviderFlowBackground'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const _DEFAULT_GRID_SIZE = 20;
|
|
36
|
+
const _DEFAULT_DOT_SIZE = 2;
|
|
37
|
+
const _DEFAULT_DOT_FILL = 'var(--theme-color-text-secondary, #b0b0b0)';
|
|
38
|
+
const _DEFAULT_MAJOR_EVERY = 10;
|
|
39
|
+
// Concrete fallback line color for 'graph' (var() does not resolve in an SVG
|
|
40
|
+
// presentation attribute, and graph lines are drawn with stroke="...").
|
|
41
|
+
const _DEFAULT_GRID_LINE = '#cbd5e1';
|
|
42
|
+
|
|
43
|
+
// Named, ready-to-use backgrounds. preset(name) returns a fresh clone so callers
|
|
44
|
+
// can tweak one without mutating the catalog.
|
|
45
|
+
const _PRESETS =
|
|
46
|
+
{
|
|
47
|
+
'dots': { Style: 'dots', GridSize: 20, DotSize: 2 },
|
|
48
|
+
'dots-small': { Style: 'dots', GridSize: 14, DotSize: 1 },
|
|
49
|
+
'dots-light': { Style: 'dots', GridSize: 20, DotSize: 2, Color: '#dcdcdc' },
|
|
50
|
+
'dots-dark': { Style: 'dots', GridSize: 22, DotSize: 2.4, Color: '#64748b' },
|
|
51
|
+
'grid': { Style: 'grid', GridSize: 20 },
|
|
52
|
+
'grid-fine': { Style: 'grid', GridSize: 12, Color: '#e2e8f0' },
|
|
53
|
+
// "10-square grid with light and more-light-blue lines": minor light-blue lines
|
|
54
|
+
// every 16px, a heavier sky-blue line every 10 cells, on white paper.
|
|
55
|
+
'graph-blue': { Style: 'graph', GridSize: 16, MajorEvery: 10, Color: '#dbeafe', MajorColor: '#93c5fd', LineWidth: 1, MajorLineWidth: 1.5, Paper: '#ffffff' },
|
|
56
|
+
// Classic dark blueprint: light-blue lines on deep navy paper.
|
|
57
|
+
'blueprint': { Style: 'graph', GridSize: 16, MajorEvery: 10, Color: '#3b6ea5', MajorColor: '#6fa8dc', LineWidth: 1, MajorLineWidth: 1.5, Paper: '#0f2a4a' },
|
|
58
|
+
'solid': { Style: 'solid', Color: '#faf7f2' },
|
|
59
|
+
'none': { Style: 'none' }
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
class PictProviderFlowBackground extends libPictProvider
|
|
63
|
+
{
|
|
64
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
65
|
+
{
|
|
66
|
+
let tmpOptions = Object.assign({}, _ProviderConfiguration, pOptions);
|
|
67
|
+
super(pFable, tmpOptions, pServiceHash);
|
|
68
|
+
|
|
69
|
+
this.serviceType = 'PictProviderFlowBackground';
|
|
70
|
+
|
|
71
|
+
this._FlowView = (pOptions && pOptions.FlowView) ? pOptions.FlowView : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The pattern element id for a view + style.
|
|
76
|
+
* @param {string} pViewIdentifier
|
|
77
|
+
* @param {string} pStyle
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
patternId(pViewIdentifier, pStyle)
|
|
81
|
+
{
|
|
82
|
+
return `flow-bg-${pStyle}-${pViewIdentifier}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Generate the <pattern> markup for grid/dots backgrounds. Returns '' for
|
|
87
|
+
* styles that need no pattern (solid, image, none) or when nothing is set.
|
|
88
|
+
* Pure.
|
|
89
|
+
* @param {string} pViewIdentifier
|
|
90
|
+
* @param {Object} pBackground
|
|
91
|
+
* @returns {string}
|
|
92
|
+
*/
|
|
93
|
+
generatePatternMarkup(pViewIdentifier, pBackground)
|
|
94
|
+
{
|
|
95
|
+
if (!pBackground || !pBackground.Style)
|
|
96
|
+
{
|
|
97
|
+
return '';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Optional solid fill painted behind the pattern (paper color). Empty unless set.
|
|
101
|
+
let tmpPaper = function (pW, pH)
|
|
102
|
+
{
|
|
103
|
+
return pBackground.Paper ? `<rect width="${pW}" height="${pH}" fill="${pBackground.Paper}" />` : '';
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
if (pBackground.Style === 'grid')
|
|
107
|
+
{
|
|
108
|
+
let tmpSize = (typeof pBackground.GridSize === 'number') ? pBackground.GridSize : _DEFAULT_GRID_SIZE;
|
|
109
|
+
// With no explicit Color the lines inherit the theme via the existing
|
|
110
|
+
// CSS class, matching the template grid; a Color overrides inline.
|
|
111
|
+
let tmpStroke = pBackground.Color ? ` style="stroke:${pBackground.Color}"` : '';
|
|
112
|
+
let tmpWidth = (typeof pBackground.LineWidth === 'number') ? ` stroke-width="${pBackground.LineWidth}"` : '';
|
|
113
|
+
let tmpId = this.patternId(pViewIdentifier, 'grid');
|
|
114
|
+
return `<pattern id="${tmpId}" width="${tmpSize}" height="${tmpSize}" patternUnits="userSpaceOnUse">`
|
|
115
|
+
+ tmpPaper(tmpSize, tmpSize)
|
|
116
|
+
+ `<line x1="${tmpSize}" y1="0" x2="${tmpSize}" y2="${tmpSize}" class="pict-flow-grid-pattern"${tmpStroke}${tmpWidth} />`
|
|
117
|
+
+ `<line x1="0" y1="${tmpSize}" x2="${tmpSize}" y2="${tmpSize}" class="pict-flow-grid-pattern"${tmpStroke}${tmpWidth} />`
|
|
118
|
+
+ `</pattern>`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (pBackground.Style === 'dots')
|
|
122
|
+
{
|
|
123
|
+
let tmpSize = (typeof pBackground.GridSize === 'number') ? pBackground.GridSize : _DEFAULT_GRID_SIZE;
|
|
124
|
+
let tmpDot = (typeof pBackground.DotSize === 'number') ? pBackground.DotSize : _DEFAULT_DOT_SIZE;
|
|
125
|
+
let tmpFill = pBackground.Color ? pBackground.Color : _DEFAULT_DOT_FILL;
|
|
126
|
+
let tmpId = this.patternId(pViewIdentifier, 'dots');
|
|
127
|
+
return `<pattern id="${tmpId}" width="${tmpSize}" height="${tmpSize}" patternUnits="userSpaceOnUse">`
|
|
128
|
+
+ tmpPaper(tmpSize, tmpSize)
|
|
129
|
+
+ `<circle cx="${tmpSize / 2}" cy="${tmpSize / 2}" r="${tmpDot}" fill="${tmpFill}" />`
|
|
130
|
+
+ `</pattern>`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (pBackground.Style === 'graph')
|
|
134
|
+
{
|
|
135
|
+
// Graph paper: a fine minor grid tiled inside a heavier major grid drawn
|
|
136
|
+
// every MajorEvery cells. Two patterns — the major one fills itself with the
|
|
137
|
+
// minor pattern, then strokes the heavier lines on top.
|
|
138
|
+
let tmpMinor = (typeof pBackground.GridSize === 'number') ? pBackground.GridSize : _DEFAULT_GRID_SIZE;
|
|
139
|
+
let tmpMajorEvery = (typeof pBackground.MajorEvery === 'number') ? pBackground.MajorEvery : _DEFAULT_MAJOR_EVERY;
|
|
140
|
+
let tmpMajor = tmpMinor * tmpMajorEvery;
|
|
141
|
+
let tmpMinorColor = pBackground.Color || _DEFAULT_GRID_LINE;
|
|
142
|
+
let tmpMajorColor = pBackground.MajorColor || tmpMinorColor;
|
|
143
|
+
let tmpMinorWidth = (typeof pBackground.LineWidth === 'number') ? pBackground.LineWidth : 1;
|
|
144
|
+
let tmpMajorWidth = (typeof pBackground.MajorLineWidth === 'number') ? pBackground.MajorLineWidth : 1.5;
|
|
145
|
+
let tmpMinorId = this.patternId(pViewIdentifier, 'graph-minor');
|
|
146
|
+
let tmpId = this.patternId(pViewIdentifier, 'graph');
|
|
147
|
+
|
|
148
|
+
let tmpMinorPattern = `<pattern id="${tmpMinorId}" width="${tmpMinor}" height="${tmpMinor}" patternUnits="userSpaceOnUse">`
|
|
149
|
+
+ `<line x1="${tmpMinor}" y1="0" x2="${tmpMinor}" y2="${tmpMinor}" stroke="${tmpMinorColor}" stroke-width="${tmpMinorWidth}" />`
|
|
150
|
+
+ `<line x1="0" y1="${tmpMinor}" x2="${tmpMinor}" y2="${tmpMinor}" stroke="${tmpMinorColor}" stroke-width="${tmpMinorWidth}" />`
|
|
151
|
+
+ `</pattern>`;
|
|
152
|
+
let tmpMajorPattern = `<pattern id="${tmpId}" width="${tmpMajor}" height="${tmpMajor}" patternUnits="userSpaceOnUse">`
|
|
153
|
+
+ tmpPaper(tmpMajor, tmpMajor)
|
|
154
|
+
+ `<rect width="${tmpMajor}" height="${tmpMajor}" fill="url(#${tmpMinorId})" />`
|
|
155
|
+
+ `<line x1="${tmpMajor}" y1="0" x2="${tmpMajor}" y2="${tmpMajor}" stroke="${tmpMajorColor}" stroke-width="${tmpMajorWidth}" />`
|
|
156
|
+
+ `<line x1="0" y1="${tmpMajor}" x2="${tmpMajor}" y2="${tmpMajor}" stroke="${tmpMajorColor}" stroke-width="${tmpMajorWidth}" />`
|
|
157
|
+
+ `</pattern>`;
|
|
158
|
+
return tmpMinorPattern + tmpMajorPattern;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return '';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Resolve the fill value for the background rect. Pure.
|
|
166
|
+
* grid/dots -> url(#pattern); solid -> Color; image -> url(Image);
|
|
167
|
+
* none -> 'none'. Returns null when nothing is configured.
|
|
168
|
+
* @param {string} pViewIdentifier
|
|
169
|
+
* @param {Object} pBackground
|
|
170
|
+
* @returns {string|null}
|
|
171
|
+
*/
|
|
172
|
+
resolveFill(pViewIdentifier, pBackground)
|
|
173
|
+
{
|
|
174
|
+
if (!pBackground || !pBackground.Style)
|
|
175
|
+
{
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
switch (pBackground.Style)
|
|
180
|
+
{
|
|
181
|
+
case 'grid': return `url(#${this.patternId(pViewIdentifier, 'grid')})`;
|
|
182
|
+
case 'dots': return `url(#${this.patternId(pViewIdentifier, 'dots')})`;
|
|
183
|
+
case 'graph': return `url(#${this.patternId(pViewIdentifier, 'graph')})`;
|
|
184
|
+
case 'solid': return pBackground.Color || 'transparent';
|
|
185
|
+
case 'image': return pBackground.Image ? `url(${pBackground.Image})` : 'none';
|
|
186
|
+
case 'none': return 'none';
|
|
187
|
+
default: return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Resolve the effective background for a flow view: ViewState wins, then the
|
|
193
|
+
* static option. Returns null/false when none is configured.
|
|
194
|
+
* @param {Object} pFlowView
|
|
195
|
+
*/
|
|
196
|
+
resolveBackground(pFlowView)
|
|
197
|
+
{
|
|
198
|
+
if (!pFlowView)
|
|
199
|
+
{
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
let tmpViewStateBackground = (pFlowView._FlowData && pFlowView._FlowData.ViewState)
|
|
203
|
+
? pFlowView._FlowData.ViewState.Background
|
|
204
|
+
: null;
|
|
205
|
+
if (tmpViewStateBackground)
|
|
206
|
+
{
|
|
207
|
+
return tmpViewStateBackground;
|
|
208
|
+
}
|
|
209
|
+
return (pFlowView.options && pFlowView.options.Background) ? pFlowView.options.Background : null;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Fetch a named background preset as a fresh object (safe to tweak / store on
|
|
214
|
+
* ViewState). Unknown names return null.
|
|
215
|
+
* @param {string} pName
|
|
216
|
+
* @returns {Object|null}
|
|
217
|
+
*/
|
|
218
|
+
preset(pName)
|
|
219
|
+
{
|
|
220
|
+
let tmpPreset = _PRESETS[pName];
|
|
221
|
+
return tmpPreset ? JSON.parse(JSON.stringify(tmpPreset)) : null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* The available preset names, in catalog order.
|
|
226
|
+
* @returns {string[]}
|
|
227
|
+
*/
|
|
228
|
+
presetNames()
|
|
229
|
+
{
|
|
230
|
+
return Object.keys(_PRESETS);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Apply the configured background to the live SVG. No-op when nothing is
|
|
235
|
+
* configured (the template grid stands). DOM-touching; verified in browser.
|
|
236
|
+
* @param {Object} [pFlowView]
|
|
237
|
+
* @returns {boolean} true when a background was applied
|
|
238
|
+
*/
|
|
239
|
+
apply(pFlowView)
|
|
240
|
+
{
|
|
241
|
+
let tmpFlowView = pFlowView || this._FlowView;
|
|
242
|
+
if (!tmpFlowView || !tmpFlowView._SVGElement)
|
|
243
|
+
{
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
let tmpBackground = this.resolveBackground(tmpFlowView);
|
|
248
|
+
if (!tmpBackground || !tmpBackground.Style)
|
|
249
|
+
{
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
let tmpViewIdentifier = tmpFlowView.options.ViewIdentifier;
|
|
254
|
+
let tmpSVG = tmpFlowView._SVGElement;
|
|
255
|
+
|
|
256
|
+
// Replace any pattern we previously injected, then add the new one.
|
|
257
|
+
let tmpDefs = tmpSVG.querySelector('defs');
|
|
258
|
+
if (tmpDefs)
|
|
259
|
+
{
|
|
260
|
+
let tmpOld = tmpDefs.querySelectorAll('[data-flow-bg-pattern]');
|
|
261
|
+
for (let i = 0; i < tmpOld.length; i++)
|
|
262
|
+
{
|
|
263
|
+
tmpOld[i].remove();
|
|
264
|
+
}
|
|
265
|
+
let tmpMarkup = this.generatePatternMarkup(tmpViewIdentifier, tmpBackground);
|
|
266
|
+
if (tmpMarkup)
|
|
267
|
+
{
|
|
268
|
+
let tmpScratch = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
269
|
+
tmpScratch.innerHTML = tmpMarkup;
|
|
270
|
+
while (tmpScratch.firstChild)
|
|
271
|
+
{
|
|
272
|
+
let tmpChild = tmpScratch.firstChild;
|
|
273
|
+
if (tmpChild.setAttribute)
|
|
274
|
+
{
|
|
275
|
+
tmpChild.setAttribute('data-flow-bg-pattern', 'true');
|
|
276
|
+
}
|
|
277
|
+
tmpDefs.appendChild(tmpChild);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
let tmpFill = this.resolveFill(tmpViewIdentifier, tmpBackground);
|
|
283
|
+
let tmpRect = tmpSVG.querySelector('.pict-flow-grid-background');
|
|
284
|
+
if (tmpRect && tmpFill !== null)
|
|
285
|
+
{
|
|
286
|
+
tmpRect.setAttribute('fill', tmpFill);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// A solid color also tints the container behind the (transparent) rect.
|
|
290
|
+
let tmpContainer = (typeof tmpSVG.closest === 'function') ? tmpSVG.closest('.pict-flow-svg-container') : null;
|
|
291
|
+
if (tmpContainer)
|
|
292
|
+
{
|
|
293
|
+
tmpContainer.style.backgroundColor = (tmpBackground.Style === 'solid' && tmpBackground.Color) ? tmpBackground.Color : '';
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
module.exports = PictProviderFlowBackground;
|
|
301
|
+
|
|
302
|
+
module.exports.default_configuration = _ProviderConfiguration;
|
|
303
|
+
module.exports.PRESETS = _PRESETS;
|
|
@@ -205,16 +205,19 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
205
205
|
.pict-flow-svg {
|
|
206
206
|
width: 100%;
|
|
207
207
|
height: 100%;
|
|
208
|
-
cursor:
|
|
208
|
+
cursor: default;
|
|
209
209
|
user-select: none;
|
|
210
210
|
-webkit-user-select: none;
|
|
211
211
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
212
|
+
/* The canvas cursor is owned by the CursorManager: it sets data-flow-cursor
|
|
213
|
+
on the SVG from the interaction state + view mode, and these map the
|
|
214
|
+
tokens to real cursors. Element-scoped hover cursors (ports, handles,
|
|
215
|
+
panel chrome, toolbar buttons) still win for their own elements. */
|
|
216
|
+
.pict-flow-svg[data-flow-cursor="grab"] { cursor: grab; }
|
|
217
|
+
.pict-flow-svg[data-flow-cursor="grabbing"] { cursor: grabbing; }
|
|
218
|
+
.pict-flow-svg[data-flow-cursor="crosshair"] { cursor: crosshair; }
|
|
219
|
+
.pict-flow-svg[data-flow-cursor="resize"] { cursor: nwse-resize; }
|
|
220
|
+
.pict-flow-svg[data-flow-cursor="default"] { cursor: default; }
|
|
218
221
|
.pict-flow-grid-pattern line {
|
|
219
222
|
stroke: var(--pf-grid-stroke);
|
|
220
223
|
stroke-width: 0.5;
|
|
@@ -1307,6 +1310,33 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
1307
1310
|
background-color: var(--pf-button-active-bg);
|
|
1308
1311
|
border-color: var(--pf-button-hover-border);
|
|
1309
1312
|
}
|
|
1313
|
+
/* Toggle-state LED: a status dot in the corner of a toggle button (one marked
|
|
1314
|
+
Toggle:true). Action buttons render no LED; a toggle shows an empty outline
|
|
1315
|
+
when off and a filled green dot when on (the .active class). Works on the
|
|
1316
|
+
docked and floating toolbars. */
|
|
1317
|
+
.pict-flow-toolbar-btn, .pict-flow-floating-btn {
|
|
1318
|
+
position: relative;
|
|
1319
|
+
}
|
|
1320
|
+
.pict-flow-toolbar-btn-led {
|
|
1321
|
+
display: none;
|
|
1322
|
+
position: absolute;
|
|
1323
|
+
right: 2px;
|
|
1324
|
+
bottom: 2px;
|
|
1325
|
+
width: 7px;
|
|
1326
|
+
height: 7px;
|
|
1327
|
+
box-sizing: border-box;
|
|
1328
|
+
border-radius: 50%;
|
|
1329
|
+
border: 1.5px solid var(--pf-button-border, #c2cad6);
|
|
1330
|
+
background: transparent;
|
|
1331
|
+
pointer-events: none;
|
|
1332
|
+
}
|
|
1333
|
+
.pict-flow-toolbar-btn-toggle .pict-flow-toolbar-btn-led {
|
|
1334
|
+
display: block;
|
|
1335
|
+
}
|
|
1336
|
+
.pict-flow-toolbar-btn-toggle.pict-flow-toolbar-btn-active .pict-flow-toolbar-btn-led {
|
|
1337
|
+
background: var(--theme-color-status-success, #27ae60);
|
|
1338
|
+
border-color: var(--theme-color-status-success, #27ae60);
|
|
1339
|
+
}
|
|
1310
1340
|
/* An icon-only host button (ToolbarExtraButtons with no Label) renders an empty text span. */
|
|
1311
1341
|
.pict-flow-toolbar-btn-text:empty {
|
|
1312
1342
|
display: none;
|
|
@@ -2019,6 +2049,12 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
2019
2049
|
// Remove existing CSS first so we can re-register with updated theme overrides
|
|
2020
2050
|
this.fable.CSSMap.removeCSS('PictSectionFlow-CSS');
|
|
2021
2051
|
this.fable.CSSMap.addCSS('PictSectionFlow-CSS', this.generateCSS(), 500, 'PictProviderFlowCSS');
|
|
2052
|
+
|
|
2053
|
+
// Supplemental CSS (read-only chrome hiding + content frame), at a
|
|
2054
|
+
// priority above the base so the hides win.
|
|
2055
|
+
this.fable.CSSMap.removeCSS('PictSectionFlow-Supplemental-CSS');
|
|
2056
|
+
this.fable.CSSMap.addCSS('PictSectionFlow-Supplemental-CSS', this._supplementalCSS(), 502, 'PictProviderFlowCSS');
|
|
2057
|
+
|
|
2022
2058
|
// Re-inject into the DOM to apply the updated CSS
|
|
2023
2059
|
this.fable.CSSMap.injectCSS();
|
|
2024
2060
|
}
|
|
@@ -2053,6 +2089,36 @@ class PictProviderFlowCSS extends libFableServiceProviderBase
|
|
|
2053
2089
|
this.fable.CSSMap.addCSS('PictSectionFlow-Renderer-CSS', tmpCSS, 501, 'PictProviderFlowCSS');
|
|
2054
2090
|
this.fable.CSSMap.injectCSS();
|
|
2055
2091
|
}
|
|
2092
|
+
|
|
2093
|
+
/**
|
|
2094
|
+
* Supplemental CSS: hides editing chrome when the container carries the
|
|
2095
|
+
* 'pict-flow-readonly' class (set by PictView-Flow.setReadOnly), and styles
|
|
2096
|
+
* the content-frame rectangle. Replaces the ad-hoc CSS consumers (e.g.
|
|
2097
|
+
* moodboard) used to inject for a read-only look or a board frame.
|
|
2098
|
+
* @returns {string}
|
|
2099
|
+
*/
|
|
2100
|
+
_supplementalCSS()
|
|
2101
|
+
{
|
|
2102
|
+
return /*css*/`
|
|
2103
|
+
.pict-flow-readonly .pict-flow-port,
|
|
2104
|
+
.pict-flow-readonly .pict-flow-port-hint,
|
|
2105
|
+
.pict-flow-readonly .pict-flow-node-resize-handle { display: none; }
|
|
2106
|
+
.pict-flow-readonly [data-flow-action="add-node"],
|
|
2107
|
+
.pict-flow-readonly [data-flow-action="delete-selected"],
|
|
2108
|
+
.pict-flow-readonly [data-flow-action="cards-popup"] { display: none; }
|
|
2109
|
+
.pict-flow-frame { fill: none; stroke: var(--theme-color-border, #9aa3ab); stroke-width: 1.5; stroke-dasharray: 8 6; pointer-events: none; }
|
|
2110
|
+
.pict-flow-frame-handle { fill: var(--theme-color-background-panel, #ffffff); stroke: var(--theme-color-brand-primary, #2e7d74); stroke-width: 1.5; }
|
|
2111
|
+
.pict-flow-frame-handle:hover { fill: var(--theme-color-brand-primary, #2e7d74); }
|
|
2112
|
+
.pict-flow-frame-handle-n, .pict-flow-frame-handle-s { cursor: ns-resize; }
|
|
2113
|
+
.pict-flow-frame-handle-e, .pict-flow-frame-handle-w { cursor: ew-resize; }
|
|
2114
|
+
.pict-flow-frame-move-handle { cursor: move; rx: 6; }
|
|
2115
|
+
.pict-flow-node-rotate-arm { stroke: var(--theme-color-brand-primary, #2e7d74); stroke-width: 1.5; }
|
|
2116
|
+
.pict-flow-node-rotate-handle { fill: var(--theme-color-background-panel, #ffffff); stroke: var(--theme-color-brand-primary, #2e7d74); stroke-width: 1.5; cursor: grab; }
|
|
2117
|
+
.pict-flow-node-rotate-handle:hover { fill: var(--theme-color-brand-primary, #2e7d74); }
|
|
2118
|
+
.pict-flow-readonly .pict-flow-node-rotate-arm,
|
|
2119
|
+
.pict-flow-readonly .pict-flow-node-rotate-handle { display: none; }
|
|
2120
|
+
`;
|
|
2121
|
+
}
|
|
2056
2122
|
}
|
|
2057
2123
|
|
|
2058
2124
|
module.exports = PictProviderFlowCSS;
|