Merge pull request #6496 from dotCooCoo/feat/ruler-artboard-guides

Guides: an option makes Cmd/Ctrl ruler drags artboard guides
This commit is contained in:
BFlat
2026-11-11 09:04:35 +07:00
committed by GitHub
36 changed files with 229 additions and 7 deletions
+1
View File
@@ -229,6 +229,7 @@ pub const PREF_SPECS: &[PrefSpec] = &[
p!("guideColor", "Guides & Grid", "Guides", "Color", color),
p!("guideStyle", "Guides & Grid", "Guides", "Style", choice(LINE_STYLE)),
p!("lockGuidesByDefault", "Guides & Grid", "Guides", "Lock Guides by Default", bool),
p!("cmdRulerDragArtboardGuides", "Guides & Grid", "Guides", "Artboard Guides with Cmd/Ctrl + Ruler Drag", bool),
p!("gridColor", "Guides & Grid", "Grid", "Color", color),
p!("gridStyle", "Guides & Grid", "Grid", "Style", choice(LINE_STYLE)),
p!("gridlineEvery", "Guides & Grid", "Grid", "Gridline every", len(1.0, 16383.0, General)),
+4
View File
@@ -124,6 +124,9 @@ pub struct Prefs {
pub guide_style: String,
/// Lock Guides by Default: the app starts with View › Guides › Lock Guides on.
pub lock_guides_by_default: bool,
/// Artboard Guides with Cmd/Ctrl + Ruler Drag: Cmd/Ctrl held when a guide is dragged out of a
/// ruler makes it a guide of the active artboard, or with the Artboard tool a canvas guide.
pub cmd_ruler_drag_artboard_guides: bool,
pub grid_color: String,
pub grid_style: String,
pub gridline_every: f64,
@@ -434,6 +437,7 @@ impl Default for Prefs {
guide_color: s("#4affff"),
guide_style: s("lines"),
lock_guides_by_default: false,
cmd_ruler_drag_artboard_guides: false,
grid_color: s("#c8c8c8"),
grid_style: s("lines"),
gridline_every: 72.0,
+71
View File
@@ -4294,6 +4294,77 @@ fn guides_dragged_out_of_a_ruler_snap_and_take_the_artboard_tool_s_artboard() {
);
}
/// With Preferences › Guides & Grid › Artboard Guides with Cmd/Ctrl + Ruler Drag on, Cmd/Ctrl held
/// when a guide is dragged out of a ruler makes a guide of the view's active artboard (one undo
/// step), shown and made only where it lies within that artboard; with the Artboard tool it makes
/// a canvas guide instead. The key counts on the drag's first event only. With the preference off,
/// Cmd/Ctrl changes nothing.
#[test]
fn cmd_ruler_drags_make_guides_of_the_active_artboard_when_the_preference_is_on() {
use vectorcraft_tools::{Mods, PointerEvent, PointerKind};
let mut s = session();
s.execute("artboard.new", &json!({"x": 900, "y": 0, "width": 400, "height": 300})).unwrap();
let v = ViewInfo { artboard: 1, ..ViewInfo::default() };
let cmd = Mods { cmd: true, ..Mods::default() };
let ev = |kind, x, y, mods| PointerEvent::new(kind, x, y).with_mods(mods);
let owners = |s: &mut Session| -> Vec<Value> {
let list = s.execute("guide.list", &json!({})).unwrap();
list.as_array().unwrap().iter().map(|g| g.get("artboard").cloned().unwrap_or(Value::Null)).collect()
};
let drag = |s: &mut Session, view: ViewInfo, vertical: bool, at: f64, first: Mods| {
let (x, y) = if vertical { (at, 30.0) } else { (1000.0, at) };
s.ruler_guide(vertical, &ev(PointerKind::Drag, x, y, first), true, view).unwrap();
// Letting go of the key during the drag keeps the kind of guide.
s.ruler_guide(vertical, &ev(PointerKind::Up, x, y, Mods::default()), true, view).unwrap();
};
// Off by default: a Cmd/Ctrl drag makes a canvas guide.
assert!(!s.prefs.cmd_ruler_drag_artboard_guides);
drag(&mut s, v, true, 1010.0, cmd);
assert_eq!(owners(&mut s), [Value::Null]);
s.execute("prefs.set", &json!({"key": "cmdRulerDragArtboardGuides", "value": true})).unwrap();
let n = undo_len(&s);
drag(&mut s, v, true, 1020.0, cmd);
drag(&mut s, v, false, 120.0, cmd);
assert_eq!(guides(&s)[1..], [(true, 1020.0), (false, 120.0)]);
assert_eq!(owners(&mut s)[1..], [json!(1), json!(1)]);
assert_eq!(undo_len(&s), n + 2);
s.execute("edit.undo", &json!({})).unwrap();
s.execute("edit.redo", &json!({})).unwrap();
assert_eq!(owners(&mut s)[1..], [json!(1), json!(1)], "redo keeps the artboard");
// Outside the active artboard (left of it, and below it): no preview, no guide, no undo step.
let n = undo_len(&s);
s.ruler_guide(true, &ev(PointerKind::Drag, 500.0, 30.0, cmd), true, v).unwrap();
assert_eq!(guides(&s).len(), 3, "no preview");
s.ruler_guide(true, &ev(PointerKind::Up, 500.0, 30.0, cmd), true, v).unwrap();
drag(&mut s, v, false, 450.0, cmd);
assert_eq!((guides(&s).len(), undo_len(&s)), (3, n));
// Dragged in and out again: the preview goes and nothing is made.
s.ruler_guide(true, &ev(PointerKind::Drag, 1100.0, 30.0, cmd), true, v).unwrap();
assert_eq!(guides(&s).len(), 4, "the preview within the artboard");
s.ruler_guide(true, &ev(PointerKind::Drag, 700.0, 30.0, Mods::default()), true, v).unwrap();
s.ruler_guide(true, &ev(PointerKind::Up, 700.0, 30.0, Mods::default()), true, v).unwrap();
assert_eq!((guides(&s).len(), undo_len(&s)), (3, n));
// An active artboard the document doesn't have: nothing is made.
drag(&mut s, ViewInfo { artboard: 7, ..v }, true, 1030.0, cmd);
assert_eq!((guides(&s).len(), undo_len(&s)), (3, n));
// Without the key: a canvas guide, as before.
drag(&mut s, v, true, 1040.0, Mods::default());
assert_eq!(owners(&mut s)[3], Value::Null);
// The Artboard tool: Cmd/Ctrl makes a canvas guide, and a plain drag an artboard guide.
s.select_tool("artboard", v).unwrap();
s.set_tool_option("active", &json!(1));
drag(&mut s, v, true, 400.0, cmd);
drag(&mut s, v, true, 1050.0, Mods::default());
assert_eq!(guides(&s)[4..], [(true, 400.0), (true, 1050.0)]);
assert_eq!(owners(&mut s)[4..], [Value::Null, json!(1)]);
}
/// Guides saved before guides had layers are put on a layer when the document opens.
#[test]
fn guides_from_older_files_are_put_on_a_layer() {
+16 -3
View File
@@ -709,15 +709,28 @@ impl Session {
/// release), over the canvas or not (`on_canvas`). The guide shows where the pointer is over
/// the canvas, snapped as a moved guide is, and is made where the button is released over it
/// (one undo step); released anywhere else, none is. With the Artboard tool it is an artboard
/// guide of the active artboard.
/// guide of the active artboard. With Preferences › Guides & Grid › Artboard Guides with
/// Cmd/Ctrl + Ruler Drag on, `mods.cmd` on the drag's first event swaps the two: with another
/// tool the guide is one of the view's active artboard (`view.artboard`), shown and made only
/// where it lies within that artboard, and with the Artboard tool it is a canvas guide.
pub fn ruler_guide(&mut self, vertical: bool, ev: &PointerEvent, on_canvas: bool, view: ViewInfo) -> Result<()> {
use vectorcraft_tools::rulerguide::NewGuide;
let g = match self.ruler_guide.take() {
Some(g) => Some(g),
None => {
let boards = self.active().map_or(0, |d| d.doc.artboards.len());
let active = (self.tool.id() == "artboard").then(|| self.tool.options()["active"].as_u64()).flatten();
let artboard_tool = self.tool.id() == "artboard";
let swap = self.prefs.cmd_ruler_drag_artboard_guides && ev.mods.cmd;
let active = artboard_tool.then(|| self.tool.options()["active"].as_u64()).flatten();
let artboard = active.and_then(|i| usize::try_from(i).ok()).filter(|i| *i < boards);
self.with_tool_cx(view, |_, cx| Some(vectorcraft_tools::rulerguide::NewGuide::new(cx, vertical, artboard)))
let view_board = view.artboard;
self.with_tool_cx(view, |_, cx| {
Some(match (swap, artboard_tool) {
(false, _) => NewGuide::new(cx, vertical, artboard),
(true, true) => NewGuide::new(cx, vertical, None),
(true, false) => NewGuide::within(cx, vertical, view_board),
})
})
}
};
let Some(mut g) = g else { return Ok(()) };
+27 -4
View File
@@ -167,6 +167,8 @@ pub struct NewGuide {
vertical: bool,
/// The artboard (index) it belongs to: an artboard guide.
artboard: Option<usize>,
/// Made only within its artboard ([`Self::within`]).
within: bool,
snap: GuideSnap,
/// The preview's orientation and position (none off the canvas), and the pointer.
at: Option<(bool, f64)>,
@@ -177,7 +179,24 @@ impl NewGuide {
/// A vertical guide out of the left ruler, else a horizontal one out of the top ruler; an
/// artboard guide of `artboard`, if any.
pub fn new(cx: &ToolContext, vertical: bool, artboard: Option<usize>) -> Self {
Self { vertical, artboard, snap: GuideSnap::new(cx), at: None, pointer: Point::ZERO }
Self { vertical, artboard, within: false, snap: GuideSnap::new(cx), at: None, pointer: Point::ZERO }
}
/// An artboard guide of `artboard` that shows, and is made, only where it lies within that
/// artboard: a vertical guide between its left and right edges, a horizontal one between its
/// top and bottom. With no such artboard, it never shows and nothing is made.
pub fn within(cx: &ToolContext, vertical: bool, artboard: usize) -> Self {
Self { within: true, ..Self::new(cx, vertical, Some(artboard)) }
}
/// May the guide go at `at` (the x of a vertical guide, the y of a horizontal one)?
fn fits(&self, cx: &ToolContext, vertical: bool, at: f64) -> bool {
if !self.within {
return true;
}
let Some(r) = self.artboard.and_then(|i| cx.doc.artboards.get(i)).map(|a| a.rect) else { return false };
let (lo, hi) = if vertical { (r.min_x(), r.max_x()) } else { (r.min_y(), r.max_y()) };
lo <= at && at <= hi
}
/// The pointer at `ev`, over the canvas or not (`on_canvas`): the actions that show the guide
@@ -185,9 +204,13 @@ impl NewGuide {
pub fn pointer(&mut self, cx: &ToolContext, ev: &PointerEvent, on_canvas: bool) -> Vec<Action> {
let mut out = vec![];
self.pointer = ev.pos;
if on_canvas {
let vertical = self.vertical != ev.mods.alt;
let at = self.snap.snap(cx, vertical, if vertical { ev.pos.x } else { ev.pos.y }, ev.mods.shift);
let place = on_canvas
.then(|| {
let vertical = self.vertical != ev.mods.alt;
(vertical, self.snap.snap(cx, vertical, if vertical { ev.pos.x } else { ev.pos.y }, ev.mods.shift))
})
.filter(|(vertical, at)| self.fits(cx, *vertical, *at));
if let Some((vertical, at)) = place {
if self.at.is_none() {
out.push(Action::Begin("New Guide".into()));
}
+30
View File
@@ -148,6 +148,36 @@ fn a_new_guide_is_made_on_release_over_the_canvas_only() {
assert_eq!(g.pointer(&c, &ev(PointerKind::Up, -5.0, 40.0, m), false), vec![Action::Cancel]);
}
/// A guide made only within its artboard ([`NewGuide::within`]) shows and is made where its
/// position, on the axis Alt gives it, lies within the artboard (edges included). Outside it, or
/// with an artboard the document doesn't have, it goes as it does off the canvas.
#[test]
fn a_guide_within_its_artboard_is_made_only_inside_it() {
let (d, _) = doc_with_rect();
let (s, p) = (Selection::default(), paint());
let c = ToolContext { smart_guides: false, snap_to_point: false, ..cx(&d, &s, &p) };
let m = Mods::default();
let alt = Mods { alt: true, ..m };
let preview = |vertical: bool, pos: f64| Action::Preview("guide.add".into(), json!({"vertical": vertical, "pos": pos, "artboard": 0}));
let mut g = NewGuide::within(&c, true, 0);
// Right of the 500 pt artboard: nothing, then its right edge.
assert_eq!(g.pointer(&c, &ev(PointerKind::Drag, 520.0, 40.0, m), true), vec![]);
assert_eq!(g.pointer(&c, &ev(PointerKind::Drag, 500.0, 40.0, m), true), vec![Action::Begin("New Guide".into()), preview(true, 500.0)]);
// Alt makes it horizontal: y 40 is inside, y 600 is not.
assert_eq!(g.pointer(&c, &ev(PointerKind::Drag, 700.0, 40.0, alt), true), vec![preview(false, 40.0)]);
assert_eq!(g.pointer(&c, &ev(PointerKind::Drag, 300.0, 600.0, alt), true), vec![Action::Cancel]);
assert!(g.overlays(&c).is_empty());
assert_eq!(g.pointer(&c, &ev(PointerKind::Up, 300.0, 600.0, alt), true), vec![]);
// Released inside: made.
let mut g = NewGuide::within(&c, false, 0);
assert_eq!(g.pointer(&c, &ev(PointerKind::Drag, 900.0, 0.0, m), true), vec![Action::Begin("New Guide".into()), preview(false, 0.0)]);
assert_eq!(g.pointer(&c, &ev(PointerKind::Up, 900.0, 0.0, m), true), vec![Action::Commit]);
// No artboard 3: never shown.
let mut g = NewGuide::within(&c, true, 3);
assert_eq!(g.pointer(&c, &ev(PointerKind::Drag, 100.0, 40.0, m), true), vec![]);
assert_eq!(g.pointer(&c, &ev(PointerKind::Up, 100.0, 40.0, m), true), vec![]);
}
#[test]
fn new_ruler_guide_alt_switches_axis_and_uses_the_release_position() {
let (d, _) = doc_with_rect();
+46
View File
@@ -1412,6 +1412,52 @@ fn new_ruler_guide_alt_cancel_keeps_document_and_redo() {
}
}
/// With Preferences › Guides & Grid › Artboard Guides with Cmd/Ctrl + Ruler Drag on, Cmd/Ctrl held
/// when a drag leaves either ruler makes a guide of the active artboard, even when the key is let
/// go before the release; a guide outside the artboard is not made. With the preference off, the
/// same drag makes a canvas guide.
#[test]
fn cmd_ruler_drags_make_artboard_guides_with_the_preference_on() {
use egui::{Event, Modifiers};
for source_vertical in [false, true] {
for on in [false, true] {
let mut app = VectorcraftApp::new(Session::new(), Default::default());
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
app.session.execute("prefs.set", &json!({"key": "cmdRulerDragArtboardGuides", "value": on})).unwrap();
app.ui.view.rulers = true;
app.ui.view.smart_guides = false;
app.ui.view.snap_to_point = false;
app.select_tool("rectangle");
let ctx = egui::Context::default();
frame(&mut app, &ctx, vec![]);
let rect = app.canvas_rect.unwrap();
let xf = Xf::new(rect, app.view().unwrap());
let from =
if source_vertical { pos2(rect.left() - RULER / 2.0, rect.center().y) } else { pos2(rect.center().x, rect.top() - RULER / 2.0) };
let drag = |app: &mut VectorcraftApp, to: Point| {
let at = xf.to_screen(to);
assert!(rect.contains(at));
let button = |pos, pressed, modifiers| Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers };
frame(app, &ctx, vec![Event::ModifiersChanged(Modifiers::COMMAND), Event::PointerMoved(from)]);
frame(app, &ctx, vec![button(from, true, Modifiers::COMMAND)]);
frame(app, &ctx, vec![Event::PointerMoved(at)]);
frame(app, &ctx, vec![Event::ModifiersChanged(Modifiers::NONE), Event::PointerMoved(at), button(at, false, Modifiers::NONE)]);
};
let board = app.session.active().unwrap().doc.artboards[0].id;
drag(&mut app, Point::new(80.0, 120.0));
let st = app.session.active().unwrap();
assert_eq!(st.doc.guides.len(), 1, "vertical {source_vertical}, on {on}");
assert_eq!(st.doc.guides[0].vertical, source_vertical);
assert_eq!(st.doc.guides[0].artboard, on.then_some(board), "vertical {source_vertical}, on {on}");
// Beyond the artboard's right or bottom edge.
let beyond = xf.to_doc(rect.right_bottom() - egui::vec2(2.0, 2.0));
assert!(beyond.x > 400.0 && beyond.y > 300.0, "{beyond:?}");
drag(&mut app, beyond);
assert_eq!(app.session.active().unwrap().doc.guides.len(), if on { 1 } else { 2 }, "vertical {source_vertical}, on {on}");
}
}
}
/// #451: a guide dragged out of a ruler lands on the art's side midpoints (halving an
/// artboard-sized rectangle) and on the artboard's edges; an artboard guide is drawn across
/// its artboard only.
+1
View File
@@ -1826,6 +1826,7 @@ font-technology Variable Променливи
Lock Grid Заключване на мрежата
Lock Guides Заключване на водачите
Lock Guides by Default Заключване на водачите по подразбиране
Artboard Guides with Cmd/Ctrl + Ruler Drag Водачи за работната област с Cmd/Ctrl + плъзгане от линийка
Lock Others Заключване на другите
Lock Slices Заключване на фрагментите
Lock Station Point Заключване на базовата точка
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -601,6 +601,7 @@
Show Guides Prikaži vodilice
Lock Guides Zaključaj vodilice
Lock Guides by Default Zaključaj vodilice po zadanom
Artboard Guides with Cmd/Ctrl + Ruler Drag Vodilice radne ploče uz Cmd/Ctrl + povlačenje s ravnala
Unlock Guides Otključaj vodilice
Make Guides Napravi vodilice
Release Guides Oslobodi vodilice
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2350,6 +2350,7 @@ digits Malayalam Malaiàlam
Lock Grid Bloca la quadrícula
Lock Guides Bloca les guies
Lock Guides by Default Bloca les guies per defecte
Artboard Guides with Cmd/Ctrl + Ruler Drag Guies del tauler amb Cmd/Ctrl + arrossegament des de la regla
Lock Others Bloca la resta
Lock Selected Bloca la selecció
Lock Slices Bloca els talls
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -610,6 +610,7 @@
Show Guides Zobrazit vodítka
Lock Guides Zamknout vodítka
Lock Guides by Default Ve výchozím stavu zamknout vodítka
Artboard Guides with Cmd/Ctrl + Ruler Drag Vodítka pracovní plochy tažením z pravítka s Cmd/Ctrl
Unlock Guides Odemknout vodítka
Make Guides Vytvořit vodítka
Release Guides Uvolnit vodítka
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -560,6 +560,7 @@
Show Guides Vis hjælpelinjer
Lock Guides Lås hjælpelinjer
Lock Guides by Default Lås hjælpelinjer som standard
Artboard Guides with Cmd/Ctrl + Ruler Drag Hjælpelinjer til kunstplade med Cmd/Ctrl + træk fra lineal
Unlock Guides Lås hjælpelinjer op
Make Guides Opret hjælpelinjer
Release Guides Frigør hjælpelinjer
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1893,6 +1893,7 @@ file-filter Templates Vorlagen
Lock Grid Raster sperren
Lock Guides Hilfslinien sperren
Lock Guides by Default Hilfslinien standardmäßig sperren
Artboard Guides with Cmd/Ctrl + Ruler Drag Zeichenflächen-Hilfslinien mit Cmd/Ctrl + Ziehen aus dem Lineal
Lock Others Andere sperren
Lock Slices Slices sperren
Lock Station Point Standpunkt sperren
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1725,6 +1725,7 @@ font-technology Variable Μεταβλητές
Lock Κλείδωμα
Lock Guides Κλείδωμα οδηγών
Lock Guides by Default Κλείδωμα οδηγών από προεπιλογή
Artboard Guides with Cmd/Ctrl + Ruler Drag Οδηγοί πίνακα σχεδίασης με Cmd/Ctrl + σύρσιμο από χάρακα
Lock Slices Κλείδωμα τομών
Low Χαμηλή
Luminosity Φωτεινότητα
Can't render this file because it is too large.
+1
View File
@@ -1896,6 +1896,7 @@ font-technology Variable Variables
Lock Grid Bloquear cuadrícula
Lock Guides Bloquear guías
Lock Guides by Default Bloquear guías de forma predeterminada
Artboard Guides with Cmd/Ctrl + Ruler Drag Guías de mesa de trabajo con Cmd/Ctrl + arrastre desde la regla
Lock Others Bloquear otros
Lock Slices Bloquear sectores
Lock Station Point Bloquear punto de estación
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -601,6 +601,7 @@
Show Guides Näytä apuviivat
Lock Guides Lukitse apuviivat
Lock Guides by Default Lukitse apuviivat oletuksena
Artboard Guides with Cmd/Ctrl + Ruler Drag Piirtoalustan apuviivat Cmd/Ctrl + vetämällä viivaimesta
Unlock Guides Avaa apuviivojen lukitus
Make Guides Luo apuviivat
Release Guides Vapauta apuviivat
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1890,6 +1890,7 @@ font-technology Variable Variables
Lock Grid Verrouiller la grille
Lock Guides Verrouiller les repères
Lock Guides by Default Verrouiller les repères par défaut
Artboard Guides with Cmd/Ctrl + Ruler Drag Repères de plan de travail avec Cmd/Ctrl + glissement depuis la règle
Lock Others Verrouiller les autres
Lock Slices Verrouiller les tranches
Lock Station Point Verrouiller le point d’observation
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2567,6 +2567,7 @@ antiAlias Sharp शार्प
Lock Grid लॉक ग्रिड
Lock Guides गाइड्स लॉक करें
Lock Guides by Default गाइड्स डिफ़ॉल्ट रूप से लॉक करें
Artboard Guides with Cmd/Ctrl + Ruler Drag Cmd/Ctrl + रूलर से ड्रैग करके आर्टबोर्ड गाइड्स
Lock Others लॉक अन्य
Lock Selected लॉक सिलेक्टेड
Lock Slices स्लाइस लॉक करें
Can't render this file because it is too large.
+1
View File
@@ -2377,6 +2377,7 @@ file-filter Templates Sablonok
Lock Grid Rács zárolása
Lock Guides Segédvonalak zárolása
Lock Guides by Default Segédvonalak zárolása alapértelmezetten
Artboard Guides with Cmd/Ctrl + Ruler Drag Rajztábla-segédvonalak Cmd/Ctrl + húzással a vonalzóból
Lock Others Többi zárolása
Lock Slices Szeletek zárolása
Lock Station Point Nézőpont zárolása
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -560,6 +560,7 @@
Show Guides Tampilkan panduan
Lock Guides Kunci panduan
Lock Guides by Default Kunci panduan secara default
Artboard Guides with Cmd/Ctrl + Ruler Drag Panduan artboard dengan Cmd/Ctrl + seret dari penggaris
Unlock Guides Buka kunci panduan
Make Guides Buat panduan
Release Guides Lepaskan panduan
1 # Indonesian (id) catalog. Same format as zh-hant.tsv: context <TAB> source <TAB> translation
560
561
562
563
564
565
566
+1
View File
@@ -1925,6 +1925,7 @@ file-filter Templates Modelli
Lock Grid Blocca griglia
Lock Guides Blocca guide
Lock Guides by Default Blocca guide per impostazione predefinita
Artboard Guides with Cmd/Ctrl + Ruler Drag Guide della tavola da disegno con Cmd/Ctrl + trascinamento dal righello
Lock Others Blocca altri
Lock Slices Blocca sezioni
Lock Station Point Blocca punto di osservazione
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -628,6 +628,7 @@ digits Malayalam マラヤーラム数字
Hide Guides ガイドを隠す
Lock Guides ガイドをロック
Lock Guides by Default ガイドを初期設定でロック
Artboard Guides with Cmd/Ctrl + Ruler Drag Cmd/Ctrl + 定規からのドラッグでアートボードガイド
Make Guides ガイドを作成
Release Guides ガイドを解除
Clear Guides ガイドを消去
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -522,6 +522,7 @@
Show Guides დამხმარე ხაზების ჩვენება
Lock Guides დამხმარე ხაზების ჩაკეტვა
Lock Guides by Default დამხმარე ხაზების ნაგულისხმევად ჩაკეტვა
Artboard Guides with Cmd/Ctrl + Ruler Drag სამუშაო დაფის დამხმარე ხაზები Cmd/Ctrl + სახაზავიდან გადათრევით
Unlock Guides დამხმარე ხაზების განბლოკვა
Make Guides დამხმარე ხაზების შექმნა
Release Guides დამხმარე ხაზების მოხსნა
Can't render this file because it is too large.
+1
View File
@@ -623,6 +623,7 @@ digits Malayalam 말라얄람어
Hide Guides 안내선 숨기기
Lock Guides 안내선 잠그기
Lock Guides by Default 기본적으로 안내선 잠그기
Artboard Guides with Cmd/Ctrl + Ruler Drag Cmd/Ctrl + 눈금자 드래그로 아트보드 안내선
Make Guides 안내선 만들기
Release Guides 안내선 해제
Clear Guides 안내선 지우기
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -574,6 +574,7 @@
Show Guides Hulplijnen tonen
Lock Guides Hulplijnen vergrendelen
Lock Guides by Default Hulplijnen standaard vergrendelen
Artboard Guides with Cmd/Ctrl + Ruler Drag Tekenbordhulplijnen met Cmd/Ctrl + slepen vanuit liniaal
Unlock Guides Hulplijnen ontgrendelen
Make Guides Hulplijnen maken
Release Guides Hulplijnen vrijgeven
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -567,6 +567,7 @@
Show Guides Pokaż linie pomocnicze
Lock Guides Zablokuj linie pomocnicze
Lock Guides by Default Domyślnie blokuj linie pomocnicze
Artboard Guides with Cmd/Ctrl + Ruler Drag Linie pomocnicze obszaru kompozycji z Cmd/Ctrl + przeciąganiem z linijki
Unlock Guides Odblokuj linie pomocnicze
Make Guides Utwórz linie pomocnicze
Release Guides Uwolnij linie pomocnicze
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1617,6 +1617,7 @@ antiAlias Sharp Nítido
Lock Grid Bloquear Grade
Lock Guides Bloquear Guias
Lock Guides by Default Bloquear Guias por Padrão
Artboard Guides with Cmd/Ctrl + Ruler Drag Guias de Prancheta com Cmd/Ctrl + Arrastar da Régua
Lock Slices Bloquear Fatias
Lock Station Point Bloquear Ponto de Estação
Lossless (lossy WebP isn't available yet) Sem Perdas (WebP com perdas ainda não está disponível)
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1
View File
@@ -1922,6 +1922,7 @@ file-filter Templates Шаблоны
Lock Grid Заблокировать сетку
Lock Guides Заблокировать направляющие
Lock Guides by Default Блокировать направляющие по умолчанию
Artboard Guides with Cmd/Ctrl + Ruler Drag Направляющие монтажной области с Cmd/Ctrl + перетаскиванием с линейки
Lock Others Заблокировать остальные
Lock Slices Заблокировать фрагменты
Lock Station Point Заблокировать точку стояния
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1837,6 +1837,7 @@ font-technology Variable Variabla
Lock Grid Lås rutnät
Lock Guides Lås stödlinjer
Lock Guides by Default Lås stödlinjer som standard
Artboard Guides with Cmd/Ctrl + Ruler Drag Stödlinjer för rityta med Cmd/Ctrl + dra från linjal
Lock Others Lås övriga
Lock Slices Lås skivor
Lock Station Point Lås betraktarpunkt
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -1730,6 +1730,7 @@ font-technology Variable Değişken
Lock Grid Izgarayı Kilitle
Lock Guides Kilit Kılavuzları
Lock Guides by Default Kılavuzları Varsayılan Olarak Kilitle
Artboard Guides with Cmd/Ctrl + Ruler Drag Cmd/Ctrl + Cetvelden Sürükleme ile Çalışma Yüzeyi Kılavuzları
Lock Others Diğerlerini Kilitle
Lock Slices Dilimleri Kilitle
Lock Station Point Kilit İstasyon Noktası
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -1919,6 +1919,7 @@ file-filter Templates Шаблони
Lock Grid Заблокувати сітку
Lock Guides Заблокувати напрямні
Lock Guides by Default Блокувати напрямні за замовчуванням
Artboard Guides with Cmd/Ctrl + Ruler Drag Напрямні монтажної області з Cmd/Ctrl + перетягуванням з лінійки
Lock Others Заблокувати решту
Lock Slices Заблокувати фрагменти
Lock Station Point Заблокувати точку стояння
Can't render this file because it contains an unexpected character in line 182 and column 5.
+1
View File
@@ -2203,6 +2203,7 @@ digits Hindi Hindi
Lock Grid Khóa lưới
Lock Guides Khóa đường căn
Lock Guides by Default Khóa đường căn theo mặc định
Artboard Guides with Cmd/Ctrl + Ruler Drag Đường căn bảng vẽ với Cmd/Ctrl + kéo từ thước
Lock Others Khóa các mục khác
Lock Slices Khóa lát cắt
Lock Station Point Khóa điểm trạm
Can't render this file because it contains an unexpected character in line 204 and column 5.
+1
View File
@@ -1806,6 +1806,7 @@ file-filter Templates 模板
Lock Grid 锁定网格
Lock Guides 锁定参考线
Lock Guides by Default 默认锁定参考线
Artboard Guides with Cmd/Ctrl + Ruler Drag 按住 Cmd/Ctrl 从标尺拖动创建画板参考线
Lock Slices 锁定切片
Lock Station Point 锁定基准点
Lossless (lossy WebP isn't available yet) 无失真 (尚未提供有失真的 WebP)
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2830,6 +2830,7 @@ file-filter Templates 範本
Lock Grid 鎖定格點
Lock Guides 鎖定參考線
Lock Guides by Default 預設鎖定參考線
Artboard Guides with Cmd/Ctrl + Ruler Drag 按住 Cmd/Ctrl 從尺標拖曳建立工作區域參考線
Lock Others 鎖定其他
Lock Slices 鎖定切片
Lock Station Point 鎖定基準點
Can't render this file because it contains an unexpected character in line 6 and column 47.
+6
View File
@@ -1986,6 +1986,12 @@ Guides off, View › Snap to Point pulls it onto anchors. In the desktop app a g
same way and is made where it is released over the canvas (with the Artboard tool, as an artboard guide of the
active artboard), a guide dropped off the canvas onto its ruler is deleted, and hidden guides (View › Guides › Hide
Guides) can't be picked. An artboard guide is picked, drawn and snapped to across its artboard only.
Preferences › Guides & Grid › Artboard Guides with Cmd/Ctrl + Ruler Drag (`cmdRulerDragArtboardGuides`, off by
default) is VectorCraft's own option. With it on, Cmd/Ctrl held when a drag leaves a ruler makes the guide an artboard
guide of the active artboard, with any tool but the Artboard tool, and with the Artboard tool a canvas guide. The key
is read when the drag starts, so letting it go during the drag keeps the kind of guide. Such an artboard guide shows,
and is made, only where it lies within the active artboard: a vertical guide between its left and right edges, a
horizontal guide between its top and bottom. Released anywhere else, it makes no guide and no undo step.
```json
{"name":"run_command","arguments":{"command":"guide.add","params":{"vertical":true,"pos":100}}}
+1
View File
@@ -640,6 +640,7 @@ since 2026-10-01.
Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a feature lands.
- **New ruler guides (G1):** Alt swaps orientation while dragging from either ruler, following the [public shortcut reference](https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html). Preview, snapping and final placement use the current axis. Tool and egui event tests exercise both rulers, modifier changes, cancellation and one-step Undo/Redo; existing-guide Alt-copy and ruler-origin gestures are unchanged.
- **Artboard guides with Cmd/Ctrl + ruler drag:** VectorCraft's own option, Preferences › Guides & Grid › Artboard Guides with Cmd/Ctrl + Ruler Drag (`cmdRulerDragArtboardGuides`), off by default. With it on, Cmd/Ctrl held when a drag leaves a ruler makes a guide of the active artboard, and with the Artboard tool a canvas guide; the key is read when the drag starts. The guide is made only where it lies within the active artboard. The documented way to limit a guide to one artboard, dragging it out with the Artboard tool ([Align objects with guides](https://helpx.adobe.com/illustrator/desktop/measure-and-align/grids-and-guides/align-graphic-objects-with-guides.html)), is unchanged when the option is off. Tests `rulerguide::tests::a_guide_within_its_artboard_is_made_only_inside_it`, `tests::menucmds::cmd_ruler_drags_make_guides_of_the_active_artboard_when_the_preference_is_on` and `canvas::tests::cmd_ruler_drags_make_artboard_guides_with_the_preference_on`.
- **Width-point finite-arithmetic follow-up (G1/M3):** Adjoining adjustments avoid intermediate overflow; non-finite normalized or resulting factors are rejected before committing. Engine regressions in `tests/widthpoints.rs` cover finite extremes, small nonzero results, atomic rejection, Undo/Redo and native save/reopen. Historical focused validation on the `a3357121` integration observed 2 expected RED failures with 11 passing controls, then all 13 tests passing with the repair; none were ignored. All three added regressions passed in current full CI. A full CI retry on the five-unit combined source at `a0671777` passed all seven stages with 6,613 test outcomes on 2026-10-14. An earlier full-CI run on the identical source panicked in the randomized `ai_mutated_save_never_panics` test; the cause remains unresolved. This five-fix batch does not claim to repair that failure. Scores and hours unchanged.
- **Width-point creation (G1):** double-click a stroked segment with the Width tool to open Width Point Edit using sampled side widths. OK creates the point and optionally adjusts adjoining widths in one undo step. Cancel or Delete discards a prospective point without changing the document or redo history. Command and pointer tests cover profiles, compound paths, adjoining adjustment, existing-point editing and Undo/Redo. Message-catalog checks and full CI passed; the original capture verifies opening and Cancel, and the dialog layout was reviewed (2026-10-13: 28 focused Width tests, all seven cargo xtask ci stages, and a headless opening/Cancel capture with original PNG review). [Variable-width strokes](https://helpx.adobe.com/illustrator/using/stroke-object.html).