Dock: floating groups, floating title bar menu, translations

- A docked group floats as one window: drag its edge band over the
  drawing or double-click the band. Floating windows hold a stack of
  pallets with splitters; the vertical title bar shows each pallet's
  icon (press one to drag that pallet out). Dragging the bar moves the
  whole window; dropping it on an edge docks or joins it as a group.
- Right-click a floating title bar: Pallets submenu (add or hide
  pallets in the window), Dock left, Dock right.
- Close on a floating bar closes every pallet in the window; its pin
  sets auto-hide for the whole window.
- Older configs with single floating pallets still load.
- Translate the new dock texts (Auto-hide, Dock left/right, New group,
  Pallets, Browser, Node Graph) in all 21 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RyGiMXcsf9HTKfqDxaQGt
This commit is contained in:
Claude committed 2026-10-10 10:40:55 +00:00
1 parent 4e210f65b5
commit f19948bc07
27 files changed
+1024 -225

No files matched your search

+46 -13
View File
@@ -205,7 +205,7 @@ fn dock_drop_over_the_viewport_floats_the_panel() {
);
assert!(matches!(target, Some(DropTarget::Float { .. })));
assert!(app.dock.right.is_empty());
let f = app.dock.float_rect(PanelId::BlockPalette).expect("floating");
let f = app.dock.float_rect(PanelId::BlockPalette).expect("floating").clone();
assert!(f.x > 600.0 && f.x < 800.0 && f.y > 350.0 && f.y < 400.0);
// Dragging a floating panel keeps the grab point under the pointer.
let target = drag_panel(
@@ -275,14 +275,53 @@ fn dock_grip_drag_moves_a_whole_group() {
app.dock.left[1].panels,
vec![PanelId::Properties, PanelId::Browser]
);
// A group dropped over the viewport does not float or split up.
let before = app.dock.clone();
// A group dropped over the viewport floats as one window.
let _ = app.on_dock(DockMsg::GroupGrab(DockSide::Left, 1));
let _ = app.on_dock(DockMsg::DragMove(iced::Point::new(18.0, 300.0)));
let _ = app.on_dock(DockMsg::DragMove(iced::Point::new(800.0, 400.0)));
assert_eq!(drag_target(&app), None);
let _ = app.on_dock(DockMsg::DragRelease);
assert_eq!(app.dock, before);
assert_eq!(app.dock.left.len(), 1);
let f = app.dock.float_rect(PanelId::Browser).expect("floats");
assert_eq!(f.group.panels, vec![PanelId::Properties, PanelId::Browser]);
// Dragging the window's title bar onto the strip docks it whole again.
let _ = app.on_dock(DockMsg::FloatGrab(PanelId::Properties));
let _ = app.on_dock(DockMsg::DragMove(iced::Point::new(800.0, 400.0)));
let _ = app.on_dock(DockMsg::DragMove(iced::Point::new(18.0, plus_top + 10.0)));
let _ = app.on_dock(DockMsg::DragRelease);
assert!(app.dock.floating.is_empty());
assert_eq!(
app.dock.left[1].panels,
vec![PanelId::Properties, PanelId::Browser]
);
}
#[test]
fn floating_menu_adds_pallets_and_docks_the_window() {
use crate::app::config::DockSide;
use crate::ui::dock::{DockMsg, PanelId};
let mut app = dock_app();
let _ = app.on_dock(DockMsg::FloatOut(PanelId::BlockPalette));
let _ = app.on_dock(DockMsg::FloatMenu(Some(PanelId::BlockPalette)));
let _ = app.on_dock(DockMsg::FloatMenuPallets(true));
// Picking a pallet adds it to the window, opens it and closes the menu.
let _ = app.on_dock(DockMsg::FloatMenuToggle(PanelId::BlockPalette, PanelId::Browser));
assert!(app.show_browser);
assert_eq!(app.dock_float_menu, None);
let f = app.dock.float_rect(PanelId::BlockPalette).unwrap();
assert_eq!(f.group.panels, vec![PanelId::BlockPalette, PanelId::Browser]);
// Picking a checked one hides it but keeps its place.
let _ = app.on_dock(DockMsg::FloatMenuToggle(PanelId::BlockPalette, PanelId::Browser));
assert!(!app.show_browser);
assert!(app.dock.float_rect(PanelId::Browser).is_some());
// Dock left takes the whole window to the left edge.
let _ = app.on_dock(DockMsg::DockTo(PanelId::BlockPalette, DockSide::Left));
assert!(app.dock.floating.is_empty());
let (side, gi) = app.dock.location(PanelId::Browser).unwrap();
assert_eq!(side, DockSide::Left);
assert_eq!(
app.dock.groups(side)[gi].panels,
vec![PanelId::BlockPalette, PanelId::Browser]
);
}
#[test]
@@ -361,18 +400,12 @@ fn dock_hover_reveals_groups_only_on_an_auto_hiding_edge() {
fn dock_float_resize_grows_the_panel() {
use crate::ui::dock::{DockMsg, FloatPanel, PanelId};
let mut app = dock_app();
app.dock.float(FloatPanel {
id: PanelId::BlockPalette,
x: 100.0,
y: 100.0,
w: 260.0,
h: 300.0,
});
app.dock.float(FloatPanel::new(PanelId::BlockPalette, 100.0, 100.0, 260.0, 300.0));
let _ = app.on_dock(DockMsg::FloatResizeGrab(PanelId::BlockPalette, false));
let _ = app.on_dock(DockMsg::DragMove(iced::Point::new(360.0, 400.0)));
let _ = app.on_dock(DockMsg::DragMove(iced::Point::new(400.0, 450.0)));
let _ = app.on_dock(DockMsg::DragRelease);
let f = app.dock.float_rect(PanelId::BlockPalette).unwrap();
let f = app.dock.float_rect(PanelId::BlockPalette).unwrap().clone();
assert_eq!((f.w, f.h), (300.0, 350.0));
// The bottom-left grip grows the panel leftward, keeping its right edge.
let _ = app.on_dock(DockMsg::FloatResizeGrab(PanelId::BlockPalette, true));