Skip to content

Commit 47e86b4

Browse files
Added flip selection command
1 parent fd4416e commit 47e86b4

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

src/canvas-extensions/commands-canvas-extension.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { Canvas } from "src/@types/Canvas"
1+
import { Canvas, CanvasEdge, CanvasEdgeData, CanvasNodeData } from "src/@types/Canvas"
22
import CanvasHelper from "src/utils/canvas-helper"
33
import { FileSelectModal } from "src/utils/modal-helper"
44
import CanvasExtension from "../core/canvas-extension"
5+
import BBoxHelper from "src/utils/bbox-helper"
56

67
type Direction = 'up' | 'down' | 'left' | 'right'
78
const 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
}

src/utils/bbox-helper.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ export default class BBoxHelper {
9595
}
9696
}
9797

98+
static getOppositeSide(side: Side): Side {
99+
switch (side) {
100+
case 'top':
101+
return 'bottom'
102+
case 'right':
103+
return 'left'
104+
case 'bottom':
105+
return 'top'
106+
case 'left':
107+
return 'right'
108+
}
109+
}
110+
98111
static isHorizontal(side: Side): boolean {
99112
return side === 'left' || side === 'right'
100113
}

0 commit comments

Comments
 (0)