mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-24 02:26:46 -06:00
Scroll Into View: a Mix request lasts one frame, so a hidden track doesn't scroll the Mix when it comes back
This commit is contained in:
@@ -47,11 +47,14 @@ pub(crate) fn content(app: &mut SoundApp, ui: &mut Ui) {
|
||||
let ids: Vec<TrackId> = app.engine.session().tracks.iter().filter(|x| !x.hidden && x.kind != TrackKind::Video).map(|x| x.id).collect();
|
||||
// Per-channel peaks for multichannel meters (read once per frame).
|
||||
let snap = app.player.as_ref().filter(|_| app.meters_live()).map(|p| p.meters());
|
||||
// Taken for this frame only: a strip that isn't drawn (hidden track) must not scroll the Mix
|
||||
// whenever it comes back. A request made during this frame (the strip's menu) waits for the next.
|
||||
let scroll_to = app.mix_scroll_into_view.take();
|
||||
egui::ScrollArea::horizontal().auto_shrink([false, false]).show(ui, |ui| {
|
||||
ui.horizontal_top(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 1.0;
|
||||
for id in ids {
|
||||
strip(app, ui, id, snap.as_ref());
|
||||
strip(app, ui, id, snap.as_ref(), scroll_to == Some(id));
|
||||
}
|
||||
let rest = Rect::from_min_max(pos2(ui.cursor().min.x, ui.clip_rect().min.y), ui.clip_rect().max);
|
||||
if rest.width() > 4.0 && ui.interact(rest, ui.id().with("past_strips"), Sense::click()).double_clicked() {
|
||||
@@ -149,7 +152,7 @@ pub(crate) fn route_popup(app: &mut SoundApp, resp: &egui::Response, id: TrackId
|
||||
egui::Popup::menu(resp).close_behavior(egui::PopupCloseBehavior::CloseOnClickOutside).show(|ui| route_menu(app, ui, id, input));
|
||||
}
|
||||
|
||||
fn strip(app: &mut SoundApp, ui: &mut Ui, id: TrackId, snap: Option<&MeterSnapshot>) {
|
||||
fn strip(app: &mut SoundApp, ui: &mut Ui, id: TrackId, snap: Option<&MeterSnapshot>, scroll_here: bool) {
|
||||
let t = Tokens::current();
|
||||
let session = app.engine.session_arc();
|
||||
let Some(track) = session.track(id) else { return };
|
||||
@@ -157,8 +160,7 @@ fn strip(app: &mut SoundApp, ui: &mut Ui, id: TrackId, snap: Option<&MeterSnapsh
|
||||
let w = strip_width(narrow);
|
||||
let h = ui.available_height().max(560.0);
|
||||
let (r, _) = ui.allocate_exact_size(vec2(w, h), Sense::hover());
|
||||
if app.mix_scroll_into_view == Some(id) {
|
||||
app.mix_scroll_into_view = None;
|
||||
if scroll_here {
|
||||
// egui stops `item_spacing` short of the edge (the scroll area's, not the strips' 1 pt),
|
||||
// which would leave a sliver of the previous strip showing.
|
||||
let margin = ui.ctx().global_style().spacing.item_spacing.x;
|
||||
|
||||
@@ -150,3 +150,19 @@ fn the_command_takes_a_track_by_name_from_the_control_channel() {
|
||||
assert!(h.state_mut().run("view.scroll_into_view", json!({"track": "T99"})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_hidden_track_leaves_no_scroll_waiting_in_the_mix() {
|
||||
let mut h = harness(20);
|
||||
h.state_mut().ui.window = MainWindow::Mix;
|
||||
h.state_mut().run("track.hide", json!({"tracks": ["T08"], "hidden": true})).unwrap();
|
||||
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);
|
||||
|
||||
// Shown again later, T08 must not pull the Mix to itself: the request was for frames long gone.
|
||||
h.state_mut().run("track.hide", json!({"tracks": ["T08"], "hidden": false})).unwrap();
|
||||
h.run_steps(4);
|
||||
let now = plate(&h, "T01").expect("T01 still on screen").x;
|
||||
assert!((now - first).abs() < 1.0, "the Mix stayed put: T01 at {now}, was at {first}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user