diff --git a/Cargo.lock b/Cargo.lock index 32fcfc62ad..777c482379 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6928,6 +6928,7 @@ name = "vectorcraft-ui-egui" version = "0.24.1" dependencies = [ "bytemuck", + "chrono", "craft-keymap", "craft-ui", "craft-update", diff --git a/crates/mcp/src/ui_catalog.rs b/crates/mcp/src/ui_catalog.rs index 1ae99d0c25..7cb80e08da 100644 --- a/crates/mcp/src/ui_catalog.rs +++ b/crates/mcp/src/ui_catalog.rs @@ -432,6 +432,12 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[ ), ("view.nextArtboard", "Next Artboard", "", "{} the navigator's Next Artboard button: view.goToArtboard {index: \"next\"} → {index}"), ("view.lastArtboard", "Last Artboard", "", "{} the navigator's Last Artboard button: view.goToArtboard {index: \"last\"} → {index}"), + ( + "view.statusBarShow", + "Status Bar Show", + "", + "{show: \"artboardName\" | \"currentTool\" | \"dateTime\" | \"undos\" | \"colorProfile\"} the status bar's Show menu (a click on its info field): the field shows the name of the artboard the navigator shows, the tool in use (the default), the date and time (local on the desktop, UTC on the web), the active document's undo and redo step counts, or the profile its colors use (the one assigned for its color mode, else, or when that one is not available, that mode's working space); kept with the UI state; any other value is an error → show", + ), ("view.edges", "Hide Edges", "Cmd+H", "{}"), ("view.artboards", "Hide Artboards", "Cmd+Shift+H", "{}"), ( diff --git a/crates/ui-egui/Cargo.toml b/crates/ui-egui/Cargo.toml index 2ea7ac8079..92a942f4c5 100644 --- a/crates/ui-egui/Cargo.toml +++ b/crates/ui-egui/Cargo.toml @@ -54,6 +54,9 @@ log = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] craft-ui = { workspace = true, features = ["native-windows"] } craft-update = { workspace = true } +# The local date and time the status bar's Date and Time readout shows (`chrono::Local`). Already in +# Cargo.lock with the time-zone crates `clock` uses. +chrono = { workspace = true, features = ["clock"] } [target.'cfg(target_arch = "wasm32")'.dependencies] # `now_ms` (src/lib.rs) reads the page's `performance.now()` with this crate in the web build. It is diff --git a/crates/ui-egui/src/chrome.rs b/crates/ui-egui/src/chrome.rs index fc0234885b..35431690e3 100644 --- a/crates/ui-egui/src/chrome.rs +++ b/crates/ui-egui/src/chrome.rs @@ -28,9 +28,9 @@ use control_bar::{CONTROL_BAR_FLOAT_AT, ISOLATION_BUTTON}; #[cfg(test)] use hints::hint_segments; pub use hints::{hint_bar, hint_strings}; -pub use status_bar::status_bar; +pub use status_bar::{StatusBarShow, deserialize_status_bar_show, set_status_bar_show, status_bar}; #[cfg(test)] -use status_bar::{StatusReadoutWidths, status_readouts}; +use status_bar::{StatusReadoutWidths, color_profile_name, date_time_label, status_readouts}; #[cfg(test)] use tabs::{CLOSE_BEFORE_TITLE, first_tab_shown, tab_drop, tab_groups, tab_title}; pub use tabs::{doc_tabs, isolation_bar, step_document}; diff --git a/crates/ui-egui/src/chrome/status_bar.rs b/crates/ui-egui/src/chrome/status_bar.rs index 1e946b56da..45cd600771 100644 --- a/crates/ui-egui/src/chrome/status_bar.rs +++ b/crates/ui-egui/src/chrome/status_bar.rs @@ -73,19 +73,37 @@ pub fn status_bar(app: &mut VectorcraftApp, ui: &mut Ui) { app.status(e); } ui.separator(); - let tool = vectorcraft_tools::tool_info(app.session.tool_id()) - .map(|t| { - // The catalog keys carry the full label ("Selection Tool"); only English drops the suffix. - let shown = tl!(t.label); - if crate::i18n::current() == crate::i18n::Lang::EN { shown.trim_end_matches(" Tool") } else { shown } - }) - .unwrap_or(""); - // The tool name leaves the status message its least width and ends in an ellipsis first. + let (info, next) = info_text(app); + if let Some(secs) = next { + ui.ctx().request_repaint_after(std::time::Duration::from_secs(secs)); + } + // The info field leaves the status message its least width and ends in an ellipsis first. + // An empty readout shows a dash, so the field can still be clicked. let room = (ui.available_width() - MESSAGE_MIN - ui.spacing().item_spacing.x).max(0.0); - ui.scope(|ui| { - ui.set_max_width(room); - clipped_label(ui, egui::RichText::new(tool).size(11.5).color(t.text_dim)); + let shown = if info.is_empty() { "–" } else { info.as_str() }; + let field = ui + .scope(|ui| { + ui.set_max_width(room); + clipped_label(ui, egui::RichText::new(shown).size(11.5).color(t.text_dim)) + }) + .inner + .interact(Sense::click()); + let mut pick = None; + egui::Popup::menu(&field).show(|ui| { + ui.menu_button(tl!("Show"), |ui| { + for show in StatusBarShow::ALL { + if widgets::menu_item_name(ui, show.label(), true, app.ui.status_bar_show == show) { + pick = Some(show); + ui.close(); + } + } + }); }); + if let Some(show) = pick + && let Err(e) = app.run("view.statusBarShow", json!({ "show": show.param() })) + { + app.status(e); + } status_readouts(app, ui, &t); }); }); @@ -95,6 +113,152 @@ pub fn status_bar(app: &mut VectorcraftApp, ui: &mut Ui) { /// The least width the status message keeps when the window is narrow. const MESSAGE_MIN: f32 = 180.0; +/// What the status bar's info field shows, chosen from the Show menu that a click on the field +/// opens (`view.statusBarShow`). Kept with the UI state ([`crate::UiState::status_bar_show`]). +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub enum StatusBarShow { + /// The name of the artboard the navigator shows. + ArtboardName, + /// The name of the tool in use. + #[default] + CurrentTool, + /// The date and time. + DateTime, + /// How many steps the active document can undo and redo. + Undos, + /// The profile the active document's colors use. + ColorProfile, +} + +impl StatusBarShow { + /// Every choice, in the Show menu's order. + pub const ALL: [StatusBarShow; 5] = + [StatusBarShow::ArtboardName, StatusBarShow::CurrentTool, StatusBarShow::DateTime, StatusBarShow::Undos, StatusBarShow::ColorProfile]; + + /// The `show` param of `view.statusBarShow`. + pub fn param(self) -> &'static str { + match self { + StatusBarShow::ArtboardName => "artboardName", + StatusBarShow::CurrentTool => "currentTool", + StatusBarShow::DateTime => "dateTime", + StatusBarShow::Undos => "undos", + StatusBarShow::ColorProfile => "colorProfile", + } + } + + /// The choice whose param is `param`. + pub fn from_param(param: &str) -> Option { + StatusBarShow::ALL.into_iter().find(|s| s.param() == param) + } + + /// The Show menu's label, in the interface language. + pub fn label(self) -> &'static str { + match self { + StatusBarShow::ArtboardName => tl!("Artboard Name"), + StatusBarShow::CurrentTool => tl!("Current Tool"), + StatusBarShow::DateTime => tl!("Date and Time"), + StatusBarShow::Undos => tl!("Number of Undos"), + StatusBarShow::ColorProfile => tl!("Document Color Profile"), + } + } +} + +/// Serde reader for the saved choice ([`crate::UiState::status_bar_show`]): a value this version +/// does not know reads as Current Tool. +pub fn deserialize_status_bar_show<'de, D: serde::Deserializer<'de>>(d: D) -> Result { + let v = ::deserialize(d)?; + Ok(v.as_str().and_then(StatusBarShow::from_param).unwrap_or_default()) +} + +/// `view.statusBarShow {show}`: the info field shows that readout from now on → the choice. +pub fn set_status_bar_show(app: &mut VectorcraftApp, p: &serde_json::Value) -> Result { + let key = "show"; + let Some(show) = p.get(key).and_then(serde_json::Value::as_str).and_then(StatusBarShow::from_param) else { + let all: Vec<&str> = StatusBarShow::ALL.iter().map(|s| s.param()).collect(); + return Err(format!("`{key}` must be one of {}", all.join(", "))); + }; + app.ui.status_bar_show = show; + Ok(json!(show.param())) +} + +/// The info field's text for the choice in the Show menu, and for Date and Time the seconds until +/// the minute it shows ends (when the bar draws again). +pub(super) fn info_text(app: &VectorcraftApp) -> (String, Option) { + let st = app.session.active(); + match app.ui.status_bar_show { + StatusBarShow::CurrentTool => { + let tool = vectorcraft_tools::tool_info(app.session.tool_id()) + .map(|t| { + // The catalog keys carry the full label ("Selection Tool"); only English drops the suffix. + let shown = tl!(t.label); + if crate::i18n::current() == crate::i18n::Lang::EN { shown.trim_end_matches(" Tool") } else { shown } + }) + .unwrap_or(""); + (tool.to_string(), None) + } + StatusBarShow::ArtboardName => { + let name = st.and_then(|d| { + let n = d.doc.artboards.len(); + d.doc.artboards.get(crate::panels::artboards::selected(app, n)).map(|a| a.name.clone()) + }); + (name.unwrap_or_default(), None) + } + StatusBarShow::DateTime => { + let (text, next) = date_time_now(); + (text, Some(next)) + } + StatusBarShow::Undos => { + let text = st.map(|d| format!("{}: {} {}: {}", tl!("Undos"), d.history.undo.len(), tl!("Redos"), d.history.redo.len())); + (text.unwrap_or_default(), None) + } + StatusBarShow::ColorProfile => (st.map(|d| color_profile_name(&d.doc)).unwrap_or_default(), None), + } +} + +/// The profile `doc`'s colors use for its color mode, as the context it draws through has it +/// ([`vectorcraft_engine::cmd::colormgmt::doc_cms`]): the one assigned (Edit › Assign Profile), else +/// the working space of that mode (Edit › Color Settings), also when the assigned one is not +/// available. +pub(super) fn color_profile_name(doc: &vectorcraft_doc::Document) -> String { + let cms = vectorcraft_engine::cmd::colormgmt::doc_cms(doc); + let settings = cms.settings(); + let name = match doc.color_mode { + vectorcraft_doc::ColorMode::Rgb => &settings.rgb, + vectorcraft_doc::ColorMode::Cmyk => &settings.cmyk, + }; + vectorcraft_color::cms::canonical_name(name).to_string() +} + +/// `[year, month, day, hour, minute, second]` as the info field shows it: `2026-11-15 14:03`. +pub(super) fn date_time_label([y, mo, d, h, mi, _]: [i64; 6]) -> String { + format!("{y:04}-{mo:02}-{d:02} {h:02}:{mi:02}") +} + +/// The local date and time ([`date_time_label`]) and the seconds until the minute ends. +#[cfg(not(target_arch = "wasm32"))] +fn date_time_now() -> (String, u64) { + use chrono::{Datelike, Timelike}; + let now = chrono::Local::now(); + let parts = [ + i64::from(now.year()), + i64::from(now.month()), + i64::from(now.day()), + i64::from(now.hour()), + i64::from(now.minute()), + i64::from(now.second()), + ]; + (date_time_label(parts), 60 - u64::from(now.second().min(59))) +} + +/// The web build reads no time zone, so it shows the date and time in UTC. +#[cfg(target_arch = "wasm32")] +fn date_time_now() -> (String, u64) { + let secs = web_time::SystemTime::now().duration_since(web_time::UNIX_EPOCH).map_or(0, |d| d.as_secs()); + let parts = vectorcraft_doc::metadata::civil(i64::try_from(secs).unwrap_or(i64::MAX)); + (format!("{} UTC", date_time_label(parts)), 60 - u64::try_from(parts[5].clamp(0, 59)).unwrap_or(0)) +} + /// A label that ends in an ellipsis when it is wider than the room left in `ui`. Only a cut label /// shows its full text in a tooltip; screen readers always receive the full text. pub(super) fn clipped_label(ui: &mut Ui, text: impl Into) -> egui::Response { diff --git a/crates/ui-egui/src/chrome/tests.rs b/crates/ui-egui/src/chrome/tests.rs index be37f10a29..ecba2ad38d 100644 --- a/crates/ui-egui/src/chrome/tests.rs +++ b/crates/ui-egui/src/chrome/tests.rs @@ -576,6 +576,155 @@ fn a_clipped_tool_name_shows_in_full_on_hover() { } } +/// The texts of one status bar frame after `events`, `dt` seconds after the last one. +fn status_after(app: &mut crate::VectorcraftApp, ctx: &egui::Context, dt: f64, events: Vec) -> Vec { + let t = ctx.input(|i| i.time) + dt; + bar_frame(app, ctx, 1400.0, Some(t), events, super::status_bar).0 +} + +/// A press and release of the primary button at `pos`. +fn click_at(pos: egui::Pos2) -> Vec { + let button = |pressed| egui::Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() }; + vec![egui::Event::PointerMoved(pos), button(true), button(false)] +} + +/// The center of the first text that is `text`. +fn text_center(texts: &[StatusText], text: &str) -> egui::Pos2 { + let at = texts.iter().find(|t| t.text == text).unwrap_or_else(|| panic!("no {text:?} in {texts:?}")); + at.clip.intersect(at.bounds).center() +} + +/// The status bar's info field shows the readout `view.statusBarShow` chooses: the navigator's +/// artboard name, the tool in use, the date and time, the undo and redo counts, or the document's +/// color profile. +#[test] +fn the_status_bar_info_field_shows_the_chosen_readout() { + let (mut app, ctx) = status_readout_app(); + let texts = status_after(&mut app, &ctx, 0.1, vec![]); + assert!(texts.iter().any(|t| t.text == "Selection"), "Current Tool by default: {texts:?}"); + + app.run("artboard.new", json!({"x": 200, "y": 0, "width": 100, "height": 100, "name": "Back Cover"})).unwrap(); + app.run("view.statusBarShow", json!({"show": "artboardName"})).unwrap(); + let first = app.session.active().unwrap().doc.artboards[0].name.clone(); + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == first), "the first artboard's name"); + app.run("view.goToArtboard", json!({"index": 1})).unwrap(); + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == "Back Cover"), "the navigator's artboard"); + + app.run("view.statusBarShow", json!({"show": "undos"})).unwrap(); + let counts = |app: &crate::VectorcraftApp| { + let h = &app.session.active().unwrap().history; + format!("Undos: {} Redos: {}", h.undo.len(), h.redo.len()) + }; + let before = app.session.active().unwrap().history.undo.len(); + app.session.execute("shape.rectangle", &json!({"x": 0, "y": 0, "width": 10, "height": 10})).unwrap(); + assert_eq!(counts(&app), format!("Undos: {} Redos: 0", before + 1)); + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == counts(&app))); + app.run("edit.undo", json!({})).unwrap(); + assert_eq!(counts(&app), format!("Undos: {before} Redos: 1")); + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == counts(&app)), "the redo step counts"); + + app.run("view.statusBarShow", json!({"show": "colorProfile"})).unwrap(); + let working = vectorcraft_color::cms::working_settings(); + let mode_working = |app: &crate::VectorcraftApp| match app.session.active().unwrap().doc.color_mode { + vectorcraft_doc::ColorMode::Rgb => working.rgb.clone(), + vectorcraft_doc::ColorMode::Cmyk => working.cmyk.clone(), + }; + let untagged = vectorcraft_color::cms::canonical_name(&mode_working(&app)).to_string(); + assert_eq!(super::color_profile_name(&app.session.active().unwrap().doc), untagged, "untagged: the working space"); + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == untagged)); + // A profile assigned for the document's color mode shows; one that is not available shows the + // working space the document draws through. + let (key, assigned) = match app.session.active().unwrap().doc.color_mode { + vectorcraft_doc::ColorMode::Rgb => ("rgb", vectorcraft_color::cms::PROPHOTO_RGB), + vectorcraft_doc::ColorMode::Cmyk => ("cmyk", vectorcraft_color::cms::DEVICE_CMYK), + }; + app.run("edit.assignProfile", json!({ key: assigned })).unwrap(); + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == assigned), "the assigned profile"); + let st = app.session.active_mut().unwrap(); + std::sync::Arc::make_mut(&mut st.doc).color_profiles = + vectorcraft_doc::ColorProfiles { rgb: Some("Not Installed".into()), cmyk: Some("Not Installed".into()) }; + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == untagged), "an unavailable profile: the working space"); + + app.run("view.statusBarShow", json!({"show": "dateTime"})).unwrap(); + let texts = status_after(&mut app, &ctx, 0.1, vec![]); + let is_date = |s: &str| { + let b = s.as_bytes(); + b.len() == 16 + && b.iter().enumerate().all(|(i, c)| match i { + 4 | 7 => *c == b'-', + 10 => *c == b' ', + 13 => *c == b':', + _ => c.is_ascii_digit(), + }) + }; + assert!(texts.iter().any(|t| is_date(&t.text)), "a date and time: {texts:?}"); + assert_eq!(super::date_time_label([2026, 3, 7, 9, 5, 59]), "2026-03-07 09:05"); + + // Without a document the field shows a dash, which can still be clicked. + app.run("view.statusBarShow", json!({"show": "undos"})).unwrap(); + while app.session.active().is_some() { + app.session.execute("file.close", &json!({})).unwrap(); + } + assert!(status_after(&mut app, &ctx, 0.1, vec![]).iter().any(|t| t.text == "–")); +} + +/// A click on the info field opens its Show menu, which checks the readout shown and changes it. +#[test] +fn a_click_on_the_info_field_opens_the_show_menu() { + let (mut app, ctx) = status_readout_app(); + status_after(&mut app, &ctx, 1.0, vec![egui::Event::PointerGone]); + let texts = status_after(&mut app, &ctx, 0.1, vec![]); + let field = text_center(&texts, "Selection"); + status_after(&mut app, &ctx, 0.1, click_at(field)); + let texts = status_after(&mut app, &ctx, 0.1, vec![]); + let show = text_center(&texts, "Show"); + status_after(&mut app, &ctx, 0.1, vec![egui::Event::PointerMoved(show)]); + status_after(&mut app, &ctx, 0.5, vec![]); + let texts = status_after(&mut app, &ctx, 0.5, vec![]); + for label in [" Artboard Name", "✓ Current Tool", " Date and Time", " Number of Undos", " Document Color Profile"] { + assert!(texts.iter().any(|t| t.text == label), "no {label:?} in {texts:?}"); + } + let undos = text_center(&texts, " Number of Undos"); + status_after(&mut app, &ctx, 0.1, vec![egui::Event::PointerMoved(egui::pos2(undos.x, show.y)), egui::Event::PointerMoved(undos)]); + status_after(&mut app, &ctx, 0.1, click_at(undos)); + assert_eq!(app.ui.status_bar_show, super::StatusBarShow::Undos); + assert_eq!(crate::menus::checked(&app, "view.statusBarShow", &json!({"show": "undos"})), Some(true)); + assert_eq!(crate::menus::checked(&app, "view.statusBarShow", &json!({"show": "currentTool"})), Some(false)); +} + +/// `view.statusBarShow` takes only the five readouts, leaving the choice as it was otherwise, and the +/// choice is saved with the UI state, which reads a value it does not know as Current Tool. +#[test] +fn the_status_bar_show_choice_is_checked_and_saved() { + let (mut app, _ctx) = status_readout_app(); + assert_eq!(app.run("view.statusBarShow", json!({"show": "dateTime"})).unwrap(), json!("dateTime")); + for bad in [json!({}), json!({"show": "zoom"}), json!({"show": 2}), json!({"show": null}), json!({"show": "DateTime"})] { + let err = app.run("view.statusBarShow", bad.clone()).unwrap_err(); + assert!(err.contains("`show` must be one of artboardName, currentTool, dateTime, undos, colorProfile"), "{bad}: {err}"); + assert_eq!(app.ui.status_bar_show, super::StatusBarShow::DateTime, "{bad} leaves the choice"); + } + let saved = serde_json::to_value(&app.ui).unwrap(); + assert_eq!(saved["status_bar_show"], json!("dateTime")); + let read: crate::state::UiState = serde_json::from_value(saved.clone()).unwrap(); + assert_eq!(read.status_bar_show, super::StatusBarShow::DateTime); + for (stored, shown) in [ + (json!("colorProfile"), super::StatusBarShow::ColorProfile), + (json!("zoom"), super::StatusBarShow::CurrentTool), + (json!(7), super::StatusBarShow::CurrentTool), + ] { + let mut v = saved.clone(); + v["status_bar_show"] = stored; + assert_eq!(serde_json::from_value::(v).unwrap().status_bar_show, shown); + } + let mut v = saved; + v.as_object_mut().unwrap().remove("status_bar_show"); + assert_eq!( + serde_json::from_value::(v).unwrap().status_bar_show, + super::StatusBarShow::CurrentTool, + "state saved before it" + ); +} + /// Busy-job transitions preserve message placement, labels and accessibility. #[test] fn background_activity_keeps_the_status_message_origin() { diff --git a/crates/ui-egui/src/i18n/bg.tsv b/crates/ui-egui/src/i18n/bg.tsv index 948b295e17..05b99a0c72 100644 --- a/crates/ui-egui/src/i18n/bg.tsv +++ b/crates/ui-egui/src/i18n/bg.tsv @@ -1346,6 +1346,14 @@ font-technology Variable Променливи Previous Artboard Предишна работна област Next Artboard Следваща работна област Last Artboard Последна работна област + Status Bar Show Показване в лентата на състоянието + Artboard Name Име на работната област + Current Tool Текущ инструмент + Date and Time Дата и час + Number of Undos Брой отмени + Document Color Profile Цветови профил на документа + Undos Отмени + Redos Повторения Go To Link Към връзката GPL palettes keep solid colours only, as RGB. Палитрите GPL запазват само плътни цветове като RGB. GPU Performance Производителност на графичния процесор diff --git a/crates/ui-egui/src/i18n/bs.tsv b/crates/ui-egui/src/i18n/bs.tsv index f8d6fa263b..3f1c7cc242 100644 --- a/crates/ui-egui/src/i18n/bs.tsv +++ b/crates/ui-egui/src/i18n/bs.tsv @@ -1079,6 +1079,14 @@ lighting Light Svjetlo Previous Artboard Prethodna radna ploča Next Artboard Sljedeća radna ploča Last Artboard Posljednja radna ploča + Status Bar Show Prikaz u traci stanja + Artboard Name Naziv radne ploče + Current Tool Trenutni alat + Date and Time Datum i vrijeme + Number of Undos Broj poništavanja + Document Color Profile Profil boja dokumenta + Undos Poništavanja + Redos Ponavljanja Graphic Style Options… Opcije grafičkog stila… Symbol Options Opcije simbola Symbol Options… Opcije simbola… diff --git a/crates/ui-egui/src/i18n/ca.tsv b/crates/ui-egui/src/i18n/ca.tsv index 3ed3ca8331..653b916a53 100644 --- a/crates/ui-egui/src/i18n/ca.tsv +++ b/crates/ui-egui/src/i18n/ca.tsv @@ -2281,6 +2281,14 @@ digits Malayalam Malaiàlam Enclosing Lasso Llaç envoltant Last Últim Last Artboard Últim tauler + Status Bar Show Mostra a la barra d'estat + Artboard Name Nom del tauler + Current Tool Eina actual + Date and Time Data i hora + Number of Undos Nombre de desfets + Document Color Profile Perfil de color del document + Undos Desfets + Redos Refets Last commit Últim commit Last Effect: {name} Últim efecte: {name} Last Effect: {} Últim efecte: {} diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 161e235c56..38c9d37700 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -1103,6 +1103,14 @@ lighting Light Světlo Previous Artboard Předchozí pracovní plocha Next Artboard Další pracovní plocha Last Artboard Poslední pracovní plocha + Status Bar Show Zobrazit ve stavovém řádku + Artboard Name Název pracovní plochy + Current Tool Aktuální nástroj + Date and Time Datum a čas + Number of Undos Počet kroků zpět + Document Color Profile Barevný profil dokumentu + Undos Zpět + Redos Znovu Graphic Style Options… Možnosti grafického stylu… Symbol Options Možnosti symbolu Symbol Options… Možnosti symbolu… diff --git a/crates/ui-egui/src/i18n/da.tsv b/crates/ui-egui/src/i18n/da.tsv index fd0b7c042e..8c26868327 100644 --- a/crates/ui-egui/src/i18n/da.tsv +++ b/crates/ui-egui/src/i18n/da.tsv @@ -6414,6 +6414,14 @@ swatch Bright Violet Kraftig violet Color wheel Farvehjul First Artboard Første kunstplade Last Artboard Sidste kunstplade + Status Bar Show Vis i statuslinjen + Artboard Name Kunstpladens navn + Current Tool Aktuelt værktøj + Date and Time Dato og klokkeslæt + Number of Undos Antal fortrydelser + Document Color Profile Dokumentets farveprofil + Undos Fortrydelser + Redos Gentagelser Next Artboard Næste kunstplade Previous Artboard Forrige kunstplade Step up or down Trinvis op eller ned diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index 2a5f32a5d9..5676a32f1f 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -1391,6 +1391,14 @@ file-filter Templates Vorlagen Previous Artboard Vorherige Zeichenfläche Next Artboard Nächste Zeichenfläche Last Artboard Letzte Zeichenfläche + Status Bar Show In Statusleiste anzeigen + Artboard Name Name der Zeichenfläche + Current Tool Aktuelles Werkzeug + Date and Time Datum und Uhrzeit + Number of Undos Anzahl der Rückgängig-Schritte + Document Color Profile Farbprofil des Dokuments + Undos Rückgängig + Redos Wiederholen Go To Link Gehe zu Verknüpfung GPL palettes keep solid colours only, as RGB. GPL-Paletten enthalten nur einfarbige Farben, als RGB. GPU Performance GPU-Leistung diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index b1b7b4d039..b0a4e001ec 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -1321,6 +1321,14 @@ font-technology Variable Μεταβλητές Previous Artboard Προηγούμενος πίνακας σχεδίασης Next Artboard Επόμενος πίνακας σχεδίασης Last Artboard Τελευταίος πίνακας σχεδίασης + Status Bar Show Εμφάνιση στη γραμμή κατάστασης + Artboard Name Όνομα πίνακα σχεδίασης + Current Tool Τρέχον εργαλείο + Date and Time Ημερομηνία και ώρα + Number of Undos Αριθμός αναιρέσεων + Document Color Profile Χρωματικό προφίλ εγγράφου + Undos Αναιρέσεις + Redos Επαναλήψεις Go To Link Μετάβαση στη σύνδεση GPL palettes keep solid colours only, as RGB. Οι παλέτες GPL διατηρούν μόνο συμπαγή χρώματα σε RGB. GPU Performance Απόδοση GPU diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index 5b3c675f7b..ee4834b6b1 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -1400,6 +1400,14 @@ font-technology Variable Variables Previous Artboard Mesa de trabajo anterior Next Artboard Mesa de trabajo siguiente Last Artboard Última mesa de trabajo + Status Bar Show Mostrar en la barra de estado + Artboard Name Nombre de la mesa de trabajo + Current Tool Herramienta actual + Date and Time Fecha y hora + Number of Undos Número de deshacer + Document Color Profile Perfil de color del documento + Undos Deshacer + Redos Rehacer Go To Link Ir al vínculo GPL palettes keep solid colours only, as RGB. Las paletas GPL solo conservan colores sólidos, en RGB. GPU Performance Rendimiento de GPU diff --git a/crates/ui-egui/src/i18n/fi.tsv b/crates/ui-egui/src/i18n/fi.tsv index e77a617c52..35934828f0 100644 --- a/crates/ui-egui/src/i18n/fi.tsv +++ b/crates/ui-egui/src/i18n/fi.tsv @@ -1082,6 +1082,14 @@ lighting Light Valo Previous Artboard Edellinen piirtoalusta Next Artboard Seuraava piirtoalusta Last Artboard Viimeinen piirtoalusta + Status Bar Show Näytä tilarivillä + Artboard Name Piirtoalustan nimi + Current Tool Nykyinen työkalu + Date and Time Päivämäärä ja aika + Number of Undos Kumousten määrä + Document Color Profile Asiakirjan väriprofiili + Undos Kumoukset + Redos Uudelleentekot Graphic Style Options… Grafiikkatyylin asetukset… Symbol Options Symbolin asetukset Symbol Options… Symbolin asetukset… diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 2762d2a954..f394a85124 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -1394,6 +1394,14 @@ font-technology Variable Variables Previous Artboard Plan de travail précédent Next Artboard Plan de travail suivant Last Artboard Dernier plan de travail + Status Bar Show Afficher dans la barre d'état + Artboard Name Nom du plan de travail + Current Tool Outil actif + Date and Time Date et heure + Number of Undos Nombre d'annulations + Document Color Profile Profil colorimétrique du document + Undos Annulations + Redos Rétablissements Go To Link Atteindre le lien GPL palettes keep solid colours only, as RGB. Les palettes GPL ne conservent que les couleurs unies, en RVB. GPU Performance Performances GPU diff --git a/crates/ui-egui/src/i18n/gu.tsv b/crates/ui-egui/src/i18n/gu.tsv index 1c96900b2b..795176eb2c 100644 --- a/crates/ui-egui/src/i18n/gu.tsv +++ b/crates/ui-egui/src/i18n/gu.tsv @@ -1864,6 +1864,14 @@ Lasso Tool લાસો ટૂલ Last છેલ્લું Last Artboard છેલ્લું આર્ટબોર્ડ + Status Bar Show સ્ટેટસ બારમાં બતાવો + Artboard Name આર્ટબોર્ડનું નામ + Current Tool વર્તમાન ટૂલ + Date and Time તારીખ અને સમય + Number of Undos પૂર્વવત્ કરવાની સંખ્યા + Document Color Profile દસ્તાવેજની રંગ પ્રોફાઇલ + Undos પૂર્વવત્ + Redos ફરીથી કરો Last Effect: {name} છેલ્લી ઇફેક્ટ: {name} Last Effect… છેલ્લી ઇફેક્ટ… Last Page છેલ્લું પેજ diff --git a/crates/ui-egui/src/i18n/hi.tsv b/crates/ui-egui/src/i18n/hi.tsv index 548f961f51..3c05538c66 100644 --- a/crates/ui-egui/src/i18n/hi.tsv +++ b/crates/ui-egui/src/i18n/hi.tsv @@ -2526,6 +2526,14 @@ antiAlias Sharp शार्प Lasso Tool लैस्सो टूल Last अंतिम Last Artboard अंतिम आर्टबोर्ड + Status Bar Show स्टेटस बार में दिखाएँ + Artboard Name आर्टबोर्ड का नाम + Current Tool मौजूदा टूल + Date and Time तारीख और समय + Number of Undos पूर्ववत करने की संख्या + Document Color Profile दस्तावेज़ की रंग प्रोफ़ाइल + Undos पूर्ववत + Redos फिर से करें Last commit अंतिम कमिट Last Effect: {} अंतिम इफ़ेक्ट: {} Last Effect: {name} अंतिम इफ़ेक्ट: {name} diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index 200b45d1b1..d9d10b9766 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -1737,6 +1737,14 @@ file-filter Templates Sablonok Previous Artboard Előző rajztábla Next Artboard Következő rajztábla Last Artboard Utolsó rajztábla + Status Bar Show Megjelenítés az állapotsorban + Artboard Name Rajztábla neve + Current Tool Aktuális eszköz + Date and Time Dátum és idő + Number of Undos Visszavonások száma + Document Color Profile Dokumentum színprofilja + Undos Visszavonások + Redos Újra Go to Conflict Ugrás az ütközésre Go To Link Ugrás a csatoláshoz Good Jó diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv index f3dcca3874..29e73566f4 100644 --- a/crates/ui-egui/src/i18n/id.tsv +++ b/crates/ui-egui/src/i18n/id.tsv @@ -5804,6 +5804,14 @@ swatch Bright Violet Violet cerah Color wheel Roda warna First Artboard Artboard pertama Last Artboard Artboard terakhir + Status Bar Show Tampilkan di bilah status + Artboard Name Nama artboard + Current Tool Alat saat ini + Date and Time Tanggal dan waktu + Number of Undos Jumlah urungkan + Document Color Profile Profil warna dokumen + Undos Urungkan + Redos Ulangi Next Artboard Artboard berikutnya Previous Artboard Artboard sebelumnya Step up or down Naikkan atau turunkan bertahap diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index 90ec79404c..76d1e6361c 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -1421,6 +1421,14 @@ file-filter Templates Modelli Previous Artboard Tavola da disegno precedente Next Artboard Tavola da disegno successiva Last Artboard Ultima tavola da disegno + Status Bar Show Mostra nella barra di stato + Artboard Name Nome tavola da disegno + Current Tool Strumento attivo + Date and Time Data e ora + Number of Undos Numero di annullamenti + Document Color Profile Profilo colore del documento + Undos Annullamenti + Redos Ripristini Go To Link Vai al collegamento GPL palettes keep solid colours only, as RGB. Le palette GPL conservano solo i colori pieni, in RGB. GPU Performance Prestazioni GPU diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index d98acfa22d..d15d71f906 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -1883,6 +1883,14 @@ antiAlias Sharp シャープ Previous Artboard 前のアートボード Next Artboard 次のアートボード Last Artboard 最後のアートボード + Status Bar Show ステータスバーの表示 + Artboard Name アートボード名 + Current Tool 現在のツール + Date and Time 日付と時刻 + Number of Undos 取り消し回数 + Document Color Profile ドキュメントのカラープロファイル + Undos 取り消し + Redos やり直し Gradient Fill: click to apply, drag onto art グラデーションの塗り: クリックで適用、アートにドラッグ Gradient Mesh グラデーションメッシュ Gradient Tool グラデーションツール diff --git a/crates/ui-egui/src/i18n/ka.tsv b/crates/ui-egui/src/i18n/ka.tsv index 794e5454a9..8d3b873a76 100644 --- a/crates/ui-egui/src/i18n/ka.tsv +++ b/crates/ui-egui/src/i18n/ka.tsv @@ -6031,6 +6031,14 @@ imageTrace Outline კონტური JavaScript: JavaScript: Large Gaps დიდი ღრეჩოები Last Artboard ბოლო სამუშაო დაფა + Status Bar Show ჩვენება მდგომარეობის ზოლში + Artboard Name სამუშაო დაფის სახელი + Current Tool მიმდინარე ხელსაწყო + Date and Time თარიღი და დრო + Number of Undos დაბრუნებების რაოდენობა + Document Color Profile დოკუმენტის ფერის პროფილი + Undos დაბრუნებები + Redos ხელახლა შესრულებები Levels დონეები Library Panel Options ბიბლიოთეკის პანელის პარამეტრები Locate Library… ბიბლიოთეკის მოძებნა… diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index bb8676df71..bdad160786 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -1873,6 +1873,14 @@ antiAlias Sharp 날카롭게 Previous Artboard 이전 아트보드 Next Artboard 다음 아트보드 Last Artboard 마지막 아트보드 + Status Bar Show 상태 표시줄 표시 + Artboard Name 아트보드 이름 + Current Tool 현재 도구 + Date and Time 날짜 및 시간 + Number of Undos 실행 취소 횟수 + Document Color Profile 문서 색상 프로파일 + Undos 실행 취소 + Redos 다시 실행 Gradient Fill: click to apply, drag onto art 그레이디언트 칠: 클릭하여 적용, 아트웍에 끌어 놓기 Gradient Mesh 그레이디언트 메시 Gradient Tool 그레이디언트 도구 diff --git a/crates/ui-egui/src/i18n/nl.tsv b/crates/ui-egui/src/i18n/nl.tsv index a597a03fd0..d8146a49fc 100644 --- a/crates/ui-egui/src/i18n/nl.tsv +++ b/crates/ui-egui/src/i18n/nl.tsv @@ -8203,6 +8203,14 @@ swatch Bright Violet Felviolet Color wheel Kleurenwiel First Artboard Eerste tekenbord Last Artboard Laatste tekenbord + Status Bar Show Weergeven in statusbalk + Artboard Name Naam van tekenbord + Current Tool Huidig gereedschap + Date and Time Datum en tijd + Number of Undos Aantal ongedaan gemaakte stappen + Document Color Profile Kleurprofiel van document + Undos Ongedaan maken + Redos Opnieuw uitvoeren Next Artboard Volgende tekenbord Previous Artboard Vorige tekenbord Step up or down Stapsgewijs verhogen of verlagen diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 99ee2080b8..4fc1ab7340 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -1039,6 +1039,14 @@ lighting Light Światło Previous Artboard Poprzedni obszar kompozycji Next Artboard Następny obszar kompozycji Last Artboard Ostatni obszar kompozycji + Status Bar Show Pokaż na pasku stanu + Artboard Name Nazwa obszaru kompozycji + Current Tool Bieżące narzędzie + Date and Time Data i godzina + Number of Undos Liczba cofnięć + Document Color Profile Profil kolorów dokumentu + Undos Cofnięcia + Redos Ponowienia Graphic Style Options… Opcje stylu graficznego… Symbol Options Opcje symbolu Symbol Options… Opcje symbolu… diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 677c8e460f..bb343e8ec8 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -1256,6 +1256,14 @@ antiAlias Sharp Nítido Previous Artboard Mesa de trabalho anterior Next Artboard Próxima mesa de trabalho Last Artboard Última mesa de trabalho + Status Bar Show Mostrar na barra de status + Artboard Name Nome da prancheta + Current Tool Ferramenta atual + Date and Time Data e hora + Number of Undos Número de ações desfeitas + Document Color Profile Perfil de cor do documento + Undos Desfazer + Redos Refazer Gradient Gradiente Gradient Fill: click to apply, drag onto art Preenchimento de Gradiente: clique para aplicar, arraste sobre a arte Gradient Finishes Finalizações de Gradiente diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 106343cddd..bf94e5647b 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -1410,6 +1410,14 @@ file-filter Templates Шаблоны Previous Artboard Предыдущая монтажная область Next Artboard Следующая монтажная область Last Artboard Последняя монтажная область + Status Bar Show Показ в строке состояния + Artboard Name Имя монтажной области + Current Tool Текущий инструмент + Date and Time Дата и время + Number of Undos Число отмен + Document Color Profile Цветовой профиль документа + Undos Отмены + Redos Повторы Go To Link Перейти по ссылке GPL palettes keep solid colours only, as RGB. Палитры GPL сохраняют только сплошные цвета в RGB. GPU Performance Производительность GPU diff --git a/crates/ui-egui/src/i18n/sv.tsv b/crates/ui-egui/src/i18n/sv.tsv index cc854aa362..1e12b2cac1 100644 --- a/crates/ui-egui/src/i18n/sv.tsv +++ b/crates/ui-egui/src/i18n/sv.tsv @@ -1359,6 +1359,14 @@ font-technology Variable Variabla Previous Artboard Föregående rityta Next Artboard Nästa rityta Last Artboard Sista ritytan + Status Bar Show Visa i statusfältet + Artboard Name Ritytans namn + Current Tool Aktuellt verktyg + Date and Time Datum och tid + Number of Undos Antal ångringar + Document Color Profile Dokumentets färgprofil + Undos Ångringar + Redos Gör om Go To Link Gå till länk GPL palettes keep solid colours only, as RGB. GPL-paletter sparar bara enfärgade färger, som RGB. GPU Performance GPU-prestanda diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index f2888a30f0..fc3e7dcca6 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -6037,6 +6037,14 @@ theme Appearance Görünüm JavaScript: JavaScript: Large Gaps Büyük Boşluklar Last Artboard Son Çalışma Yüzeyi + Status Bar Show Durum Çubuğunda Göster + Artboard Name Çalışma Yüzeyi Adı + Current Tool Geçerli Araç + Date and Time Tarih ve Saat + Number of Undos Geri Alma Sayısı + Document Color Profile Belge Renk Profili + Undos Geri Al + Redos Yinele Levels Düzeyler Library Panel Options Kütüphane Paneli Seçenekleri Link JavaScript Files… JavaScript Dosyalarını Bağla… diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 411b2c3baf..1fa0830f67 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -1415,6 +1415,14 @@ file-filter Templates Шаблони Previous Artboard Попередня монтажна область Next Artboard Наступна монтажна область Last Artboard Остання монтажна область + Status Bar Show Показ у рядку стану + Artboard Name Назва монтажної області + Current Tool Поточний інструмент + Date and Time Дата й час + Number of Undos Кількість скасувань + Document Color Profile Колірний профіль документа + Undos Скасування + Redos Повтори Go To Link Перейти за посиланням GPL palettes keep solid colours only, as RGB. Палітри GPL зберігають лише суцільні кольори RGB. GPU Performance Продуктивність GPU diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 1460910197..a1caea9732 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -1646,6 +1646,14 @@ file-filter Templates Mẫu Previous Artboard Bảng vẽ trước Next Artboard Bảng vẽ tiếp theo Last Artboard Bảng vẽ cuối cùng + Status Bar Show Hiển thị trên thanh trạng thái + Artboard Name Tên bảng vẽ + Current Tool Công cụ hiện tại + Date and Time Ngày và giờ + Number of Undos Số lần hoàn tác + Document Color Profile Hồ sơ màu của tài liệu + Undos Hoàn tác + Redos Làm lại Go To Link Đến liên kết Good Tốt GPL palettes keep solid colours only, as RGB. Bảng màu GPL chỉ lưu màu đặc theo RGB. diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index 3fe2f9e009..031aad1945 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -1350,6 +1350,14 @@ file-filter Templates 模板 Previous Artboard 上一个画板 Next Artboard 下一个画板 Last Artboard 最后一个画板 + Status Bar Show 状态栏显示 + Artboard Name 画板名称 + Current Tool 当前工具 + Date and Time 日期和时间 + Number of Undos 撤销次数 + Document Color Profile 文档颜色配置文件 + Undos 撤销 + Redos 重做 Go To Link 转到链接 GPL palettes keep solid colours only, as RGB. GPL 调板仅保留为 RGB 的纯色。 GPU Performance GPU 性能 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index ab7f9d9dd2..0acc8efa49 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -1385,6 +1385,14 @@ file-filter Templates 範本 Previous Artboard 上一個工作區域 Next Artboard 下一個工作區域 Last Artboard 最後一個工作區域 + Status Bar Show 狀態列顯示 + Artboard Name 工作區域名稱 + Current Tool 目前工具 + Date and Time 日期和時間 + Number of Undos 復原次數 + Document Color Profile 文件色彩描述檔 + Undos 復原 + Redos 重做 Go To Link 前往連結 GPL palettes keep solid colours only, as RGB. GPL 調色盤僅保留純色,並以 RGB 儲存。 GPU Performance GPU 效能 diff --git a/crates/ui-egui/src/menus/run.rs b/crates/ui-egui/src/menus/run.rs index df3f08b55e..994f3e571a 100644 --- a/crates/ui-egui/src/menus/run.rs +++ b/crates/ui-egui/src/menus/run.rs @@ -455,6 +455,7 @@ fn run_ui_part5(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option go_to_artboard(app, p), + "view.statusBarShow" => crate::chrome::set_status_bar_show(app, p), // The navigator's four buttons as commands of their own, so Edit › Keyboard Shortcuts lists // them (view.goToArtboard needs an index, so a key alone can't run it). "view.firstArtboard" => go_to_artboard(app, &json!({ "index": "first" })), diff --git a/crates/ui-egui/src/menus/state.rs b/crates/ui-egui/src/menus/state.rs index 98c13ec06e..f08bd87998 100644 --- a/crates/ui-egui/src/menus/state.rs +++ b/crates/ui-egui/src/menus/state.rs @@ -63,6 +63,7 @@ pub fn checked(app: &VectorcraftApp, id: &str, p: &Value) -> Option { "view.rotate" => app.view().zip(p.get("angle").and_then(Value::as_f64)).is_some_and(|(view, a)| (view.rotation - a).abs() < 1e-9), "window.control" => app.ui.control_bar, "window.helpBar" => app.ui.help_bar, + "view.statusBarShow" => p.get("show").and_then(Value::as_str) == Some(app.ui.status_bar_show.param()), "window.control.dock" => p.get("edge").and_then(Value::as_str) == Some(crate::chrome::control_bar_placement(&app.ui)), "window.control.options" => p .get("group") diff --git a/crates/ui-egui/src/menus/ui_commands.rs b/crates/ui-egui/src/menus/ui_commands.rs index d83f03d376..ed2ab69bb7 100644 --- a/crates/ui-egui/src/menus/ui_commands.rs +++ b/crates/ui-egui/src/menus/ui_commands.rs @@ -433,6 +433,12 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[ ), ("view.nextArtboard", "Next Artboard", "", "{} the navigator's Next Artboard button: view.goToArtboard {index: \"next\"} → {index}"), ("view.lastArtboard", "Last Artboard", "", "{} the navigator's Last Artboard button: view.goToArtboard {index: \"last\"} → {index}"), + ( + "view.statusBarShow", + "Status Bar Show", + "", + "{show: \"artboardName\" | \"currentTool\" | \"dateTime\" | \"undos\" | \"colorProfile\"} the status bar's Show menu (a click on its info field): the field shows the name of the artboard the navigator shows, the tool in use (the default), the date and time (local on the desktop, UTC on the web), the active document's undo and redo step counts, or the profile its colors use (the one assigned for its color mode, else, or when that one is not available, that mode's working space); kept with the UI state; any other value is an error → show", + ), ("view.edges", "Hide Edges", "Cmd+H", "{}"), ("view.artboards", "Hide Artboards", "Cmd+Shift+H", "{}"), ( diff --git a/crates/ui-egui/src/state.rs b/crates/ui-egui/src/state.rs index 8c9956b474..4590a2ca9f 100644 --- a/crates/ui-egui/src/state.rs +++ b/crates/ui-egui/src/state.rs @@ -550,6 +550,10 @@ pub struct UiState { #[serde(default)] pub toolbar_right: bool, pub status_bar: bool, + /// What the status bar's info field shows (its Show menu, `view.statusBarShow`): Current Tool by + /// default and in state saved without it ([`crate::chrome::deserialize_status_bar_show`]). + #[serde(default, deserialize_with = "crate::chrome::deserialize_status_bar_show")] + pub status_bar_show: crate::chrome::StatusBarShow, pub help_bar: bool, pub dock: bool, /// The bars that Tab (`window.dock`) hid, which the next Tab shows again; none when Tab has not @@ -1169,6 +1173,7 @@ impl Default for UiState { tools_beside_canvas: false, toolbar_right: false, status_bar: true, + status_bar_show: crate::chrome::StatusBarShow::CurrentTool, help_bar: true, dock: true, tab_hid: None, diff --git a/docs/mcp.md b/docs/mcp.md index 8ca4121032..34c6f06ed9 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -6393,6 +6393,22 @@ Reset Rotate View is the command `view.rotateReset`: the angle the selected objects share (`selectionRotation` in `document.inspect`, 0 when their angles differ), so their bounding box is square to the window. It returns `{angle}`, and with nothing selected it returns "nothing selected". +`view.statusBarShow` (desktop app, the Show menu that a click on the status bar's info field opens) chooses what that +field shows, with `show` set to one of these values: + +- `artboardName`: the name of the artboard the status bar's navigator shows. +- `currentTool`: the name of the tool in use. This is the default. +- `dateTime`: the date and time, as `2026-11-15 14:03`. The desktop app shows local time, and the web build shows UTC + with ` UTC` after it. +- `undos`: the active document's undo and redo step counts, as `Undos: 3 Redos: 1`. +- `colorProfile`: the profile the active document's colors use. That is the profile assigned for its color mode + (Edit › Assign Profile), or that mode's working space (Edit › Color Settings) when none is assigned or the + assigned one is not available. + +It returns the value set. The choice is kept with the UI state. A missing or other `show` fails with +``` `show` must be one of artboardName, currentTool, dateTime, undos, colorProfile ``` and leaves the choice as it was. +Without a document, the readouts that need one show a dash. + The Smart Guides preferences (Preferences › Smart Guides) apply to `pointer_gesture` with Smart Guides on (the default view) and to the mouse; they change what the tools show and how far a target pulls, and only Construction Guides change where a snapped point lands: diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 082e565bd2..b73f36069f 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -453,6 +453,7 @@ next unit in the order a right-click on a ruler lists them, from Feet back to Po | Workspaces (save, reset, switch); each remembers the layout changes made in it across switches and restarts until Reset | done | `UiState::workspace_changes` | | Opening a file: after 0.4 s a progress window with the file name, a moving bar (reading counts no steps), how many more files wait, Cancel (Esc: the file doesn't open) and Continue in Background; never over another dialog or progress window | done | #5930; `opening::show`, `file.cancelOpen`, `file.openInBackground`. Save, Place and Close still show only the status bar's spinner (Place and Save run off the UI thread; Close is immediate) | | Window › Help Bar shows or hides the tool-help strip apart from the status bar; kept with the preferences and in saved workspaces; Presentation Mode hides both bars | done | `window.helpBar`; `help_bar_toggle_is_independent_and_saved_in_workspaces`, `help_bar_and_status_bar_render_independently`, `legacy_help_bar_visibility_follows_each_layouts_status_bar` | +| Status bar: a click on the info field opens a Show menu that chooses its readout: Artboard Name, Current Tool (the default), Date and Time, Number of Undos (undo and redo counts) or Document Color Profile; kept with the UI state | done | `view.statusBarShow`; [public behavior reference](https://web.archive.org/web/2014/https://helpx.adobe.com/illustrator/using/workspace-basics.html); `the_status_bar_info_field_shows_the_chosen_readout`, `a_click_on_the_info_field_opens_the_show_menu`, `the_status_bar_show_choice_is_checked_and_saved`. The menu labels are VectorCraft's own | | Background Export: a progress dialog with the file name, the artboard count and a bar (busy for one artboard and for formats made in one go), Cancel (Esc) and Continue in Background; it opens after 0.4 s and never over another dialog. A cancelled export writes no file | done | #2564; on the shared `vectorcraft_doc::cancel` token (#2546), so a cancelled render keeps no half-drawn pattern tile or effect raster. The bar moves between artboards, not within one. Save As, Export for Screens and Export Selection don't show it yet | | Swatch, graphic style and symbol library panels: each library opens in a panel of its own, several at once, that floats, groups, docks and closes like any panel; opening an open library brings its panel forward; Previous / Next Library change the library in place; the panel menu's Persistent reopens the panel at startup with its view and find field (a library loaded from a file is read again; when its file is missing the panel reopens showing the file's path with Locate Library…, and the status bar names the file) | done | #2603; panel ids `library::`, `ui.libraryPanel {panel, library?, view?, showFind?, persistent?}`, `ui.libraryPanel.locate {panel, path?}`; the library panels have no sort option, as before | | DXF export/import preserves intended curve closure | done | #1299; R13–2018 closed SPLINE bit set/read; an open curve ending at its start stays open; knots and control points unchanged; circular cubic paths export as native CIRCLE/ARC where stroke semantics permit; DXF Options' Preset menu and `document.exportDxf`'s `dxfPreset: "cnc"` set the CNC / CAM options (#5500) |