diff --git a/crates/ui-egui/src/docking.rs b/crates/ui-egui/src/docking.rs index 9d14cd55..91276156 100644 --- a/crates/ui-egui/src/docking.rs +++ b/crates/ui-egui/src/docking.rs @@ -472,6 +472,11 @@ pub fn show(app: &mut crate::SoundApp, ui: &mut egui::Ui, window: crate::MainWin // and bottom edges take frames (`drop_edges` keeps its default). style.new_dock_zones = true; style.side_edge_zones = false; + // The MIDI body's rect stands for a piano roll on screen (the arrow keys go to it), so only a + // frame that draws the panel records one: open behind another tab, the old rect is gone. + if edit { + ui.ctx().data_mut(|data| data.remove::(egui::Id::unique("soundcraft-midi-body"))); + } let output = DockArea::new(area(edit)).show_with_limits( ui, &workspace.layout, diff --git a/crates/ui-egui/tests/it/shortcuts.rs b/crates/ui-egui/tests/it/shortcuts.rs index 7422caa1..426717e0 100644 --- a/crates/ui-egui/tests/it/shortcuts.rs +++ b/crates/ui-egui/tests/it/shortcuts.rs @@ -190,3 +190,32 @@ fn the_piano_roll_keeps_the_plain_arrows() { assert!(note_start(&app) > before, "the note moved right"); assert_eq!(app.engine.session().edit.zoom.scroll, scroll, "the Edit window kept its view"); } + +/// The MIDI editor open behind another tab has no piano roll on screen: the panel in front of it takes no +/// arrows, so they centre the Edit window there as anywhere else. +#[test] +fn a_midi_editor_behind_another_tab_leaves_the_arrows_to_the_edit_window() { + let mut app = SoundApp::new(soundcraft_engine::demo::demo_engine(), None, Services::default()); + app.ui.show_midi_editor = true; + let (clip_id, clip) = app.engine.session().tracks.iter().flat_map(|t| t.clips()).find(|c| c.start > 100_000).map(|c| (c.id, c.range())).unwrap(); + app.run("view.zoom_set", json!({"samples_per_px": 10.0})).unwrap(); + app.run("view.scroll", json!({"to": 0})).unwrap(); + let ctx = egui::Context::default(); + for _ in 0..6 { + app_frame(&ctx, &mut app, vec![]); + } + let body = ctx.data(|d| d.get_temp::(egui::Id::unique("soundcraft-midi-body"))).unwrap(); + app.run("ui.dock", json!({"operation": "open", "panel": "history"})).unwrap(); + app.run("ui.dock", json!({"operation": "move", "panel": "history", "target": "midi", "zone": "tab"})).unwrap(); + for _ in 0..3 { + app_frame(&ctx, &mut app, vec![]); + } + assert!(app.ui.show_midi_editor, "the MIDI editor is still open"); + assert_ne!(app.ui.docking.layout.panel_state(&soundcraft_ui_egui::docking::Panel::Midi), craft_ui::docking::PanelState::Front); + app_frame(&ctx, &mut app, vec![egui::Event::PointerMoved(body.center())]); + app.run("edit.select", json!({"clips": [clip_id.0]})).unwrap(); + + app_frame(&ctx, &mut app, arrow(Key::ArrowLeft)); + let (x, middle) = x_and_middle(&app, clip.start); + assert!((x - middle).abs() < 1.0, "Left: the clip start at {x}, the middle at {middle}"); +}