From 84b9469896881385027dae05137af2eea778212b Mon Sep 17 00:00:00 2001 From: "Robin E.R. Davies" Date: Mon, 15 Jun 2026 09:30:52 -0400 Subject: [PATCH] Allow dragging of Splits --- vite/src/pipedal/Draggable.tsx | 2 + vite/src/pipedal/Pedalboard.tsx | 17 ++++ vite/src/pipedal/PedalboardView.tsx | 138 +++++++++++++++++++--------- 3 files changed, 112 insertions(+), 45 deletions(-) diff --git a/vite/src/pipedal/Draggable.tsx b/vite/src/pipedal/Draggable.tsx index 7f2f553..d7887b1 100644 --- a/vite/src/pipedal/Draggable.tsx +++ b/vite/src/pipedal/Draggable.tsx @@ -251,6 +251,7 @@ const Draggable = if (this.pointerType !== "touch") { this.dragTarget.style.transform = "scale(" + SELECT_SCALE + ")"; this.dragTarget.style.zIndex = "3"; + this.dragTarget.style.position = "absolute"; } } } @@ -259,6 +260,7 @@ const Draggable = element.style.transform = ""; element.style.zIndex = this.savedIndex; element.style.opacity = this.savedOpacity; + element.style.position = "relative"; } onPointerCancel(e: PointerEvent) { diff --git a/vite/src/pipedal/Pedalboard.tsx b/vite/src/pipedal/Pedalboard.tsx index b6d83b5..e2afa4f 100644 --- a/vite/src/pipedal/Pedalboard.tsx +++ b/vite/src/pipedal/Pedalboard.tsx @@ -144,6 +144,23 @@ export class PedalboardItem implements Deserializable { } + isChild(instanceId: number): boolean { + if (this.instanceId === instanceId) return true; + if (this.isSplit()) + { + let splitItem = this as unknown as PedalboardSplitItem; + for (let topItem of splitItem.topChain) + { + if (topItem.isChild(instanceId)) return true; + } + for (let bottomItem of splitItem.bottomChain) + { + if (bottomItem.isChild(instanceId)) return true; + } + } + return false; + } + getControlValue(key: string): number { for (let i = 0; i < this.controlValues.length; ++i) { let v = this.controlValues[i]; diff --git a/vite/src/pipedal/PedalboardView.tsx b/vite/src/pipedal/PedalboardView.tsx index 5eca3f7..aeed9b2 100644 --- a/vite/src/pipedal/PedalboardView.tsx +++ b/vite/src/pipedal/PedalboardView.tsx @@ -147,24 +147,36 @@ const pedalboardStyles = (theme: Theme) => createStyles({ top: -6, fill: theme.palette.text.secondary }), - iconFrame: css({ - display: "flex", - alignItems: "center", - justifyContent: "center", + pedalButton: css({ + position: "relative", - background: theme.palette.background.default, marginLeft: (CELL_WIDTH - FRAME_SIZE) / 2, marginRight: (CELL_WIDTH - FRAME_SIZE) / 2, marginTop: (CELL_HEIGHT - FRAME_SIZE) / 2, marginBottom: (CELL_HEIGHT - FRAME_SIZE) / 2, + width: FRAME_SIZE, + height: FRAME_SIZE, + padding: 0, + borderRadius: 8 + }), + + iconFrame: css({ + + display: "flex", + alignItems: "center", + justifyContent: "center", + position: "relative", + background: theme.palette.background.paper, + width: FRAME_SIZE, height: FRAME_SIZE, borderColor: "#777", borderWidth: 2, borderStyle: "solid", - padding: 1, + overflow: "hidden", + padding: 0, borderRadius: 8 }), selectedIconFrame: css({ @@ -173,12 +185,7 @@ const pedalboardStyles = (theme: Theme) => createStyles({ alignItems: "center", justifyContent: "center", position: "relative", - - background: theme.palette.background.default, - marginLeft: (CELL_WIDTH - FRAME_SIZE) / 2, - marginRight: (CELL_WIDTH - FRAME_SIZE) / 2, - marginTop: (CELL_HEIGHT - FRAME_SIZE) / 2, - marginBottom: (CELL_HEIGHT - FRAME_SIZE) / 2, + background: theme.palette.background.paper, width: FRAME_SIZE, height: FRAME_SIZE, borderColor: theme.palette.primary.main, @@ -195,10 +202,6 @@ const pedalboardStyles = (theme: Theme) => createStyles({ justifyContent: "center", background: "transparent", - marginLeft: (CELL_WIDTH - FRAME_SIZE) / 2, - marginRight: (CELL_WIDTH - FRAME_SIZE) / 2, - marginTop: (CELL_HEIGHT - FRAME_SIZE) / 2, - marginBottom: (CELL_HEIGHT - FRAME_SIZE) / 2, width: FRAME_SIZE, height: FRAME_SIZE, border: "0px #666 solid", @@ -458,6 +461,20 @@ const PedalboardView = // touchyMove. :-/ } + isSplitterChild(item: PedalboardItem, splitterInstanceId: number) { + if (item.instanceId === splitterInstanceId) { + return true; + } + let pedalboard: Pedalboard | undefined = this.state.pedalboard; + if (!pedalboard) return false; + + let splitter = pedalboard.maybeGetItem(splitterInstanceId); + if (splitter === null) { + return false; + } + return splitter.isChild(item.instanceId); + } + onDragEnd(instanceId: number, clientX: number, clientY: number) { if (!this.props.enableStructureEditing) { return; @@ -483,10 +500,18 @@ const PedalboardView = if (item.isSplitter() && item.pedalItem) { if (item.bounds.contains(clientX, clientY)) { if (clientX < item.bounds.x + CELL_WIDTH / 2) { + if (this.isSplitterChild(item.pedalItem, instanceId)) + { + return; + } this.model.movePedalboardItemBefore(instanceId, item.pedalItem.instanceId); this.setSelection(instanceId); return; } else if (clientX > item.bounds.right - CELL_WIDTH / 2) { + if (this.isSplitterChild(item.pedalItem, instanceId)) + { + return; + } this.model.movePedalboardItemAfter(instanceId, item.pedalItem.instanceId); this.setSelection(instanceId); return; @@ -501,6 +526,11 @@ const PedalboardView = if (clientX < item.topChildren[0].bounds.x) { let topPedalItem = item.topChildren[0].pedalItem; if (topPedalItem) { + if (this.isSplitterChild(topPedalItem, instanceId)) + { + return; + } + this.model.movePedalboardItemBefore(instanceId, topPedalItem.instanceId); this.setSelection(instanceId); return; @@ -509,6 +539,9 @@ const PedalboardView = let lastTop = item.topChildren[item.topChildren.length - 1]; if (clientX >= lastTop.bounds.right && clientX < item.bounds.right - CELL_WIDTH / 2) { if (lastTop.pedalItem) { + if (this.isSplitterChild(lastTop.pedalItem, instanceId)) { + return; + } this.model.movePedalboardItemAfter(instanceId, lastTop.pedalItem.instanceId); this.setSelection(instanceId); return; @@ -522,6 +555,9 @@ const PedalboardView = if (clientX < item.bottomChildren[0].bounds.x) { let bottomPedalItem = item.bottomChildren[0].pedalItem; if (bottomPedalItem) { + if (this.isSplitterChild(bottomPedalItem, instanceId)) { + return; + } this.model.movePedalboardItemBefore(instanceId, bottomPedalItem.instanceId); this.setSelection(instanceId); return; @@ -530,6 +566,9 @@ const PedalboardView = let lastBottom = item.bottomChildren[item.bottomChildren.length - 1]; if (clientX >= lastBottom.bounds.right && clientX < item.bounds.right - CELL_WIDTH / 2) { if (lastBottom.pedalItem) { + if (this.isSplitterChild(lastBottom.pedalItem, instanceId)) { + return; + } this.model.movePedalboardItemAfter(instanceId, lastBottom.pedalItem.instanceId); this.setSelection(instanceId); return; @@ -552,10 +591,22 @@ const PedalboardView = if (item.pedalItem) { let margin = (CELL_WIDTH - FRAME_SIZE) / 2; if (clientX < item.bounds.x + margin) { + if (this.isSplitterChild(item.pedalItem,instanceId)) + { + return; + } this.model.movePedalboardItemBefore(instanceId, item.pedalItem.instanceId); } else if (clientX > item.bounds.right - margin) { + if (this.isSplitterChild(item.pedalItem,instanceId)) + { + return; + } this.model.movePedalboardItemAfter(instanceId, item.pedalItem.instanceId); } else { + if (this.isSplitterChild(item.pedalItem,instanceId)) + { + return; + } this.model.movePedalboardItem(instanceId, item.pedalItem.instanceId); } this.setSelection(instanceId); @@ -1036,39 +1087,35 @@ const PedalboardView = } return ( -
{ e.preventDefault(); }} - > - {/* {!enabled && ( -
- -
- - )} */} - - + { this.onItemClick(e, instanceId); }} onDoubleClick={(e: SyntheticEvent) => { this.onItemDoubleClick(e, instanceId); }} onContextMenu={(e: SyntheticEvent) => { this.onItemLongClick(e, instanceId); }} > - { e.preventDefault(); }} > - this.getScrollContainer()} - onDragEnd={(x, y) => { this.onDragEnd(instanceId, x, y) }} - style={{ opacity: enabled ? 0.99 : 0.3 }} - + -
- -
+
+
+ this.getScrollContainer()} + onDragEnd={(x, y) => { this.onDragEnd(instanceId, x, y) }} + style={{ opacity: enabled ? 0.99 : 0.3 }} - - + > +
+ +
+ + + ); @@ -1146,7 +1193,7 @@ const PedalboardView = result.push(
- {this.pedalButton(item.pedalItem?.instanceId ?? -1, this.getSplitterIcon(item), "", false, true, true, false, false)} + {this.pedalButton(item.pedalItem?.instanceId ?? -1, this.getSplitterIcon(item), "", true, true, true, false, false)}
); @@ -1157,9 +1204,10 @@ const PedalboardView = position: "absolute", left: item.bounds.x, width: CELL_WIDTH, top: item.bounds.bottom - 12, paddingLeft: 2, paddingRight: 2 }}> {item.name} )