M3: the Tools panel has no tab strip while docked alone (#2244)

A "Tools" tab sat over the tool panel although nothing else shared its
group; Acrobat's tool pane has no such strip. Tools docked on its own is
now drawn bare. Grouped with another panel, or floating, it keeps its
tab so it can be dragged away again, and its side stays a preference
and a dock command. The docking test groups Inspector with Tools by
command, since there is no tab to drop on.

Co-authored-by: abc2cb <271337822+abc2cb@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
This commit is contained in:
abc2cb
2026-10-21 18:11:05 -04:00
committed by GitHub
co-authored by abc2cb Claude Opus 5.5 aiongg
parent 18b61e2401
commit 193754502f
2 changed files with 11 additions and 12 deletions
+6 -1
View File
@@ -396,12 +396,17 @@ pub fn show(app: &mut crate::PdfCraftApp, ui: &mut egui::Ui) {
// Availability is a render projection: the saved group, selection and width survive Home.
let _ = rendered.apply(Action::Close { panel: Panel::Inspector });
}
// Tools docked on its own is drawn bare, without a tab strip, like Acrobat's tool pane. Grouped
// with another panel, or floating, it keeps its tab so it can be dragged away again; moving it
// to the other side stays a preference and a command.
let bare_tools = rendered.location(&Panel::Tools).is_ok_and(|l| l.floating.is_none() && matches!(l.placement, Placement::Split(_)));
let render_permissions = move |panel: &Panel| if bare_tools && *panel == Panel::Tools { Permissions::PROTECTED } else { permissions(panel) };
let output = DockArea::new(egui::Id::new("pdfcraft-docking")).show_with_limits(
ui,
&rendered,
&style,
|panel| crate::i18n::t(panel.label()).into(),
permissions,
render_permissions,
panel_limits,
|ui, panel| match panel {
Panel::Canvas => {
+5 -11
View File
@@ -1299,19 +1299,13 @@ fn docking_pointer_group_float_close_restore_and_document_commands() {
let (mut h, c) = harness();
ok(&mut h, &c, "ui.set", json!({"key":"panel", "value":"bookmarks"}));
h.run_steps(4);
let from = h.get_by_role_and_label(egui::accesskit::Role::Tab, "Inspector").rect().center();
let to = h.get_by_role_and_label(egui::accesskit::Role::Tab, "Tools").rect().center();
h.event(egui::Event::PointerMoved(from));
h.run_steps(2);
h.event(egui::Event::PointerButton { pos: from, button: egui::PointerButton::Primary, pressed: true, modifiers: egui::Modifiers::NONE });
h.run_steps(2);
for step in 1..=8 {
h.event(egui::Event::PointerMoved(from.lerp(to, step as f32 / 8.0)));
h.run_steps(1);
}
h.event(egui::Event::PointerButton { pos: to, button: egui::PointerButton::Primary, pressed: false, modifiers: egui::Modifiers::NONE });
// Tools docked alone has no tab strip (as Acrobat's tool pane), so it is grouped by command.
assert!(h.query_by_role_and_label(egui::accesskit::Role::Tab, "Tools").is_none());
ok(&mut h, &c, "ui.dock", json!({"operation":"move", "panel":"inspector", "target":"tools", "zone":"center"}));
h.run_steps(4);
assert_eq!(h.state().docking.layout.location(&Panel::Inspector).unwrap().anchor, Some(Panel::Tools));
// Grouped, Tools has its tab again.
h.get_by_role_and_label(egui::accesskit::Role::Tab, "Tools");
h.get_by_role_and_label(egui::accesskit::Role::Tab, "Inspector").click_button(egui::PointerButton::Secondary);
h.run_steps(3);
h.get_by_label("Float panel").click();