diff --git a/crates/ui-egui/src/canvas/home.rs b/crates/ui-egui/src/canvas/home.rs index d73a5c5bb..672f2dd3d 100644 --- a/crates/ui-egui/src/canvas/home.rs +++ b/crates/ui-egui/src/canvas/home.rs @@ -25,18 +25,21 @@ pub(super) fn home(app: &mut VectorcraftApp, ui: &mut Ui, rect: egui::Rect) { /// The Home screen's column: welcome, New / Open, Recent Files, presets and community links. fn home_content(app: &mut VectorcraftApp, ui: &mut Ui) { let t = Tokens::get(ui.ctx()); - ui.label(egui::RichText::new(tl!("Welcome to VectorCraft")).font(theme::semibold(26.0)).color(t.text)); - ui.add_space(4.0); - ui.label(egui::RichText::new(tl!("Vector illustration — fast, open, scriptable.")).size(14.0).color(t.text_dim)); - ui.add_space(22.0); - ui.horizontal(|ui| { - if widgets::primary_button(ui, tl!("New file")).clicked() { - app.run("file.newDialog", json!({})).ok(); - } - ui.add_space(8.0); - if widgets::secondary_button(ui, tl!("Open")).clicked() { - app.run("file.open", json!({})).ok(); - } + // The welcome and the New / Open buttons sit centred, as PhotoCraft's Home screen does (#4684). + ui.vertical_centered(|ui| { + ui.label(egui::RichText::new(tl!("Welcome to VectorCraft")).font(theme::semibold(26.0)).color(t.text)); + ui.add_space(4.0); + ui.label(egui::RichText::new(tl!("Vector illustration — fast, open, scriptable.")).size(14.0).color(t.text_dim)); + ui.add_space(22.0); + ui.horizontal(|ui| { + if widgets::primary_button(ui, tl!("New file")).clicked() { + app.run("file.newDialog", json!({})).ok(); + } + ui.add_space(8.0); + if widgets::secondary_button(ui, tl!("Open")).clicked() { + app.run("file.open", json!({})).ok(); + } + }); }); recent(app, ui); ui.add_space(28.0); @@ -54,9 +57,11 @@ fn home_content(app: &mut VectorcraftApp, ui: &mut Ui) { } }); ui.add_space(28.0); - ui.label(egui::RichText::new(tl!("Community")).font(theme::semibold(14.0)).color(t.text)); - ui.add_space(10.0); - crate::community::links(app, ui); + ui.vertical_centered(|ui| { + ui.label(egui::RichText::new(tl!("Community")).font(theme::semibold(14.0)).color(t.text)); + ui.add_space(10.0); + crate::community::links(app, ui); + }); } /// The Home screen's Recent Files (#663): the first of File › Open Recent Files, each its name and diff --git a/crates/ui-egui/src/community.rs b/crates/ui-egui/src/community.rs index 7ed5eb984..089a421ce 100644 --- a/crates/ui-egui/src/community.rs +++ b/crates/ui-egui/src/community.rs @@ -32,7 +32,10 @@ pub fn discord_button(app: &mut VectorcraftApp, ui: &mut Ui, large: bool) -> egu let at = egui::pos2(0.0, r.center().y - galley.size().y / 2.0); let ir = egui::Rect::from_center_size(r.left_center() + vec2(h * 0.35 + icon / 2.0, 0.0), vec2(icon, icon)); if large { - let fill = if resp.hovered() { DISCORD.gamma_multiply(0.85) } else { DISCORD }; + // The theme's accent, as the primary buttons use it, so the call to action matches the + // rest of the window (and PhotoCraft's, #4684); Discord's colour stays on the app-bar icon. + let t = Tokens::get(ui.ctx()); + let fill = if resp.hovered() { t.accent } else { t.accent_strong }; ui.painter().rect_filled(r, CornerRadius::same((h / 2.0) as u8), fill); icons::paint(ui, "message-circle", ir, Color32::WHITE); ui.painter().galley(egui::pos2(ir.right() + h * 0.2, at.y), galley, Color32::WHITE); diff --git a/crates/ui-egui/src/tests/home.rs b/crates/ui-egui/src/tests/home.rs index 96f50716d..249aa7f76 100644 --- a/crates/ui-egui/src/tests/home.rs +++ b/crates/ui-egui/src/tests/home.rs @@ -438,3 +438,34 @@ fn a_queued_reopen_keeps_the_roots_it_was_asked_in() { assert_eq!(app.session.documents().len(), 1, "the file outside the roots is not opened"); let _ = std::fs::remove_dir_all(d); } + +/// The x-centre of the first text shape whose text is `text` on a drawn Home screen, and the +/// window's centre (#4684). +fn text_centre_x(app: &mut VectorcraftApp, text: &str) -> Option<(f32, f32)> { + fn find(s: &egui::Shape, text: &str) -> Option { + match s { + egui::Shape::Text(t) if t.galley.text() == text => Some(t.pos.x + t.galley.size().x / 2.0), + egui::Shape::Vec(v) => v.iter().find_map(|s| find(s, text)), + _ => None, + } + } + app.canvas_rect = None; + let ctx = egui::Context::default(); + crate::theme::install_fonts(&ctx); + let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1000.0, 700.0)); + let raw = egui::RawInput { screen_rect: Some(screen), ..Default::default() }; + let mut out = ctx.run_ui(raw, |ui| canvas::show(app, ui)); + out.textures_delta.clear(); + let x = out.shapes.iter().find_map(|c| find(&c.shape, text))?; + Some((x, screen.center().x)) +} + +/// The Home screen centres its welcome and its community block, as PhotoCraft's does (#4684). +#[test] +fn home_welcome_and_community_are_centred() { + let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), crate::Services::default()); + for text in ["Welcome to VectorCraft", "Community"] { + let (x, centre) = text_centre_x(&mut app, text).unwrap_or_else(|| panic!("{text} is drawn")); + assert!((x - centre).abs() < 2.0, "{text} is centred: {x} vs {centre}"); + } +} diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 5ba97bacb..3bdb39930 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -39,6 +39,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard | Date | Change | Summary | |---|---|---| +| 2026-10-30 | minor | Home screen: welcome, New / Open and Community are centred and the large Discord button uses the theme accent, part of #4684; scores and estimates unchanged (estimated) | | 2026-11-06 | minor | Snap to Grid: a straight segment dragged with Direct Selection lands its anchors on the grid, not the pressed point (#3835); scores and estimates unchanged | | 2026-11-06 | minor | Drop Shadow: a swatch beside Color follows the hex and a double-click opens the Color Picker over the dialog, whose OK fills Color (#5364); scores and estimates unchanged | | 2026-11-06 | minor | Drop Shadow, Outer Glow and Inner Glow: spinner arrows beside Opacity, the offsets, Blur and Darkness (#5367, #5368); scores and estimates unchanged | @@ -434,6 +435,8 @@ next unit in the order a right-click on a ruler lists them, from Feet back to Po ## Look and feel +- [x] Home screen (part of #4684, shared UI with PhotoCraft): the welcome, New / Open buttons and Community block are centred, and the large Discord button takes the theme's accent instead of Discord's colour; the layout and wording of the preset cards and Recent Files are unchanged. Still open from #4684: shortcut hints on the buttons, PhotoCraft's PRO and STUDIO themes, the Preferences layout (search box, theme swatches, Apply) and the title bar. + - [x] Recolor Artwork › Assign: double-click a row's new color to pick it in the Color Picker, in the model it was picked in (part of #4028); a Lab new color is kept but can't be typed yet (the picker's Lab fields work in RGB); Lab entry, swatch libraries and the row menu remain. - [x] Recolor Artwork Edit color chips scroll within the screen, preserving the wheel and actions (#3416); 5, 20, 200 and 400 colors, resizing and UI scaling, final-chip editing and preview/history covered by egui_kittest.