mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-25 02:07:09 -06:00
Step 3 of the Rectangular Grid tool and Arc tool help pages (https://helpx.adobe.com/illustrator/using/tool-techniques/rectangular-grid-tool.html, https://helpx.adobe.com/illustrator/using/tool-techniques/arc-tool.html) and the Tools page (https://helpx.adobe.com/illustrator/using/tools.html) say a double-click on the tool opens its Tool Options. For these four tools the double-click (tool.options, and Enter once #2891 lands) said the tool had no options (#2691). The Tool Options are the tool's click dialog in dialogs/shapes.rs, opened without a place to draw (shapes::open_options; a `__toolOptions` field marks it), as the review of #2979 asked: no copied form code. Its OK runs tool.setOption and draws nothing; Cancel changes nothing. The grids' dialogs are titled Rectangular Grid / Polar Grid Tool Options there. The options are what the next drag draws with and what a click's dialog opens at: - Line Segment: Length and Angle (now kept by the tool and used by the click dialog) and Fill Line (new: shape.line {fill: true} gives the line the current fill; the click dialog has it too); - Arc: lengths, Reference Point, Type, Base Along, Slope, Fill Arc; - the grids: dividers, skews and switches, plus the Default Size and Reference Point, now kept by the tool (width, height, reference) for the click dialog; a drag leaves them out of its command. The grids' Reference Point is drawn only as the 9-point locator (it also showed as a plain number field). New strings (Rectangular Grid Tool Options, Polar Grid Tool Options, Fill Line) have rows in all 24 catalogs. Verification: toolbar::tests::double_clicking_the_line_arc_and_grid_tools_opens_their_tool_options double-clicks each tool's toolbar button: the dialog and its title, Cancel leaves the next drag as it was, OK draws nothing, the next drag uses the option and a click's dialog opens at it (a grid at its Default Size); line_segment_options_and_fill_line, grid_default_size_is_an_option_the_drag_leaves_out, fill_line_gives_a_new_line_the_current_fill. Grid dialog tests now expect the stored Default Size. Live: double-clicking the Rectangular Grid tool in the release build opens Rectangular Grid Tool Options; OK with 2 and 3 dividers, then a drag, draws a 3 × 4 grid.
124 lines
5.2 KiB
Rust
124 lines
5.2 KiB
Rust
//! Tool options that persist: a tool keeps them when another tool is chosen and they are saved
|
|
//! with the preferences, as the reference app keeps each tool's options. Options that are the
|
|
//! state of an interaction (pins, a reference point, the text being edited, the files a place
|
|
//! cursor holds) aren't listed: they start afresh.
|
|
//!
|
|
//! Each row names the tools it covers, the store their values live in and the option keys. A row
|
|
//! with a shared store gives every tool it lists one set of values: the Liquify tools share their
|
|
//! Global Brush Dimensions, the Symbolism tools their brush. Otherwise each tool has its own store,
|
|
//! named after its id.
|
|
|
|
/// (tools, the store they share (None: each tool's own), option keys).
|
|
type Row = (&'static [&'static str], Option<&'static str>, &'static [&'static str]);
|
|
|
|
/// The Liquify tools.
|
|
pub const LIQUIFY: &[&str] = &["warp", "twirl", "pucker", "bloat", "scallop", "crystallize", "wrinkle"];
|
|
|
|
/// The Symbolism tools.
|
|
pub const SYMBOLISM: &[&str] =
|
|
&["symbolSprayer", "symbolShifter", "symbolScruncher", "symbolSizer", "symbolSpinner", "symbolStainer", "symbolScreener", "symbolStyler"];
|
|
|
|
const ROWS: &[Row] = &[
|
|
(&["dimension"], None, &["mode", "style"]),
|
|
// Global Brush Dimensions.
|
|
(LIQUIFY, Some("liquify"), &["width", "height", "angle", "intensity", "usePressure", "showBrush"]),
|
|
(LIQUIFY, None, &["detail", "simplify", "simplifyOn", "rate", "complexity", "horizontal", "vertical", "affectAnchors", "affectIn", "affectOut"]),
|
|
(SYMBOLISM, Some("symbolism"), &["diameter", "intensity", "density"]),
|
|
(&["mirrorCut"], None, &["axis", "keep"]),
|
|
(&["puppetWarp"], None, &["showMesh", "expand"]),
|
|
(&["arc"], None, &["closed", "lengthX", "lengthY", "reference", "baseAlong", "slope", "fillArc"]),
|
|
(&["spiral"], None, &["decay", "segments", "clockwise"]),
|
|
// The grids' Tool Options: the dividers and switches the drag uses, the Default Size and
|
|
// Reference Point a click's dialog opens with.
|
|
(&["rectangularGrid"], None, &["rows", "columns", "rowSkew", "columnSkew", "frame", "fill", "width", "height", "reference"]),
|
|
(&["polarGrid"], None, &["concentric", "radial", "concentricSkew", "radialSkew", "compound", "fill", "width", "height", "reference"]),
|
|
// 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 (the Paintbrush has no such option).
|
|
(&["pencil"], None, &["altSmooth"]),
|
|
(&["smooth"], None, &["fidelity"]),
|
|
(&["blobBrush", "eraser"], None, &["size"]),
|
|
(&["blobBrush"], None, &["keepSelected", "mergeOnlySelection"]),
|
|
// Live Paint Selection Tool Options (`builder::LivePaintSelectionTool`).
|
|
(&["livePaintSelection"], None, &["selectFills", "selectStrokes", "color", "width"]),
|
|
(&["polygon"], None, &["sides"]),
|
|
(&["star"], None, &["points"]),
|
|
(&["freeTransform"], None, &["constrain"]),
|
|
// Shape Builder Tool Options (`builder::ShapeBuilderOptions`).
|
|
(
|
|
&["shapeBuilder"],
|
|
None,
|
|
&[
|
|
"openFilledAsClosed",
|
|
"pickColorFrom",
|
|
"cursorSwatchPreview",
|
|
"selection",
|
|
"highlightFill",
|
|
"gapDetection",
|
|
"gapLength",
|
|
"clickStrokeSplitsPath",
|
|
"highlightStroke",
|
|
"highlightColor",
|
|
],
|
|
),
|
|
(&["artboard"], None, &["moveArt", "scaleArt"]),
|
|
// Flare Tool Options (`extra::FLARE_OPTIONS` and the Rays and Rings checkboxes).
|
|
(
|
|
&["flare"],
|
|
None,
|
|
&[
|
|
"diameter",
|
|
"opacity",
|
|
"brightness",
|
|
"growth",
|
|
"fuzziness",
|
|
"raysOn",
|
|
"rays",
|
|
"longest",
|
|
"rayFuzziness",
|
|
"ringsOn",
|
|
"pathLength",
|
|
"rings",
|
|
"largest",
|
|
"direction",
|
|
],
|
|
),
|
|
];
|
|
|
|
/// The stores `tool`'s persistent options live in, each with the option keys it holds.
|
|
pub fn stores(tool: &str) -> impl Iterator<Item = (&'static str, &'static [&'static str])> + '_ {
|
|
ROWS.iter().filter_map(move |(tools, shared, keys)| {
|
|
let id = tools.iter().find(|t| **t == tool)?;
|
|
Some((shared.unwrap_or(id), *keys))
|
|
})
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn every_listed_option_is_one_the_tool_reports() {
|
|
for (tools, _, keys) in ROWS {
|
|
for id in *tools {
|
|
assert!(crate::tool_info(id).is_some(), "{id} is a tool");
|
|
let opts = crate::create(id).options();
|
|
for k in *keys {
|
|
assert!(opts.get(*k).is_some(), "{id} reports `{k}` in {opts}");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn liquify_tools_share_the_global_brush() {
|
|
let warp: Vec<_> = stores("warp").collect();
|
|
let twirl: Vec<_> = stores("twirl").collect();
|
|
assert_eq!(warp[0], twirl[0]);
|
|
assert_eq!(warp[0].0, "liquify");
|
|
assert_eq!((warp[1].0, twirl[1].0), ("warp", "twirl"));
|
|
assert_eq!(stores("selection").count(), 0);
|
|
}
|
|
}
|