UI: double-clicking the status bar's preflight count shows the Preflight panel

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
moppeeer
2026-10-15 16:57:42 +02:00
co-authored by Claude Opus 5.5
parent ba0b0ec110
commit e2ad5cafa2
3 changed files with 44 additions and 15 deletions
+1
View File
@@ -347,6 +347,7 @@ list) · [roadmap.md](docs/roadmap.md) (milestones, plan) · [parity-checklist.m
Newest first.
- 2026-10-15: Double-clicking the status bar's preflight count or its light shows the Preflight panel, as in InDesign.
- **2026-10-14** · The Type tool draws a new text frame over a locked empty frame, as InDesign does, instead of turning the locked frame into a text frame. No readiness percentage change.
- **2026-10-14** · 100% black shows as pure black on screen by default, as InDesign's Appearance of Black does out of the box (Display All Blacks as Rich Black); Preferences › Appearance of Black › Display All Blacks Accurately still shows it as the dark grey it prints, and a saved choice is kept. No readiness percentage change.
- **2026-10-14** · Pathfinder keeps the frontmost object, as InDesign does: a photo placed over shapes and intersected with them shows through the shapes (it was dropped, and the shapes kept their black fill); Add, Exclude Overlap and Minus Back take the front object's fill too, Subtract still keeps the back one. No readiness percentage change.
+23 -2
View File
@@ -703,7 +703,7 @@ pub fn status_bar(app: &mut DesignApp, ui: &mut egui::Ui) {
ui.add_space(8.0);
// Preflight: overset text is an error.
let errors = panels::preflight_errors(app);
let (r, _) = ui.allocate_exact_size(vec2(9.0, 9.0), Sense::hover());
let (r, dot) = ui.allocate_exact_size(vec2(9.0, 9.0), Sense::click());
ui.painter().circle_filled(
r.center(),
4.0,
@@ -718,12 +718,17 @@ pub fn status_bar(app: &mut DesignApp, ui: &mut egui::Ui) {
)
};
// As in InDesign, the count opens a menu that leads to the Preflight panel.
crate::menus::menu_button(ui, egui::RichText::new(count).font(small.clone()), |ui| {
let menu = crate::menus::menu_button(ui, egui::RichText::new(count).font(small.clone()), |ui| {
if ui.button(crate::i18n::tr(&app.ui.language, "Preflight Panel…")).clicked() {
let _ = app.run("window.panel", json!({"panel": "preflight"}));
ui.close();
}
});
// Double-clicking the light or the count shows the panel straight away (the
// second click has closed the menu the first one opened).
if dot.double_clicked() || menu.response.double_clicked() {
let _ = app.run("window.panel", json!({"panel": "preflight"}));
}
ui.add_space(12.0);
ui.label(egui::RichText::new(&app.ui.status).font(small).color(t.text_dim));
});
@@ -914,6 +919,22 @@ mod tests {
h.get_by_label("Preflight");
}
/// As in InDesign, double-clicking the preflight count (or its light) shows the panel.
#[test]
fn double_clicking_the_status_bar_error_count_opens_the_preflight_panel() {
let mut app = app();
app.run("file.new", serde_json::json!({})).unwrap();
app.ui.dock_tab = "properties".into();
let mut h = test_window::open_stepped(app, vec2(1200.0, 700.0), 1.0, 1.0 / 60.0);
let count = h.get_by_label("No errors ▾");
count.click();
count.click();
h.run_steps(3);
assert_eq!(h.state().app.ui.open_panel.as_deref(), Some("preflight"));
h.get_by_label("Preflight");
assert!(h.query_by_label("Preflight Panel…").is_none(), "the menu isn't left open");
}
/// A very long document name made its tab grow past the window, hiding the close button
/// and the tabs after it (#603).
#[test]
+20 -13
View File
@@ -2300,22 +2300,29 @@ pub(crate) mod test_window {
}
/// The window at a size in points and a scale, with a new document open.
pub fn open_scaled(mut app: crate::DesignApp, size: egui::Vec2, pixels_per_point: f32) -> Harness<'static, Window> {
pub fn open_scaled(app: crate::DesignApp, size: egui::Vec2, pixels_per_point: f32) -> Harness<'static, Window> {
open_stepped(app, size, pixels_per_point, 0.25)
}
/// As `open_scaled`, with `step_dt` seconds between frames (a double-click needs its two
/// clicks closer together than the default quarter second).
pub fn open_stepped(mut app: crate::DesignApp, size: egui::Vec2, pixels_per_point: f32, step_dt: f32) -> Harness<'static, Window> {
if app.session.active().is_none() {
app.run("file.new", serde_json::json!({})).unwrap();
}
let mut h = Harness::builder().with_size(size).with_pixels_per_point(pixels_per_point).with_max_steps(1000).build_ui_state(
|ui, w: &mut Window| {
// The builder runs a frame before the texture size can be raised: skip it.
if !w.ready {
return;
}
let ctx = ui.ctx().clone();
w.app.logic(&ctx);
w.app.ui(ui);
},
Window { app, ready: false },
);
let mut h =
Harness::builder().with_size(size).with_pixels_per_point(pixels_per_point).with_max_steps(1000).with_step_dt(step_dt).build_ui_state(
|ui, w: &mut Window| {
// The builder runs a frame before the texture size can be raised: skip it.
if !w.ready {
return;
}
let ctx = ui.ctx().clone();
w.app.logic(&ctx);
w.app.ui(ui);
},
Window { app, ready: false },
);
h.input_mut().max_texture_side = Some(8192);
h.state_mut().ready = true;
h.run_steps(6);