UI: toggle the Help Bar independently and save its visibility

This commit is contained in:
dotCooCoo
2026-11-03 04:53:43 -08:00
parent 94abb6ae9c
commit a319686833
42 changed files with 175 additions and 7 deletions
+3 -1
View File
@@ -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
+4 -1
View File
@@ -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());
}
+2 -1
View File
@@ -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.
+62
View File
@@ -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>();
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+1
View File
@@ -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.
+11
View File
@@ -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:?}");
+1
View File
@@ -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) {
+1
View File
@@ -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) {
+23
View File
@@ -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)> {
+1
View File
@@ -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()),
+1
View File
@@ -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",
+2
View File
@@ -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(),
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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. |
+4 -1
View File
@@ -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
View File
@@ -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. |