mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-24 02:26:46 -06:00
Scroll Into View is a UI command, view.scroll_into_view, and the track name menu dispatches it
This commit is contained in:
@@ -1480,8 +1480,7 @@ pub(crate) fn track_context_menu(app: &mut SoundApp, ui: &mut Ui, id: TrackId) {
|
||||
}
|
||||
// Only the track clicked: the command has one target, and the selection stays as it is.
|
||||
if ui.button("Scroll Into View").clicked() {
|
||||
app.edit_scroll_into_view = Some(id);
|
||||
app.mix_scroll_into_view = Some(id);
|
||||
let _ = app.run("view.scroll_into_view", json!({"track": id.0}));
|
||||
}
|
||||
ui.separator();
|
||||
ui.menu_button("Track Height", |ui| {
|
||||
|
||||
@@ -69,6 +69,7 @@ pub const UI_COMMANDS: &[(&str, &str, &str, Option<&str>)] = &[
|
||||
("window.io_setup", "I/O Setup", "", None),
|
||||
("window.shortcuts", "Keyboard Shortcuts", "", None),
|
||||
("view.mix_section", "Mix Window View", "", None),
|
||||
("view.scroll_into_view", "Scroll Into View", "", None),
|
||||
("ui.new_tracks_dialog", "New Tracks…", "", None),
|
||||
("ui.bounce_dialog", "Bounce Mix…", "", None),
|
||||
("ui.set", "Set UI State", "", None),
|
||||
@@ -647,6 +648,20 @@ pub fn run_ui_command(app: &mut SoundApp, id: &str, p: &Value) -> Option<Result<
|
||||
}
|
||||
json!({"mix_views": app.ui.mix_views})
|
||||
}
|
||||
"view.scroll_into_view" => {
|
||||
// `track` (id or name), else the first selected track: the palette passes no params.
|
||||
let track = match soundcraft_engine::cmd::track_param(&app.engine, id, p, "track") {
|
||||
Ok(Some(t)) => t,
|
||||
Ok(None) => match app.engine.session().edit.selected_tracks.first() {
|
||||
Some(t) => *t,
|
||||
None => return Some(Err("view.scroll_into_view: pass `track` or select a track".into())),
|
||||
},
|
||||
Err(e) => return Some(Err(e.to_string())),
|
||||
};
|
||||
app.edit_scroll_into_view = Some(track);
|
||||
app.mix_scroll_into_view = Some(track);
|
||||
json!({"track": track.0})
|
||||
}
|
||||
"ui.new_tracks_dialog" => {
|
||||
return Some(Err("ui.new_tracks_dialog opens a dialog from the menu only; call track.new with parameters".into()));
|
||||
}
|
||||
|
||||
@@ -132,3 +132,21 @@ fn a_track_in_a_closed_folder_scrolls_the_mix_but_not_the_edit_window() {
|
||||
h.run_steps(4);
|
||||
assert_eq!(h.state().edit_layout.scroll_y, 0.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_command_takes_a_track_by_name_from_the_control_channel() {
|
||||
let mut h = harness(20);
|
||||
h.state_mut().ui.window = MainWindow::Mix;
|
||||
h.run_steps(4);
|
||||
let first = plate(&h, "T01").expect("the first strip's name").x;
|
||||
h.state_mut().run("view.scroll_into_view", json!({"track": "T08"})).unwrap();
|
||||
h.run_steps(4);
|
||||
|
||||
let now = plate(&h, "T08").expect("T08 on screen").x;
|
||||
assert!((now - first).abs() < 1.0, "T08 is the leftmost strip: at {now}, the first was at {first}");
|
||||
h.state_mut().ui.window = MainWindow::Edit;
|
||||
h.run_steps(4);
|
||||
assert_eq!(edit_row(&h, "T08")[1], h.state().edit_layout.timeline[1], "the Edit window scrolled too");
|
||||
assert!(h.state_mut().run("view.scroll_into_view", json!({"track": "T99"})).is_err());
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,10 @@ When the integration cannot report an appearance, System uses Dark. Manual Light
|
||||
fixed when the OS appearance changes. An offscreen render without `--system-theme` supplies no
|
||||
OS appearance and therefore resolves System to Dark.
|
||||
|
||||
`view.scroll_into_view {"track":"Bass"}` (a track id or name; without it, the first selected
|
||||
track) brings the track to the top of the Edit window and the left of the Mix window, the same as
|
||||
Scroll Into View in the track name menu. A window not on screen catches up when it is next shown.
|
||||
|
||||
## Panel docking
|
||||
|
||||
Tracks and Groups, Clips, MIDI Editor, Memory Locations, and Undo History use movable panels. Commands target the active Edit or Mix view; floating panels stay inside the current viewport. Edit and Mix retain separate arrangements; Clips and MIDI Editor belong to Edit. Transport, plug-in, and specialist utility windows retain their existing hosts. The document/session view is protected. Layouts, active tabs, panel visibility, and floating rectangles are saved with the app's existing UI preferences. These operations do not edit document contents.
|
||||
|
||||
Reference in New Issue
Block a user