Multi-iPad dest_id routing, activity ring, context menu hide, live label/visibility sync
Desktop: - Replace Remote checkbox with T: dest_spin (0=Off, 1-9=tablet) on all widgets - dest_id persisted in get_state/set_state, broadcast in tablet snapshot - dest_spin.valueChanged triggers save + broadcast to iPad - _on_widget_visibility_from_tablet updates dest_spin from iPad hide event - _broadcast_preset_update shared helper; ws_server.has_clients guard - label editingFinished triggers live label sync to iPad iOS: - VC-Arrange/VC-Logging/Widgets-Reusable-UI file reorganisation - ArrangeObjects/ArrangeView rename, 7-bucket Arrange-Functions split - myTabletId (UserDefaults) + tabletIdField next to port in toolbar - Preset filter: destId == myTabletId instead of visible bool - BaseWidget activity ring: long press gesture (touch) + final update() flash - Context menu long press (arrange mode): hide widget, save layout, send dest_id:0 - Same-UUID preset check skips Preset Switched alert on visibility/label updates - autoSwitchEnabled, toolbarStatusLabel, presetLabel, statusToken Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+55
-5
@@ -135,11 +135,21 @@ containerMain = QWidget()
|
||||
#MARK: PRESET ROW
|
||||
hstack_preset_row = QHBoxLayout()
|
||||
|
||||
#MARK: PRESENT
|
||||
#MARK: PRESENT
|
||||
menuPresets = QComboBox()
|
||||
menuPresets.setMinimumWidth(160)
|
||||
menuPresets.currentTextChanged.connect(lambda name: on_preset_selected(menuPresets, app_window, ready, loaded_presets, on_load=preset_load))
|
||||
|
||||
buttonPresetPrev = QPushButton("◀")
|
||||
buttonPresetPrev.setFixedWidth(28)
|
||||
buttonPresetPrev.setToolTip("Previous preset")
|
||||
buttonPresetPrev.clicked.connect(lambda: menuPresets.setCurrentIndex(max(0, menuPresets.currentIndex() - 1)))
|
||||
|
||||
buttonPresetNext = QPushButton("▶")
|
||||
buttonPresetNext.setFixedWidth(28)
|
||||
buttonPresetNext.setToolTip("Next preset")
|
||||
buttonPresetNext.clicked.connect(lambda: menuPresets.setCurrentIndex(min(menuPresets.count() - 1, menuPresets.currentIndex() + 1)))
|
||||
|
||||
|
||||
#button new blank preset
|
||||
buttonNew = QPushButton("New")
|
||||
@@ -781,6 +791,8 @@ for _label, _cc in [("Play", 117), ("Stop", 116), ("Record", 118), ("Arm", 119)]
|
||||
_t.on_select_callback = lambda strip: check_and_update_selected_strip(strip)
|
||||
_t.on_context_menu_callback = lambda strip, pos: strip_context_menu(strip, pos)
|
||||
_t.on_zone_change_callback = lambda strip: handle_transport_zone_change(strip)
|
||||
_t.dest_spin.valueChanged.connect(lambda val: _on_remote_checkbox_changed())
|
||||
_t.title_edit.editingFinished.connect(lambda: _broadcast_preset_update())
|
||||
del _t, _label, _cc
|
||||
|
||||
# MARK: SELECTED CHANNEL ROW MODULE
|
||||
@@ -964,6 +976,8 @@ class MainWindow(QMainWindow):
|
||||
main_layout.addLayout(hstack_preset_row)
|
||||
|
||||
hstack_preset_row.addWidget(menuPresets) #dropdown
|
||||
hstack_preset_row.addWidget(buttonPresetPrev)
|
||||
hstack_preset_row.addWidget(buttonPresetNext)
|
||||
hstack_preset_row.addWidget(buttonNew)
|
||||
hstack_preset_row.addWidget(buttonSave) #save button
|
||||
hstack_preset_row.addWidget(buttonSaveAs) #save as button
|
||||
@@ -2181,6 +2195,8 @@ def toggle_add(insert_after=None):
|
||||
toggle.on_context_menu_callback = strip_context_menu
|
||||
toggle.on_zone_change_callback = handle_toggle_zone_change
|
||||
toggle.learn_btn.clicked.connect(lambda: check_and_start_midi_learn(toggle))
|
||||
toggle.dest_spin.valueChanged.connect(lambda val: _on_remote_checkbox_changed())
|
||||
toggle.title_edit.editingFinished.connect(_broadcast_preset_update)
|
||||
update_window_width()
|
||||
check_and_index_strip_labels()
|
||||
_update_toggle_placeholder()
|
||||
@@ -2214,6 +2230,8 @@ def fader_add(insert_after=None):
|
||||
fader.on_select_callback = check_and_update_selected_strip
|
||||
fader.on_context_menu_callback = strip_context_menu
|
||||
fader.on_zone_change_callback = handle_fader_zone_change
|
||||
fader.dest_spin.valueChanged.connect(lambda val: _on_remote_checkbox_changed())
|
||||
fader.title_edit.editingFinished.connect(_broadcast_preset_update)
|
||||
update_window_width()
|
||||
check_and_index_strip_labels()
|
||||
_update_fader_placeholder()
|
||||
@@ -2238,6 +2256,8 @@ def transport_toggle_add(label, default_cc, insert_after=None):
|
||||
t.on_zone_change_callback = lambda strip: handle_transport_zone_change(strip)
|
||||
t.plus_btn.clicked.connect(lambda: transport_toggle_add(f"T{len(transports)+1}", 20, insert_after=t))
|
||||
t.minus_btn.clicked.connect(lambda: transport_remove(t))
|
||||
t.dest_spin.valueChanged.connect(lambda val: _on_remote_checkbox_changed())
|
||||
t.title_edit.editingFinished.connect(_broadcast_preset_update)
|
||||
params_visible = not transport_show_hide_config
|
||||
for attr in ['grp_learn', 'arrow_lbl', 'grp_cc', 'zone_btn', 'minus_btn',
|
||||
'plus_btn', 'title_edit', 'id_sep', 'id_label', 'color_swatch_btn']:
|
||||
@@ -2351,9 +2371,9 @@ def _build_tablet_snapshot():
|
||||
"preset_uuid": label_preset_uuid.text().strip(),
|
||||
"preset_name": name,
|
||||
"big_title": big_title_edit.text() if big_title_edit else "",
|
||||
"faders": [{"uid": f.uid, "label": f.title_edit.text(), "value": f.fader.value(), "visible": True, "color": PALETTE_HEX.get(f.color_name, "#00e676")} for f in faders],
|
||||
"toggles": [{"uid": t.uid, "label": t.title_edit.text(), "state": t.toggle_state, "visible": True, "color": PALETTE_HEX.get(t.color_name, "#00e676")} for t in toggles],
|
||||
"transports": [{"uid": t.uid, "label": t.title_edit.text(), "visible": True} for t in transports],
|
||||
"faders": [{"uid": f.uid, "label": f.title_edit.text(), "value": f.fader.value(), "dest_id": f.dest_spin.value(), "color": PALETTE_HEX.get(f.color_name, "#00e676")} for f in faders],
|
||||
"toggles": [{"uid": t.uid, "label": t.title_edit.text(), "state": t.toggle_state, "dest_id": t.dest_spin.value(), "color": PALETTE_HEX.get(t.color_name, "#00e676")} for t in toggles],
|
||||
"transports": [{"uid": t.uid, "label": t.title_edit.text(), "dest_id": t.dest_spin.value()} for t in transports],
|
||||
}
|
||||
return snapshot, saved_layout
|
||||
|
||||
@@ -2365,6 +2385,35 @@ def _on_tablet_connected():
|
||||
log_ws_outgoing(snapshot)
|
||||
|
||||
|
||||
def _on_widget_visibility_from_tablet(uid, dest_id):
|
||||
for w in faders + toggles + transports:
|
||||
if w.uid == uid:
|
||||
w.dest_spin.blockSignals(True)
|
||||
w.dest_spin.setValue(dest_id)
|
||||
w.dest_spin.blockSignals(False)
|
||||
name = menuPresets.currentText()
|
||||
if name and name in loaded_presets.get("presets", {}):
|
||||
loaded_presets["presets"][name].update(preset_build_snapshot(name))
|
||||
save_presets_file(loaded_presets)
|
||||
show_save_status()
|
||||
break
|
||||
|
||||
|
||||
def _broadcast_preset_update():
|
||||
name = menuPresets.currentText()
|
||||
if name and name in loaded_presets.get("presets", {}):
|
||||
loaded_presets["presets"][name].update(preset_build_snapshot(name))
|
||||
save_presets_file(loaded_presets)
|
||||
if ws_server and ws_server.has_clients:
|
||||
snapshot, layout = _build_tablet_snapshot()
|
||||
ws_server.broadcast_preset(snapshot, layout)
|
||||
log_ws_outgoing(snapshot)
|
||||
|
||||
|
||||
def _on_remote_checkbox_changed():
|
||||
_broadcast_preset_update()
|
||||
|
||||
|
||||
def _on_tablet_layout_saved(preset_uuid, layout):
|
||||
name = menuPresets.currentText()
|
||||
if name and name in loaded_presets.get("presets", {}):
|
||||
@@ -2498,7 +2547,7 @@ def preset_load(preset):
|
||||
|
||||
check_and_index_strip_labels()
|
||||
|
||||
if ws_server:
|
||||
if ws_server and ws_server.has_clients:
|
||||
snapshot, layout = _build_tablet_snapshot()
|
||||
ws_server.broadcast_preset(snapshot, layout)
|
||||
log_ws_outgoing(snapshot)
|
||||
@@ -2865,6 +2914,7 @@ def _start_tablet_server():
|
||||
ws_server.raw_in_signal.connect(log_ws_incoming)
|
||||
ws_server.control_received.connect(lambda uid, val: midi_receiver.hw_cc_signal.emit(uid, val))
|
||||
ws_server.layout_saved.connect(_on_tablet_layout_saved)
|
||||
ws_server.widget_visibility_received.connect(_on_widget_visibility_from_tablet)
|
||||
ws_server.client_connected.connect(_on_tablet_connected)
|
||||
try:
|
||||
s = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM)
|
||||
|
||||
Reference in New Issue
Block a user