Multi-select, context menu, section strikethrough, rename/duplicate presets

- Multi-select strips with click, Ctrl+click (toggle), Shift+click (range, same zone)
- Right-click selected strip: context menu with Cascade CC, Assign Channel, Deselect All
- Right-click unselected strip: clears all selections
- Selection status label shows count and type (faders/toggles/transport toggles)
- Rename preset button added to preset row
- Duplicate preset button auto-generates new UUID
- Layout panel section buttons show strikethrough when hidden, normal when visible
- Renamed Preset Browser to Instrument Browser in UI
- Transport strips wired for multi-select and context menu

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Paul Lipscomb
2026-06-29 21:53:45 -04:00
parent 327ca7e00a
commit 22e4fa770e
3 changed files with 145 additions and 31 deletions
+15 -4
View File
@@ -206,6 +206,7 @@ class FaderWidget(QWidget):
self.fader.valueChanged.connect(self.on_fader_moved)
self.cc_spin.valueChanged.connect(self.on_cc_changed)
self.on_select_callback = None
self.on_context_menu_callback = None
self.hw_cc = None # bound hardware CC number
self.is_learning = False
self.zone = None # None, "left", or "right"
@@ -219,15 +220,25 @@ class FaderWidget(QWidget):
def eventFilter(self, obj, event):
if event.type() == QEvent.Type.MouseButtonPress:
if self.on_select_callback:
self.on_select_callback(self)
if event.button() != Qt.MouseButton.RightButton:
if self.on_select_callback:
self.on_select_callback(self)
elif event.type() == QEvent.Type.ContextMenu:
if self.on_context_menu_callback:
self.on_context_menu_callback(self, event.globalPos())
return True
return False
def mousePressEvent(self, event):
if self.on_select_callback:
self.on_select_callback(self)
if event.button() != Qt.MouseButton.RightButton:
if self.on_select_callback:
self.on_select_callback(self)
super().mousePressEvent(event)
def contextMenuEvent(self, event):
if self.on_context_menu_callback:
self.on_context_menu_callback(self, event.globalPos())
def on_pickup_changed(self, state):
self.pickup_mode = bool(state)
if self.pickup_mode: