mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 18:15:49 +00:00
UI: toggle the Help Bar independently and save its visibility
This commit is contained in:
+3
-1
@@ -1,5 +1,7 @@
|
||||
# VectorCraft Roadmap
|
||||
|
||||
- UI: Window → Help Bar toggles the tool-help strip separately from the status bar and saves visibility with workspaces. Scores and estimates unchanged.
|
||||
|
||||
- PDF.R1: editable PDF import uses the shared reader, scans page content in windows, and rejects known incomplete input before returning a document.
|
||||
- PDF.W1: PDF export and print composition use the shared optional writer for configuration, metadata, font preparation and guarded finalization; drawing and output policy remain app-owned.
|
||||
|
||||
@@ -9,7 +11,7 @@
|
||||
|
||||
**Stage: alpha** · next: beta, ~13 points (ready for real work ~62% → ~75%, and reliable `.ai` exchange) and ~170–270 h away
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-02 · **Change:** minor (font-family fields accept the mouse wheel, #5253; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (independent Help Bar visibility; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
VectorCraft is a clean-room, open-source, pure-Rust reimplementation of the Adobe Illustrator workflow. It runs
|
||||
on macOS, Windows, Linux, FreeBSD and the web (WASM), and agents can drive all of it over MCP, the CLI and a JSON
|
||||
|
||||
@@ -511,8 +511,11 @@ impl VectorcraftApp {
|
||||
}
|
||||
if self.ui.status_bar && self.ui.screen_mode < 3 {
|
||||
chrome::status_bar(self, ui);
|
||||
}
|
||||
if self.ui.help_bar && self.ui.screen_mode < 3 {
|
||||
chrome::hint_bar(self, ui);
|
||||
} else {
|
||||
}
|
||||
if self.ui.screen_mode >= 3 || (!self.ui.status_bar && !self.ui.help_bar) {
|
||||
// Keeps the previous frame's value valid for menus drawn above, before the bars.
|
||||
widgets::set_menu_floor(&ctx, ctx.content_rect().bottom());
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use super::{Arc, ROTATE_VIEW_ANGLES, Sense, Stroke, Tokens, Ui, VectorcraftApp,
|
||||
/// Draw the status message, bounded readouts and artboard navigation controls.
|
||||
pub fn status_bar(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
egui::Panel::bottom("status_bar")
|
||||
let panel = egui::Panel::bottom("status_bar")
|
||||
.exact_size(24.0)
|
||||
.frame(egui::Frame::NONE.fill(t.panel).inner_margin(egui::Margin::symmetric(8, 0)).stroke(Stroke::new(1.0, t.border)))
|
||||
.show(ui, |ui| {
|
||||
@@ -84,6 +84,7 @@ pub fn status_bar(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
status_readouts(app, ui, &t);
|
||||
});
|
||||
});
|
||||
widgets::set_menu_floor(ui.ctx(), panel.response.rect.top());
|
||||
}
|
||||
|
||||
/// The most recently measured status widths, scoped to this UI and display settings.
|
||||
|
||||
@@ -14,6 +14,68 @@ use crate::theme::Tokens;
|
||||
use serde_json::json;
|
||||
use vectorcraft_engine::Session;
|
||||
|
||||
#[test]
|
||||
fn help_bar_and_status_bar_render_independently() {
|
||||
for (help, status, screen_mode) in [(true, true, 0), (false, true, 0), (true, false, 0), (false, false, 0), (true, true, 3)] {
|
||||
let (mut app, ctx) = status_readout_app();
|
||||
app.ui.help_bar = help;
|
||||
app.ui.status_bar = status;
|
||||
app.ui.screen_mode = screen_mode;
|
||||
let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1200.0, 800.0));
|
||||
let mut parent = None;
|
||||
let mut output = ctx.run_ui(egui::RawInput { screen_rect: Some(screen), ..Default::default() }, |ui| {
|
||||
parent = Some(ui.scope_id());
|
||||
app.ui(ui);
|
||||
});
|
||||
output.textures_delta.clear();
|
||||
for _ in 0..2 {
|
||||
output = ctx.run_ui(egui::RawInput { screen_rect: Some(screen), ..Default::default() }, |ui| app.ui(ui));
|
||||
output.textures_delta.clear();
|
||||
}
|
||||
fn text(shape: &egui::Shape, out: &mut Vec<String>) {
|
||||
match shape {
|
||||
egui::Shape::Text(t) => out.push(t.galley.text().to_string()),
|
||||
egui::Shape::Vec(shapes) => shapes.iter().for_each(|s| text(s, out)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let mut shown = Vec::new();
|
||||
for shape in &output.shapes {
|
||||
text(&shape.shape, &mut shown);
|
||||
}
|
||||
assert_eq!(shown.iter().any(|t| t == "?"), help && screen_mode < 3, "{help}/{status}/{screen_mode}: {shown:?}");
|
||||
assert_eq!(shown.iter().any(|t| t.contains("Saved recovery data")), status && screen_mode < 3, "{help}/{status}/{screen_mode}: {shown:?}");
|
||||
let floor = ctx.data(|data| data.get_temp::<f32>(egui::Id::unique("menu_floor"))).unwrap();
|
||||
let expected = if screen_mode < 3 && (help || status) {
|
||||
let id = parent.unwrap().with(if help { "hint_bar" } else { "status_bar" });
|
||||
egui::containers::panel::PanelState::load(&ctx, id).unwrap().outer_rect.top()
|
||||
} else {
|
||||
screen.bottom()
|
||||
};
|
||||
assert!((floor - expected).abs() < 1.0, "menu floor {floor}, expected {expected}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "Renders the Help Bar visibility examples; set HELP_BAR_SCREENSHOTS to an output directory"]
|
||||
fn help_bar_visibility_screenshots() {
|
||||
let dir = std::path::PathBuf::from(std::env::var_os("HELP_BAR_SCREENSHOTS").expect("output directory"));
|
||||
for shown in [true, false] {
|
||||
let mut app = crate::VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.run("file.new", json!({"width": 500, "height": 400})).unwrap();
|
||||
if !shown {
|
||||
crate::menus::run_ui_command(&mut app, "window.helpBar", &serde_json::Value::Null).unwrap().unwrap();
|
||||
}
|
||||
let mut h = egui_kittest::Harness::builder()
|
||||
.with_size(egui::vec2(1000.0, 700.0))
|
||||
.with_accessibility_check(false)
|
||||
.wgpu()
|
||||
.build_ui_state(|ui, app: &mut crate::VectorcraftApp| app.ui(ui), app);
|
||||
h.run_steps(6);
|
||||
h.render().unwrap().save(dir.join(if shown { "help-visible.png" } else { "help-hidden.png" })).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hints_name_keys_as_the_menus_do() {
|
||||
let text = |tool: &str| super::hint_segments(tool).into_iter().map(|(s, _)| s).collect::<String>();
|
||||
|
||||
@@ -6111,3 +6111,4 @@ breakText Glyphs Глифи
|
||||
Create Swatch Legend Създаване на легенда на образците
|
||||
Create Swatch Legend… Създаване на легенда на образците…
|
||||
HEX HEX
|
||||
Help Bar Лента за помощ
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6145,3 +6145,4 @@ shape Open Otvoren
|
||||
Create Swatch Legend Kreiraj legendu uzoraka boja
|
||||
Create Swatch Legend… Kreiraj legendu uzoraka boja…
|
||||
HEX HEX
|
||||
Help Bar Traka pomoći
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6245,3 +6245,4 @@ breakText Glyphs Glifs
|
||||
Create Swatch Legend Crea una llegenda de mostres
|
||||
Create Swatch Legend… Crea una llegenda de mostres…
|
||||
HEX HEX
|
||||
Help Bar Barra d’ajuda
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6259,3 +6259,4 @@ breakText Glyphs Glyfy
|
||||
Create Swatch Legend Vytvořit legendu vzorníku
|
||||
Create Swatch Legend… Vytvořit legendu vzorníku…
|
||||
HEX HEX
|
||||
Help Bar Panel nápovědy
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6127,3 +6127,4 @@ breakText Glyphs Glyffer
|
||||
Create Swatch Legend Opret farveprøveforklaring
|
||||
Create Swatch Legend… Opret farveprøveforklaring…
|
||||
HEX HEX
|
||||
Help Bar Hjælpelinje
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5845,3 +5845,4 @@ breakText Glyphs Glyphen
|
||||
Create Swatch Legend Farbfeldlegende erstellen
|
||||
Create Swatch Legend… Farbfeldlegende erstellen…
|
||||
HEX HEX
|
||||
Help Bar Hilfeleiste
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6211,3 +6211,4 @@ breakText Glyphs Γλύφοι
|
||||
Create Swatch Legend Δημιουργία υπομνήματος δειγμάτων χρωμάτων
|
||||
Create Swatch Legend… Δημιουργία υπομνήματος δειγμάτων χρωμάτων…
|
||||
HEX HEX
|
||||
Help Bar Γραμμή βοήθειας
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 163 and column 5.
|
@@ -6201,3 +6201,4 @@ breakText Glyphs Glifos
|
||||
Create Swatch Legend Crear leyenda de muestras
|
||||
Create Swatch Legend… Crear leyenda de muestras…
|
||||
HEX HEX
|
||||
Help Bar Barra de ayuda
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6289,3 +6289,4 @@ breakText Glyphs Merkit
|
||||
Create Swatch Legend Luo värimallien selite
|
||||
Create Swatch Legend… Luo värimallien selite…
|
||||
HEX HEX
|
||||
Help Bar Ohjepalkki
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6254,3 +6254,4 @@ breakText Glyphs Glyphes
|
||||
Create Swatch Legend Créer une légende des nuances
|
||||
Create Swatch Legend… Créer une légende des nuances…
|
||||
HEX HEX
|
||||
Help Bar Barre d’aide
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6127,3 +6127,4 @@ breakText Glyphs Glif
|
||||
Create Swatch Legend Buat Legenda Swatch
|
||||
Create Swatch Legend… Buat Legenda Swatch…
|
||||
HEX HEX
|
||||
Help Bar Bilah Bantuan
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2211 and column 5.
|
@@ -5879,3 +5879,4 @@ breakText Glyphs Glifi
|
||||
Create Swatch Legend Crea legenda campioni
|
||||
Create Swatch Legend… Crea legenda campioni…
|
||||
HEX HEX
|
||||
Help Bar Barra della guida
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5944,3 +5944,4 @@ breakText Glyphs 字形
|
||||
Create Swatch Legend スウォッチの凡例を作成
|
||||
Create Swatch Legend… スウォッチの凡例を作成…
|
||||
HEX HEX
|
||||
Help Bar ヘルプバー
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6247,3 +6247,4 @@ breakText Glyphs გლიფები
|
||||
Create Swatch Legend ფერის ნიმუშების ლეგენდის შექმნა
|
||||
Create Swatch Legend… ფერის ნიმუშების ლეგენდის შექმნა…
|
||||
HEX HEX
|
||||
Help Bar დახმარების ზოლი
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -5840,3 +5840,4 @@ breakText Glyphs 글리프
|
||||
Create Swatch Legend 견본 범례 만들기
|
||||
Create Swatch Legend… 견본 범례 만들기…
|
||||
HEX HEX
|
||||
Help Bar 도움말 표시줄
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6171,3 +6171,4 @@ breakText Glyphs Glyphs
|
||||
Create Swatch Legend Stalenlegenda maken
|
||||
Create Swatch Legend… Stalenlegenda maken…
|
||||
HEX HEX
|
||||
Help Bar Helpbalk
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6114,3 +6114,4 @@ breakText Glyphs Glify
|
||||
Create Swatch Legend Utwórz legendę próbek
|
||||
Create Swatch Legend… Utwórz legendę próbek…
|
||||
HEX HEX
|
||||
Help Bar Pasek pomocy
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6332,3 +6332,4 @@ swatch Yellow Green Verde-amarelado
|
||||
Create Swatch Legend Criar Legenda de Amostras
|
||||
Create Swatch Legend… Criar Legenda de Amostras…
|
||||
HEX HEX
|
||||
Help Bar Barra de ajuda
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -6348,3 +6348,4 @@ breakText Glyphs Глифы
|
||||
digits Hindi Хинди
|
||||
font-script Japanese Японский
|
||||
shape Open Открытый
|
||||
Help Bar Панель подсказок
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -6315,3 +6315,4 @@ breakText Glyphs Glyfer
|
||||
# The strings the report listed as missing for sv.
|
||||
Font Size: Teckenstorlek:
|
||||
digits Hindi Hindi
|
||||
Help Bar Hjälpfält
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -6216,3 +6216,4 @@ breakText Glyphs Glifler
|
||||
Create Swatch Legend Renk Örneği Açıklaması Oluştur
|
||||
Create Swatch Legend… Renk Örneği Açıklaması Oluştur…
|
||||
HEX HEX
|
||||
Help Bar Yardım Çubuğu
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -5859,3 +5859,4 @@ breakText Glyphs Гліфи
|
||||
Create Swatch Legend Створити легенду зразків
|
||||
Create Swatch Legend… Створити легенду зразків…
|
||||
HEX HEX
|
||||
Help Bar Панель підказок
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 177 and column 5.
|
@@ -5860,3 +5860,4 @@ breakText Glyphs Glyph
|
||||
Create Swatch Legend Tạo chú giải mẫu màu
|
||||
Create Swatch Legend… Tạo chú giải mẫu màu…
|
||||
HEX HEX
|
||||
Help Bar Thanh trợ giúp
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 199 and column 5.
|
@@ -6100,3 +6100,4 @@ breakText Glyphs 字形
|
||||
Create Swatch Legend 创建色板图例
|
||||
Create Swatch Legend… 创建色板图例…
|
||||
HEX HEX
|
||||
Help Bar 帮助栏
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5897,3 +5897,4 @@ breakText Glyphs 字符
|
||||
Create Swatch Legend 建立色票圖例
|
||||
Create Swatch Legend… 建立色票圖例…
|
||||
HEX HEX
|
||||
Help Bar 說明列
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -44,10 +44,12 @@ impl UiState {
|
||||
pub fn read_preferences(bytes: &[u8]) -> Option<ReadPreferences> {
|
||||
let mut saved: Value = serde_json::from_slice(bytes).ok()?;
|
||||
let fields = saved.as_object_mut()?;
|
||||
help_bar_visibility(fields, "status_bar", "help_bar");
|
||||
let mut intact = recover(fields, Keys::SNAKE);
|
||||
for key in ["custom_workspaces", "workspace_changes"] {
|
||||
if let Some(Value::Array(workspaces)) = fields.get_mut(key) {
|
||||
for workspace in workspaces.iter_mut().filter_map(Value::as_object_mut) {
|
||||
help_bar_visibility(workspace, "statusBar", "helpBar");
|
||||
intact &= recover(workspace, Keys::CAMEL);
|
||||
}
|
||||
}
|
||||
@@ -58,6 +60,15 @@ impl UiState {
|
||||
}
|
||||
}
|
||||
|
||||
/// Older layouts used status-bar visibility for both bottom bars. Preserve that choice until
|
||||
/// the layout has an independent Help Bar setting.
|
||||
fn help_bar_visibility(fields: &mut Map<String, Value>, status: &str, help: &str) {
|
||||
if !fields.contains_key(help) {
|
||||
let visible = fields.get(status).and_then(Value::as_bool).unwrap_or(true);
|
||||
fields.insert(help.into(), Value::Bool(visible));
|
||||
}
|
||||
}
|
||||
|
||||
/// The JSON keys of the docking fields: `UiState` is snake_case, [`Workspace`] camelCase.
|
||||
struct Keys {
|
||||
hidden: &'static str,
|
||||
|
||||
@@ -14,6 +14,26 @@ fn read(saved: &Value) -> ReadPreferences {
|
||||
UiState::read_preferences(&serde_json::to_vec(saved).unwrap()).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn legacy_help_bar_visibility_follows_each_layouts_status_bar() {
|
||||
let prefs = read(&json!({
|
||||
"status_bar": false,
|
||||
"custom_workspaces": [{"name":"Hidden", "statusBar": false}, {"name":"Shown", "statusBar":true}],
|
||||
"workspace_changes": [{"name":"Changed", "statusBar":false}]
|
||||
}));
|
||||
assert!(!prefs.ui.help_bar);
|
||||
assert!(!prefs.ui.custom_workspaces[0].help_bar);
|
||||
assert!(prefs.ui.custom_workspaces[1].help_bar);
|
||||
assert!(!prefs.ui.workspace_changes[0].help_bar);
|
||||
assert!(read(&json!({})).ui.help_bar);
|
||||
for (status, help) in [(true, false), (false, true)] {
|
||||
let prefs = read(&json!({"status_bar":status, "help_bar":help,
|
||||
"custom_workspaces":[{"name":"Explicit", "statusBar":status, "helpBar":help}]}));
|
||||
assert_eq!(prefs.ui.help_bar, help);
|
||||
assert_eq!(prefs.ui.custom_workspaces[0].help_bar, help);
|
||||
}
|
||||
}
|
||||
|
||||
/// The dock of a layout in the current shape: the canvas beside a dock at the end edge.
|
||||
fn dock(layout: &Layout<String>) -> &[Column<String>] {
|
||||
assert!(docking::valid(layout), "{layout:?}");
|
||||
|
||||
@@ -433,6 +433,7 @@ fn run_ui_part5(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<Result<
|
||||
Ok(Value::Null)
|
||||
}
|
||||
"window.control" => flag(&mut app.ui.control_bar),
|
||||
"window.helpBar" => flag(&mut app.ui.help_bar),
|
||||
"window.toolbar" => flag(&mut app.ui.toolbar),
|
||||
"window.toolbarColumns" => {
|
||||
let toolbar = match crate::custom_toolbars::target(&app.ui, p) {
|
||||
|
||||
@@ -59,6 +59,7 @@ pub fn checked(app: &VectorcraftApp, id: &str, p: &Value) -> Option<bool> {
|
||||
// a document no item is checked.
|
||||
"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,
|
||||
"window.toolbar" => app.ui.toolbar,
|
||||
"window.toolbarAdvanced" => app.ui.toolbar_advanced,
|
||||
"window.toolbarColumns" => match p.get("toolbar").and_then(Value::as_str) {
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
use super::*;
|
||||
use crate::theme;
|
||||
|
||||
#[test]
|
||||
fn help_bar_toggle_is_independent_and_saved_in_workspaces() {
|
||||
let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), crate::Services::default());
|
||||
assert!(app.ui.help_bar);
|
||||
assert_eq!(checked(&app, "window.helpBar", &Value::Null), Some(true));
|
||||
assert_eq!(run_ui_command(&mut app, "window.helpBar", &Value::Null).unwrap().unwrap(), json!(false));
|
||||
assert!(app.ui.status_bar);
|
||||
assert_eq!(checked(&app, "window.helpBar", &Value::Null), Some(false));
|
||||
let saved = crate::workspaces::capture(&app.ui, "No help");
|
||||
let saved: crate::workspaces::Workspace = serde_json::from_value(serde_json::to_value(saved).unwrap()).unwrap();
|
||||
app.ui.help_bar = true;
|
||||
app.ui.status_bar = false;
|
||||
crate::workspaces::apply(&mut app.ui, &saved);
|
||||
assert!(!app.ui.help_bar && app.ui.status_bar);
|
||||
assert_eq!(run_ui_command(&mut app, "window.helpBar", &Value::Null).unwrap().unwrap(), json!(true));
|
||||
let legacy: crate::workspaces::Workspace = serde_json::from_value(json!({"name":"Old workspace"})).unwrap();
|
||||
assert!(legacy.help_bar);
|
||||
let restored: crate::state::UiState = serde_json::from_value(serde_json::to_value(&app.ui).unwrap()).unwrap();
|
||||
assert!(restored.help_bar);
|
||||
let (_, window) = menu_tree().into_iter().find(|(title, _)| *title == "Window").unwrap();
|
||||
assert!(window.iter().any(|item| matches!(item, Item::Cmd("Help Bar", "window.helpBar", _))));
|
||||
}
|
||||
|
||||
/// One headless frame of the in-window menu bar; returns its titles (left to right) as
|
||||
/// (rect, id of the title's popup).
|
||||
fn bar_frame(app: &mut VectorcraftApp, ctx: &egui::Context, events: Vec<egui::Event>) -> Vec<(egui::Rect, egui::Id)> {
|
||||
|
||||
@@ -622,6 +622,7 @@ pub fn menu_tree_named(english_names: bool) -> Vec<(&'static str, Vec<Item>)> {
|
||||
sub("Workspace", crate::workspaces::menu_items()),
|
||||
Sep,
|
||||
c("Control", "window.control"),
|
||||
c("Help Bar", "window.helpBar"),
|
||||
c("Contextual Task Bar", "window.taskBar"),
|
||||
c("Tools", "window.toolbar"),
|
||||
sub("Toolbars", crate::custom_toolbars::menu_items()),
|
||||
|
||||
@@ -441,6 +441,7 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
||||
),
|
||||
("view.rotateReset", "Reset Rotate View", "Cmd+Shift+1", "{}"),
|
||||
("window.control", "Control", "", "{}"),
|
||||
("window.helpBar", "Help Bar", "", "{} toggle the tool-help strip independently of the status bar; returns the new visibility"),
|
||||
("window.toolbar", "Tools", "", "{}"),
|
||||
(
|
||||
"window.toolbarColumns",
|
||||
|
||||
@@ -432,6 +432,7 @@ pub struct UiState {
|
||||
#[serde(default)]
|
||||
pub toolbar_pos: Option<[f32; 2]>,
|
||||
pub status_bar: bool,
|
||||
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
|
||||
/// hidden them since it last showed them, or a workspace was applied since.
|
||||
@@ -940,6 +941,7 @@ impl Default for UiState {
|
||||
dock_width: None,
|
||||
toolbar_pos: None,
|
||||
status_bar: true,
|
||||
help_bar: true,
|
||||
dock: true,
|
||||
tab_hid: None,
|
||||
view: ViewFlags::default(),
|
||||
|
||||
@@ -32,6 +32,7 @@ pub struct Workspace {
|
||||
pub dock_collapsed: bool,
|
||||
pub open_panel: Option<String>,
|
||||
pub status_bar: bool,
|
||||
pub help_bar: bool,
|
||||
/// Tool groups torn off the toolbar into floating strips (built-in workspaces: none).
|
||||
pub floating_flyouts: Vec<FloatingFlyout>,
|
||||
/// Floating panel groups in workspaces saved before the canvas joined `docking`; read only
|
||||
@@ -185,6 +186,7 @@ pub fn capture(ui: &UiState, name: &str) -> Workspace {
|
||||
dock_collapsed: ui.dock_collapsed,
|
||||
open_panel: ui.open_panel.clone(),
|
||||
status_bar: ui.status_bar,
|
||||
help_bar: ui.help_bar,
|
||||
floating_flyouts: ui.floating_flyouts.clone(),
|
||||
floating_panels: Vec::new(),
|
||||
docking: ui.docking.clone(),
|
||||
@@ -212,6 +214,7 @@ pub fn apply(ui: &mut UiState, w: &Workspace) {
|
||||
ui.dock_collapsed = w.dock_collapsed;
|
||||
ui.open_panel = w.open_panel.clone();
|
||||
ui.status_bar = w.status_bar;
|
||||
ui.help_bar = w.help_bar;
|
||||
ui.floating_flyouts = w.floating_flyouts.clone();
|
||||
ui.docking_generation = ui.docking_generation.wrapping_add(1);
|
||||
ui.docking = w.docking.clone().filter(crate::panel_docking::valid);
|
||||
|
||||
+4
-1
@@ -1,9 +1,11 @@
|
||||
# Gaps
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (G15: a compound path's assembled path is kept between frames; estimate unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (independent Help Bar visibility; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
Window → Help Bar toggles the bottom tool-help strip independently of the status bar. Its visibility is saved with workspaces and UI preferences; Presentation Mode hides both bars. Scores and estimates are unchanged.
|
||||
|
||||
The closed font-family fields in Character, Properties and Control now accept the
|
||||
mouse wheel for selected text (#5253). Each effective notch applies one family and
|
||||
adds one undo step; the list follows saved font filters, ignores search text, and
|
||||
@@ -26,6 +28,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-03 | minor | Help Bar has its own Window menu toggle and workspace visibility setting. Scores and estimates unchanged. |
|
||||
| 2026-11-02 | minor | Font-family fields step selected text with the mouse wheel (#5253); no scored gap or estimate reassessed. |
|
||||
| 2026-10-24 | minor | G12: General › Corner Radius is the Rounded Rectangle tool's radius, a change while the tool is active reaches it, and the radius ↑/↓ set while drawing (or a Tool Options value) becomes the preference, within 0–1296 pt (#394, `crates/engine/src/tests/constrain_tools.rs`); no entry closed, estimate unchanged. |
|
||||
| 2026-10-22 | minor | Reconcile upstream documentation after review F-3; preserve every dated revision and the original scaleArt runtime evidence without repeating completed jobs. |
|
||||
|
||||
+4
-1
@@ -1,9 +1,11 @@
|
||||
# Roadmap: milestones and what's next
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (font-family fields accept the mouse wheel, #5253; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (independent Help Bar visibility; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
Window → Help Bar toggles the bottom tool-help strip independently of the status bar. Its visibility is saved with workspaces and UI preferences; Presentation Mode hides both bars. Scores and estimates are unchanged.
|
||||
|
||||
**Feature evidence last updated:** 2026-11-03.
|
||||
|
||||
The shared assessment status line and revision history are current upstream; this dated section records the submission's feature evidence and revisions without rescoring upstream or claiming a new combined build or runtime measurement.
|
||||
@@ -19,6 +21,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-03 | minor | Help Bar has its own Window menu toggle and workspace visibility setting. Scores and estimates unchanged. |
|
||||
| 2026-10-30 | minor | M4: G9: `.ai`/EPS editing data: a blend takes the transparency (opacity, blend mode, knockout) in its state block after its record, so its steps knock each other out as the page draws them; a user's file comes in 0.6% from its page instead of 1.3%. Scores and estimates unchanged. |
|
||||
| 2026-10-30 | minor | M4: File formats: `.ai`/EPS editing-data fidelity from an audit of a user's files: All Caps and Small Caps (#4708); placed files at their box's corner, kept where they draw closer to the page (#4664, #4723, #4742); pages cropped to the art, with `UserUnit` (#4658, #4727); gradient mesh corners with handle weights of 0 and the state written after a mesh (#4738, #4744, #4748); type on a path spaced as the file lays it out (#4743); synthetic regressions in `crates/eps`; scores and estimates unchanged. |
|
||||
| 2026-10-30 | minor | Raster effects: bounded length fields in effect dialogs clamp on commit and reject invalid inputs visibly (#4638); estimates unchanged. |
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
# Parity with Adobe Illustrator
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (font-family fields accept the mouse wheel, #5253; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026; Units › East Asian Type acts, with Q and Ha units; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (independent Help Bar visibility; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026; Units › East Asian Type acts, with Q and Ha units; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
Window → Help Bar toggles the bottom tool-help strip independently of the status bar. Its visibility is saved with workspaces and UI preferences; Presentation Mode hides both bars. Scores and estimates are unchanged.
|
||||
|
||||
**Feature evidence last updated:** 2026-11-03.
|
||||
|
||||
The shared assessment status line and revision history are current upstream; this dated section records the submission's feature evidence and revisions without rescoring upstream or claiming a new combined build or runtime measurement.
|
||||
@@ -19,6 +21,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-03 | minor | Help Bar has its own Window menu toggle and workspace visibility setting. Scores and estimates unchanged. |
|
||||
| 2026-11-02 | minor | Legacy `.ai` saves (version 7) write type with rotated characters as outlines that keep each character's rotation, with a warning unless `outlineText` is on (#5186); scores unchanged. |
|
||||
| 2026-10-31 | minor | Object › Path › Smooth smooths a path along its length before refitting it, so Auto-Smooth takes a shaky line to one smooth curve instead of leaving its jags, and with anchor points direct-selected it smooths only that section; scores unchanged. |
|
||||
| 2026-10-31 | minor | New Document: More Settings has the Save Preset button beside the name too, saving its settings (artboard layout included) as a preset (#4893); scores unchanged. |
|
||||
|
||||
+4
-1
@@ -1,9 +1,11 @@
|
||||
# UI and interaction parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (font-family fields accept the mouse wheel, #5253; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-03 · **Change:** minor (independent Help Bar visibility; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
Window → Help Bar toggles the bottom tool-help strip independently of the status bar. Its visibility is saved with workspaces and UI preferences; Presentation Mode hides both bars. Scores and estimates are unchanged.
|
||||
|
||||
**Feature evidence last updated:** 2026-11-03.
|
||||
|
||||
The shared assessment status line and revision history are current upstream; this dated section records the submission's feature evidence and revisions without rescoring upstream or claiming a new combined build or runtime measurement.
|
||||
@@ -19,6 +21,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-03 | minor | Help Bar has its own Window menu toggle and workspace visibility setting. Scores and estimates unchanged. |
|
||||
| 2026-10-26 | minor | Pencil Fidelity goes down to 0.01 pt (dialog, tool and engine; Smooth keeps 0.05) on a logarithmic slider across the Tool Options row, with hundredths in the field and key steps that fit the range (#3328); scores and estimates unchanged (estimated) |
|
||||
| 2026-10-22 | minor | Reconcile upstream documentation after review F-3; preserve every dated revision and the original scaleArt runtime evidence without repeating completed jobs. |
|
||||
| 2026-10-22 | minor | Reconcile upstream documentation after review F-2; preserve every dated revision and the original scaleArt runtime evidence without repeating completed jobs. |
|
||||
|
||||
Reference in New Issue
Block a user