mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Rotate View: a two-finger rotation on a Mac trackpad turns the view about the pointer
A two-finger rotation on a Mac trackpad did not turn the view. With the new General preference Trackpad Gesture to Rotate View (`trackpadRotateView`, on by default) and the pointer over the canvas, the rotation turns the view about the pointer, keeping the document point under it in place. The view does not turn until the rotation reaches 5°; it then turns by the whole rotation and follows each later rotation event. A rotation ends 0.25 s after its last event. A rotation in the same frame as a pinch zooms and turns about the same point. egui reports the gesture as `Event::Rotate`: egui-winit makes it from winit's macOS rotation gesture, and eframe makes it from Safari's gesture events in the web build. Rotation events that arrive while fingers are on a touch screen do not turn the view. With the preference off, the gesture does not turn the view. Docs: docs/mcp.md, docs/target-app-parity.md, docs/hardware-parity.md.
This commit is contained in:
@@ -138,6 +138,7 @@ pub const PREF_SPECS: &[PrefSpec] = &[
|
||||
p!("scaleStrokes", "General", "Options", "Scale Strokes & Effects", bool),
|
||||
p!("zoomWithMouseWheel", "General", "Options", "Zoom with Mouse Wheel", bool),
|
||||
p!("scrubNumericFields", "General", "Options", "Scrub Numeric Fields by Dragging", bool),
|
||||
p!("trackpadRotateView", "General", "Options", "Trackpad Gesture to Rotate View", bool),
|
||||
// Selection & Anchor Display
|
||||
p!("selectionTolerance", "Selection & Anchor Display", "Selection", "Tolerance", num(1.0, 8.0, "px")),
|
||||
p!("objectSelectionByPathOnly", "Selection & Anchor Display", "Selection", "Object Selection by Path Only", bool),
|
||||
|
||||
@@ -737,6 +737,8 @@ pub struct Prefs {
|
||||
pub zoom_with_mouse_wheel: bool,
|
||||
/// A horizontal drag on a numeric field or its label steps its value (#400).
|
||||
pub scrub_numeric_fields: bool,
|
||||
/// A two-finger rotation on a Mac trackpad turns the view about the pointer once it reaches 5°.
|
||||
pub trackpad_rotate_view: bool,
|
||||
/// Offset for Paste / duplicate (Illustrator pastes to the view centre; we offset by this).
|
||||
pub paste_offset: f64,
|
||||
// Selection & Anchor Display
|
||||
@@ -992,6 +994,7 @@ impl Default for Prefs {
|
||||
scale_strokes: false,
|
||||
zoom_with_mouse_wheel: false,
|
||||
scrub_numeric_fields: true,
|
||||
trackpad_rotate_view: true,
|
||||
paste_offset: 10.0,
|
||||
selection_tolerance: 3.0,
|
||||
object_selection_by_path_only: false,
|
||||
|
||||
@@ -709,7 +709,7 @@ fn handle_input(app: &mut VectorcraftApp, ui: &Ui, resp: &egui::Response, rect:
|
||||
});
|
||||
|
||||
// Zoom around the pointer, and scroll ([`wheel`]): fingers pinching on a touch screen may also
|
||||
// slide.
|
||||
// slide. Then turn the view about the pointer for a trackpad rotation ([`trackpad_turn`]).
|
||||
if resp.hovered() {
|
||||
if (factor - 1.0).abs() > 1e-6
|
||||
&& let (Some(p), Some(vm)) = (hover, app.view_mut())
|
||||
@@ -722,6 +722,12 @@ fn handle_input(app: &mut VectorcraftApp, ui: &Ui, resp: &egui::Response, rect:
|
||||
let d = Xf { rect, zoom: vm.zoom, center: vm.center, rot: vm.rotation.to_radians() }.delta_to_doc(scroll);
|
||||
vm.center -= d;
|
||||
}
|
||||
if let Some(p) = hover
|
||||
&& let Some(deg) = trackpad_turn(ui, app.session.prefs.trackpad_rotate_view)
|
||||
&& let Some(vm) = app.view_mut()
|
||||
{
|
||||
rotate_about(vm, rect, p, deg);
|
||||
}
|
||||
}
|
||||
|
||||
// In Presentation Mode a click anywhere goes to the next artboard. The tool receives no press,
|
||||
@@ -981,6 +987,65 @@ fn zoom_about(vm: &mut View, rect: egui::Rect, p: Pos2, zoom: f64) {
|
||||
vm.center += before - Xf::new(rect, vm).to_doc(p);
|
||||
}
|
||||
|
||||
/// Turn view `vm` of the canvas `rect` by `degrees` clockwise, keeping the document point under
|
||||
/// screen point `p` where it is.
|
||||
fn rotate_about(vm: &mut View, rect: egui::Rect, p: Pos2, degrees: f64) {
|
||||
let before = Xf::new(rect, vm).to_doc(p);
|
||||
vm.rotation = vectorcraft_geom::normalize_deg(vm.rotation + degrees);
|
||||
vm.center += before - Xf::new(rect, vm).to_doc(p);
|
||||
}
|
||||
|
||||
/// How far a trackpad rotation turns before it turns the view, in degrees.
|
||||
const ROTATE_DEAD_ZONE: f64 = 5.0;
|
||||
/// How long after its last rotation event a trackpad rotation ends, in seconds.
|
||||
const ROTATE_GESTURE_END: f64 = 0.25;
|
||||
|
||||
/// A trackpad rotation under way ([`trackpad_turn`]).
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct TrackpadTurn {
|
||||
/// Degrees it has turned so far, clockwise.
|
||||
total: f64,
|
||||
/// When its last rotation event came (egui's input time, in seconds).
|
||||
last: f64,
|
||||
/// It has reached [`ROTATE_DEAD_ZONE`] and turns the view.
|
||||
turning: bool,
|
||||
}
|
||||
|
||||
/// General › Trackpad Gesture to Rotate View (`on`): the degrees, clockwise, that a two-finger
|
||||
/// rotation on a Mac trackpad turns the view this frame. egui sends the rotation as
|
||||
/// [`egui::Event::Rotate`], from winit on macOS and from Safari's gesture events in the web build.
|
||||
/// A rotation does not turn the view until it reaches [`ROTATE_DEAD_ZONE`]; it then turns the view
|
||||
/// by all of it, and by each later event as it comes. It ends [`ROTATE_GESTURE_END`] after its last
|
||||
/// event. Rotation events that come while fingers are on a touch screen do not turn the view.
|
||||
fn trackpad_turn(ui: &Ui, on: bool) -> Option<f64> {
|
||||
if !on {
|
||||
return None;
|
||||
}
|
||||
let (deg, now) = ui.input(|i| {
|
||||
let rad: f32 =
|
||||
if i.multi_touch().is_some() { 0.0 } else { i.events.iter().map(|e| if let egui::Event::Rotate(r) = e { *r } else { 0.0 }).sum() };
|
||||
(f64::from(rad).to_degrees(), i.time)
|
||||
});
|
||||
if deg == 0.0 || !deg.is_finite() {
|
||||
return None;
|
||||
}
|
||||
let id = egui::Id::new("canvas-trackpad-turn");
|
||||
let kept: Option<TrackpadTurn> = ui.data(|d| d.get_temp(id));
|
||||
let mut t = kept.filter(|t| now - t.last <= ROTATE_GESTURE_END).unwrap_or(TrackpadTurn { total: 0.0, last: now, turning: false });
|
||||
t.total += deg;
|
||||
t.last = now;
|
||||
let turn = if t.turning {
|
||||
Some(deg)
|
||||
} else if t.total.abs() >= ROTATE_DEAD_ZONE {
|
||||
t.turning = true;
|
||||
Some(t.total)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
ui.data_mut(|d| d.insert_temp(id, t));
|
||||
turn
|
||||
}
|
||||
|
||||
/// One scroll bar along its axis, in screen points: the span it scrolls over (`lo..hi`) and the
|
||||
/// part of it the canvas shows (`v0..v1`).
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
@@ -5111,6 +5176,96 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// A canvas frame at input time `t` (seconds) with `events`, for the trackpad rotation tests.
|
||||
fn timed_frame(app: &mut VectorcraftApp, ctx: &egui::Context, t: f64, events: Vec<egui::Event>) {
|
||||
let raw = egui::RawInput {
|
||||
screen_rect: Some(egui::Rect::from_min_size(Pos2::ZERO, vec2(800.0, 600.0))),
|
||||
time: Some(t),
|
||||
events,
|
||||
..Default::default()
|
||||
};
|
||||
let mut out = ctx.run_ui(raw, |ui| show(app, ui));
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
|
||||
/// General › Trackpad Gesture to Rotate View, on by default: a two-finger rotation on a Mac
|
||||
/// trackpad (egui's `Event::Rotate`, clockwise radians) turns the view about the pointer, also
|
||||
/// in the frame of a pinch, which zooms about the same point. With the preference off, the view
|
||||
/// does not turn.
|
||||
#[test]
|
||||
fn a_trackpad_rotation_turns_the_view_about_the_pointer() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
timed_frame(&mut app, &ctx, 0.0, vec![]);
|
||||
let rect = app.canvas_rect.unwrap();
|
||||
let at = rect.center() + vec2(60.0, 40.0);
|
||||
timed_frame(&mut app, &ctx, 0.1, vec![egui::Event::PointerMoved(at)]);
|
||||
let under = |app: &VectorcraftApp| Xf::new(rect, app.view().unwrap()).to_doc(at);
|
||||
let before = (*app.view().unwrap(), under(&app));
|
||||
timed_frame(&mut app, &ctx, 0.2, vec![egui::Event::Rotate(0.25)]);
|
||||
let after = *app.view().unwrap();
|
||||
assert!((after.rotation - before.0.rotation - 0.25f64.to_degrees()).abs() < 1e-4, "turned by 14.32°: {}", after.rotation);
|
||||
assert!((after.zoom - before.0.zoom).abs() < 1e-12, "no zoom");
|
||||
assert!(under(&app).distance(before.1) < 1e-6, "the point under the pointer stays: {:?}", under(&app));
|
||||
// A pinch and a rotation in one frame, in a new gesture.
|
||||
let before = (*app.view().unwrap(), under(&app));
|
||||
timed_frame(&mut app, &ctx, 1.0, vec![egui::Event::Zoom(1.25), egui::Event::Rotate(0.25)]);
|
||||
let after = *app.view().unwrap();
|
||||
assert!((after.zoom / before.0.zoom - 1.25).abs() < 1e-6, "the pinch zooms: {}", after.zoom / before.0.zoom);
|
||||
assert!((after.rotation - before.0.rotation - 0.25f64.to_degrees()).abs() < 1e-4, "and the rotation turns: {}", after.rotation);
|
||||
assert!(under(&app).distance(before.1) < 1e-6, "about the same point: {:?}", under(&app));
|
||||
app.session.execute("prefs.set", &json!({"key": "trackpadRotateView", "value": false})).unwrap();
|
||||
let before = *app.view().unwrap();
|
||||
timed_frame(&mut app, &ctx, 2.0, vec![egui::Event::Rotate(0.25)]);
|
||||
timed_frame(&mut app, &ctx, 2.1, vec![egui::Event::Rotate(0.25)]);
|
||||
let after = *app.view().unwrap();
|
||||
assert!(after.rotation == before.rotation && after.center == before.center, "off: the view does not turn ({})", after.rotation);
|
||||
}
|
||||
|
||||
/// A trackpad rotation turns the view only once it reaches 5°, so a pinch that twists a little
|
||||
/// only zooms. It then turns the view by all of it and follows each later rotation event, until
|
||||
/// a quarter of a second passes without one.
|
||||
#[test]
|
||||
fn a_trackpad_rotation_turns_nothing_until_it_reaches_five_degrees() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
timed_frame(&mut app, &ctx, 0.0, vec![]);
|
||||
let at = app.canvas_rect.unwrap().center() + vec2(60.0, 40.0);
|
||||
timed_frame(&mut app, &ctx, 0.1, vec![egui::Event::PointerMoved(at)]);
|
||||
let rotate = |deg: f32| egui::Event::Rotate(deg.to_radians());
|
||||
let zoom = app.view().unwrap().zoom;
|
||||
timed_frame(&mut app, &ctx, 1.0, vec![egui::Event::Zoom(1.25), rotate(1.0)]);
|
||||
assert!(app.view().unwrap().zoom > zoom * 1.2, "the pinch zooms");
|
||||
timed_frame(&mut app, &ctx, 1.1, vec![egui::Event::Zoom(1.25), rotate(1.0)]);
|
||||
timed_frame(&mut app, &ctx, 1.2, vec![egui::Event::Zoom(1.25), rotate(1.0)]);
|
||||
assert_eq!(app.view().unwrap().rotation, 0.0, "3° in all does not turn the view");
|
||||
timed_frame(&mut app, &ctx, 1.3, vec![rotate(3.0)]);
|
||||
assert!((app.view().unwrap().rotation - 6.0).abs() < 1e-4, "6° in all turns by 6°: {}", app.view().unwrap().rotation);
|
||||
timed_frame(&mut app, &ctx, 1.4, vec![rotate(-1.0)]);
|
||||
assert!((app.view().unwrap().rotation - 5.0).abs() < 1e-4, "then each event turns it: {}", app.view().unwrap().rotation);
|
||||
timed_frame(&mut app, &ctx, 2.0, vec![rotate(3.0)]);
|
||||
assert!((app.view().unwrap().rotation - 5.0).abs() < 1e-4, "a new rotation starts under 5° again: {}", app.view().unwrap().rotation);
|
||||
}
|
||||
|
||||
/// Rotation events that come while two fingers are on a touch screen (Safari on an iPad sends
|
||||
/// them with the touches) do not turn the view.
|
||||
#[test]
|
||||
fn a_rotation_with_fingers_on_a_touch_screen_turns_nothing() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
timed_frame(&mut app, &ctx, 0.0, vec![]);
|
||||
let c = app.canvas_rect.unwrap().center();
|
||||
let touch = |n: u64, phase, pos| egui::Event::Touch { device_id: egui::TouchDeviceId(1), id: egui::TouchId(n), phase, pos, force: None };
|
||||
timed_frame(&mut app, &ctx, 0.1, vec![egui::Event::PointerMoved(c - vec2(40.0, 0.0))]);
|
||||
let before = app.view().unwrap().rotation;
|
||||
let start = vec![touch(1, egui::TouchPhase::Start, c - vec2(40.0, 0.0)), touch(2, egui::TouchPhase::Start, c + vec2(40.0, 0.0))];
|
||||
timed_frame(&mut app, &ctx, 0.2, [start, vec![egui::Event::Rotate(0.25)]].concat());
|
||||
assert_eq!(app.view().unwrap().rotation, before, "the view does not turn");
|
||||
}
|
||||
|
||||
/// General › Display Print Size at 100% Zoom (#394): `view.actualSize` is one document point per
|
||||
/// screen point with it off, and 96 screen points per document inch with it on.
|
||||
#[test]
|
||||
|
||||
@@ -2488,6 +2488,7 @@
|
||||
Rotate 90° CW Завъртане на 90° по часовниковата стрелка
|
||||
Rotate Tool Инструмент „Завъртане“
|
||||
Rotate View Tool Инструмент „Завъртане на изглед“
|
||||
Trackpad Gesture to Rotate View Завъртане на изгледа с жест на тракпада
|
||||
Rotate… Завъртане…
|
||||
Rotation Завъртане
|
||||
Roughen… Грапавост…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1227,6 +1227,7 @@ lighting Light Světlo
|
||||
Reshape Tool Nástroj Přetvarování
|
||||
Rotate Tool Nástroj Otočení
|
||||
Rotate View Tool Nástroj Otočení zobrazení
|
||||
Trackpad Gesture to Rotate View Otáčet zobrazení gestem na trackpadu
|
||||
Rotate View Otočení zobrazení
|
||||
Rounded Rectangle Tool Nástroj Zaoblený obdélník
|
||||
Scale Tool Nástroj Změna velikosti
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1152,6 +1152,7 @@ lighting Light Lys
|
||||
Reshape Tool Omformningsværktøj
|
||||
Rotate Tool Roteringsværktøj
|
||||
Rotate View Tool Visningsroteringsværktøj
|
||||
Trackpad Gesture to Rotate View Rotér visning med bevægelse på pegefeltet
|
||||
Rotate View Rotér visning
|
||||
Rounded Rectangle Tool Afrundet rektangelværktøj
|
||||
Scale Tool Skaleringsværktøj
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2500,6 +2500,7 @@ mark-style Japanese Japanisch
|
||||
Rotate 90° CW Um 90° im Uhrzeigersinn drehen
|
||||
Rotate Tool Drehen-Werkzeug
|
||||
Rotate View Tool Ansichtdrehung-Werkzeug
|
||||
Trackpad Gesture to Rotate View Ansicht mit Trackpad-Geste drehen
|
||||
Rotate… Drehen…
|
||||
Rotation Drehung
|
||||
Roughen… Aufrauen…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1670,6 +1670,7 @@
|
||||
Roman Hanging Punctuation Κρεμαστή στίξη όρθιας γραφής
|
||||
Rotate Περιστροφή
|
||||
Rotate View Tool Εργαλείο περιστροφής προβολής (Rotate View Tool)
|
||||
Trackpad Gesture to Rotate View Περιστροφή προβολής με χειρονομία στην επιφάνεια αφής
|
||||
Rotate… Περιστροφή…
|
||||
Rotation Περιστροφή
|
||||
Rows: Γραμμές:
|
||||
|
||||
|
@@ -2534,6 +2534,7 @@
|
||||
Rotate 90° CW Rotar 90° en sentido horario
|
||||
Rotate Tool Herramienta Rotar
|
||||
Rotate View Tool Herramienta Rotar vista
|
||||
Trackpad Gesture to Rotate View Rotar vista con un gesto del trackpad
|
||||
Rotate… Rotar…
|
||||
Rotation Rotación
|
||||
Roughen… Hacer áspero…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1203,6 +1203,7 @@ lighting Light Valo
|
||||
Reshape Tool Uudelleenmuotoilutyökalu
|
||||
Rotate Tool Kiertotyökalu
|
||||
Rotate View Tool Näkymän kiertotyökalu
|
||||
Trackpad Gesture to Rotate View Kierrä näkymää ohjauslevyn eleellä
|
||||
Rotate View Kierrä näkymää
|
||||
Rounded Rectangle Tool Pyöristetyn suorakulmion työkalu
|
||||
Scale Tool Skaalaustyökalu
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2531,6 +2531,7 @@
|
||||
Rotate 90° CW Rotation de 90° horaire
|
||||
Rotate Tool Outil Rotation
|
||||
Rotate View Tool Outil Faire pivoter l’affichage
|
||||
Trackpad Gesture to Rotate View Faire pivoter l’affichage avec un geste du trackpad
|
||||
Rotate… Rotation…
|
||||
Rotation Rotation
|
||||
Roughen… Rugosité…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -3095,6 +3095,7 @@ mark-style Japanese Japán
|
||||
Rotate Tool Elforgatás
|
||||
Rotate View Nézet elforgatása
|
||||
Rotate View Tool Nézet elforgatása
|
||||
Trackpad Gesture to Rotate View Nézet elforgatása kézmozdulattal az érintőpadon
|
||||
Rotate… Elforgatás…
|
||||
Rotation Elforgatás
|
||||
Rotation relative to: Elforgatás viszonyítási alapja:
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1152,6 +1152,7 @@ lighting Light Cahaya
|
||||
Reshape Tool Alat pembentuk ulang
|
||||
Rotate Tool Alat putar
|
||||
Rotate View Tool Alat putar tampilan
|
||||
Trackpad Gesture to Rotate View Putar tampilan dengan gestur trackpad
|
||||
Rotate View Putar tampilan
|
||||
Rounded Rectangle Tool Alat persegi panjang bulat
|
||||
Scale Tool Alat skala
|
||||
|
||||
|
@@ -2551,6 +2551,7 @@ mark-style Japanese Giapponese
|
||||
Rotate 90° CW Ruota di 90° in senso orario
|
||||
Rotate Tool Strumento Ruota
|
||||
Rotate View Tool Strumento Ruota vista
|
||||
Trackpad Gesture to Rotate View Ruota vista con un gesto sul trackpad
|
||||
Rotate… Ruota…
|
||||
Rotation Rotazione
|
||||
Roughen… Irruvidisci…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2482,6 +2482,7 @@ mark-style Japanese 日本式
|
||||
Rotate 回転
|
||||
Rotate Tool 回転ツール
|
||||
Rotate View Tool 回転ビューツール
|
||||
Trackpad Gesture to Rotate View トラックパッドのジェスチャーでビューを回転
|
||||
Rotation 回転
|
||||
Round Cap 丸型線端
|
||||
Round Join ラウンド結合
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2476,6 +2476,7 @@ mark-style Japanese 일본식
|
||||
Rotate 회전
|
||||
Rotate Tool 회전 도구
|
||||
Rotate View Tool 보기 회전 도구
|
||||
Trackpad Gesture to Rotate View 트랙패드 제스처로 보기 회전
|
||||
Rotation 회전
|
||||
Round Cap 둥근 끝
|
||||
Round Join 둥근 연결
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1152,6 +1152,7 @@ lighting Light Licht
|
||||
Reshape Tool Hervormen-gereedschap
|
||||
Rotate Tool Draaien-gereedschap
|
||||
Rotate View Tool Weergave draaien-gereedschap
|
||||
Trackpad Gesture to Rotate View Weergave draaien met trackpadgebaar
|
||||
Rotate View Weergave draaien
|
||||
Rounded Rectangle Tool Afgeronde rechthoek-gereedschap
|
||||
Scale Tool Schalen-gereedschap
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -1149,6 +1149,7 @@ lighting Light Światło
|
||||
Reshape Tool Narzędzie Zmiana kształtu
|
||||
Rotate Tool Narzędzie Obrót
|
||||
Rotate View Tool Narzędzie Obrót widoku
|
||||
Trackpad Gesture to Rotate View Obracaj widok gestem na gładziku
|
||||
Rounded Rectangle Tool Narzędzie Zaokrąglony prostokąt
|
||||
Scale Tool Narzędzie Skalowanie
|
||||
Scallop Tool Narzędzie Ząbkowanie
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2094,6 +2094,7 @@
|
||||
Rotate Girar
|
||||
Rotate Tool Ferramenta Girar
|
||||
Rotate View Tool Ferramenta Girar Visualização
|
||||
Trackpad Gesture to Rotate View Girar Visualização com Gesto do Trackpad
|
||||
Rotate… Girar…
|
||||
Rotation Rotação
|
||||
Roughen… Enrugar…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2547,6 +2547,7 @@ mark-style Japanese Японский
|
||||
Rotate 90° CW Повернуть на 90° по часовой стрелке
|
||||
Rotate Tool Инструмент «Поворот»
|
||||
Rotate View Tool Инструмент «Поворот вида»
|
||||
Trackpad Gesture to Rotate View Поворачивать вид жестом трекпада
|
||||
Rotate… Повернуть…
|
||||
Rotation Поворот
|
||||
Roughen… Огрубление…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2488,6 +2488,7 @@
|
||||
Rotate 90° CW Rotera 90° medurs
|
||||
Rotate Tool Rotationsverktyg
|
||||
Rotate View Tool Verktyget Rotera vy
|
||||
Trackpad Gesture to Rotate View Rotera vyn med en gest på styrplattan
|
||||
Rotate… Rotera…
|
||||
Rotation Rotation
|
||||
Roughen… Ojämn…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -2543,6 +2543,7 @@ mark-style Japanese Японський
|
||||
Rotate 90° CW Повернути на 90° за годинниковою стрілкою
|
||||
Rotate Tool Інструмент «Поворот»
|
||||
Rotate View Tool Інструмент «Поворот виду»
|
||||
Trackpad Gesture to Rotate View Повертати вид жестом трекпада
|
||||
Rotate… Повернути…
|
||||
Rotation Поворот
|
||||
Roughen… Надати нерівності…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 723 and column 40.
|
@@ -2834,6 +2834,7 @@ mark-style Japanese Kiểu Nhật
|
||||
Rotate 90° CW Xoay 90° theo chiều kim đồng hồ
|
||||
Rotate Tool Công cụ Xoay
|
||||
Rotate View Tool Công cụ Xoay chế độ xem
|
||||
Trackpad Gesture to Rotate View Xoay chế độ xem bằng cử chỉ trên bàn di chuột
|
||||
Rotate… Xoay…
|
||||
Rotation Góc xoay
|
||||
Rotation relative to: Xoay tương đối với:
|
||||
|
||||
|
@@ -2441,6 +2441,7 @@ mark-style Japanese 日式
|
||||
Rotate 90° CW 顺时针旋转 90°
|
||||
Rotate Tool 旋转工具
|
||||
Rotate View Tool 旋转视图工具
|
||||
Trackpad Gesture to Rotate View 使用触控板手势旋转视图
|
||||
Rotate… 旋转…
|
||||
Rotation 旋转
|
||||
Roughen… 粗糙效果…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2525,6 +2525,7 @@ mark-style Japanese 日式
|
||||
Rotate 90° CW 順時針旋轉 90°
|
||||
Rotate Tool 旋轉工具
|
||||
Rotate View Tool 旋轉檢視工具
|
||||
Trackpad Gesture to Rotate View 使用觸控式軌跡板手勢旋轉檢視
|
||||
Rotate… 旋轉…
|
||||
Rotation 旋轉
|
||||
Roughen… 粗糙效果…
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -22,7 +22,7 @@ on huge documents. Pen input is pressure-only and Windows-first.
|
||||
| Pen pressure | yes (Wacom, Windows Ink, macOS tablet events) | **no** (winit reports none, #852) | yes (pointer force via `WM_POINTER`) | X11 only via XWayland (Preferences › Performance › Linux Display Server, #1151); none on Wayland (#491, #764) | browser pointer events, with coalesced events; Apple Pencil on iPad (hover, palm rejection: fingers navigate after a pen contact until reload) | partial: 4–8 h for macOS and Wayland (winit 0.31) |
|
||||
| Pen tilt, bearing, barrel rotation (6D Art Pen) | yes, drives brushes | no | no | no | no | missing: 4–8 h after the input layer (#372) |
|
||||
| Pen eraser end | yes | no | no | no | no | missing |
|
||||
| Touch gestures (pinch zoom, two-finger pan, rotate view, Touch workspace) | yes (Windows touch, Surface) | trackpad pinch and scroll | pinch, pan; two-finger tap undo, three-finger redo (#585) | same where winit reports touch | eframe until the first pen contact, then Pointer Events (pen and fingers told apart); long press opens the context menu | partial: touch workspace and rotate gesture missing, 3–5 h |
|
||||
| Touch gestures (pinch zoom, two-finger pan, rotate view, Touch workspace) | yes (Windows touch, Surface) | trackpad pinch, scroll and rotate | pinch, pan; two-finger tap undo, three-finger redo (#585) | same where winit reports touch | eframe until the first pen contact, then Pointer Events (pen and fingers told apart); long press opens the context menu | partial: touch workspace and touch-screen rotation missing, 3–5 h |
|
||||
| Trackpad (smooth scroll, pinch) | yes | yes | precision touchpads | yes | yes | done |
|
||||
| HiDPI / Retina, per-monitor scale | yes | yes | yes | yes | yes | done; a window dragged between monitors of different scale can still grow on Windows (#1459, open); the custom title bar's window on Windows stays truly borderless so the pointer lines up with what is drawn (#1791, #1758; awaiting the reporter's confirmation) |
|
||||
| Multiple monitors: panels and document windows on another screen | yes | no (one OS window) | no | no | — | missing: 6–10 h (with multiple windows, gap G7) |
|
||||
|
||||
+3
-1
@@ -2123,7 +2123,9 @@ The Selection & Anchor Display and General preferences apply to `pointer_gesture
|
||||
|
||||
The preferences for the view need the desktop app (`vectorcraft-cli mcp --connect`): `zoomWithMouseWheel` (the
|
||||
wheel zooms about the pointer, Shift-wheel scrolls up and down, Cmd/Ctrl-wheel sideways; the control channel's
|
||||
`ui.wheel` turns the wheel), `zoomToSelection` (on: Zoom In and Zoom Out centre the selection), `showToolTips`,
|
||||
`ui.wheel` turns the wheel), `trackpadRotateView` (on by default: a two-finger rotation on a Mac trackpad, in the
|
||||
macOS app or in Safari, turns the view about the pointer once it reaches 5°; with it off, the gesture does not turn
|
||||
the view), `zoomToSelection` (on: Zoom In and Zoom Out centre the selection), `showToolTips`,
|
||||
`anchorSize` (1–7), `gridColor`, `gridStyle`, `gridsInBack`, `guideColor`, `guideStyle`, `showPixelGrid` (on by
|
||||
default: in View › Pixel Preview at 600% zoom and above, a line at every document pixel over the art),
|
||||
`recentFontsCount`, `antiAliasedArtwork` (on by default; off, the canvas draws the art with hard edges — a pixel is
|
||||
|
||||
@@ -561,6 +561,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
View › Rotate View turns the view to the status bar's preset angles (`view.rotate {angle}`, which takes any angle). View › Rotate View to Selection turns the view to the angle of the selected objects' bounding box, so the box is square to the window (`view.rotateToSelection`).
|
||||
When the view angle changes (a Rotate View drag, the status bar's angle menu, Reset Rotate View or a saved view) and the desktop app renders the frame at the new angle on the render worker, the canvas draws the last frame turned to the new angle until that frame is ready. It used to draw no art until then.
|
||||
With the view rotated, a second Escape less than a second after the first resets the rotation, as Reset Rotate View does. The first Escape may end something else, such as isolation mode or a path being drawn. The second resets the view only when it has nothing else to end, and an Escape that closes a menu does not count. After a click, or a press of another key that is not a modifier (Shift, Control, Alt/Option or Command), the next Escape counts as the first. With the Rotate View tool chosen, one Escape resets the view.
|
||||
A two-finger rotation on a Mac trackpad turns the view about the pointer once it reaches 5° (Preferences › General › Trackpad Gesture to Rotate View, on by default).
|
||||
The status bar navigator's field shows the active artboard's number and name, and its drop-down lists every artboard by number and name, as the Artboards panel does. Choosing an artboard in the list makes it the active artboard and fits it in the window (`view.goToArtboard`). The list opens on the active artboard's row and lays out only the rows in view and at most one more.
|
||||
- **Geometry and effects:**
|
||||
- **Open-path anchor Delete:** Delete/Backspace removes selected anchors and their adjoining segments, leaving drawable runs as separate open subpaths of the original object. Surviving curves and appearance stay intact; one Undo restores the document and selection, and a second Delete removes the selected remainder. Explicit Remove Anchor Points still reconnects/refits. Four core regressions, one full-frame Delete/Backspace regression and three existing removal/segment controls pass, covering these distinctions, multiple deletions, transformed geometry and mixed whole-object selection. Behaviour references: the legacy public [Illustrator reference guide, Add or delete an anchor point](https://helpx.adobe.com/content/dam/help/en/pdf/illustrator_reference.pdf) distinguishes keyboard deletion from dedicated removal; the current [Add or remove anchor points](https://helpx.adobe.com/illustrator/desktop/draw-shapes-and-paths/modify-paths/add-or-remove-anchor-points.html) describes the dedicated tools. Other G11 gaps and scores/hours remain unchanged.
|
||||
|
||||
Reference in New Issue
Block a user