1- import { Canvas } from "src/@types/Canvas"
1+ import { Canvas , CanvasEdge , CanvasEdgeData , CanvasNodeData } from "src/@types/Canvas"
22import CanvasHelper from "src/utils/canvas-helper"
33import { FileSelectModal } from "src/utils/modal-helper"
44import CanvasExtension from "../core/canvas-extension"
5+ import BBoxHelper from "src/utils/bbox-helper"
56
67type Direction = 'up' | 'down' | 'left' | 'right'
78const DIRECTIONS = [ 'up' , 'down' , 'left' , 'right' ] as Direction [ ]
@@ -73,6 +74,26 @@ export default class CommandsCanvasExtension extends CanvasExtension {
7374 )
7475 } )
7576 }
77+
78+ this . plugin . addCommand ( {
79+ id : 'flip-selection-horizontally' ,
80+ name : 'Flip selection horizontally' ,
81+ checkCallback : CanvasHelper . canvasCommand (
82+ this . plugin ,
83+ ( canvas : Canvas ) => ! canvas . readonly && canvas . selection . size > 0 ,
84+ ( canvas : Canvas ) => this . flipSelection ( canvas , true
85+ ) )
86+ } )
87+
88+ this . plugin . addCommand ( {
89+ id : 'flip-selection-vertically' ,
90+ name : 'Flip selection vertically' ,
91+ checkCallback : CanvasHelper . canvasCommand (
92+ this . plugin ,
93+ ( canvas : Canvas ) => ! canvas . readonly && canvas . selection . size > 0 ,
94+ ( canvas : Canvas ) => this . flipSelection ( canvas , false )
95+ )
96+ } )
7697 }
7798
7899 private createTextNode ( canvas : Canvas ) {
@@ -138,4 +159,54 @@ export default class CommandsCanvasExtension extends CanvasExtension {
138159 height : node . height + expand . y * expandNodeStepSize
139160 } )
140161 }
162+
163+ private flipSelection ( canvas : Canvas , horizontally : boolean ) {
164+ const selectionData = canvas . getSelectionData ( )
165+ if ( selectionData . nodes . length === 0 ) return
166+
167+ const nodeIds = new Set ( )
168+
169+ // Flip nodes
170+ for ( const nodeData of selectionData . nodes ) {
171+ nodeIds . add ( nodeData . id )
172+
173+ const node = canvas . nodes . get ( nodeData . id )
174+ if ( ! node ) continue
175+
176+ const newX = horizontally ?
177+ 2 * selectionData . center . x - nodeData . x - nodeData . width :
178+ nodeData . x
179+
180+ const newY = horizontally ?
181+ nodeData . y :
182+ 2 * selectionData . center . y - nodeData . y - nodeData . height
183+
184+ node . setData ( {
185+ ...nodeData ,
186+ x : newX ,
187+ y : newY
188+ } )
189+ }
190+
191+ // Flip edges
192+ for ( const edge of canvas . edges . values ( ) ) {
193+ const edgeData = edge . getData ( ) as CanvasEdgeData
194+
195+ let newFromSide = edgeData . fromSide
196+ if ( nodeIds . has ( edgeData . fromNode ) && BBoxHelper . isHorizontal ( edgeData . fromSide ) === horizontally )
197+ newFromSide = BBoxHelper . getOppositeSide ( edgeData . fromSide )
198+
199+ let newToSide = edgeData . toSide
200+ if ( nodeIds . has ( edgeData . toNode ) && BBoxHelper . isHorizontal ( edgeData . toSide ) === horizontally )
201+ newToSide = BBoxHelper . getOppositeSide ( edgeData . toSide )
202+
203+ edge . setData ( {
204+ ...edgeData ,
205+ fromSide : newFromSide ,
206+ toSide : newToSide
207+ } )
208+ }
209+
210+ canvas . pushHistory ( canvas . getData ( ) )
211+ }
141212}
0 commit comments