mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #3507 from nrq6993-a11y/stream/vc-feat-g11-arc-tool-dialog
G11: Open Arc tool options on canvas click
This commit is contained in:
@@ -32,7 +32,15 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
),
|
||||
cmd!("shape.line", "Line Segment", [], None, "{x1, y1, x2, y2} → {id}", has_doc, line),
|
||||
cmd!("shape.spiral", "Spiral", [], None, "{cx, cy, radius, decay=80 (%), segments=10, clockwise?} → {id}", has_doc, spiral),
|
||||
cmd!("shape.arc", "Arc", [], None, "{x1, y1, x2, y2, closed?} → {id}", has_doc, arc),
|
||||
cmd!(
|
||||
"shape.arc",
|
||||
"Arc",
|
||||
[],
|
||||
None,
|
||||
"{x1, y1, x2, y2, closed?, slope?} or {x, y, lengthX, lengthY, reference?, baseAlong?: x|y, slope?, closed?, fillArc?} → {id}",
|
||||
has_doc,
|
||||
arc
|
||||
),
|
||||
cmd!(
|
||||
"shape.rectangularGrid",
|
||||
"Rectangular Grid",
|
||||
@@ -393,9 +401,34 @@ fn spiral(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
|
||||
fn arc(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let a = Point::new(f64_req(p, "x1", "shape.arc")?, f64_req(p, "y1", "shape.arc")?);
|
||||
let b = Point::new(f64_req(p, "x2", "shape.arc")?, f64_req(p, "y2", "shape.arc")?);
|
||||
add_art(s, "Arc", path_kind(shapes::arc(a, b, 0.0, switch_or(p, "closed", false, "shape.arc")?), None), None)
|
||||
let closed = switch_or(p, "closed", false, "shape.arc")?;
|
||||
let fill_arc = switch_or(p, "fillArc", false, "shape.arc")?;
|
||||
let base_x = !matches!(p.get("baseAlong").and_then(Value::as_str), Some("y" | "Y"));
|
||||
let path = if p.get("lengthX").is_some() || p.get("lengthY").is_some() {
|
||||
let anchor = Point::new(f64_req(p, "x", "shape.arc")?, f64_req(p, "y", "shape.arc")?);
|
||||
let reference = p.get("reference").and_then(Value::as_u64).unwrap_or(0) as usize;
|
||||
shapes::arc_segment(
|
||||
anchor,
|
||||
reference,
|
||||
number_or(p, "lengthX", 100.0, "shape.arc")?,
|
||||
number_or(p, "lengthY", 100.0, "shape.arc")?,
|
||||
base_x,
|
||||
number_or(p, "slope", 50.0, "shape.arc")?,
|
||||
closed,
|
||||
)
|
||||
} else {
|
||||
let a = Point::new(f64_req(p, "x1", "shape.arc")?, f64_req(p, "y1", "shape.arc")?);
|
||||
let b = Point::new(f64_req(p, "x2", "shape.arc")?, f64_req(p, "y2", "shape.arc")?);
|
||||
let slope = number_or(p, "slope", 100.0, "shape.arc")?;
|
||||
shapes::arc(a, b, slope, closed, base_x)
|
||||
};
|
||||
let fill = if fill_arc { s.paint.fill.clone() } else { vectorcraft_color::Paint::None };
|
||||
let look = s.new_art_look(
|
||||
fill,
|
||||
if s.paint.stroke.is_none() { vectorcraft_color::Paint::solid(vectorcraft_color::Color::BLACK) } else { s.paint.stroke.clone() },
|
||||
s.paint.stroke_width.max(0.1),
|
||||
);
|
||||
add_look(s, "Arc", path_kind(path, None), look, None)
|
||||
}
|
||||
|
||||
/// The grid `paths` (bottom first) as one selected group in the new-art stroke, filled with the
|
||||
|
||||
+28
-10
@@ -176,17 +176,33 @@ pub fn line(a: Point, b: Point) -> PathData {
|
||||
PathData::single(SubPath::polyline(&[a, b], false))
|
||||
}
|
||||
|
||||
/// Quarter-ellipse arc from `a` to `b` (Arc tool default: concave, open, x-axis base).
|
||||
pub fn arc(a: Point, b: Point, slope: f64, closed: bool) -> PathData {
|
||||
// Corner of the arc's bounding box is at (a.x, b.y): the arc bows away from it.
|
||||
let k = KAPPA * (1.0 + slope.clamp(-1.0, 1.0) * 0.0);
|
||||
let corner = Point::new(b.x, a.y);
|
||||
let h1 = a + (corner - a) * k;
|
||||
let h2 = b + (corner - b) * k;
|
||||
/// Bounding box of an arc segment when reference point `reference` (0…8) is placed on `anchor`.
|
||||
pub fn arc_bbox(anchor: Point, reference: usize, length_x: f64, length_y: f64) -> Rect {
|
||||
let w = length_x.abs().max(1e-9);
|
||||
let h = length_y.abs().max(1e-9);
|
||||
let rp = crate::reference_point(Rect::new(0.0, 0.0, w, h), reference.min(8));
|
||||
Rect::new(anchor.x - rp.x, anchor.y - rp.y, anchor.x - rp.x + w, anchor.y - rp.y + h)
|
||||
}
|
||||
|
||||
/// Arc segment from the Arc tool dialog: lengths, reference point, base axis, slope and open/closed.
|
||||
pub fn arc_segment(anchor: Point, reference: usize, length_x: f64, length_y: f64, base_along_x: bool, slope: f64, closed: bool) -> PathData {
|
||||
let r = arc_bbox(anchor, reference, length_x, length_y).abs();
|
||||
let (a, b) = if base_along_x { (Point::new(r.x0, r.y0), Point::new(r.x1, r.y1)) } else { (Point::new(r.x0, r.y1), Point::new(r.x1, r.y0)) };
|
||||
arc(a, b, slope, closed, base_along_x)
|
||||
}
|
||||
|
||||
/// Quarter-ellipse arc from `a` to `b` (Arc tool default: open, x-axis base when `base_along_x`).
|
||||
/// `slope` is −100…100 (concave…convex); 0 is a straight chord.
|
||||
pub fn arc(a: Point, b: Point, slope: f64, closed: bool, base_along_x: bool) -> PathData {
|
||||
let t = slope.clamp(-100.0, 100.0) / 100.0;
|
||||
let corner = if t >= 0.0 { Point::new(b.x, a.y) } else { Point::new(a.x, b.y) };
|
||||
let k = KAPPA * t.abs();
|
||||
let h1 = if k == 0.0 { a } else { a + (corner - a) * k };
|
||||
let h2 = if k == 0.0 { b } else { b + (corner - b) * k };
|
||||
let mut anchors =
|
||||
vec![Anchor { p: a, h_in: a, h_out: h1, kind: AnchorKind::Corner }, Anchor { p: b, h_in: h2, h_out: b, kind: AnchorKind::Corner }];
|
||||
if closed {
|
||||
let o = Point::new(a.x, b.y);
|
||||
let o = if base_along_x { Point::new(a.x, b.y) } else { Point::new(b.x, a.y) };
|
||||
anchors.push(Anchor::corner(o));
|
||||
}
|
||||
PathData::single(SubPath::new(anchors, closed))
|
||||
@@ -531,7 +547,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn arc_open_and_closed() {
|
||||
assert_eq!(arc(Point::ZERO, Point::new(10.0, 10.0), 0.0, false).anchor_count(), 2);
|
||||
assert!(arc(Point::ZERO, Point::new(10.0, 10.0), 0.0, true).subpaths[0].closed);
|
||||
assert_eq!(arc(Point::ZERO, Point::new(10.0, 10.0), 0.0, false, true).anchor_count(), 2);
|
||||
assert!(arc(Point::ZERO, Point::new(10.0, 10.0), 0.0, true, true).subpaths[0].closed);
|
||||
let seg = arc_segment(Point::ZERO, 0, 100.0, 50.0, true, 50.0, false);
|
||||
assert_eq!(seg.anchor_count(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_geom::Point;
|
||||
|
||||
use crate::guides::{DrawSnap, Leave, square};
|
||||
use crate::guides::{DrawSnap, Leave};
|
||||
use crate::shape::drag_rect;
|
||||
use crate::{Action, Cursor, Mods, Overlay, PointerEvent, PointerKind, Tool, ToolContext, ToolKey};
|
||||
|
||||
@@ -20,6 +20,12 @@ pub struct FamilyTool {
|
||||
mods: Mods,
|
||||
began: bool,
|
||||
pub closed: bool,
|
||||
length_x: f64,
|
||||
length_y: f64,
|
||||
reference: usize,
|
||||
base_along: &'static str,
|
||||
slope: f64,
|
||||
fill_arc: bool,
|
||||
pub decay: f64,
|
||||
pub segments: u32,
|
||||
pub clockwise: bool,
|
||||
@@ -53,6 +59,12 @@ impl FamilyTool {
|
||||
mods: Mods::default(),
|
||||
began: false,
|
||||
closed: false,
|
||||
length_x: 100.0,
|
||||
length_y: 100.0,
|
||||
reference: 0,
|
||||
base_along: "x",
|
||||
slope: 50.0,
|
||||
fill_arc: false,
|
||||
decay: 80.0,
|
||||
segments: 10,
|
||||
clockwise: true,
|
||||
@@ -101,9 +113,24 @@ impl FamilyTool {
|
||||
(format!("shape.{}", self.id), params)
|
||||
}
|
||||
_ => {
|
||||
let d = if m.shift { square(p - start) } else { p - start };
|
||||
let (a, b) = if m.alt { (start - d, start + d) } else { (start, start + d) };
|
||||
("shape.arc".into(), json!({"x1": a.x, "y1": a.y, "x2": b.x, "y2": b.y, "closed": self.closed}))
|
||||
let r = drag_rect(start, p, m).abs();
|
||||
let (w, h) = (r.width().max(1e-9), r.height().max(1e-9));
|
||||
let rp = vectorcraft_geom::reference_point(vectorcraft_geom::Rect::new(0.0, 0.0, w, h), self.reference.min(8));
|
||||
let anchor = Point::new(r.x0 + rp.x, r.y0 + rp.y);
|
||||
(
|
||||
"shape.arc".into(),
|
||||
json!({
|
||||
"x": anchor.x,
|
||||
"y": anchor.y,
|
||||
"lengthX": w,
|
||||
"lengthY": h,
|
||||
"reference": self.reference,
|
||||
"baseAlong": self.base_along,
|
||||
"slope": self.slope,
|
||||
"closed": self.closed,
|
||||
"fillArc": self.fill_arc,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,12 +246,30 @@ impl Tool for FamilyTool {
|
||||
"polarGrid" => json!({
|
||||
"concentric": self.rows, "radial": self.columns, "concentricSkew": self.skew[0], "radialSkew": self.skew[1], "compound": self.compound, "fill": self.fill,
|
||||
}),
|
||||
_ => json!({"closed": self.closed}),
|
||||
_ => json!({
|
||||
"closed": self.closed,
|
||||
"lengthX": self.length_x,
|
||||
"lengthY": self.length_y,
|
||||
"reference": self.reference,
|
||||
"baseAlong": self.base_along,
|
||||
"slope": self.slope,
|
||||
"fillArc": self.fill_arc,
|
||||
}),
|
||||
}
|
||||
}
|
||||
fn set_option(&mut self, key: &str, v: &Value) {
|
||||
match key {
|
||||
"closed" => self.closed = v.as_bool().unwrap_or(self.closed),
|
||||
"lengthX" => self.length_x = arc_length(v, self.length_x),
|
||||
"lengthY" => self.length_y = arc_length(v, self.length_y),
|
||||
"reference" => self.reference = v.as_u64().unwrap_or(self.reference as u64).min(8) as usize,
|
||||
"baseAlong" => {
|
||||
if let Some(s) = v.as_str() {
|
||||
self.base_along = if s.eq_ignore_ascii_case("y") { "y" } else { "x" };
|
||||
}
|
||||
}
|
||||
"slope" => self.slope = v.as_f64().filter(|n| n.is_finite()).map_or(self.slope, |n| n.clamp(-100.0, 100.0)),
|
||||
"fillArc" => self.fill_arc = v.as_bool().unwrap_or(self.fill_arc),
|
||||
"decay" => self.decay = v.as_f64().unwrap_or(self.decay).clamp(5.0, 150.0),
|
||||
"segments" => self.segments = v.as_u64().unwrap_or(10).clamp(2, 1000) as u32,
|
||||
"clockwise" => self.clockwise = v.as_bool().unwrap_or(self.clockwise),
|
||||
@@ -240,6 +285,11 @@ impl Tool for FamilyTool {
|
||||
}
|
||||
}
|
||||
|
||||
/// Arc segment length from a dialog or preference value.
|
||||
fn arc_length(v: &Value, current: f64) -> f64 {
|
||||
v.as_f64().filter(|n| n.is_finite()).map_or(current, |n| n.abs().max(1e-9))
|
||||
}
|
||||
|
||||
/// A grid divider skew from option value `v`: a finite number within the range, else `current`.
|
||||
fn grid_skew(v: &Value, current: f64) -> f64 {
|
||||
let max = vectorcraft_geom::shapes::GRID_SKEW_MAX;
|
||||
@@ -327,7 +377,52 @@ mod tests {
|
||||
let t = FamilyTool::new("arc");
|
||||
let (c, v) = t.command(Point::new(0.0, 0.0), Point::new(10.0, 4.0), Mods { shift: true, ..Default::default() });
|
||||
assert_eq!(c, "shape.arc");
|
||||
assert_eq!(v, json!({"x1": 0.0, "y1": 0.0, "x2": 10.0, "y2": 10.0, "closed": false}));
|
||||
assert_eq!(
|
||||
v,
|
||||
json!({
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"lengthX": 10.0,
|
||||
"lengthY": 10.0,
|
||||
"reference": 0,
|
||||
"baseAlong": "x",
|
||||
"slope": 50.0,
|
||||
"closed": false,
|
||||
"fillArc": false,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arc_drag_uses_stored_segment_options() {
|
||||
let mut t = FamilyTool::new("arc");
|
||||
for (key, value) in [
|
||||
("lengthX", json!(80.0)),
|
||||
("lengthY", json!(40.0)),
|
||||
("reference", json!(4)),
|
||||
("baseAlong", json!("y")),
|
||||
("slope", json!(-25.0)),
|
||||
("closed", json!(true)),
|
||||
("fillArc", json!(true)),
|
||||
] {
|
||||
t.set_option(key, &value);
|
||||
}
|
||||
let (command, params) = t.command(Point::new(10.0, 20.0), Point::new(50.0, 70.0), Mods::default());
|
||||
assert_eq!(command, "shape.arc");
|
||||
assert_eq!(
|
||||
params,
|
||||
json!({
|
||||
"x": 30.0,
|
||||
"y": 45.0,
|
||||
"lengthX": 40.0,
|
||||
"lengthY": 50.0,
|
||||
"reference": 4,
|
||||
"baseAlong": "y",
|
||||
"slope": -25.0,
|
||||
"closed": true,
|
||||
"fillArc": true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/// The start and the dragged corner snap to Smart Guides (#506), Shift sliding the corner of
|
||||
|
||||
@@ -26,7 +26,7 @@ const ROWS: &[Row] = &[
|
||||
(SYMBOLISM, Some("symbolism"), &["diameter", "intensity", "density"]),
|
||||
(&["mirrorCut"], None, &["axis", "keep"]),
|
||||
(&["puppetWarp"], None, &["showMesh", "expand"]),
|
||||
(&["arc"], None, &["closed"]),
|
||||
(&["arc"], None, &["closed", "lengthX", "lengthY", "reference", "baseAlong", "slope", "fillArc"]),
|
||||
(&["spiral"], None, &["decay", "segments", "clockwise"]),
|
||||
(&["rectangularGrid"], None, &["rows", "columns", "rowSkew", "columnSkew", "frame", "fill"]),
|
||||
(&["polarGrid"], None, &["concentric", "radial", "concentricSkew", "radialSkew", "compound", "fill"]),
|
||||
|
||||
@@ -64,6 +64,7 @@ fn lengths(kind: &str) -> &'static [&'static str] {
|
||||
"polygon" => &["radius"],
|
||||
"star" => &["radius1", "radius2"],
|
||||
"lineSegment" => &["length"],
|
||||
"arc" => &["lengthX", "lengthY"],
|
||||
"offsetPath" => &["offset"],
|
||||
_ => &[],
|
||||
}
|
||||
@@ -73,7 +74,7 @@ fn lengths(kind: &str) -> &'static [&'static str] {
|
||||
/// number: fields that ↑/↓ step by one (Shift: ten) and that do math, as the distances do.
|
||||
fn suffix(kind: &str, key: &str) -> Option<&'static str> {
|
||||
match (kind, key) {
|
||||
("rotate" | "shear" | "reflect" | "move", "angle") => Some("°"),
|
||||
("rotate" | "shear" | "reflect" | "move" | "lineSegment", "angle") => Some("°"),
|
||||
("scale", "sx" | "sy") => Some("%"),
|
||||
_ => None,
|
||||
}
|
||||
@@ -96,6 +97,7 @@ fn order(kind: &str) -> &'static [&'static str] {
|
||||
"rectangularGrid" => &["width", "height", "rows", "rowSkew", "columns", "columnSkew"],
|
||||
"polarGrid" => &["width", "height", "concentric", "concentricSkew", "radial", "radialSkew"],
|
||||
"artboardOptions" => &["name", "width", "height"],
|
||||
"lineSegment" => &["length", "angle"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ macro_rules! registry {
|
||||
registry! {
|
||||
DimensionOptions: [dimension::KIND] => dimension::SPEC,
|
||||
NewDocument: [new_document::KIND] => new_document::SPEC,
|
||||
Shape: ["rectangle", "roundedRectangle", "ellipse", "polygon", "star", "lineSegment", "rectangularGrid", "polarGrid"] => shapes::SPEC,
|
||||
Shape: ["rectangle", "roundedRectangle", "ellipse", "polygon", "star", "lineSegment", "arc", "rectangularGrid", "polarGrid"] => shapes::SPEC,
|
||||
Transform: ["move", "rotate", "scale", "reflect", "shear"] => transform::SPEC,
|
||||
PathOp: ["average", "offsetPath", "simplify", "splitIntoGrid"] => path_ops::SPEC,
|
||||
DocumentSetup: ["documentSetup"] => document_setup::SPEC,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//! Shape size dialogs (a click with a shape tool): Rectangle, Rounded Rectangle, Ellipse, Polygon,
|
||||
//! Star, Line Segment Tool Options and the two grids (size, divider counts and skews, switches).
|
||||
//! Star, Line Segment and Arc tool options, and the two grids (size, divider counts and skews, switches).
|
||||
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_doc::Unit;
|
||||
use vectorcraft_geom::{Point, Rect};
|
||||
|
||||
use super::{DialogSpec, form, run_and_close};
|
||||
@@ -21,6 +22,7 @@ fn title(kind: &str) -> &'static str {
|
||||
"star" => tl!("Star"),
|
||||
"rectangularGrid" => tl!("Rectangular Grid"),
|
||||
"polarGrid" => tl!("Polar Grid"),
|
||||
"arc" => tl!("Arc Segment Tool Options"),
|
||||
_ => tl!("Line Segment Tool Options"),
|
||||
}
|
||||
}
|
||||
@@ -48,6 +50,21 @@ fn set_grid_placed(d: &mut Dialog, r: Rect) {
|
||||
d.fields.insert("height".into(), json!(r.height()));
|
||||
}
|
||||
|
||||
/// Arc segment dialog: keep reference `refi` on the canvas click (`__anchorX`/`__anchorY`).
|
||||
pub(crate) fn arc_pin_to_anchor(d: &mut Dialog) {
|
||||
let anchor = Point::new(d.f64("__anchorX", d.f64("x", 0.0)), d.f64("__anchorY", d.f64("y", 0.0)));
|
||||
let refi = d.fields.get("reference").and_then(|v| v.as_u64()).map(|n| (n as usize).min(8)).unwrap_or(0);
|
||||
let w = d.f64("lengthX", 100.0).abs().max(1e-9);
|
||||
let h = d.f64("lengthY", 100.0).abs().max(1e-9);
|
||||
let rp = vectorcraft_geom::reference_point(Rect::new(0.0, 0.0, w, h), refi);
|
||||
d.fields.insert("x".into(), json!(anchor.x - rp.x));
|
||||
d.fields.insert("y".into(), json!(anchor.y - rp.y));
|
||||
}
|
||||
|
||||
fn arc_reference(d: &Dialog) -> usize {
|
||||
d.fields.get("reference").and_then(|v| v.as_u64()).map(|n| (n as usize).min(8)).unwrap_or(0)
|
||||
}
|
||||
|
||||
/// Top-left `x`/`y` so reference point `refi` sits on the canvas click (`__anchorX`/`__anchorY`).
|
||||
pub(crate) fn grid_pin_to_anchor(d: &mut Dialog) {
|
||||
let anchor = Point::new(d.f64("__anchorX", d.f64("x", 0.0)), d.f64("__anchorY", d.f64("y", 0.0)));
|
||||
@@ -78,6 +95,8 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
set_grid_placed(d, artboard_rect(was, refi, None, None, Some(w), Some(h), false));
|
||||
}
|
||||
});
|
||||
} else if d.kind == "arc" {
|
||||
arc_form(ui, d, unit);
|
||||
} else {
|
||||
form::grid(ui, d, unit);
|
||||
}
|
||||
@@ -93,6 +112,50 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn arc_form(ui: &mut egui::Ui, d: &mut Dialog, unit: Unit) {
|
||||
ui.horizontal(|ui| {
|
||||
let refi = arc_reference(d);
|
||||
if let Some(i) = widgets::reference_point(ui, refi) {
|
||||
d.fields.insert("reference".into(), json!(i));
|
||||
arc_pin_to_anchor(d);
|
||||
}
|
||||
});
|
||||
ui.add_space(4.0);
|
||||
let rail = crate::theme::Tokens::get(ui.ctx()).input_border;
|
||||
egui::Grid::new("arc-dlg").num_columns(2).spacing([10.0, 8.0]).show(ui, |ui| {
|
||||
let lx0 = d.f64("lengthX", 100.0);
|
||||
form::length_field(ui, d, "lengthX", tl!("Length X-Axis:"), unit);
|
||||
if d.f64("lengthX", 100.0) != lx0 {
|
||||
arc_pin_to_anchor(d);
|
||||
}
|
||||
let ly0 = d.f64("lengthY", 100.0);
|
||||
form::length_field(ui, d, "lengthY", tl!("Length Y-Axis:"), unit);
|
||||
if d.f64("lengthY", 100.0) != ly0 {
|
||||
arc_pin_to_anchor(d);
|
||||
}
|
||||
form::choice(ui, d, "arcType", tl!("Type:"), (form::FIELD_W, form::FIELD_W - 12.0), &[("open", tl!("Open")), ("closed", tl!("Closed"))]);
|
||||
form::choice(
|
||||
ui,
|
||||
d,
|
||||
"baseAlong",
|
||||
tl!("Base Along:"),
|
||||
(form::FIELD_W, form::FIELD_W - 12.0),
|
||||
&[
|
||||
("x", crate::i18n::tr_ctx(crate::i18n::current(), "axis", "X Axis")),
|
||||
("y", crate::i18n::tr_ctx(crate::i18n::current(), "axis", "Y Axis")),
|
||||
],
|
||||
);
|
||||
form::row_label(ui, tl!("Slope:"));
|
||||
ui.vertical(|ui| {
|
||||
form::slider_field_named(ui, d, "slope", tl!("Slope:"), -100.0..=100.0, "", &|_| rail);
|
||||
form::slider_ends(ui, form::SLIDER_LABEL, (tl!("Concave"), tl!("Convex")));
|
||||
});
|
||||
ui.end_row();
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
form::check(ui, d, "fillArc", tl!("Fill Arc"));
|
||||
}
|
||||
|
||||
/// The top-left corner of a rectangle or ellipse: the click itself, or with Alt held (draw from centre) the click minus half the size.
|
||||
fn box_origin(d: &Dialog) -> (f64, f64) {
|
||||
let (x, y) = (d.f64("x", 0.0), d.f64("y", 0.0));
|
||||
@@ -109,11 +172,25 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
"star" => Some(("points", 5.0, 2.0)),
|
||||
_ => None,
|
||||
};
|
||||
let options = count.map(|(key, default, min)| {
|
||||
let mut values = json!({});
|
||||
values[key] = json!(d.f64(key, default).clamp(min, 1000.0) as u64);
|
||||
values
|
||||
});
|
||||
let options = count
|
||||
.map(|(key, default, min)| {
|
||||
let mut values = json!({});
|
||||
values[key] = json!(d.f64(key, default).clamp(min, 1000.0) as u64);
|
||||
values
|
||||
})
|
||||
.or_else(|| {
|
||||
(d.kind == "arc").then(|| {
|
||||
json!({
|
||||
"closed": d.str("arcType").eq_ignore_ascii_case("closed"),
|
||||
"lengthX": d.f64("lengthX", 100.0),
|
||||
"lengthY": d.f64("lengthY", 100.0),
|
||||
"reference": arc_reference(d),
|
||||
"baseAlong": d.str("baseAlong"),
|
||||
"slope": d.f64("slope", 50.0),
|
||||
"fillArc": d.bool("fillArc"),
|
||||
})
|
||||
})
|
||||
});
|
||||
let (x, y) = (d.f64("x", 0.0), d.f64("y", 0.0));
|
||||
let (bx, by) = box_origin(d);
|
||||
let (id, params) = match d.kind.as_str() {
|
||||
@@ -140,6 +217,23 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
let (l, a) = (d.f64("length", 100.0), d.f64("angle", 0.0).to_radians());
|
||||
("shape.line", json!({"x1": x, "y1": y, "x2": x + l * a.cos(), "y2": y - l * a.sin()}))
|
||||
}
|
||||
"arc" => {
|
||||
let anchor = Point::new(d.f64("__anchorX", x), d.f64("__anchorY", y));
|
||||
(
|
||||
"shape.arc",
|
||||
json!({
|
||||
"x": anchor.x,
|
||||
"y": anchor.y,
|
||||
"lengthX": d.f64("lengthX", 100.0),
|
||||
"lengthY": d.f64("lengthY", 100.0),
|
||||
"reference": arc_reference(d),
|
||||
"baseAlong": d.str("baseAlong"),
|
||||
"slope": d.f64("slope", 50.0),
|
||||
"closed": d.str("arcType").eq_ignore_ascii_case("closed"),
|
||||
"fillArc": d.bool("fillArc"),
|
||||
}),
|
||||
)
|
||||
}
|
||||
_ => (
|
||||
"shape.rectangle",
|
||||
json!({"x": bx, "y": by, "width": d.f64("width", 100.0), "height": d.f64("height", 100.0), "radius": d.f64("radius", 0.0)}),
|
||||
|
||||
@@ -41,6 +41,7 @@ fn kinds_map_to_their_dialogs() {
|
||||
("newDocument", DialogKind::NewDocument),
|
||||
("roundedRectangle", DialogKind::Shape),
|
||||
("lineSegment", DialogKind::Shape),
|
||||
("arc", DialogKind::Shape),
|
||||
("rectangularGrid", DialogKind::Shape),
|
||||
("polarGrid", DialogKind::Shape),
|
||||
("shear", DialogKind::Transform),
|
||||
@@ -88,6 +89,7 @@ fn every_dialog_draws() {
|
||||
"polygon",
|
||||
"star",
|
||||
"lineSegment",
|
||||
"arc",
|
||||
"rectangularGrid",
|
||||
"polarGrid",
|
||||
"rotate",
|
||||
@@ -1711,6 +1713,25 @@ fn polar_grid_shared_canvas_click_defaults_units_counts_and_history() {
|
||||
assert_eq!(app.session.doc().unwrap().doc, made);
|
||||
}
|
||||
|
||||
/// Part of gap G11: an Arc tool click opens its options at the pointer; OK draws an arc there.
|
||||
#[test]
|
||||
fn arc_click_opens_options_and_ok_draws() {
|
||||
use vectorcraft_doc::NodeKind;
|
||||
let mut app = app();
|
||||
open_tool_dialog(&mut app, "arc", json!({"x": 100.0, "y": 50.0}));
|
||||
let d = app.ui.dialog.as_ref().unwrap();
|
||||
assert_eq!(d.kind, "arc");
|
||||
assert!(d.fields.contains_key("lengthX") && d.fields.contains_key("lengthY"));
|
||||
super::confirm(&mut app).unwrap();
|
||||
let n = app.session.doc().unwrap().doc.layers[0].children().unwrap().last().unwrap();
|
||||
assert!(matches!(n.kind, NodeKind::Path { .. }));
|
||||
let pd = n.path_data().unwrap();
|
||||
let a0 = pd.subpaths[0].anchors[0].p;
|
||||
let a1 = pd.subpaths[0].anchors[1].p;
|
||||
assert!((a0.x - 100.0).abs() < 1e-6 && (a0.y - 50.0).abs() < 1e-6);
|
||||
assert!((a1.x - 200.0).abs() < 1e-6 && (a1.y - 150.0).abs() < 1e-6);
|
||||
}
|
||||
|
||||
/// #1377: Polar Grid's dialog has a skew slider under each divider count, Create Compound Path
|
||||
/// From Ellipses and Fill Grid, opened with the tool's stored values; OK draws with them and
|
||||
/// stores them.
|
||||
|
||||
@@ -20,6 +20,28 @@ pub fn open_tool_dialog(app: &mut VectorcraftApp, kind: &str, p: Value) {
|
||||
Dialog::new(kind, json!({"x": x, "y": y, "radius1": "50 pt", "radius2": "25 pt", "points": app.session.tool_options_of(kind)["points"]}))
|
||||
}
|
||||
"lineSegment" => Dialog::new(kind, json!({"x": x, "y": y, "length": "100 pt", "angle": 0})),
|
||||
"arc" => {
|
||||
let opts = app.session.tool_options_of(kind);
|
||||
let closed = opts.get("closed").and_then(Value::as_bool).unwrap_or(false);
|
||||
let mut d = Dialog::new(
|
||||
kind,
|
||||
json!({
|
||||
"__anchorX": x,
|
||||
"__anchorY": y,
|
||||
"x": x,
|
||||
"y": y,
|
||||
"lengthX": opts.get("lengthX").cloned().unwrap_or(json!("100 pt")),
|
||||
"lengthY": opts.get("lengthY").cloned().unwrap_or(json!("100 pt")),
|
||||
"reference": opts.get("reference").cloned().unwrap_or(json!(0)),
|
||||
"arcType": if closed { "closed" } else { "open" },
|
||||
"baseAlong": opts.get("baseAlong").cloned().unwrap_or(json!("x")),
|
||||
"slope": opts.get("slope").cloned().unwrap_or(json!(50)),
|
||||
"fillArc": opts.get("fillArc").and_then(Value::as_bool).unwrap_or(false),
|
||||
}),
|
||||
);
|
||||
super::shapes::arc_pin_to_anchor(&mut d);
|
||||
d
|
||||
}
|
||||
// The grids: the tool's stored options (divider counts and skews, switches) at the default size.
|
||||
"rectangularGrid" | "polarGrid" => {
|
||||
let mut obj = match app.session.tool_options_of(kind) {
|
||||
|
||||
@@ -5358,6 +5358,16 @@ theme Appearance Външен вид
|
||||
Fresco Фреска
|
||||
Effect Gallery… Галерия с ефекти…
|
||||
Effect Gallery Dialog Диалог „Галерия с ефекти“
|
||||
Arc Segment Tool Options Опции на инструмента „Дъгов сегмент“
|
||||
Base Along: Основа по:
|
||||
Closed Затворен
|
||||
Convex Изпъкнал
|
||||
Fill Arc Запълване на дъга
|
||||
Length X-Axis: Дължина по X:
|
||||
Length Y-Axis: Дължина по Y:
|
||||
Slope: Наклон:
|
||||
axis X Axis X ос
|
||||
axis Y Axis Y ос
|
||||
@msg Packaged {n} file(s) in {folder} Пакетирани са {n} файла в {folder}
|
||||
@msg Packaged {n} file(s) {note} Пакетирани са {n} файла {note}
|
||||
@msg Packaged {n} file(s) Пакетирани са {n} файла
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5402,6 +5402,16 @@ mark-style Japanese Japonské
|
||||
Fresco Freska
|
||||
Effect Gallery… Galerie efektů…
|
||||
Effect Gallery Dialog Dialog Galerie efektů
|
||||
Arc Segment Tool Options Možnosti nástroje Obloukový segment
|
||||
Base Along: Základna podél:
|
||||
Closed Uzavřený
|
||||
Convex Konvexní
|
||||
Fill Arc Výplň oblouku
|
||||
Length X-Axis: Délka na ose X:
|
||||
Length Y-Axis: Délka na ose Y:
|
||||
Slope: Sklon:
|
||||
axis X Axis osa X
|
||||
axis Y Axis osa Y
|
||||
@msg Packaged {n} file(s) in {folder} Zabaleno souborů: {n} do {folder}
|
||||
@msg Packaged {n} file(s) {note} Zabaleno souborů: {n} {note}
|
||||
@msg Packaged {n} file(s) Zabaleno souborů: {n}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5374,6 +5374,16 @@ swatch Bright Violet Kraftig violet
|
||||
Fresco Fresko
|
||||
Effect Gallery… Effektgalleri…
|
||||
Effect Gallery Dialog Dialogboksen Effektgalleri
|
||||
Arc Segment Tool Options Indstillinger for buesegmentværktøj
|
||||
Base Along: Base langs:
|
||||
Closed Lukket
|
||||
Convex Konvex
|
||||
Fill Arc Udfyld bue
|
||||
Length X-Axis: Længde X-akse:
|
||||
Length Y-Axis: Længde Y-akse:
|
||||
Slope: Hældning:
|
||||
axis X Axis X-akse
|
||||
axis Y Axis Y-akse
|
||||
@msg Packaged {n} file(s) in {folder} Pakkede {n} fil(er) i {folder}
|
||||
@msg Packaged {n} file(s) {note} Pakkede {n} fil(er) {note}
|
||||
@msg Packaged {n} file(s) Pakkede {n} fil(er)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4983,6 +4983,17 @@ effect Soft Weich
|
||||
Fresco Fresko
|
||||
Effect Gallery… Effekt-Galerie…
|
||||
Effect Gallery Dialog Dialogfeld „Effekt-Galerie“
|
||||
Arc Segment Tool Options Optionen für das Bogensegment-Werkzeug
|
||||
Base Along: Basis entlang:
|
||||
Closed Geschlossen
|
||||
Concave Konkav
|
||||
Convex Konvex
|
||||
Fill Arc Bogen füllen
|
||||
Length X-Axis: Länge X-Achse:
|
||||
Length Y-Axis: Länge Y-Achse:
|
||||
Slope: Steigung:
|
||||
axis X Axis X-Achse
|
||||
axis Y Axis Y-Achse
|
||||
@msg Packaged {n} file(s) in {folder} {n} Datei(en) in {folder} verpackt
|
||||
@msg Packaged {n} file(s) {note} {n} Datei(en) verpackt {note}
|
||||
@msg Packaged {n} file(s) {n} Datei(en) verpackt
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5354,6 +5354,16 @@ effect Points Σημεία
|
||||
Fresco Νωπογραφία
|
||||
Effect Gallery… Συλλογή εφέ…
|
||||
Effect Gallery Dialog Παράθυρο διαλόγου Συλλογή εφέ
|
||||
Arc Segment Tool Options Επιλογές εργαλείου τμήματος τόξου
|
||||
Base Along: Βάση κατά:
|
||||
Closed Κλειστό
|
||||
Convex Κυρτό
|
||||
Fill Arc Γέμισμα τόξου
|
||||
Length X-Axis: Μήκος άξονα X:
|
||||
Length Y-Axis: Μήκος άξονα Y:
|
||||
Slope: Κλίση:
|
||||
axis X Axis Άξονας X
|
||||
axis Y Axis Άξονας Y
|
||||
@msg Packaged {n} file(s) in {folder} Συσκευάστηκαν {n} αρχεία στον φάκελο {folder}
|
||||
@msg Packaged {n} file(s) {note} Συσκευάστηκαν {n} αρχεία {note}
|
||||
@msg Packaged {n} file(s) Συσκευάστηκαν {n} αρχεία
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2045 and column 19.
|
@@ -5344,6 +5344,16 @@ mark-style Japanese Japonesas
|
||||
Fresco Fresco
|
||||
Effect Gallery… Galería de efectos…
|
||||
Effect Gallery Dialog Cuadro de diálogo Galería de efectos
|
||||
Arc Segment Tool Options Opciones de la herramienta Segmento de arco
|
||||
Base Along: Base a lo largo de:
|
||||
Closed Cerrado
|
||||
Convex Convexo
|
||||
Fill Arc Rellenar arco
|
||||
Length X-Axis: Longitud eje X:
|
||||
Length Y-Axis: Longitud eje Y:
|
||||
Slope: Pendiente:
|
||||
axis X Axis Eje X
|
||||
axis Y Axis Eje Y
|
||||
@msg Packaged {n} file(s) in {folder} Se empaquetaron {n} archivo(s) en {folder}
|
||||
@msg Packaged {n} file(s) {note} Se empaquetaron {n} archivo(s) {note}
|
||||
@msg Packaged {n} file(s) Se empaquetaron {n} archivo(s)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5433,6 +5433,16 @@ swatch Bright Violet Kirkas violetti
|
||||
Fresco Fresko
|
||||
Effect Gallery… Tehostegalleria…
|
||||
Effect Gallery Dialog Tehostegalleria-valintaikkuna
|
||||
Arc Segment Tool Options Kaarisegmenttityökalun asetukset
|
||||
Base Along: Pohja pitkin:
|
||||
Closed Suljettu
|
||||
Convex Kupera
|
||||
Fill Arc Täytä kaari
|
||||
Length X-Axis: Pituus X-akseli:
|
||||
Length Y-Axis: Pituus Y-akseli:
|
||||
Slope: Kaltevuus:
|
||||
axis X Axis X-akseli
|
||||
axis Y Axis Y-akseli
|
||||
@msg Packaged {n} file(s) in {folder} Paketoitiin {n} tiedosto(a) kansioon {folder}
|
||||
@msg Packaged {n} file(s) {note} Paketoitiin {n} tiedosto(a) {note}
|
||||
@msg Packaged {n} file(s) Paketoitiin {n} tiedosto(a)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5401,6 +5401,16 @@ theme Appearance Apparence
|
||||
Fresco Fresque
|
||||
Effect Gallery… Galerie d'effets…
|
||||
Effect Gallery Dialog Boîte de dialogue Galerie d'effets
|
||||
Arc Segment Tool Options Options de l’outil Segment d’arc
|
||||
Base Along: Base le long de :
|
||||
Closed Fermé
|
||||
Convex Convexe
|
||||
Fill Arc Remplir l’arc
|
||||
Length X-Axis: Longueur axe X :
|
||||
Length Y-Axis: Longueur axe Y :
|
||||
Slope: Pente :
|
||||
axis X Axis Axe X
|
||||
axis Y Axis Axe Y
|
||||
@msg Packaged {n} file(s) in {folder} {n} fichier(s) assemblé(s) dans {folder}
|
||||
@msg Packaged {n} file(s) {note} {n} fichier(s) assemblé(s) {note}
|
||||
@msg Packaged {n} file(s) {n} fichier(s) assemblé(s)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5388,6 +5388,16 @@ imageTrace Outline Körvonal
|
||||
Fresco Freskó
|
||||
Effect Gallery… Effektusgaléria…
|
||||
Effect Gallery Dialog Effektusgaléria párbeszédpanel
|
||||
Arc Segment Tool Options Ívszakasz eszköz beállításai
|
||||
Base Along: Alap mentén:
|
||||
Closed Zárt
|
||||
Convex Domború
|
||||
Fill Arc Ív kitöltése
|
||||
Length X-Axis: Hossz X tengely:
|
||||
Length Y-Axis: Hossz Y tengely:
|
||||
Slope: Lejtés:
|
||||
axis X Axis X tengely
|
||||
axis Y Axis Y tengely
|
||||
@msg Packaged {n} file(s) in {folder} Becsomagolt fájlok: {n}, mappa: {folder}
|
||||
@msg Packaged {n} file(s) {note} Becsomagolt fájlok: {n} {note}
|
||||
@msg Packaged {n} file(s) Becsomagolt fájlok: {n}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5374,6 +5374,16 @@ swatch Bright Violet Violet cerah
|
||||
Fresco Fresko
|
||||
Effect Gallery… Galeri Efek…
|
||||
Effect Gallery Dialog Dialog Galeri Efek
|
||||
Arc Segment Tool Options Opsi alat segmen busur
|
||||
Base Along: Dasar sepanjang:
|
||||
Closed Tertutup
|
||||
Convex Cembung
|
||||
Fill Arc Isi busur
|
||||
Length X-Axis: Panjang sumbu X:
|
||||
Length Y-Axis: Panjang sumbu Y:
|
||||
Slope: Kemiringan:
|
||||
axis X Axis Sumbu X
|
||||
axis Y Axis Sumbu Y
|
||||
@msg Packaged {n} file(s) in {folder} Berhasil mengemas {n} file di {folder}
|
||||
@msg Packaged {n} file(s) {note} Berhasil mengemas {n} file {note}
|
||||
@msg Packaged {n} file(s) Berhasil mengemas {n} file
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3816 and column 19.
|
@@ -5017,6 +5017,17 @@ lighting Light Luce
|
||||
Fresco Affresco
|
||||
Effect Gallery… Galleria effetti…
|
||||
Effect Gallery Dialog Finestra di dialogo Galleria effetti
|
||||
Arc Segment Tool Options Opzioni strumento Segmento arco
|
||||
Base Along: Base lungo:
|
||||
Closed Chiuso
|
||||
Concave Concavo
|
||||
Convex Convesso
|
||||
Fill Arc Riempi arco
|
||||
Length X-Axis: Lunghezza asse X:
|
||||
Length Y-Axis: Lunghezza asse Y:
|
||||
Slope: Pendenza:
|
||||
axis X Axis Asse X
|
||||
axis Y Axis Asse Y
|
||||
@msg Packaged {n} file(s) in {folder} Pacchetto creato con {n} file in {folder}
|
||||
@msg Packaged {n} file(s) {note} Pacchetto creato con {n} file {note}
|
||||
@msg Packaged {n} file(s) Pacchetto creato con {n} file
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5079,6 +5079,17 @@ lighting Light ライト
|
||||
Simulate prints overprints as Overprint Preview shows them; separations always keep them. A preset flattens transparency before printing (PostScript files always flatten it). シミュレートでは、オーバープリントプレビューと同じ見え方でオーバープリントを印刷します。分版では常にオーバープリントが保持されます。プリセットを選ぶと、印刷前に透明が分割・統合されます (PostScript ファイルでは常に分割・統合されます)。
|
||||
Effect Gallery… 効果ギャラリー…
|
||||
Effect Gallery Dialog 効果ギャラリーダイアログ
|
||||
Arc Segment Tool Options 円弧セグメントツールオプション
|
||||
Base Along: 基準方向:
|
||||
Closed 閉じる
|
||||
Concave 凹
|
||||
Convex 凸
|
||||
Fill Arc 円弧を塗りつぶす
|
||||
Length X-Axis: X 軸の長さ:
|
||||
Length Y-Axis: Y 軸の長さ:
|
||||
Slope: 勾配:
|
||||
axis X Axis X 軸
|
||||
axis Y Axis Y 軸
|
||||
@msg Packaged {n} file(s) in {folder} {n} 個のファイルを {folder} にパッケージしました
|
||||
@msg Packaged {n} file(s) {note} {n} 個のファイルをパッケージしました {note}
|
||||
@msg Packaged {n} file(s) {n} 個のファイルをパッケージしました
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5311,6 +5311,16 @@ imageTrace Outline კონტური
|
||||
Select artwork to apply effects აირჩიეთ ნამუშევარი ეფექტების გამოსაყენებლად
|
||||
Effect Gallery… ეფექტების გალერეა…
|
||||
Effect Gallery Dialog ეფექტების გალერეა დიალოგი
|
||||
Arc Segment Tool Options რკალის სეგმენტის ხელსაწყოს პარამეტრები
|
||||
Base Along: საფუძველი გასწვრივ:
|
||||
Closed დახურული
|
||||
Convex ამობზარი
|
||||
Fill Arc რკალის შევსება
|
||||
Length X-Axis: სიგრძე X ღერძზე:
|
||||
Length Y-Axis: სიგრძე Y ღერძზე:
|
||||
Slope: დახრა:
|
||||
axis X Axis X ღერძი
|
||||
axis Y Axis Y ღერძი
|
||||
@msg Packaged {n} file(s) in {folder} შეფუთულია ფაილი ({n}) საქაღალდეში {folder}
|
||||
@msg Packaged {n} file(s) {note} შეფუთულია ფაილი ({n}) {note}
|
||||
@msg Packaged {n} file(s) შეფუთულია ფაილი ({n})
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4980,6 +4980,17 @@ lighting Light 광원
|
||||
Fresco 프레스코
|
||||
Effect Gallery… 효과 갤러리…
|
||||
Effect Gallery Dialog 효과 갤러리 대화 상자
|
||||
Arc Segment Tool Options 호 세그먼트 도구 옵션
|
||||
Base Along: 기준 방향:
|
||||
Closed 닫힘
|
||||
Concave 오목
|
||||
Convex 볼록
|
||||
Fill Arc 호 채우기
|
||||
Length X-Axis: X축 길이:
|
||||
Length Y-Axis: Y축 길이:
|
||||
Slope: 기울기:
|
||||
axis X Axis X축
|
||||
axis Y Axis Y축
|
||||
@msg Packaged {n} file(s) in {folder} {folder}에 파일 {n}개를 패키지했습니다
|
||||
@msg Packaged {n} file(s) {note} 파일 {n}개를 패키지했습니다 {note}
|
||||
@msg Packaged {n} file(s) 파일 {n}개를 패키지했습니다
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5417,6 +5417,16 @@ swatch Bright Violet Felviolet
|
||||
Fresco Fresco
|
||||
Effect Gallery… Effectgalerij…
|
||||
Effect Gallery Dialog Dialoogvenster Effectgalerij
|
||||
Arc Segment Tool Options Opties boogsegmentgereedschap
|
||||
Base Along: Basis langs:
|
||||
Closed Gesloten
|
||||
Convex Concaaf
|
||||
Fill Arc Boog vullen
|
||||
Length X-Axis: Lengte X-as:
|
||||
Length Y-Axis: Lengte Y-as:
|
||||
Slope: Helling:
|
||||
axis X Axis X-as
|
||||
axis Y Axis Y-as
|
||||
@msg Packaged {n} file(s) in {folder} {n} bestand(en) verpakt in {folder}
|
||||
@msg Packaged {n} file(s) {note} {n} bestand(en) verpakt {note}
|
||||
@msg Packaged {n} file(s) {n} bestand(en) verpakt
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5254,6 +5254,16 @@ mark-style Japanese Japońskie
|
||||
Fresco Fresk
|
||||
Effect Gallery… Galeria efektów…
|
||||
Effect Gallery Dialog Okno dialogowe Galeria efektów
|
||||
Arc Segment Tool Options Opcje narzędzia Segment łuku
|
||||
Base Along: Podstawa wzdłuż:
|
||||
Closed Zamknięty
|
||||
Convex Wypukła
|
||||
Fill Arc Wypełnij łuk
|
||||
Length X-Axis: Długość osi X:
|
||||
Length Y-Axis: Długość osi Y:
|
||||
Slope: Nachylenie:
|
||||
axis X Axis Oś X
|
||||
axis Y Axis Oś Y
|
||||
@msg Packaged {n} file(s) in {folder} Spakowane pliki: {n} w {folder}
|
||||
@msg Packaged {n} file(s) {note} Spakowane pliki: {n} {note}
|
||||
@msg Packaged {n} file(s) Spakowane pliki: {n}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5319,6 +5319,16 @@ mark-style Japanese Japonesas
|
||||
Fresco Afresco
|
||||
Effect Gallery… Galeria de Efeitos…
|
||||
Effect Gallery Dialog Caixa de diálogo Galeria de Efeitos
|
||||
Arc Segment Tool Options Opções da Ferramenta Segmento de Arco
|
||||
Base Along: Base ao longo de:
|
||||
Closed Fechado
|
||||
Convex Convexo
|
||||
Fill Arc Preencher arco
|
||||
Length X-Axis: Comprimento eixo X:
|
||||
Length Y-Axis: Comprimento eixo Y:
|
||||
Slope: Inclinação:
|
||||
axis X Axis Eixo X
|
||||
axis Y Axis Eixo Y
|
||||
@msg Packaged {n} file(s) in {folder} {n} arquivo(s) empacotado(s) em {folder}
|
||||
@msg Packaged {n} file(s) {note} {n} arquivo(s) empacotado(s) {note}
|
||||
@msg Packaged {n} file(s) {n} arquivo(s) empacotado(s)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -5013,6 +5013,17 @@ lighting Light Свет
|
||||
Fresco Фреска
|
||||
Effect Gallery… Галерея эффектов…
|
||||
Effect Gallery Dialog Диалог «Галерея эффектов»
|
||||
Arc Segment Tool Options Параметры инструмента «Дуговой сегмент»
|
||||
Base Along: Основание вдоль:
|
||||
Closed Замкнутый
|
||||
Concave Вогнутый
|
||||
Convex Выпуклый
|
||||
Fill Arc Заливка дуги
|
||||
Length X-Axis: Длина по оси X:
|
||||
Length Y-Axis: Длина по оси Y:
|
||||
Slope: Уклон:
|
||||
axis X Axis Ось X
|
||||
axis Y Axis Ось Y
|
||||
@msg Packaged {n} file(s) in {folder} Упаковано файлов: {n} в {folder}
|
||||
@msg Packaged {n} file(s) {note} Упаковано файлов: {n} {note}
|
||||
@msg Packaged {n} file(s) Упаковано файлов: {n}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5358,6 +5358,16 @@ theme Appearance Utseende
|
||||
Fresco Fresk
|
||||
Effect Gallery… Effektgalleri…
|
||||
Effect Gallery Dialog Dialogrutan Effektgalleri
|
||||
Arc Segment Tool Options Alternativ för bågsegmentsverktyget
|
||||
Base Along: Bas längs:
|
||||
Closed Stängd
|
||||
Convex Konvex
|
||||
Fill Arc Fyll båge
|
||||
Length X-Axis: Längd X-axel:
|
||||
Length Y-Axis: Längd Y-axel:
|
||||
Slope: Lutning:
|
||||
axis X Axis X-axel
|
||||
axis Y Axis Y-axel
|
||||
@msg Packaged {n} file(s) in {folder} Paketerade {n} fil(er) i {folder}
|
||||
@msg Packaged {n} file(s) {note} Paketerade {n} fil(er) {note}
|
||||
@msg Packaged {n} file(s) Paketerade {n} fil(er)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -5361,6 +5361,17 @@ theme Appearance Görünüm
|
||||
Fresco Fresk
|
||||
Effect Gallery… Efekt Galerisi…
|
||||
Effect Gallery Dialog Efekt Galerisi İletişim Kutusu
|
||||
Arc Segment Tool Options Yay Segmenti Aracı Seçenekleri
|
||||
Base Along: Taban boyunca:
|
||||
Closed Kapalı
|
||||
Convex dışbükey
|
||||
Fill Arc Yayı doldur
|
||||
Length X-Axis: X ekseni uzunluğu:
|
||||
Length Y-Axis: Y ekseni uzunluğu:
|
||||
Slope: Eğim:
|
||||
axis X Axis X ekseni
|
||||
axis Y Axis Y ekseni
|
||||
|
||||
@msg Packaged {n} file(s) in {folder} {folder} biçiminde paketlenmiş {n} dosyası/dosyaları
|
||||
@msg Packaged {n} file(s) {note} Paketlenmiş {n} dosyası/dosyaları {note}
|
||||
@msg Packaged {n} file(s) Paketlenmiş {n} dosyası/dosyaları
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4997,6 +4997,17 @@ lighting Light Світло
|
||||
Fresco Фреска
|
||||
Effect Gallery… Галерея ефектів…
|
||||
Effect Gallery Dialog Діалог «Галерея ефектів»
|
||||
Arc Segment Tool Options Параметри інструменту «Дуговий сегмент»
|
||||
Base Along: Основа вздовж:
|
||||
Closed Замкнений
|
||||
Concave Увігнутий
|
||||
Convex Опуклий
|
||||
Fill Arc Заливка дуги
|
||||
Length X-Axis: Довжина вздовж осі X:
|
||||
Length Y-Axis: Довжина вздовж осі Y:
|
||||
Slope: Ухил:
|
||||
axis X Axis Вісь X
|
||||
axis Y Axis Вісь Y
|
||||
@msg Packaged {n} file(s) in {folder} Упаковано файли: {n} {folder}
|
||||
@msg Packaged {n} file(s) {note} Упаковано файли: {n} {note}
|
||||
@msg Packaged {n} file(s) Упаковано файли: {n}
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 733 and column 40.
|
@@ -4997,6 +4997,17 @@ theme Appearance Giao diện
|
||||
Fresco Bích họa
|
||||
Effect Gallery… Thư viện hiệu ứng…
|
||||
Effect Gallery Dialog Hộp thoại Thư viện hiệu ứng
|
||||
Arc Segment Tool Options Tùy chọn công cụ cung phân đoạn
|
||||
Base Along: Cơ sở dọc theo:
|
||||
Closed Đóng
|
||||
Concave Lõm
|
||||
Convex Lồi
|
||||
Fill Arc Tô cung
|
||||
Length X-Axis: Chiều dài trục X:
|
||||
Length Y-Axis: Chiều dài trục Y:
|
||||
Slope: Độ dốc:
|
||||
axis X Axis Trục X
|
||||
axis Y Axis Trục Y
|
||||
@msg Packaged {n} file(s) in {folder} Đã đóng gói {n} tệp trong {folder}
|
||||
@msg Packaged {n} file(s) {note} Đã đóng gói {n} tệp {note}
|
||||
@msg Packaged {n} file(s) Đã đóng gói {n} tệp
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 4028 and column 10.
|
@@ -5241,6 +5241,17 @@ lighting Light 光源
|
||||
Fresco 壁画
|
||||
Effect Gallery… 效果库…
|
||||
Effect Gallery Dialog 效果库对话框
|
||||
Arc Segment Tool Options 弧段工具选项
|
||||
Base Along: 基线方向:
|
||||
Closed 闭合
|
||||
Concave 凹
|
||||
Convex 凸
|
||||
Fill Arc 填充弧
|
||||
Length X-Axis: X 轴长度:
|
||||
Length Y-Axis: Y 轴长度:
|
||||
Slope: 斜率:
|
||||
axis X Axis X 轴
|
||||
axis Y Axis Y 轴
|
||||
@msg Packaged {n} file(s) in {folder} 已将 {n} 个文件打包到 {folder}
|
||||
@msg Packaged {n} file(s) {note} 已打包 {n} 个文件 {note}
|
||||
@msg Packaged {n} file(s) 已打包 {n} 个文件
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5036,6 +5036,17 @@ lighting Light 光源
|
||||
Fresco 壁畫
|
||||
Effect Gallery… 效果庫…
|
||||
Effect Gallery Dialog 效果庫對話框
|
||||
Arc Segment Tool Options 弧段工具選項
|
||||
Base Along: 基線方向:
|
||||
Closed 封閉
|
||||
Concave 凹
|
||||
Convex 凸
|
||||
Fill Arc 填色弧形
|
||||
Length X-Axis: X 軸長度:
|
||||
Length Y-Axis: Y 軸長度:
|
||||
Slope: 斜率:
|
||||
axis X Axis X 軸
|
||||
axis Y Axis Y 軸
|
||||
@msg Packaged {n} file(s) in {folder} 已將 {n} 個檔案封裝到 {folder}
|
||||
@msg Packaged {n} file(s) {note} 已封裝 {n} 個檔案 {note}
|
||||
@msg Packaged {n} file(s) 已封裝 {n} 個檔案
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
Reference in New Issue
Block a user