Merge pull request #3139 from nrq6993-a11y/stream/vc-feat1-g12-touch-workspace-pref

G12: Honor Preferences › Devices › Enable Touch Workspace
This commit is contained in:
BFlat
2026-10-22 00:00:36 +07:00
committed by GitHub
12 changed files with 91 additions and 1 deletions
+11
View File
@@ -1370,6 +1370,17 @@ fn show_font_names_in_english_preference_is_stored() {
assert!(s.prefs.font_names_in_english);
}
/// Preferences › Devices › Enable Touch Workspace (#394): stored and restored through `prefs.set`.
#[test]
fn touch_workspace_preference_is_stored() {
let mut s = Session::new();
assert!(s.prefs.touch_workspace, "on by default");
set_pref(&mut s, "touchWorkspace", json!(false));
assert!(!s.prefs.touch_workspace);
set_pref(&mut s, "touchWorkspace", json!(true));
assert!(s.prefs.touch_workspace);
}
/// Preferences › Type › Highlight Alternate Glyphs (#394): off by default so OpenType
/// substitutions are not pink on every canvas until the user turns the preference on.
#[test]
+1
View File
@@ -5077,6 +5077,7 @@ theme Appearance Външен вид
Painting Живопис
Printing and Proofing Печат и пробно отпечатване
Tracing Трасиране
Touch Докосване
Typography Типография
VectorCraft VectorCraft
Web Уеб
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4871,6 +4871,7 @@ mark-style Japanese Japansk
Painting Maling
Printing and Proofing Udskrivning og prøvetrykning
Tracing Sporing
Touch Touch
Typography Typografi
VectorCraft VectorCraft
Web Web
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4871,6 +4871,7 @@ mark-style Japanese Jepang
Painting Painting
Printing and Proofing Printing and Proofing
Tracing Tracing
Touch Touch
Typography Typography
VectorCraft VectorCraft
Web Web
Can't render this file because it contains an unexpected character in line 3800 and column 19.
+1
View File
@@ -4883,6 +4883,7 @@ mark-style Japanese Japans
Painting Schilderen
Printing and Proofing Afdrukken en proefdrukken
Tracing Tracering
Touch Touch
Typography Typografie
VectorCraft VectorCraft
Web Web
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -885,6 +885,7 @@ const MENU_KEEP_AS_IS: &[&str] = &[
"Painting",
"Printing and Proofing",
"Tracing",
"Touch",
"Typography",
"Web",
"[1P-Normal View]",
+1
View File
@@ -3180,6 +3180,7 @@ font-script Japanese 汉字
Top-to-Top Leading 上缘至上缘行距
Top: 上:
Total Width: 总宽度:
Touch 触控
Touch Type Tool 修饰文字工具
Trace 描摹
Trace the image with the Default preset 使用“默认”预设描摹图像
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -4087,6 +4087,7 @@ font-script Japanese 漢字
Top-to-Top Leading 上緣至上緣行距
Top: 上:
Total Width: 總寬度:
Touch 觸控
Touch Type 觸控文字
Touch Type Tool 觸控文字工具
Trace 描圖
Can't render this file because it contains an unexpected character in line 6 and column 47.
+3
View File
@@ -514,6 +514,8 @@ pub struct VectorcraftApp {
pub(crate) ime_discard: bool,
/// Preferences were confirmed (see [`Self::take_prefs_changed`]).
pub(crate) prefs_changed: bool,
/// Whether the last frame's input reported a touch screen (Preferences › Devices › Touch Workspace).
pub touch_screen: bool,
/// A numeric field is being scrubbed: the document's edits meanwhile are one undo step
/// ([`scrub::begin_frame`]).
scrub_group: bool,
@@ -623,6 +625,7 @@ impl VectorcraftApp {
ime_marked: None,
ime_discard: false,
prefs_changed: false,
touch_screen: false,
scrub_group: false,
scrub_scope: None,
automation_roots: None,
+9
View File
@@ -39,7 +39,11 @@ pub fn open(app: &mut VectorcraftApp, category: Option<&str>) {
pub fn confirm(app: &mut VectorcraftApp) -> Result<Value, String> {
let Some(d) = app.ui.dialog.clone() else { return Err("no dialog open".into()) };
let values: Map<String, Value> = d.fields.iter().filter(|(k, _)| !k.starts_with("__")).map(|(k, v)| (k.clone(), v.clone())).collect();
let touch_ws = values.get("touchWorkspace").and_then(Value::as_bool);
app.run("prefs.set", json!({ "values": values }))?;
if touch_ws.is_some() {
crate::workspaces::sync_touch_workspace(app, app.touch_screen);
}
app.ui.view.smart_guides = d.fields.get("__smartGuides").and_then(Value::as_bool).unwrap_or(app.ui.view.smart_guides);
app.ui.view.snap_to_grid = d.fields.get("__snapToGrid").and_then(Value::as_bool).unwrap_or(app.ui.view.snap_to_grid);
app.ui.task_bar = d.fields.get("__taskBar").and_then(Value::as_bool).unwrap_or(app.ui.task_bar);
@@ -149,6 +153,11 @@ pub fn apply_runtime(app: &mut VectorcraftApp, ctx: &egui::Context) {
if (ctx.zoom_factor() - z).abs() > 1e-3 {
ctx.set_zoom_factor(z);
}
let touch = ctx.input(|i| i.has_touch_screen());
if touch != app.touch_screen {
app.touch_screen = touch;
crate::workspaces::sync_touch_workspace(app, touch);
}
}
pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) {
+4
View File
@@ -422,6 +422,9 @@ pub struct UiState {
/// Current workspace (Window → Workspace).
#[serde(default = "default_workspace")]
pub workspace: String,
/// Workspace before Preferences › Devices › Enable Touch Workspace switched to Touch (#394).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub touch_workspace_restore: Option<String>,
/// User-saved workspaces (New Workspace…).
#[serde(default)]
pub custom_workspaces: Vec<crate::workspaces::Workspace>,
@@ -824,6 +827,7 @@ impl Default for UiState {
shortcut_overrides: Default::default(),
shortcut_set: default_shortcut_set(),
workspace: default_workspace(),
touch_workspace_restore: None,
custom_workspaces: vec![],
recent_files: vec![],
recent_fonts: vec![],
+57 -1
View File
@@ -54,6 +54,8 @@ impl Default for Workspace {
}
pub const ESSENTIALS: &str = "Essentials";
/// Touch workspace (Window → Workspace → Touch; Preferences › Devices › Enable Touch Workspace).
pub const TOUCH: &str = "Touch";
/// Built-in workspaces, in Illustrator's menu order (Essentials first).
pub fn builtins() -> Vec<Workspace> {
@@ -115,9 +117,45 @@ pub fn builtins() -> Vec<Workspace> {
x.toolbar_advanced = true;
x.open_panel = Some("symbols".into());
}),
w(TOUCH, &|x| {
x.control_bar = true;
x.toolbar = true;
x.toolbar_advanced = true;
x.task_bar = true;
x.open_panel = Some("align".into());
}),
]
}
/// Preferences › Devices › Enable Touch Workspace (#394): on, a touch screen switches to the Touch
/// workspace; off, or when no touch screen is reported, the workspace before that switch is
/// restored if Touch was entered automatically.
pub fn sync_touch_workspace(app: &mut VectorcraftApp, touch_screen: bool) {
let auto = app.session.prefs.touch_workspace && touch_screen;
if auto {
if app.ui.workspace != TOUCH {
if app.ui.touch_workspace_restore.is_none() {
app.ui.touch_workspace_restore = Some(app.ui.workspace.clone());
}
if let Some(w) = find(&app.ui, TOUCH) {
apply(&mut app.ui, &w);
}
}
} else if app.ui.touch_workspace_restore.is_some() && app.ui.workspace == TOUCH {
let back = app
.ui
.touch_workspace_restore
.take()
.filter(|n| find(&app.ui, n).is_some())
.unwrap_or_else(|| ESSENTIALS.to_string());
if let Some(w) = find(&app.ui, &back) {
apply(&mut app.ui, &w);
}
} else if !auto {
app.ui.touch_workspace_restore = None;
}
}
pub fn is_builtin(name: &str) -> bool {
builtins().iter().any(|w| w.name == name)
}
@@ -493,11 +531,29 @@ mod tests {
#[test]
fn all_requested_workspaces_exist() {
let ui = UiState::default();
for n in ["Essentials", "Essentials Classic", "Painting", "Typography", "Layout", "Tracing", "Web", "Automation"] {
for n in ["Essentials", "Essentials Classic", "Painting", "Typography", "Layout", "Tracing", "Web", "Automation", TOUCH] {
assert!(find(&ui, n).is_some(), "{n}");
}
}
#[test]
fn touch_workspace_preference_switches_and_restores() {
use crate::{Services, VectorcraftApp};
use vectorcraft_engine::Session;
let mut app = VectorcraftApp::new(Session::new(), Services::default());
app.ui.workspace = "Typography".into();
app.session.prefs.touch_workspace = true;
sync_touch_workspace(&mut app, true);
assert_eq!(app.ui.workspace, TOUCH);
assert_eq!(app.ui.touch_workspace_restore.as_deref(), Some("Typography"));
assert!(app.ui.control_bar && app.ui.open_panel.as_deref() == Some("align"));
app.session.prefs.touch_workspace = false;
sync_touch_workspace(&mut app, true);
assert_eq!(app.ui.workspace, "Typography");
assert!(app.ui.touch_workspace_restore.is_none());
}
#[test]
fn saved_workspaces_restore_dock_width() {
let mut ui = UiState { dock_width: Some(420.0), ..Default::default() };