mirror of
https://github.com/storytold/filmcraft.git
synced 2026-11-01 14:08:26 -06:00
#1985: a panel closed while floating opens again floating where it was
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6c3948a36c
commit
5510a52a06
@@ -97,6 +97,11 @@ impl FilmcraftApp {
|
||||
Action::Activate { panel } => Some(*panel),
|
||||
_ => None,
|
||||
};
|
||||
// a panel closed while floating remembers where; closed while docked, it forgets (#1985)
|
||||
let closing = match &action {
|
||||
Action::Close { panel } => Some((*panel, self.ui.floating.iter().find(|g| g.panels.contains(panel)).map(|g| g.rect))),
|
||||
_ => None,
|
||||
};
|
||||
self.commit_dock(|shared| {
|
||||
crate::dock_shared::check_last_docked(shared, &action)?;
|
||||
shared.apply(action).map_err(|error| error.to_string())
|
||||
@@ -104,6 +109,12 @@ impl FilmcraftApp {
|
||||
if let Some(panel) = reveal {
|
||||
self.pending_panel_raise = Some(panel);
|
||||
}
|
||||
if let Some((panel, rect)) = closing {
|
||||
self.ui.closed_floating.retain(|(p, _)| *p != panel);
|
||||
if let Some(rect) = rect {
|
||||
self.ui.closed_floating.push((panel, rect));
|
||||
}
|
||||
}
|
||||
if relocating
|
||||
|| self.ui.keys.maximized.is_some_and(|panel| !self.ui.dock.contains(panel) && !self.ui.floating.iter().any(|group| group.panels.contains(&panel)))
|
||||
{
|
||||
|
||||
@@ -872,6 +872,16 @@ impl FilmcraftApp {
|
||||
_ => PanelKind::Project,
|
||||
};
|
||||
self.ui.dock.open_near(p, near);
|
||||
// closed while floating: it floats again where it was (#1985)
|
||||
if let Some(i) = self.ui.closed_floating.iter().position(|(k, _)| *k == p) {
|
||||
let (_, rect) = self.ui.closed_floating.remove(i);
|
||||
if rect.iter().all(|v| v.is_finite()) {
|
||||
let rect = [rect[0], rect[1], rect[2].max(160.0), rect[3].max(120.0)];
|
||||
if let Err(e) = self.apply_dock(craft_ui::docking::Action::Float { panel: p, rect }) {
|
||||
log::warn!("could not float {} again: {e}", p.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = self.apply_dock(craft_ui::docking::Action::Activate { panel: p });
|
||||
self.ui.focused = p;
|
||||
|
||||
@@ -436,6 +436,10 @@ pub struct UiState {
|
||||
pub dock: DockNode,
|
||||
#[serde(default)]
|
||||
pub floating: Vec<crate::dock::Floating>,
|
||||
/// Where each panel closed while floating was ([x, y, width, height]): opening it again
|
||||
/// brings it back there, floating, instead of docked (#1985).
|
||||
#[serde(default)]
|
||||
pub closed_floating: Vec<(PanelKind, [f32; 4])>,
|
||||
/// Focused panel (blue outline, receives shortcuts).
|
||||
pub focused: PanelKind,
|
||||
pub timeline: TimelineView,
|
||||
@@ -960,6 +964,7 @@ impl Default for UiState {
|
||||
mode: Mode::Edit,
|
||||
workspace: "Editing".into(),
|
||||
floating: vec![],
|
||||
closed_floating: vec![],
|
||||
dock: crate::dock::workspace("Editing"),
|
||||
focused: PanelKind::Timeline,
|
||||
timeline: TimelineView::default(),
|
||||
|
||||
@@ -559,3 +559,25 @@ fn narration_selection_reveals_covered_floating_tts_once_without_editing_the_pro
|
||||
assert_eq!(h.state().ui.tts, draft);
|
||||
assert!(std::sync::Arc::ptr_eq(&project, &h.state().session.project));
|
||||
}
|
||||
|
||||
/// #1985: a panel closed while floating came back docked when opened again from the Window menu;
|
||||
/// it now floats again where it was. Closed while docked, it opens docked as before.
|
||||
#[test]
|
||||
fn a_panel_closed_while_floating_reopens_floating_where_it_was() {
|
||||
let mut app = FilmcraftApp::new(Session::default());
|
||||
let ctx = egui::Context::default();
|
||||
menus::invoke(&mut app, &ctx, "window.floatPanel", json!({"panel": "Info", "rect": [45, 65, 420, 320]})).unwrap();
|
||||
let rect = app.ui.floating.iter().find(|g| g.panels.contains(&PanelKind::Info)).unwrap().rect;
|
||||
menus::invoke(&mut app, &ctx, "window.closePanel", json!({"panel": "Info"})).unwrap();
|
||||
assert!(!app.ui.dock.contains(PanelKind::Info) && !app.ui.floating.iter().any(|g| g.panels.contains(&PanelKind::Info)));
|
||||
menus::invoke(&mut app, &ctx, &menus::panel_command_id(PanelKind::Info), json!({})).unwrap();
|
||||
let back = app.ui.floating.iter().find(|g| g.panels.contains(&PanelKind::Info)).expect("Info floats again");
|
||||
assert_eq!(back.rect, rect, "where it was");
|
||||
assert!(!app.ui.dock.contains(PanelKind::Info));
|
||||
// docked, then closed: it opens docked
|
||||
menus::invoke(&mut app, &ctx, "window.dockPanel", json!({"panel": "Info", "anchor": "Project"})).unwrap();
|
||||
menus::invoke(&mut app, &ctx, "window.closePanel", json!({"panel": "Info"})).unwrap();
|
||||
menus::invoke(&mut app, &ctx, &menus::panel_command_id(PanelKind::Info), json!({})).unwrap();
|
||||
assert!(app.ui.dock.contains(PanelKind::Info));
|
||||
assert!(!app.ui.floating.iter().any(|g| g.panels.contains(&PanelKind::Info)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user