1+ import { Canvas } from "src/@types/Canvas"
2+ import AdvancedCanvasPlugin from "src/main"
3+ import * as CanvasHelper from "src/utils/canvas-helper"
4+ import { CanvasEvent } from "src/core/events"
5+
6+ const SHAPES_MENU_OPTIONS : CanvasHelper . MenuOption [ ] = [
7+ {
8+ label : 'Default' ,
9+ icon : 'circle-off'
10+ } ,
11+ {
12+ id : 'oval' ,
13+ label : 'Oval' ,
14+ icon : 'oval'
15+ } ,
16+ {
17+ id : 'centered-rectangle' ,
18+ label : 'Rectangle' ,
19+ icon : 'rectangle-horizontal'
20+ } ,
21+ {
22+ id : 'diamond' ,
23+ label : 'Diamond' ,
24+ icon : 'diamond'
25+ } ,
26+ {
27+ id : 'parallelogram' ,
28+ label : 'Parallelogram' ,
29+ icon : 'parallelogram'
30+ } ,
31+ {
32+ id : 'circle' ,
33+ label : 'Circle' ,
34+ icon : 'circle'
35+ } ,
36+ {
37+ id : 'predefined-process' ,
38+ label : 'Predefined process' ,
39+ icon : 'predefined-process'
40+ } ,
41+ {
42+ id : 'document' ,
43+ label : 'Document' ,
44+ icon : 'document'
45+ } ,
46+ {
47+ id : 'database' ,
48+ label : 'Database' ,
49+ icon : 'database-shape'
50+ }
51+ ]
52+
53+ const BORDER_STYLES_MENU_OPTIONS : CanvasHelper . MenuOption [ ] = [
54+ {
55+ label : 'Solid' ,
56+ icon : 'square'
57+ } ,
58+ {
59+ id : 'dashed' ,
60+ label : 'Dashed' ,
61+ icon : 'box-select'
62+ } ,
63+ {
64+ id : 'dotted' ,
65+ label : 'Dotted' ,
66+ icon : 'dot'
67+ } ,
68+ {
69+ id : 'invisible' ,
70+ label : 'Invisible' ,
71+ icon : 'eye-off'
72+ }
73+ ]
74+
75+ export default class NodeStylesCanvasExtension {
76+ plugin : AdvancedCanvasPlugin
77+
78+ constructor ( plugin : AdvancedCanvasPlugin ) {
79+ this . plugin = plugin
80+
81+ if ( ! this . plugin . settings . getSetting ( 'nodeStylingFeatureEnabled' ) ) return
82+
83+ this . plugin . registerEvent ( this . plugin . app . workspace . on (
84+ CanvasEvent . PopupMenuCreated ,
85+ ( canvas : Canvas ) => this . onPopupMenuCreated ( canvas )
86+ ) )
87+ }
88+
89+ onPopupMenuCreated ( canvas : Canvas ) : void {
90+ // If the canvas is readonly or there is no valid shape in the selection, return
91+ if ( canvas . readonly || ! this . hasValidNodeInSelection ( canvas ) )
92+ return
93+
94+ // Add shapes menu option
95+ if ( this . plugin . settings . getSetting ( 'shapesFeatureEnabled' ) ) {
96+ const menuOption = CanvasHelper . createExpandablePopupMenuOption ( {
97+ id : 'node-shape-option' ,
98+ label : 'Node shape' ,
99+ icon : 'shapes'
100+ } , SHAPES_MENU_OPTIONS . map ( ( shape ) => ( {
101+ ...shape ,
102+ callback : ( ) => this . setShapeForSelection ( canvas , shape . id )
103+ } ) ) )
104+
105+ // Add menu option to menu bar
106+ CanvasHelper . addPopupMenuOption ( canvas , menuOption )
107+ }
108+
109+ // Add border styles menu option
110+ if ( this . plugin . settings . getSetting ( 'borderStyleFeatureEnabled' ) ) {
111+ const menuOption = CanvasHelper . createExpandablePopupMenuOption ( {
112+ id : 'node-border-style-option' ,
113+ label : 'Border style' ,
114+ icon : 'box-select'
115+ } , BORDER_STYLES_MENU_OPTIONS . map ( ( borderStyle ) => ( {
116+ ...borderStyle ,
117+ callback : ( ) => this . setBorderStyleForSelection ( canvas , borderStyle . id )
118+ } ) ) )
119+
120+ // Add menu option to menu bar
121+ CanvasHelper . addPopupMenuOption ( canvas , menuOption )
122+ }
123+ }
124+
125+ private hasValidNodeInSelection ( canvas : Canvas ) : boolean {
126+ const selectedNodesData = canvas . getSelectionData ( ) . nodes
127+
128+ for ( const nodeData of selectedNodesData ) {
129+ if ( nodeData . type === 'text' ) return true
130+ }
131+
132+ return false
133+ }
134+
135+ private setShapeForSelection ( canvas : Canvas , shapeId : string | undefined ) {
136+ const selectedNodesData = canvas . getSelectionData ( ) . nodes
137+
138+ for ( const nodeData of selectedNodesData ) {
139+ if ( nodeData . type !== 'text' ) continue
140+
141+ const node = canvas . nodes . get ( nodeData . id )
142+ if ( ! node ) continue
143+
144+ node . setData ( { ...nodeData , shape : shapeId } )
145+ }
146+ }
147+
148+ private setBorderStyleForSelection ( canvas : Canvas , borderId : string | undefined ) {
149+ const selectedNodesData = canvas . getSelectionData ( ) . nodes
150+
151+ for ( const nodeData of selectedNodesData ) {
152+ const node = canvas . nodes . get ( nodeData . id )
153+ if ( ! node ) continue
154+
155+ node . setData ( { ...nodeData , borderStyle : borderId } )
156+ }
157+ }
158+ }
0 commit comments