mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-28 11:47:21 -06:00
Select: select.color picks objects by fill and stroke colour, no object needed
Scripts had to know an object id before they could select art by colour
(select.same.* and select.magicWand start from one). select.color
{fill?, stroke?} takes colours as paint.setFill does and selects the
objects whose fill and stroke read as them in #rrggbb, as
document.inspect reports colours, with Select > Same's selection rules.
The label is translated in each of the 23 catalogs, which
complete_languages_translate_every_menu_string requires.
This commit is contained in:
@@ -89,6 +89,15 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
has_doc,
|
||||
anchors_many
|
||||
),
|
||||
cmd!(
|
||||
"select.color",
|
||||
"Select by Color",
|
||||
[],
|
||||
None,
|
||||
"{fill?: colour, stroke?: colour (as paint.setFill's color; at least one)} select the objects whose fill (and stroke) reads as that colour in #rrggbb, as document.inspect reports colours, whatever its swatch or tint; with both, the objects that match both. No object needs to be selected first; Select > Reselect repeats it → {count}",
|
||||
has_doc,
|
||||
select_color
|
||||
),
|
||||
cmd!(
|
||||
"select.same.fillColor",
|
||||
"Fill Color",
|
||||
@@ -528,6 +537,22 @@ fn stroke_weight(n: &Node) -> f64 {
|
||||
if paint.is_none() { 0.0 } else { width }
|
||||
}
|
||||
|
||||
/// Select by Color: the objects whose fill and stroke read as the colours given, compared as the
|
||||
/// `#rrggbb` `document.inspect` reports, so a script can pick art by colour without an object id.
|
||||
fn select_color(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
const C: &str = "select.color";
|
||||
let hex = |key: &str| match p.get(key).filter(|v| !v.is_null()) {
|
||||
None => Ok(None),
|
||||
Some(v) => color_value(v).map(|c| Some(c.to_hex())).ok_or_else(|| bad(C, format!("`{key}`: not a colour: {v}"))),
|
||||
};
|
||||
let (fill, stroke) = (hex("fill")?, hex("stroke")?);
|
||||
if fill.is_none() && stroke.is_none() {
|
||||
return Err(bad(C, "give `fill`, `stroke` or both"));
|
||||
}
|
||||
let reads_as = |paint: Paint, hex: Option<&str>| hex.is_none_or(|h| paint.color().is_some_and(|c| c.to_hex() == h));
|
||||
select_where(s, C, p, |_, n| !n.is_container() && reads_as(fill_of(n), fill.as_deref()) && reads_as(stroke_of(n).0, stroke.as_deref()))
|
||||
}
|
||||
|
||||
fn same(s: &mut Session, cmd: &str, eq: impl Fn(&Node, &Node) -> bool) -> Result<Value> {
|
||||
let st = s.doc()?;
|
||||
let refn = st.selection.objects.first().and_then(|id| st.doc.node(*id)).cloned().ok_or_else(|| bad(cmd, "nothing selected"))?;
|
||||
|
||||
Reference in New Issue
Block a user