M14.3: the Home button shows the Home screen over open documents
It used to open the New Document dialog. Now it runs the new app.home UI command: the Home screen replaces the canvas while the documents stay open as tabs; choosing a tab, or a document opening, closing or becoming active, returns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d4c4361b4a
commit
258337cf7c
|
|
@ -150,7 +150,7 @@ grade by behaviour against `plan/illustrator/`, not by whether a menu item exist
|
|||
| M11 | Artboards & views (artboard panel/tool, Trim View, middle-button pan and print tiling done; multiple windows, presentation polish) | 🟡 | 15–25 |
|
||||
| M12 | Advanced color & art (CMYK/ICC, separations, Gradient Mesh, Live Paint, Image Trace, Graphs) | 🟡 Gradient Mesh, Live Paint, Image Trace (12 presets, 18 ms/1k² image), Recolor Artwork, colour management (ICC, soft proofing, separations preview), Graphs (all 9 tools, Graph Data/Type, regenerate in place) done; graph Design/Column/Marker designs pending | 6–10 |
|
||||
| M13 | Automation (Actions ✅ record/playback, persisted; variables, scripting, batch) | 🟡 | 18–27 |
|
||||
| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor, workspaces, a custom title bar on Windows/Linux, content-sized dialogs and menus that scroll when longer than the window done; accessibility, Windows/Linux packaging pending | 18–28 |
|
||||
| M14 | 1.0 polish (preferences, shortcut editor, workspaces, accessibility, packaging for all OSes) | 🟡 Preferences, shortcut editor, workspaces, a custom title bar on Windows/Linux with a Home button, content-sized dialogs and menus that scroll when longer than the window done; accessibility, Windows/Linux packaging pending | 18–28 |
|
||||
| — | Interaction fidelity pass (every tool's modifiers, Properties panel per context, isolation, nuance) | ⬜ | 60–90 |
|
||||
| — | Hardening at scale (big-file corpus, fuzzing, cross-platform + browser QA) | 🟡 | 50–80 |
|
||||
| | **Total to full parity** (one agent; re-derived from the [Parity estimate](#parity-estimate) table) | | **~335–520** |
|
||||
|
|
|
|||
|
|
@ -127,7 +127,11 @@ pub fn fit(app: &mut VectorcraftApp, how: &str) {
|
|||
pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
let full = ui.available_rect_before_wrap();
|
||||
if app.session.active().is_none() {
|
||||
// A document that opened, closed or became active since Home was chosen replaces it.
|
||||
if app.ui.home.is_some_and(|k| k != crate::menus::home_key(app)) {
|
||||
app.ui.home = None;
|
||||
}
|
||||
if app.session.active().is_none() || app.ui.home.is_some() {
|
||||
home(app, ui, full);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@ pub fn app_bar(app: &mut VectorcraftApp, ui: &mut Ui) {
|
|||
let (r, _) = ui.allocate_exact_size(vec2(22.0, 22.0), Sense::hover());
|
||||
crate::brand::paint_mark(ui, r);
|
||||
ui.add_space(4.0);
|
||||
if widgets::icon_button(ui, "house", "Home", false, 24.0).clicked() {
|
||||
crate::dialogs::open_new_document(app);
|
||||
let on_home = app.ui.home.is_some() || app.session.active().is_none();
|
||||
if widgets::icon_button(ui, "house", "Home", on_home, 24.0).clicked() {
|
||||
app.run("app.home", json!({})).ok();
|
||||
}
|
||||
ui.add_space(2.0);
|
||||
let menus_end = if app.native_menu {
|
||||
|
|
@ -237,7 +238,8 @@ pub fn doc_tabs(app: &mut VectorcraftApp, ui: &mut Ui) {
|
|||
for (i, d) in app.session.documents().iter().enumerate() {
|
||||
let zoom = app.views.get(i).map(|v| v.zoom).unwrap_or(1.0);
|
||||
let title = tab_title(d, zoom, app.ui.view.outline);
|
||||
let is_active = Some(i) == active;
|
||||
// On the Home screen no tab is the current one.
|
||||
let is_active = Some(i) == active && app.ui.home.is_none();
|
||||
let galley = ui.painter().layout_no_wrap(title, theme::semibold(12.5), if is_active { t.text_strong } else { t.text_dim });
|
||||
let w = galley.size().x + 50.0;
|
||||
let r = egui::Rect::from_min_size(egui::pos2(x, strip.top()), vec2(w, strip.height() - 1.0));
|
||||
|
|
@ -265,6 +267,7 @@ pub fn doc_tabs(app: &mut VectorcraftApp, ui: &mut Ui) {
|
|||
app.status(e);
|
||||
}
|
||||
} else if let Some(i) = activate {
|
||||
app.ui.home = None;
|
||||
app.session.set_active(i);
|
||||
}
|
||||
// Isolation mode breadcrumb bar.
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ mod tests_clipboard;
|
|||
#[cfg(test)]
|
||||
mod tests_docsetup;
|
||||
#[cfg(test)]
|
||||
mod tests_home;
|
||||
#[cfg(test)]
|
||||
mod tests_labels;
|
||||
#[cfg(test)]
|
||||
mod tests_nativeoptions;
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
|||
),
|
||||
("file.documentSetup", "Document Setup…", "Cmd+Alt+P", "{}"),
|
||||
("file.newDialog", "New…", "Cmd+N", "{} opens the New Document dialog"),
|
||||
("app.home", "Home", "", "{} shows the Home screen (new file presets, Open) over the open documents; choosing a document tab returns to it"),
|
||||
("edit.preferences", "Preferences…", "Cmd+K", "{category?} open Preferences (engine: prefs.get / prefs.set / prefs.list)"),
|
||||
("edit.keyboardShortcuts", "Keyboard Shortcuts…", "Cmd+Alt+Shift+K", "{}"),
|
||||
("shortcuts.set", "Set Keyboard Shortcut", "", "{id: command id or tool:<id>, shortcut: \"Cmd+Shift+K\" | \"\" (none) | null (default), force?}"),
|
||||
|
|
@ -549,6 +550,10 @@ pub fn run_ui_command(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<R
|
|||
crate::dialogs::open_new_document(app);
|
||||
Ok(Value::Null)
|
||||
}
|
||||
"app.home" => {
|
||||
app.ui.home = Some(home_key(app));
|
||||
Ok(Value::Null)
|
||||
}
|
||||
"file.open" => match s("path") {
|
||||
Some(path) => io::open_path(app, &path).map(|_| Value::Null),
|
||||
None => io::open_dialog(app).map(|_| Value::Null),
|
||||
|
|
@ -1919,6 +1924,12 @@ fn render_items(app: &VectorcraftApp, ui: &mut egui::Ui, items: &[Item], clicked
|
|||
}
|
||||
}
|
||||
|
||||
/// What the Home screen remembers when it opens (`app.home`): the active document and the
|
||||
/// document count. When either changes, the Home screen gives way to the document.
|
||||
pub(crate) fn home_key(app: &VectorcraftApp) -> (Option<u64>, usize) {
|
||||
(app.session.active().map(|d| d.uid), app.session.documents().len())
|
||||
}
|
||||
|
||||
fn label_of(it: &Item) -> &'static str {
|
||||
match it {
|
||||
Item::Cmd(l, _, _) => l,
|
||||
|
|
|
|||
|
|
@ -298,6 +298,11 @@ pub struct UiState {
|
|||
/// never used).
|
||||
#[serde(default)]
|
||||
pub dxf_import: Value,
|
||||
/// The Home screen is shown over the open documents (`app.home`): the active document's uid
|
||||
/// and the document count when it opened. Choosing a tab, or a document opening, closing or
|
||||
/// becoming active, leaves it.
|
||||
#[serde(skip)]
|
||||
pub home: Option<(Option<u64>, usize)>,
|
||||
}
|
||||
|
||||
impl UiState {
|
||||
|
|
@ -359,6 +364,7 @@ impl Default for UiState {
|
|||
dxf_options: Value::Null,
|
||||
eps_options: Value::Null,
|
||||
dxf_import: Value::Null,
|
||||
home: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
//! The Home icon shows the Home screen over open documents.
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{VectorcraftApp, canvas};
|
||||
|
||||
fn app_with_doc() -> VectorcraftApp {
|
||||
let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), crate::Services::default());
|
||||
app.run("file.new", json!({})).unwrap();
|
||||
app
|
||||
}
|
||||
|
||||
/// Draw one canvas frame; whether it drew the document (else the Home screen).
|
||||
fn shows_document(app: &mut VectorcraftApp) -> bool {
|
||||
app.canvas_rect = None;
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
let raw = egui::RawInput { screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(800.0, 600.0))), ..Default::default() };
|
||||
let mut out = ctx.run_ui(raw, |ui| canvas::show(app, ui));
|
||||
out.textures_delta.clear();
|
||||
app.canvas_rect.is_some()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn home_shows_over_open_documents_until_a_document_is_chosen() {
|
||||
let mut app = app_with_doc();
|
||||
assert!(shows_document(&mut app));
|
||||
app.run("app.home", json!({})).unwrap();
|
||||
assert!(!shows_document(&mut app), "Home replaces the canvas");
|
||||
assert_eq!(app.session.documents().len(), 1, "the document stays open");
|
||||
assert!(app.ui.dialog.is_none(), "Home is not the New Document dialog");
|
||||
// Choosing the document's tab returns to it.
|
||||
app.ui.home = None;
|
||||
assert!(shows_document(&mut app));
|
||||
// A new document (from Home's presets, New… or Open) replaces Home too.
|
||||
app.run("app.home", json!({})).unwrap();
|
||||
app.run("file.new", json!({})).unwrap();
|
||||
assert!(shows_document(&mut app));
|
||||
assert!(app.ui.home.is_none());
|
||||
}
|
||||
Loading…
Reference in New Issue