mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 18:56:55 -06:00
Merge pull request #4225 from ncic/pencil-live-preview
Pencil: Live preview option in Pencil Tool Options
This commit is contained in:
@@ -2771,3 +2771,29 @@ fn pencil_redraws_a_selected_compound_path() {
|
||||
assert_eq!(s.doc().unwrap().selection.objects, compound);
|
||||
assert!(members(&s)[1] != before[1], "the hole is redrawn");
|
||||
}
|
||||
|
||||
/// With the Pencil's Live preview off, nothing is added to the document while a filled stroke is
|
||||
/// drawn; the release draws the path with its fill, as one undo step.
|
||||
#[test]
|
||||
fn pencil_with_live_preview_off_draws_the_filled_path_on_release() {
|
||||
let mut s = session();
|
||||
s.execute("select.none", &json!({})).unwrap();
|
||||
s.execute("paint.setFill", &json!({"color": "#ff0000"})).unwrap();
|
||||
s.set_tool_option_cmd(&json!({"tool": "pencil", "values": {"livePreview": false, "fill": true}})).unwrap();
|
||||
assert_eq!(s.tool_options_of("pencil")["livePreview"], json!(false));
|
||||
let v = view();
|
||||
s.select_tool("pencil", v).unwrap();
|
||||
let count = |s: &Session| s.doc().unwrap().doc.layers[0].children().map_or(0, |c| c.len());
|
||||
let (before, undo) = (count(&s), s.doc().unwrap().history.undo.len());
|
||||
s.pointer(&PointerEvent::new(PointerKind::Down, 100.0, 100.0), v).unwrap();
|
||||
for (x, y) in [(160.0, 110.0), (190.0, 170.0), (120.0, 190.0), (105.0, 120.0)] {
|
||||
s.pointer(&PointerEvent::new(PointerKind::Drag, x, y), v).unwrap();
|
||||
assert_eq!(count(&s), before, "nothing drawn while the stroke is drawn");
|
||||
}
|
||||
s.pointer(&PointerEvent::new(PointerKind::Up, 105.0, 120.0), v).unwrap();
|
||||
assert_eq!(count(&s), before + 1, "the release draws the path");
|
||||
let doc = &s.doc().unwrap().doc;
|
||||
let n = doc.layers[0].children().unwrap().last().unwrap();
|
||||
assert!(n.path_data().is_some() && !n.appearance.fill_paint().is_none(), "{:?}", n.appearance);
|
||||
assert_eq!(s.doc().unwrap().history.undo.len(), undo + 1, "one undo step");
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ pub struct GestureTool {
|
||||
/// "Alt key toggles to Smooth Tool": holding Alt with the Pencil tool smooths selected paths
|
||||
/// instead of closing the path (Pencil only, off by default).
|
||||
pub alt_smooth: bool,
|
||||
/// "Live preview" (Pencil only, on by default): the stroke shows with its fill and stroke as it
|
||||
/// is drawn. Off, only a thin line follows the pen while drawing, and the path takes its fill
|
||||
/// and stroke on release.
|
||||
pub live_preview: bool,
|
||||
/// "Live curve fitting": the Pencil's preview fits the stroke while it is drawn; off, the
|
||||
/// preview shows the points joined by straight segments and the release fits them (Pencil
|
||||
/// only, on by default).
|
||||
@@ -131,6 +135,7 @@ impl GestureTool {
|
||||
keep_selected: id != "blobBrush",
|
||||
// Off, as Pencil Tool Options ships it: Alt keeps drawing a closed path until it is on.
|
||||
alt_smooth: false,
|
||||
live_preview: true,
|
||||
live_fit: true,
|
||||
smoothing: false,
|
||||
straight: false,
|
||||
@@ -154,6 +159,12 @@ impl GestureTool {
|
||||
matches!(self.id, "pencil" | "paintbrush")
|
||||
}
|
||||
|
||||
/// Does a stroke show as the path it draws while it is drawn? Not with the Pencil's Live preview
|
||||
/// off: then the drag shows as a thin line (an overlay) until the release.
|
||||
fn previews(&self) -> bool {
|
||||
!(self.id == "pencil" && !self.live_preview)
|
||||
}
|
||||
|
||||
/// Add a stroke sample.
|
||||
fn push(&mut self, p: Point, pressure: f32) {
|
||||
let raw = self.shift_next.take();
|
||||
@@ -469,7 +480,8 @@ impl Tool for GestureTool {
|
||||
self.began = true;
|
||||
out.push(Action::Begin(self.label().into()));
|
||||
}
|
||||
if crate::previews_at(self.points.len()) {
|
||||
// With the Pencil's Live preview off a thin line shows instead (`overlays`).
|
||||
if self.previews() && crate::previews_at(self.points.len()) {
|
||||
self.previewed = self.points.len();
|
||||
let mut v = self.freehand_params(false);
|
||||
if !self.live_fit {
|
||||
@@ -567,7 +579,8 @@ impl Tool for GestureTool {
|
||||
}
|
||||
fn overlays(&self, cx: &ToolContext) -> Vec<Overlay> {
|
||||
let mut o = self.snap.guides().to_vec();
|
||||
if !self.active || self.points.len() < 2 || self.began {
|
||||
// A path being drawn shows itself, except with the Pencil's Live preview off.
|
||||
if !self.active || self.points.len() < 2 || (self.began && self.previews()) {
|
||||
return o;
|
||||
}
|
||||
let width = match self.id {
|
||||
@@ -627,6 +640,7 @@ impl Tool for GestureTool {
|
||||
"fidelity": self.fidelity,
|
||||
"fill": self.fill,
|
||||
"altSmooth": self.alt_smooth,
|
||||
"livePreview": self.live_preview,
|
||||
"liveFit": self.live_fit,
|
||||
"keepSelected": self.keep_selected,
|
||||
"editWithin": self.edit_within,
|
||||
@@ -656,6 +670,7 @@ impl Tool for GestureTool {
|
||||
"roundness" => self.roundness = v.as_f64().unwrap_or(self.roundness).clamp(1.0, 100.0),
|
||||
"fill" => self.fill = v.as_bool().unwrap_or(self.fill),
|
||||
"altSmooth" => self.alt_smooth = v.as_bool().unwrap_or(self.alt_smooth),
|
||||
"livePreview" if self.id == "pencil" => self.live_preview = v.as_bool().unwrap_or(self.live_preview),
|
||||
"liveFit" if self.id == "pencil" => self.live_fit = v.as_bool().unwrap_or(self.live_fit),
|
||||
"keepSelected" => self.keep_selected = v.as_bool().unwrap_or(self.keep_selected),
|
||||
"mergeOnlySelection" => self.merge_only_selection = v.as_bool().unwrap_or(self.merge_only_selection),
|
||||
@@ -812,6 +827,50 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// With the Pencil's Live preview off, a stroke previews nothing while it is drawn: a thin line
|
||||
/// follows the pen (an overlay), and the release draws the path with its fill and stroke. On (the
|
||||
/// default), every step previews the path and no line is shown. The Paintbrush has no such option.
|
||||
#[test]
|
||||
fn pencil_with_live_preview_off_shows_a_thin_line_until_the_release() {
|
||||
let (d, _) = doc_with_rect();
|
||||
let s = Selection::default();
|
||||
let p = paint();
|
||||
let cx = cx(&d, &s, &p);
|
||||
let previews = |acts: &[Action]| acts.iter().filter(|a| matches!(a, Action::Preview(..))).count();
|
||||
let line = |t: &GestureTool| t.overlays(&cx).iter().any(|o| matches!(o, Overlay::Path { width, .. } if *width == 1.0));
|
||||
let pts = [(0.0, 0.0), (10.0, 5.0), (20.0, 0.0), (30.0, 5.0)];
|
||||
for live in [true, false] {
|
||||
let mut t = GestureTool::new("pencil");
|
||||
assert_eq!(t.options()["livePreview"], json!(true), "on by default");
|
||||
t.set_option("livePreview", &json!(live));
|
||||
assert_eq!(t.options()["livePreview"], json!(live));
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Down, pts[0].0, pts[0].1));
|
||||
let mut during = vec![];
|
||||
for &(x, y) in &pts[1..] {
|
||||
during.extend(t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, x, y)));
|
||||
}
|
||||
assert!(matches!(during.first(), Some(Action::Begin(_))), "live {live}: {during:?}");
|
||||
assert_eq!(previews(&during), if live { 3 } else { 0 }, "live {live}: {during:?}");
|
||||
assert_eq!(line(&t), !live, "live {live}: the thin line shows only with Live preview off");
|
||||
let up = t.pointer(&cx, &PointerEvent::new(PointerKind::Up, 30.0, 5.0));
|
||||
assert!(matches!(up.as_slice(), [Action::Preview(c, _), Action::Commit] if c == "path.freehand"), "live {live}: {up:?}");
|
||||
assert!(!line(&t), "live {live}: no line after the release");
|
||||
}
|
||||
// Escape mid-stroke with Live preview off cancels the stroke it began.
|
||||
let mut t = GestureTool::new("pencil");
|
||||
t.set_option("livePreview", &json!(false));
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Down, 0.0, 0.0));
|
||||
t.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 10.0, 5.0));
|
||||
assert_eq!(t.key(&cx, ToolKey::Escape, Mods::default()), vec![Action::Cancel]);
|
||||
// The Paintbrush keeps previewing: Live preview isn't one of its options.
|
||||
let mut b = GestureTool::new("paintbrush");
|
||||
assert!(b.options().get("livePreview").is_none());
|
||||
b.set_option("livePreview", &json!(false));
|
||||
b.pointer(&cx, &PointerEvent::new(PointerKind::Down, 0.0, 0.0));
|
||||
let acts = b.pointer(&cx, &PointerEvent::new(PointerKind::Drag, 10.0, 5.0));
|
||||
assert_eq!(previews(&acts), 1, "{acts:?}");
|
||||
}
|
||||
|
||||
/// Holding Alt shows the Paintbrush's closing cursor before the press, and the Pencil's and the
|
||||
/// Paintbrush's while drawing (before a press, Alt gives the Pencil its straight-line cursor); a release
|
||||
/// with Alt still held closes the path, and Alt let go before the release leaves it open.
|
||||
|
||||
@@ -35,9 +35,9 @@ const ROWS: &[Row] = &[
|
||||
// Line Segment Tool Options: the Length and Angle a click's dialog opens with, Fill Line.
|
||||
(&["lineSegment"], None, &["length", "angle", "fillLine"]),
|
||||
(&["pencil", "paintbrush"], None, &["fidelity", "fill", "keepSelected", "editWithin", "closeWithin"]),
|
||||
// Pencil Tool Options' Alt key toggles to Smooth Tool and Live curve fitting (the Paintbrush
|
||||
// has neither option).
|
||||
(&["pencil"], None, &["altSmooth", "liveFit"]),
|
||||
// Pencil Tool Options' Alt key toggles to Smooth Tool, Live preview and Live curve fitting (the
|
||||
// Paintbrush has none of them).
|
||||
(&["pencil"], None, &["altSmooth", "livePreview", "liveFit"]),
|
||||
(&["smooth"], None, &["fidelity"]),
|
||||
(&["blobBrush", "eraser"], None, &["size"]),
|
||||
(&["blobBrush"], None, &["keepSelected", "mergeOnlySelection"]),
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
//! Fields: `tool`; `fidelity` (points; Pencil, Paintbrush and Smooth), `fill` (Pencil and
|
||||
//! Paintbrush), `keepSelected` (Pencil, Paintbrush and Blob Brush), `mergeOnlySelection` (Blob
|
||||
//! Brush), `closeWithin` and `editWithin` (screen pixels, 0 turns it off; Pencil and Paintbrush),
|
||||
//! `angle` (degrees) and `roundness` (percent; Eraser) and `size` (points; Blob Brush and Eraser).
|
||||
//! `angle` (degrees) and `roundness` (percent; Eraser), `livePreview` (Pencil: the stroke shows
|
||||
//! with its fill and stroke while it is drawn, or as a thin line until the release) and `size`
|
||||
//! (points; Blob Brush and Eraser).
|
||||
|
||||
use serde_json::{Map, Value, json};
|
||||
|
||||
@@ -25,8 +27,20 @@ pub(super) const SPEC: DialogSpec = DialogSpec { heading, body, confirm, min_wid
|
||||
pub const TOOLS: [&str; 5] = ["pencil", "paintbrush", "smooth", "blobBrush", "eraser"];
|
||||
|
||||
/// The options the dialog edits, in the order it shows them (a tool has those it reports).
|
||||
const KEYS: [&str; 11] =
|
||||
["fidelity", "angle", "roundness", "size", "fill", "altSmooth", "keepSelected", "mergeOnlySelection", "closeWithin", "editWithin", "liveFit"];
|
||||
const KEYS: [&str; 12] = [
|
||||
"fidelity",
|
||||
"angle",
|
||||
"roundness",
|
||||
"size",
|
||||
"fill",
|
||||
"altSmooth",
|
||||
"keepSelected",
|
||||
"mergeOnlySelection",
|
||||
"closeWithin",
|
||||
"editWithin",
|
||||
"livePreview",
|
||||
"liveFit",
|
||||
];
|
||||
|
||||
/// Width of the dialog's rows: every number field ends at its right edge.
|
||||
const CONTENT_W: f32 = 330.0;
|
||||
@@ -190,8 +204,14 @@ fn body(_app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
if d.fields.contains_key("editWithin") {
|
||||
number(ui, d, ("editWithin", tl!("Edit selected paths within:")), "px", 0, (0.0, 100.0));
|
||||
}
|
||||
if d.fields.contains_key("liveFit") {
|
||||
if d.fields.contains_key("livePreview") {
|
||||
ui.add_space(6.0);
|
||||
check(ui, d, "livePreview", tl!("Live preview"));
|
||||
}
|
||||
if d.fields.contains_key("liveFit") {
|
||||
if !d.fields.contains_key("livePreview") {
|
||||
ui.add_space(6.0);
|
||||
}
|
||||
check(ui, d, "liveFit", tl!("Live curve fitting"));
|
||||
}
|
||||
false
|
||||
@@ -283,6 +303,7 @@ mod tests {
|
||||
"Alt key toggles to Smooth Tool",
|
||||
"Close paths when ends are within:",
|
||||
"Edit selected paths within:",
|
||||
"Live preview",
|
||||
] {
|
||||
assert!(text.contains(label), "{label} in {text}");
|
||||
}
|
||||
@@ -310,7 +331,7 @@ mod tests {
|
||||
assert_eq!((d.f64("fidelity", 0.0), d.bool("fill")), (1.5, false));
|
||||
let pb_text = painted(&mut app);
|
||||
assert!(pb_text.contains("Paintbrush Tool Options"));
|
||||
assert!(!pb_text.contains("Alt key toggles to Smooth Tool"));
|
||||
assert!(!pb_text.contains("Alt key toggles to Smooth Tool") && !pb_text.contains("Live preview"), "{pb_text}");
|
||||
// Smooth has Fidelity only, the Eraser Size only, and the Blob Brush Size, Keep selected and Merge only with selection.
|
||||
app.run("tool.options", json!({"tool": "smooth"})).unwrap();
|
||||
let text = painted(&mut app);
|
||||
|
||||
@@ -5483,3 +5483,4 @@ axis Y Axis Y ос
|
||||
Polar Grid Tool Options Опции на инструмента „Полярна мрежа“
|
||||
Fill Line Запълване на линия
|
||||
Scale Presets Пресети за мащаб
|
||||
Live preview Преглед на живо
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5561,3 +5561,4 @@ axis Y Axis osa Y
|
||||
Scale Presets Přednastavení měřítka
|
||||
@msg a {width}×{height} screenshot's byte count overflows počet bajtů snímku {width}×{height} přeteče
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot okno {what} ({points} bodů × {scale} DPI) nemůže určit velikost snímku
|
||||
Live preview Živý náhled
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5499,3 +5499,4 @@ axis Y Axis Y-akse
|
||||
Polar Grid Tool Options Indstillinger for polært gitterværktøj
|
||||
Fill Line Udfyld linje
|
||||
Scale Presets Skaleringsforudindstillinger
|
||||
Live preview Direkte forhåndsvisning
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5143,3 +5143,4 @@ axis Y Axis Y-Achse
|
||||
Scale Presets Skalierungsvorgaben
|
||||
@msg a {width}×{height} screenshot's byte count overflows die Byteanzahl eines {width}×{height}-Screenshots läuft über
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot die {what} des Fensters ({points} Punkte × {scale} DPI) kann keinen Screenshot bemessen
|
||||
Live preview Live-Vorschau
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5513,3 +5513,4 @@ axis Y Axis Άξονας Y
|
||||
Scale Presets Προεπιλογές κλίμακας
|
||||
@msg a {width}×{height} screenshot's byte count overflows το πλήθος byte ενός στιγμιότυπου {width}×{height} υπερχειλίζει
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot το {what} του παραθύρου ({points} σημεία × {scale} DPI) δεν μπορεί να καθορίσει μέγεθος στιγμιότυπου
|
||||
Live preview Ζωντανή προεπισκόπηση
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2070 and column 19.
|
@@ -5503,3 +5503,4 @@ axis Y Axis Eje Y
|
||||
Scale Presets Ajustes predefinidos de escala
|
||||
@msg a {width}×{height} screenshot's byte count overflows el número de bytes de una captura de {width}×{height} se desborda
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot el {what} de la ventana ({points} puntos × {scale} DPI) no puede dimensionar una captura
|
||||
Live preview Vista previa en directo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5592,3 +5592,4 @@ axis Y Axis Y-akseli
|
||||
Scale Presets Skaalauksen esiasetukset
|
||||
@msg a {width}×{height} screenshot's byte count overflows {width}×{height} kuvakaappauksen tavumäärä ylittää rajan
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot ikkunan {what} ({points} pistettä × {scale} DPI) ei voi määrittää kuvakaappauksen kokoa
|
||||
Live preview Reaaliaikainen esikatselu
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5560,3 +5560,4 @@ axis Y Axis Axe Y
|
||||
Scale Presets Préréglages de mise à l'échelle
|
||||
@msg a {width}×{height} screenshot's byte count overflows le nombre d'octets d'une capture {width}×{height} dépasse la limite
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot la {what} de la fenêtre ({points} points × {scale} DPI) ne permet pas de dimensionner une capture
|
||||
Live preview Aperçu en direct
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5547,3 +5547,4 @@ axis Y Axis Y tengely
|
||||
Scale Presets Méretezési beállítások
|
||||
@msg a {width}×{height} screenshot's byte count overflows a(z) {width}×{height} képernyőkép bájtszáma túlcsordul
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot az ablak {what} ({points} pont × {scale} DPI) nem tud képernyőkép-méretet adni
|
||||
Live preview Élő előnézet
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5499,3 +5499,4 @@ axis Y Axis Sumbu Y
|
||||
Polar Grid Tool Options Opsi alat kisi polar
|
||||
Fill Line Isi garis
|
||||
Scale Presets Preset skala
|
||||
Live preview Pratinjau langsung
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3839 and column 19.
|
@@ -5177,3 +5177,4 @@ axis Y Axis Asse Y
|
||||
Scale Presets Preimpostazioni di scala
|
||||
@msg a {width}×{height} screenshot's byte count overflows il numero di byte di uno screenshot {width}×{height} va in overflow
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot la {what} della finestra ({points} punti × {scale} DPI) non può dimensionare uno screenshot
|
||||
Live preview Anteprima dal vivo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5239,3 +5239,4 @@ axis Y Axis Y 軸
|
||||
Scale Presets 拡大縮小のプリセット
|
||||
@msg a {width}×{height} screenshot's byte count overflows {width}×{height} のスクリーンショットのバイト数がオーバーフローします
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot ウィンドウの {what}({points} ポイント × {scale} DPI)ではスクリーンショットのサイズを決められません
|
||||
Live preview ライブプレビュー
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5477,3 +5477,4 @@ axis Y Axis Y ღერძი
|
||||
Scale Presets მასშტაბის წინასწარ დაყენებული მნიშვნელობები
|
||||
@msg a {width}×{height} screenshot's byte count overflows {width}×{height} ეკრანის სურათის ბაიტების რაოდენობა გადაივსო
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot ფანჯრის {what} ({points} პუნქტი × {scale} DPI) ეკრანის სურათის ზომას ვერ განსაზღვრავს
|
||||
Live preview ცოცხალი წინასწარი ნახვა
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5140,3 +5140,4 @@ axis Y Axis Y축
|
||||
Scale Presets 크기 조절 사전 설정
|
||||
@msg a {width}×{height} screenshot's byte count overflows {width}×{height} 스크린샷의 바이트 수가 넘칩니다
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot 창의 {what}({points}포인트 × {scale} DPI)로는 스크린샷 크기를 정할 수 없습니다
|
||||
Live preview 실시간 미리 보기
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5543,3 +5543,4 @@ axis Y Axis Y-as
|
||||
Polar Grid Tool Options Opties polair-rastergereedschap
|
||||
Fill Line Lijn vullen
|
||||
Scale Presets Schaalvoorinstellingen
|
||||
Live preview Live voorbeeld
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5413,3 +5413,4 @@ axis Y Axis Oś Y
|
||||
Scale Presets Ustawienia wstępne skali
|
||||
@msg a {width}×{height} screenshot's byte count overflows liczba bajtów zrzutu ekranu {width}×{height} przekracza limit
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot {what} okna ({points} punktów × {scale} DPI) nie pozwala ustalić rozmiaru zrzutu ekranu
|
||||
Live preview Podgląd na żywo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5478,3 +5478,4 @@ axis Y Axis Eixo Y
|
||||
Scale Presets Predefinições de escala
|
||||
@msg a {width}×{height} screenshot's byte count overflows a contagem de bytes de uma captura {width}×{height} transborda
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot o {what} da janela ({points} pontos × {scale} DPI) não pode dimensionar uma captura
|
||||
Live preview Visualização ao vivo
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -5173,3 +5173,4 @@ axis Y Axis Ось Y
|
||||
Scale Presets Наборы масштаба
|
||||
@msg a {width}×{height} screenshot's byte count overflows количество байтов снимка {width}×{height} переполняется
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot {what} окна ({points} пунктов × {scale} DPI) не позволяет задать размер снимка
|
||||
Live preview Просмотр в реальном времени
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5585,3 +5585,4 @@ axis Y Axis Y-axel
|
||||
Scale Presets Skalningsförval
|
||||
@msg a {width}×{height} screenshot's byte count overflows byteantalet för en skärmbild på {width}×{height} överstiger gränsen
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot fönstrets {what} ({points} punkter × {scale} DPI) kan inte bestämma en skärmbilds storlek
|
||||
Live preview Direkt förhandsgranskning
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -5518,3 +5518,4 @@ axis Y Axis Y ekseni
|
||||
Scale Presets Ölçek ön ayarları
|
||||
@msg a {width}×{height} screenshot's byte count overflows {width}×{height} ekran görüntüsünün bayt sayısı taşıyor
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot pencerenin {what} ({points} nokta × {scale} DPI) bir ekran görüntüsünü boyutlandıramaz
|
||||
Live preview Canlı önizleme
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -5157,3 +5157,4 @@ axis Y Axis Вісь Y
|
||||
Scale Presets Набори масштабу
|
||||
@msg a {width}×{height} screenshot's byte count overflows кількість байтів знімка {width}×{height} переповнюється
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot {what} вікна ({points} пунктів × {scale} DPI) не дозволяє задати розмір знімка
|
||||
Live preview Перегляд у реальному часі
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 749 and column 40.
|
@@ -5157,3 +5157,4 @@ axis Y Axis Trục Y
|
||||
Scale Presets Cài đặt sẵn tỉ lệ
|
||||
@msg a {width}×{height} screenshot's byte count overflows số byte của ảnh chụp {width}×{height} bị tràn
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot {what} của cửa sổ ({points} điểm × {scale} DPI) không thể định cỡ ảnh chụp
|
||||
Live preview Xem trước trực tiếp
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 4053 and column 10.
|
@@ -5400,3 +5400,4 @@ axis Y Axis Y 轴
|
||||
Scale Presets 缩放预设
|
||||
@msg a {width}×{height} screenshot's byte count overflows {width}×{height} 截图的字节数溢出
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot 窗口的{what}({points} 点 × {scale} DPI)无法确定截图大小
|
||||
Live preview 实时预览
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5196,3 +5196,4 @@ axis Y Axis Y 軸
|
||||
Scale Presets 縮放預設集
|
||||
@msg a {width}×{height} screenshot's byte count overflows {width}×{height} 螢幕擷取畫面的位元組數溢出
|
||||
@msg the window's {what} ({points} points × {scale} DPI) cannot size a screenshot 視窗的{what}({points} 點 × {scale} DPI)無法決定螢幕擷取畫面的大小
|
||||
Live preview 即時預覽
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -621,7 +621,7 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
|
||||
"tool.options",
|
||||
"Tool Options…",
|
||||
"",
|
||||
"{tool: id} what double-clicking a tool button opens: hand → fits the artboard in the window (view.fitArtboard), zoom → 100% (view.actualSize), rotate|scale|reflect|shear → that Object › Transform dialog (dialog `rotate`, `scale`, `reflect` or `shear`; error `nothing selected` without a selection), selection|directSelection|groupSelection → the Move dialog (dialog `move`; the same error), gradient|magicWand → the Gradient or Magic Wand panel (window.panel), artboard → Artboard Options of the active artboard (dialog `artboardOptions`, fields index, name, x, y, width, height, showCenterMark, showCrossHairs; OK runs artboard.setProps, and with other artboards selected with the Artboard tool a new width or height goes to each of them too, in its `artboards` list, each resized about the reference point the form used for that size, or about its top-left corner when the size was set in the fields directly), flare → Flare Tool Options (dialog `flareOptions`, fields diameter and pathLength (pt), opacity, brightness, growth, fuzziness, longest, rayFuzziness, largest (%), rays, rings, direction (°), raysOn, ringsOn; OK runs tool.setOption {tool: \"flare\", values}: the next flare dragged out uses them, and a Flare click's dialog, which also has x and y, draws one there with them), lineSegment|arc|rectangularGrid|polarGrid → that tool's Tool Options, its click dialog without x and y (dialog kind = the tool id, `__toolOptions: true`; lineSegment: length (pt), angle (°), fillLine; arc: lengthX, lengthY (pt), reference (0–8), arcType: open|closed, baseAlong: x|y, slope (−100…100), fillArc; rectangularGrid: width, height (pt, the Default Size), reference (0–8), rows, columns, rowSkew, columnSkew (%), frame, fill; polarGrid: the same with concentric, radial, concentricSkew, radialSkew and compound for rows, columns, the skews and frame; OK runs tool.setOption {tool, values} and draws nothing: the next drag uses them (Fill Line, the arc's type, base, slope and fill, the grids' dividers, skews and switches) and a click's dialog opens at them), columnGraph|stackedColumnGraph|barGraph|stackedBarGraph|lineGraph|areaGraph|scatterGraph|pieGraph|radarGraph → Graph Type for the selected graph (dialog `command` running graph.setType; an error without one), symbolSprayer|symbolShifter|symbolScruncher|symbolSizer|symbolSpinner|symbolStainer|symbolScreener|symbolStyler → Symbolism Tools Options (dialog `symbolismOptions`, fields tool, diameter (pt), intensity and density (1–10), shared by the eight tools; OK runs tool.setOption {tool, values}), blend → Blend Options, perspectiveGrid → Perspective Grid Options, eyedropper → Eyedropper Options (dialog `eyedropperOptions`, fields sampleSize, pickUp, apply; OK runs eyedropper.setOptions), printTiling → resets the print tiling (print.tiling.set {reset: true}), warp|twirl|pucker|bloat|scallop|crystallize|wrinkle → that tool's Tool Options (dialog `liquifyOptions`, fields tool, width, height, angle, intensity %, usePressure, detail, simplify, simplifyOn, rate, complexity, horizontal %, vertical %, affectAnchors, affectIn, affectOut, showBrush; OK runs tool.setOption {tool, values}), pencil|paintbrush|smooth|blobBrush|eraser → that tool's Tool Options (dialog `freehandOptions`, fields tool and the options the tool keeps: fidelity (pt), fill, keepSelected (on for pencil and paintbrush, off for blobBrush), mergeOnlySelection (off), closeWithin and editWithin (px, 0 is off), size (pt), angle (°, −180–180; 0) and roundness (%, 1–100; 100) of the eraser's tip; OK runs tool.setOption {tool, values}), livePaintSelection → Live Paint Selection Tool Options (dialog `livePaintSelectionOptions`, fields selectFills and selectStrokes (both on), color (the highlight color, #rrggbb or a layer color's name; #ff2a2a), width (the highlight's width, 1–20 px; 4); OK runs tool.setOption {tool: \"livePaintSelection\", values}), shapeBuilder → Shape Builder Tool Options (dialog `shapeBuilderOptions`, fields gapDetection (off), gapLength (pt, 0–72; 3), openFilledAsClosed (on), clickStrokeSplitsPath (off), pickColorFrom: artwork|swatches (artwork), cursorSwatchPreview (off), selection: freeform|straightLine (freeform), highlightFill (on), highlightStroke (on), highlightColor (#rrggbb or a layer color's name; #ff4f4f); OK runs tool.setOption {tool: \"shapeBuilder\", values})",
|
||||
"{tool: id} what double-clicking a tool button opens: hand → fits the artboard in the window (view.fitArtboard), zoom → 100% (view.actualSize), rotate|scale|reflect|shear → that Object › Transform dialog (dialog `rotate`, `scale`, `reflect` or `shear`; error `nothing selected` without a selection), selection|directSelection|groupSelection → the Move dialog (dialog `move`; the same error), gradient|magicWand → the Gradient or Magic Wand panel (window.panel), artboard → Artboard Options of the active artboard (dialog `artboardOptions`, fields index, name, x, y, width, height, showCenterMark, showCrossHairs; OK runs artboard.setProps, and with other artboards selected with the Artboard tool a new width or height goes to each of them too, in its `artboards` list, each resized about the reference point the form used for that size, or about its top-left corner when the size was set in the fields directly), flare → Flare Tool Options (dialog `flareOptions`, fields diameter and pathLength (pt), opacity, brightness, growth, fuzziness, longest, rayFuzziness, largest (%), rays, rings, direction (°), raysOn, ringsOn; OK runs tool.setOption {tool: \"flare\", values}: the next flare dragged out uses them, and a Flare click's dialog, which also has x and y, draws one there with them), lineSegment|arc|rectangularGrid|polarGrid → that tool's Tool Options, its click dialog without x and y (dialog kind = the tool id, `__toolOptions: true`; lineSegment: length (pt), angle (°), fillLine; arc: lengthX, lengthY (pt), reference (0–8), arcType: open|closed, baseAlong: x|y, slope (−100…100), fillArc; rectangularGrid: width, height (pt, the Default Size), reference (0–8), rows, columns, rowSkew, columnSkew (%), frame, fill; polarGrid: the same with concentric, radial, concentricSkew, radialSkew and compound for rows, columns, the skews and frame; OK runs tool.setOption {tool, values} and draws nothing: the next drag uses them (Fill Line, the arc's type, base, slope and fill, the grids' dividers, skews and switches) and a click's dialog opens at them), columnGraph|stackedColumnGraph|barGraph|stackedBarGraph|lineGraph|areaGraph|scatterGraph|pieGraph|radarGraph → Graph Type for the selected graph (dialog `command` running graph.setType; an error without one), symbolSprayer|symbolShifter|symbolScruncher|symbolSizer|symbolSpinner|symbolStainer|symbolScreener|symbolStyler → Symbolism Tools Options (dialog `symbolismOptions`, fields tool, diameter (pt), intensity and density (1–10), shared by the eight tools; OK runs tool.setOption {tool, values}), blend → Blend Options, perspectiveGrid → Perspective Grid Options, eyedropper → Eyedropper Options (dialog `eyedropperOptions`, fields sampleSize, pickUp, apply; OK runs eyedropper.setOptions), printTiling → resets the print tiling (print.tiling.set {reset: true}), warp|twirl|pucker|bloat|scallop|crystallize|wrinkle → that tool's Tool Options (dialog `liquifyOptions`, fields tool, width, height, angle, intensity %, usePressure, detail, simplify, simplifyOn, rate, complexity, horizontal %, vertical %, affectAnchors, affectIn, affectOut, showBrush; OK runs tool.setOption {tool, values}), pencil|paintbrush|smooth|blobBrush|eraser → that tool's Tool Options (dialog `freehandOptions`, fields tool and the options the tool keeps: fidelity (pt), fill, keepSelected (on for pencil and paintbrush, off for blobBrush), mergeOnlySelection (off), closeWithin and editWithin (px, 0 is off), livePreview (pencil, on: off draws a thin line while the stroke is drawn, and the path's fill and stroke on release), size (pt), angle (°, −180–180; 0) and roundness (%, 1–100; 100) of the eraser's tip; OK runs tool.setOption {tool, values}), livePaintSelection → Live Paint Selection Tool Options (dialog `livePaintSelectionOptions`, fields selectFills and selectStrokes (both on), color (the highlight color, #rrggbb or a layer color's name; #ff2a2a), width (the highlight's width, 1–20 px; 4); OK runs tool.setOption {tool: \"livePaintSelection\", values}), shapeBuilder → Shape Builder Tool Options (dialog `shapeBuilderOptions`, fields gapDetection (off), gapLength (pt, 0–72; 3), openFilledAsClosed (on), clickStrokeSplitsPath (off), pickColorFrom: artwork|swatches (artwork), cursorSwatchPreview (off), selection: freeform|straightLine (freeform), highlightFill (on), highlightStroke (on), highlightColor (#rrggbb or a layer color's name; #ff4f4f); OK runs tool.setOption {tool: \"shapeBuilder\", values})",
|
||||
),
|
||||
(
|
||||
"ui.colorGuideOptions",
|
||||
|
||||
Reference in New Issue
Block a user