Merge pull request #4592 from storytold/feat/roughen-pucker-sliders

Effects: Roughen, Pucker & Bloat and Tweak show sliders (#4488)
This commit is contained in:
BFlat
2026-10-29 21:35:33 +07:00
committed by GitHub
27 changed files with 173 additions and 28 deletions
+84 -28
View File
@@ -166,7 +166,9 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
None if id == TEXTURIZER => glass_fields(app, ui, d, TEXTURIZER),
None if id == TRANSFORM => transform_fields(ui, d, app.session.general_unit()),
None if id == SCRIBBLE => scribble_fields(ui, d, app.session.general_unit()),
None if id == ZIG_ZAG => zig_zag_fields(ui, d, app.session.general_unit()),
None if id == ZIG_ZAG || id == ROUGHEN => size_fields(ui, d, &id, app.session.general_unit()),
None if id == PUCKER_BLOAT => pucker_bloat_fields(ui, d),
None if id == TWEAK => tweak_fields(ui, d, app.session.general_unit()),
None if id == DROP_SHADOW => drop_shadow_fields(ui, d, app.session.general_unit()),
None if id == "artistic.filmGrain" => film_grain_fields(ui, d),
None if id == free_distort::FREE_DISTORT => {
@@ -559,49 +561,77 @@ fn transform_fields(ui: &mut egui::Ui, d: &mut Dialog, unit: vectorcraft_doc::Un
/// The Zig Zag effect (Effect › Distort & Transform › Zig Zag…).
const ZIG_ZAG: &str = "distort.zigZag";
/// Zig Zag's dialog (#1133): Size and Ridges per segment as sliders with their fields, Relative or
/// Absolute and the Points as radio buttons. Returns whether the values differ from those last
/// previewed.
fn zig_zag_fields(ui: &mut egui::Ui, d: &mut Dialog, unit: vectorcraft_doc::Unit) -> bool {
const LABEL_W: f32 = 124.0;
const FIELD_W: f32 = 70.0;
/// The Roughen effect (Effect › Distort & Transform › Roughen…).
const ROUGHEN: &str = "distort.roughen";
/// The Pucker & Bloat effect (Effect › Distort & Transform › Pucker & Bloat…).
const PUCKER_BLOAT: &str = "distort.puckerBloat";
/// The second slider of [`size_fields`]: Zig Zag's Ridges per segment, Roughen's Detail (per inch),
/// as (key, label, default, suffix).
fn second_slider(effect: &str) -> (&'static str, &'static str, f64, &'static str) {
if effect == ROUGHEN { ("detail", "Detail:", 10.0, "/in") } else { ("ridges", "Ridges per segment:", 4.0, "") }
}
/// Zig Zag's and Roughen's dialog (#1133, #4488): Size and Ridges per segment (Roughen: Detail) as
/// sliders with their fields, Relative or Absolute and the Points as radio buttons. Returns
/// whether the values differ from those last previewed.
/// The label column and field width of [`relative_rows`] and the sliders under them.
const DISTORT_LABEL_W: f32 = 124.0;
const DISTORT_FIELD_W: f32 = 70.0;
/// A slider with its field for each of `rows` (key, label, default), each a share of the object's
/// size with Relative or a distance with Absolute, then the Relative and Absolute radio buttons.
fn relative_rows(ui: &mut egui::Ui, d: &mut Dialog, rows: &[(&str, &str, f64)], unit: vectorcraft_doc::Unit) {
let rail = Tokens::get(ui.ctx()).input_border;
let track = move |_| rail;
let relative = d.bool("relative");
widgets::subheader(ui, tl!("Options"));
// Size is a share of the object's size (Relative) or a distance (Absolute).
widgets::label_row(ui, tl!("Size:"), LABEL_W, |ui| {
let shown = if relative {
Some(widgets::SliderValue::field(d.f64("size", 10.0).clamp(0.0, 100.0), 0.0..=100.0, "%", 0))
} else {
form::length_value(d, "size", unit, 0.0..=100.0)
};
form::slider_rail_valued(ui, d, "size", tl!("Size:"), 0.0..=100.0, shown, &track);
if !relative {
form::length(ui, d, "size", unit, FIELD_W);
} else if let Some(n) = widgets::range_field(ui, ("zz", "size"), d.f64("size", 10.0), 0.0..=100.0, "%", 0, FIELD_W) {
d.fields.insert("size".into(), json!(n));
}
});
for &(key, label, default) in rows {
widgets::label_row(ui, tl!(label), DISTORT_LABEL_W, |ui| {
let shown = if relative {
Some(widgets::SliderValue::field(d.f64(key, default).clamp(0.0, 100.0), 0.0..=100.0, "%", 0))
} else {
form::length_value(d, key, unit, 0.0..=100.0)
};
form::slider_rail_valued(ui, d, key, tl!(label), 0.0..=100.0, shown, &track);
if !relative {
form::length(ui, d, key, unit, DISTORT_FIELD_W);
} else if let Some(n) = widgets::range_field(ui, ("zz", key), d.f64(key, default), 0.0..=100.0, "%", 0, DISTORT_FIELD_W) {
d.fields.insert(key.into(), json!(n));
}
});
}
ui.horizontal(|ui| {
ui.add_space(LABEL_W + ui.spacing().item_spacing.x);
ui.add_space(DISTORT_LABEL_W + ui.spacing().item_spacing.x);
for (label, on) in [(tl!("Relative"), true), (tl!("Absolute"), false)] {
if widgets::radio(ui, label, relative == on, true) {
d.fields.insert("relative".into(), json!(on));
}
}
});
widgets::label_row(ui, tl!("Ridges per segment:"), LABEL_W, |ui| {
form::slider_rail_named(ui, d, "ridges", tl!("Ridges per segment:"), 0.0..=100.0, &track);
if let Some(n) = widgets::range_field(ui, ("zz", "ridges"), d.f64("ridges", 4.0), 0.0..=100.0, "", 0, FIELD_W) {
d.fields.insert("ridges".into(), json!(n));
}
fn size_fields(ui: &mut egui::Ui, d: &mut Dialog, effect: &str, unit: vectorcraft_doc::Unit) -> bool {
const LABEL_W: f32 = DISTORT_LABEL_W;
const FIELD_W: f32 = DISTORT_FIELD_W;
let rail = Tokens::get(ui.ctx()).input_border;
let track = move |_| rail;
let size = if effect == ROUGHEN { 5.0 } else { 10.0 };
widgets::subheader(ui, tl!("Options"));
// Size is a share of the object's size (Relative) or a distance (Absolute).
relative_rows(ui, d, &[("size", "Size:", size)], unit);
let (key, label, default, suffix) = second_slider(effect);
widgets::label_row(ui, tl!(label), LABEL_W, |ui| {
form::slider_rail_named(ui, d, key, tl!(label), 0.0..=100.0, &track);
if let Some(n) = widgets::range_field(ui, ("zz", key), d.f64(key, default), 0.0..=100.0, suffix, 0, FIELD_W) {
d.fields.insert(key.into(), json!(n));
}
});
ui.add_space(4.0);
widgets::subheader(ui, crate::i18n::tr_ctx(crate::i18n::current(), "effect", "Points"));
let points = d.str("points");
ui.horizontal(|ui| {
for (label, value) in choices(ZIG_ZAG, "points").unwrap_or_default() {
for (label, value) in choices(effect, "points").unwrap_or_default() {
if widgets::radio(ui, crate::i18n::tr_ctx(crate::i18n::current(), "effect", label), points == *value, true) {
d.fields.insert("points".into(), json!(value));
}
@@ -610,6 +640,32 @@ fn zig_zag_fields(ui: &mut egui::Ui, d: &mut Dialog, unit: vectorcraft_doc::Unit
values_changed(d)
}
/// The Tweak effect (Effect › Distort & Transform › Tweak…).
const TWEAK: &str = "distort.tweak";
/// Tweak's dialog (#4488): Horizontal and Vertical as sliders with their fields (a share of the
/// object's size with Relative, a distance with Absolute), then which points it moves. Returns
/// whether the values differ from those last previewed.
fn tweak_fields(ui: &mut egui::Ui, d: &mut Dialog, unit: vectorcraft_doc::Unit) -> bool {
widgets::subheader(ui, tl!("Amount"));
relative_rows(ui, d, &[("h", "Horizontal:", 10.0), ("v", "Vertical:", 10.0)], unit);
ui.add_space(4.0);
widgets::subheader(ui, tl!("Modify"));
form::check(ui, d, "anchors", tl!("Anchor Points"));
form::check(ui, d, "in", tl!("\"In\" Control Points"));
form::check(ui, d, "out", tl!("\"Out\" Control Points"));
values_changed(d)
}
/// Pucker & Bloat's dialog (#4488): its amount as a slider from Pucker (−200 %) to Bloat (200 %)
/// with its field. Returns whether the value differs from the one last previewed.
fn pucker_bloat_fields(ui: &mut egui::Ui, d: &mut Dialog) -> bool {
let rail = Tokens::get(ui.ctx()).input_border;
form::slider(ui, d, "amount", tl!("Amount:"), -200.0..=200.0, "%", &move |_| rail);
form::slider_ends(ui, form::SLIDER_LABEL, (tl!("Pucker"), tl!("Bloat")));
values_changed(d)
}
/// Drop Shadow (Effect › Stylize › Drop Shadow…).
const DROP_SHADOW: &str = "stylize.dropShadow";
+39
View File
@@ -1413,6 +1413,45 @@ fn zig_zag_has_sliders_and_radio_buttons() {
assert!(!lines.contains(&"Ridges:"), "{lines:?}");
}
/// #4488: Roughen's dialog has Size and Detail sliders laid out as Zig Zag's, Pucker & Bloat's its
/// amount as a slider from Pucker to Bloat, and Tweak's Horizontal and Vertical sliders.
#[test]
fn roughen_pucker_bloat_and_tweak_have_sliders() {
use crate::widgets::accessibility_tests::{slider_value, tree};
let mut app = app();
app.run("shape.rectangle", json!({"x": 10, "y": 10, "width": 50, "height": 50})).unwrap();
app.run("effect.dialog", json!({"effect": "distort.roughen"})).unwrap();
let text = crate::tests_labels::painted_text(&mut app, |app, ui| show(app, ui.ctx()));
let lines: Vec<&str> = text.lines().map(str::trim).collect();
for want in ["Size:", "Relative", "Absolute", "Detail:", "Points", "Smooth", "Corner"] {
assert!(lines.contains(&want), "no {want:?} in {lines:?}");
}
let shown = tree(|ui| show(&mut app, ui.ctx()));
assert_eq!(slider_value(&shown, "Size:"), (Some(5.0), Some(0.0), Some(100.0), Some("5%".into())));
assert_eq!(slider_value(&shown, "Detail:"), (Some(10.0), Some(0.0), Some(100.0), None));
app.ui.dialog = None;
app.run("effect.dialog", json!({"effect": "distort.puckerBloat"})).unwrap();
app.ui.dialog.as_mut().unwrap().fields.insert("amount".into(), json!(-60));
let text = crate::tests_labels::painted_text(&mut app, |app, ui| show(app, ui.ctx()));
let lines: Vec<&str> = text.lines().map(str::trim).collect();
for want in ["Amount:", "Pucker", "Bloat"] {
assert!(lines.contains(&want), "no {want:?} in {lines:?}");
}
let shown = tree(|ui| show(&mut app, ui.ctx()));
let (value, min, max, _) = slider_value(&shown, "Amount:");
assert_eq!((value, min, max), (Some(-60.0), Some(-200.0), Some(200.0)));
// Tweak: Horizontal and Vertical sliders, Relative / Absolute, and the points it moves.
app.ui.dialog = None;
app.run("effect.dialog", json!({"effect": "distort.tweak"})).unwrap();
let text = crate::tests_labels::painted_text(&mut app, |app, ui| show(app, ui.ctx()));
let lines: Vec<&str> = text.lines().map(str::trim).collect();
for want in ["Horizontal:", "Vertical:", "Relative", "Absolute", "Anchor Points", "\"In\" Control Points", "\"Out\" Control Points"] {
assert!(lines.contains(&want), "no {want:?} in {lines:?}");
}
let shown = tree(|ui| show(&mut app, ui.ctx()));
assert_eq!(slider_value(&shown, "Horizontal:"), (Some(10.0), Some(0.0), Some(100.0), Some("10%".into())));
}
/// Screen readers get the number and text of the field beside each dialog slider, in the field's
/// unit, with the rail's range (extended to a number past the rail's end): Transform Each's Scale
/// and Move, Zig Zag's Size and Ridges, a form slider (Vector Halftone's Frequency), the Pencil's
+2
View File
@@ -167,6 +167,8 @@
Anchor Point Опорна точка
Anchor Point Tool Инструмент „Опорна точка“
Anchor Points Опорни точки
"In" Control Points „Входящи“ контролни точки
"Out" Control Points „Изходящи“ контролни точки
Anchor Points, Handle, and Bounding Box Display Показване на опорни точки, манипулатори и ограничителна рамка
Anchor/Path Labels Етикети на опорни точки/пътища
Anchors: Опорни точки:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -277,6 +277,8 @@
Anchor Point Punt d’ancoratge
Anchor Point Tool Eina de punt d’ancoratge
Anchor Points Punts d’ancoratge
"In" Control Points Punts de control «d’entrada»
"Out" Control Points Punts de control «de sortida»
Anchor Points, Handle, and Bounding Box Display Visualització de punts d’ancoratge, nanses i quadre delimitador
Anchor/Path Labels Etiquetes d’ancoratge/traçat
Anchors Ancoratges
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -2369,6 +2369,8 @@ lighting Light Světlo
Locate Selected Objects Najít vybrané objekty
Thumbnails: Miniatury:
Anchor Points Kotevní body
"In" Control Points „Vstupní“ řídicí body
"Out" Control Points „Výstupní“ řídicí body
Brush Affects: Štětec ovlivňuje:
Complexity: Složitost:
Detail: Podrobnost:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -2163,6 +2163,8 @@ lighting Light Lys
Locate Selected Objects Lokalisér markerede objekter
Thumbnails: Miniaturer:
Anchor Points Ankerpunkter
"In" Control Points "Ind"-kontrolpunkter
"Out" Control Points "Ud"-kontrolpunkter
Brush Affects: Penslen påvirker:
Complexity: Kompleksitet:
Detail: Detaljer:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -156,6 +156,8 @@
Anchor Point Ankerpunkt
Anchor Point Tool Ankerpunkt-Werkzeug
Anchor Points Ankerpunkte
"In" Control Points „Eingehende“ Kontrollpunkte
"Out" Control Points „Ausgehende“ Kontrollpunkte
Anchor Points, Handle, and Bounding Box Display Anzeige von Ankerpunkten, Griffen und Begrenzungsrahmen
Anchor/Path Labels Anker-/Pfadbeschriftungen
Anchors: Ankerpunkte:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -161,6 +161,8 @@
Anchor Point Σημείο αγκύρωσης
Anchor Point Tool Σημείο αγκύρωσης (Anchor Point Tool)
Anchor Points Σημεία αγκύρωσης
"In" Control Points Σημεία ελέγχου «εισόδου»
"Out" Control Points Σημεία ελέγχου «εξόδου»
Anchor Points, Handle, and Bounding Box Display Εμφάνιση σημείων αγκύρωσης, λαβών και πλαισίου οριοθέτησης
Anchor/Path Labels Ετικέτες σημείων αγκύρωσης και διαδρομών
Anchors: Σημεία αγκύρωσης:
Can't render this file because it contains an unexpected character in line 164 and column 5.
+2
View File
@@ -181,6 +181,8 @@
Anchor Point Punto de ancla
Anchor Point Tool Herramienta Punto de ancla
Anchor Points Puntos de ancla
"In" Control Points Puntos de control «de entrada»
"Out" Control Points Puntos de control «de salida»
Anchor Points, Handle, and Bounding Box Display Visualización de puntos de ancla, manejadores y cuadro delimitador
Anchor/Path Labels Etiquetas de ancla/trazado
Anchors: Anclas:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -2314,6 +2314,8 @@ lighting Light Valo
Locate Selected Objects Paikanna valitut objektit
Thumbnails: Pikkukuvat:
Anchor Points Ankkuripisteet
"In" Control Points ”Sisään”-ohjauspisteet
"Out" Control Points ”Ulos”-ohjauspisteet
Brush Affects: Sivellin vaikuttaa:
Complexity: Monimutkaisuus:
Detail: Yksityiskohdat:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -182,6 +182,8 @@
Anchor Point Point d’ancrage
Anchor Point Tool Outil Point d’ancrage
Anchor Points Points d’ancrage
"In" Control Points Points de contrôle « entrants »
"Out" Control Points Points de contrôle « sortants »
Anchor Points, Handle, and Bounding Box Display Affichage des points d’ancrage, des poignées et du cadre de sélection
Anchor/Path Labels Libellés de point d’ancrage/tracé
Anchors: Points d’ancrage :
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -260,6 +260,8 @@
Anchor Point Horgonypont
Anchor Point Tool Horgonypont
Anchor Points Horgonypontok
"In" Control Points „Bemenő” vezérlőpontok
"Out" Control Points „Kimenő” vezérlőpontok
Anchor Points, Handle, and Bounding Box Display Horgonypontok, fogantyúk és befoglaló keret megjelenítése
Anchor/Path Labels Horgonypont- és útvonalcímkék
Anchors Horgonypontok
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -2163,6 +2163,8 @@ lighting Light Cahaya
Locate Selected Objects Temukan objek terpilih
Thumbnails: Miniatur:
Anchor Points Titik jangkar
"In" Control Points Titik kontrol "masuk"
"Out" Control Points Titik kontrol "keluar"
Brush Affects: Kuas memengaruhi:
Complexity: Kompleksitas:
Detail: Detail:
Can't render this file because it contains an unexpected character in line 2166 and column 5.
+2
View File
@@ -181,6 +181,8 @@
Anchor Point Punto di ancoraggio
Anchor Point Tool Strumento Punto di ancoraggio
Anchor Points Punti di ancoraggio
"In" Control Points Punti di controllo "in entrata"
"Out" Control Points Punti di controllo "in uscita"
Anchor Points, Handle, and Bounding Box Display Visualizzazione di punti di ancoraggio, maniglie e riquadro di delimitazione
Anchor/Path Labels Etichette ancoraggio/tracciato
Anchors: Ancoraggi:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -920,6 +920,8 @@ font-technology Variable バリアブル
Anchor Point アンカーポイント
Anchor Point Tool アンカーポイントツール
Anchor Points アンカーポイント
"In" Control Points 「イン」コントロールポイント
"Out" Control Points 「アウト」コントロールポイント
Anchor Points, Handle, and Bounding Box Display アンカーポイント、ハンドル、バウンディングボックスの表示
Anchor/Path Labels アンカー/パスラベル
Angle 角度
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -2060,6 +2060,8 @@ lighting Light სინათლე
Locate Selected Objects მონიშნული ობიექტების მოძებნა
Thumbnails: ესკიზები:
Anchor Points საყრდენი წერტილები
"In" Control Points „შემავალი“ საკონტროლო წერტილები
"Out" Control Points „გამავალი“ საკონტროლო წერტილები
Brush Affects: ფუნჯი მოქმედებს:
Complexity: სირთულე:
Detail: დეტალიზაცია:
Can't render this file because it is too large.
+2
View File
@@ -915,6 +915,8 @@ font-technology Variable 가변
Anchor Point 앵커 포인트
Anchor Point Tool 앵커 포인트 도구
Anchor Points 앵커 포인트
"In" Control Points "들어오는" 제어점
"Out" Control Points "나가는" 제어점
Anchor Points, Handle, and Bounding Box Display 앵커 포인트, 핸들, 경계 상자 표시
Anchor/Path Labels 앵커/패스 레이블
Angle 각도
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -2177,6 +2177,8 @@ lighting Light Licht
Locate Selected Objects Geselecteerde objecten lokaliseren
Thumbnails: Miniaturen:
Anchor Points Ankerpunten
"In" Control Points "In"-controlepunten
"Out" Control Points "Uit"-controlepunten
Brush Affects: Penseel beïnvloedt:
Complexity: Complexiteit:
Detail: Detail:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -2285,6 +2285,8 @@ lighting Light Światło
Locate Selected Objects Znajdź zaznaczone obiekty
Thumbnails: Miniatury:
Anchor Points Punkty kontrolne
"In" Control Points Punkty sterujące „wejściowe”
"Out" Control Points Punkty sterujące „wyjściowe”
Brush Affects: Pędzel wpływa na:
Complexity: Złożoność:
Detail: Szczegółowość:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -181,6 +181,8 @@
Anchor Point Ponto de Ancoragem
Anchor Point Tool Ferramenta Ponto de Ancoragem
Anchor Points Pontos de Ancoragem
"In" Control Points Pontos de controle "de entrada"
"Out" Control Points Pontos de controle "de saída"
Anchor Points, Handle, and Bounding Box Display Exibição de Pontos de Ancoragem, Alça e Caixa Delimitadora
Anchor/Path Labels Rótulos de Ponto/Ancoragem
Angle Ângulo
Can't render this file because it contains an unexpected character in line 6 and column 47.
+2
View File
@@ -179,6 +179,8 @@
Anchor Point Опорная точка
Anchor Point Tool Инструмент «Опорная точка»
Anchor Points Опорные точки
"In" Control Points «Входящие» управляющие точки
"Out" Control Points «Исходящие» управляющие точки
Anchor Points, Handle, and Bounding Box Display Отображение опорных точек, маркеров и ограничительной рамки
Anchor/Path Labels Метки опорных точек/контуров
Anchors: Опорные точки:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -169,6 +169,8 @@
Anchor Point Ankarpunkt
Anchor Point Tool Ankarpunktsverktyg
Anchor Points Ankarpunkter
"In" Control Points "In"-kontrollpunkter
"Out" Control Points "Ut"-kontrollpunkter
Anchor Points, Handle, and Bounding Box Display Visning av ankarpunkter, handtag och avgränsningsram
Anchor/Path Labels Etiketter för ankare/banor
Anchors: Ankare:
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2
View File
@@ -166,6 +166,8 @@
Anchor Point Bağlantı Noktası
Anchor Point Tool Bağlantı Noktası Aracı
Anchor Points Bağlantı Noktaları
"In" Control Points "Giriş" Kontrol Noktaları
"Out" Control Points "Çıkış" Kontrol Noktaları
Anchor Points, Handle, and Bounding Box Display Bağlantı Noktaları, Tutamaç ve Sınırlandırma Kutusu Görünümü
Anchor/Path Labels Bağlantı/Yol Etiketleri
Anchors: Çapalar:
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2
View File
@@ -175,6 +175,8 @@
Anchor Point Опорна точка
Anchor Point Tool Інструмент «Опорна точка»
Anchor Points Опорні точки
"In" Control Points «Вхідні» контрольні точки
"Out" Control Points «Вихідні» контрольні точки
Anchor Points, Handle, and Bounding Box Display Відображення опорних точок, маркерів та обмежувальної рамки
Anchor/Path Labels Мітки опорних точок/контурів
Anchors: Опорні точки:
Can't render this file because it contains an unexpected character in line 178 and column 5.
+2
View File
@@ -197,6 +197,8 @@
Anchor Point Điểm neo
Anchor Point Tool Công cụ Điểm neo
Anchor Points Các điểm neo
"In" Control Points Điểm điều khiển "vào"
"Out" Control Points Điểm điều khiển "ra"
Anchor Points, Handle, and Bounding Box Display Hiển thị điểm neo, tay nắm và hộp giới hạn
Anchor/Path Labels Nhãn điểm neo/đường dẫn
Anchors: Điểm neo:
Can't render this file because it contains an unexpected character in line 200 and column 5.
+2
View File
@@ -130,6 +130,8 @@
Anchor Point 锚点
Anchor Point Tool 锚点工具
Anchor Points 锚点
"In" Control Points “入”控制点
"Out" Control Points “出”控制点
Anchor Points, Handle, and Bounding Box Display 锚点、手柄和定界框显示
Anchor/Path Labels 锚点/路径标签
Anchors: 锚点:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -139,6 +139,8 @@
Anchor Point 錨點
Anchor Point Tool 錨點工具
Anchor Points 錨點
"In" Control Points 「入」控制點
"Out" Control Points 「出」控制點
Anchor Points, Handle, and Bounding Box Display 錨點、控制把手與邊框顯示
Anchor/Path Labels 錨點/路徑標籤
Anchors: 錨點:
Can't render this file because it contains an unexpected character in line 6 and column 47.