mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 05:37:23 -06:00
Part of gap 5: Scatter, Art and Pattern Brush Options
Double-clicking a Scatter, Art or Pattern brush in the Brushes panel (or the panel menu's Brush Options...) now opens its options dialog, as Calligraphic and Bristle brushes already did. OK runs brush.options and every stroke painted with the brush redraws. - Scatter Brush Options: Name; Size (10-1000 %), Spacing (10-10000 %), Scatter (-1000-1000 %) and Rotation (-180-180 deg), each Fixed (the first value), Random (between the two values) or Pressure (the first value at the lightest pen pressure, the second at the heaviest); Rotation relative to Page or Path. Scatter brushes now keep these modes (`modes`); brushes saved before keep their look (Random where the two values differ). - Art Brush Options: Name; Width (1-1000 %); Scale Proportionately, Stretch to Fit Stroke Length or Stretch Between Guides with the guides' Start and End (% of the art length); the four Directions; Flip Along and Across. - Pattern Brush Options: Name; Scale (1-10000 %), Spacing (0-10000 %); the five tiles (Outer Corner, Side, Inner Corner, Start, End) drawn with their art or None; Flip Along and Across; Stretch to fit, Add space to fit or Approximate path. - All three: Colorization (None, Tints, Tints and Shades, Hue Shift with its Key Color picked from the art's colours, the most used one by default) and a live preview of a stroke painted with the edited brush. Brush definitions from files and commands are now kept within these ranges (Brush::sanitize, also for Calligraphic and Bristle values); unknown modes, directions, fits or colorization methods are refused. The brush.options and ui.brushOptions docs list the new params and fields. Tests: the brush model (modes, pressure, sanitizing, art colours), engine params reaching the brush and strokes redrawing, junk params in command_sweep, and headless dialog tests for each dialog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5b198f3c00
commit
2bc6c66c94
@@ -63,7 +63,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Brush Options…",
|
||||
[],
|
||||
None,
|
||||
"{name, params?: {…fields to change (brush.get shows them; calligraphic: angle −180..180°, roundness 0..100%, size 0..1296 pt, variation: [angle°, roundness%, size pt], modes: [fixed|random|pressure for angle, roundness, size]; pressure goes from value − variation at the lightest pen pressure to value + variation at the heaviest)}, newName?} edit a brush definition (strokes using it update) → {name}",
|
||||
"{name, params?: {…fields to change (brush.get shows them; values outside their ranges are clamped). calligraphic: angle −180..180°, roundness 0..100%, size 0..1296 pt, variation: [angle°, roundness%, size pt], modes: [fixed|random|pressure for angle, roundness, size] (pressure goes from value − variation at the lightest pen pressure to value + variation at the heaviest). scatter: size [a, b] 1..10000%, spacing [a, b] 1..10000%, scatter [a, b] −1000..1000%, rotation [a, b] −180..180°, modes: [fixed|random|pressure for size, spacing, scatter, rotation] (fixed: a; random: between a and b; pressure: a at the lightest pen pressure to b at the heaviest), rotation_relative_to_path. art: width 1..1000%, scale: {mode: proportional|stretch|betweenGuides, start, end: 0..1 of the art length}, direction: leftToRight|rightToLeft|topToBottom|bottomToTop, flip_along, flip_across. pattern: scale 1..10000%, spacing 0..10000%, fit: stretch|addSpace|approximate, flip_along, flip_across. scatter, art and pattern: colorization: {method: none|tints|tintsAndShades|hueShift, key: colour (hueShift: the art colour that becomes the stroke colour)}}, newName?} edit a brush definition (strokes using it update) → {name}",
|
||||
has_doc,
|
||||
brush_options
|
||||
),
|
||||
@@ -383,12 +383,18 @@ fn brush_new(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
v[k] = serde_json::to_value(&art).unwrap_or_default();
|
||||
}
|
||||
let b: Brush = serde_json::from_value(v).map_err(|e| bad(C, format!("invalid brush: {e}")))?;
|
||||
lib.push(b);
|
||||
lib.push(parse_brush(C, v)?);
|
||||
save_library(s, "New Brush", lib, None)?;
|
||||
Ok(json!({ "name": name }))
|
||||
}
|
||||
|
||||
/// A brush definition from command params, its values kept within their ranges.
|
||||
fn parse_brush(cmd: &str, v: Value) -> Result<Brush> {
|
||||
let mut b: Brush = serde_json::from_value(v).map_err(|e| bad(cmd, format!("invalid brush: {e}")))?;
|
||||
b.sanitize();
|
||||
Ok(b)
|
||||
}
|
||||
|
||||
fn brush_delete(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let name = name_param(p, "brush.delete")?.to_string();
|
||||
let mut lib = brush::library(&s.doc()?.doc);
|
||||
@@ -431,7 +437,7 @@ fn brush_options(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
v["name"] = json!(name);
|
||||
}
|
||||
v["type"] = json!(lib[i].kind.type_id());
|
||||
lib[i] = serde_json::from_value(v).map_err(|e| bad(C, format!("invalid brush: {e}")))?;
|
||||
lib[i] = parse_brush(C, v)?;
|
||||
let out = lib[i].name.clone();
|
||||
let rename = new_name.map(|nn| (name, Some(nn)));
|
||||
save_library(s, "Brush Options", lib, rename)?;
|
||||
|
||||
Reference in New Issue
Block a user