SETVAR CECOLOR takes the colour names and indexes the color command takes (fixes #1999) (#2014)

This commit is contained in:
Marco Arnulfo
2026-10-24 01:52:00 -04:00
committed by GitHub
parent 1a76e10c20
commit ab6bff5e4e
5 changed files with 74 additions and 2 deletions
+1
View File
@@ -33,6 +33,7 @@ pub mod plotters;
mod props;
pub use draw2::breakline::BreaklineOptions;
pub use props::MatchProps;
pub(crate) use props::set_current_color_value;
mod qselect;
mod selecttools;
mod settings;
+19 -2
View File
@@ -418,7 +418,25 @@ fn run_set(s: &mut Session, p: &Value) -> Result<Value> {
fn run_color(s: &mut Session, p: &Value) -> Result<Value> {
let c = p.get("color").and_then(parse_color).ok_or_else(|| bad("color", "`color` is required"))?;
let d = s.doc_mut()?;
set_current_color(s.doc_mut()?, c);
ok()
}
/// `setvar CECOLOR`: the same input as the `color` command, stored the same way.
pub(crate) fn set_current_color_value(s: &mut Session, v: &Value) -> Option<()> {
// An out-of-range index is refused here, where `color` folds it to ByLayer.
let c = match v {
Value::String(t) => Color::parse(t),
Value::Number(n) => n.as_i64().and_then(|i| Color::parse(&i.to_string())),
_ => None,
}?;
set_current_color(s.doc_mut().ok()?, c);
Some(())
}
/// A true colour keeps its RGB in CECOLOR_RGB (which wins for new objects); any other colour must
/// clear a stale one.
fn set_current_color(d: &mut cadcraft_doc::Drawing, c: Color) {
match c {
Color::True(rgb) => {
d.header.set_i64("CECOLOR", i64::from(cadcraft_color::nearest_aci(rgb)));
@@ -429,7 +447,6 @@ fn run_color(s: &mut Session, p: &Value) -> Result<Value> {
d.header.vars.remove("CECOLOR_RGB");
}
}
ok()
}
mod linfile;
+2
View File
@@ -276,6 +276,8 @@ pub fn set(s: &mut Session, name: &str, v: &Value) -> Result<()> {
let st = &mut s.settings;
match n.as_str() {
"OSMODE" => st.osmode = v.as_u64().or_else(|| v.as_str().and_then(|s| s.trim().parse().ok())).ok_or_else(bad)? as u32 & 0x7fff,
// The `color` command's input: ByLayer, ByBlock, a name, an index or a true colour.
"CECOLOR" => crate::cmd::set_current_color_value(s, v).ok_or_else(bad)?,
"OSNAPHATCH" => st.osnaphatch = as_bool(v).ok_or_else(bad)?,
"ANNOAUTOSCALE" => st.annoautoscale = as_i(v).filter(|i| (-4..=4).contains(i)).ok_or_else(bad)? > 0,
// A scale of the drawing's list; ANNOAUTOSCALE adds it to the annotative objects.
+1
View File
@@ -108,6 +108,7 @@ mod select_similar;
mod select_underscore_keywords;
mod selection_cycling;
mod selection_modes;
mod setvar_cecolor;
mod setvar_coverage;
mod shapes;
mod snap_annotations;
+51
View File
@@ -0,0 +1,51 @@
//! `setvar CECOLOR` takes what the `color` command takes: "ByLayer", "ByBlock", a colour name or an
//! index (#1999).
use cadcraft_engine::Session;
use cadcraft_engine::doc::color::{Color, Rgb};
use serde_json::{Value, json};
fn cecolor(s: &mut Session) -> Value {
s.execute("getvar", &json!({ "name": "CECOLOR" })).unwrap()["value"].clone()
}
fn new_line_color(s: &mut Session) -> Color {
s.execute("line", &json!({ "points": [[0, 0], [10, 0]] })).unwrap();
s.doc().unwrap().model.last().unwrap().common.color
}
#[test]
fn setvar_cecolor_accepts_names() {
for (value, aci) in [("BYLAYER", 256), ("ByLayer", 256), ("BYBLOCK", 0), ("red", 1), ("250", 250)] {
let mut s = Session::new();
s.execute("setvar", &json!({ "name": "CECOLOR", "value": value })).unwrap_or_else(|e| panic!("{value}: {e}"));
assert_eq!(cecolor(&mut s), json!(aci), "{value}");
}
}
#[test]
fn setvar_cecolor_name_replaces_a_true_colour() {
let mut s = Session::new();
s.execute("color", &json!({ "color": "10,20,30" })).unwrap();
assert_eq!(new_line_color(&mut s), Color::True(Rgb(10, 20, 30)));
s.execute("setvar", &json!({ "name": "CECOLOR", "value": "ByLayer" })).unwrap();
assert_eq!(cecolor(&mut s), json!(256));
assert_eq!(new_line_color(&mut s), Color::ByLayer);
}
#[test]
fn setvar_cecolor_number_replaces_a_true_colour() {
let mut s = Session::new();
s.execute("color", &json!({ "color": "10,20,30" })).unwrap();
s.execute("setvar", &json!({ "name": "CECOLOR", "value": 250 })).unwrap();
assert_eq!(new_line_color(&mut s), Color::Index(250));
}
#[test]
fn setvar_cecolor_refuses_what_is_not_a_colour() {
let mut s = Session::new();
for bad in [json!("chartreuse"), json!(257), json!(-1), json!(true)] {
assert!(s.execute("setvar", &json!({ "name": "CECOLOR", "value": bad })).is_err(), "{bad}");
}
assert_eq!(cecolor(&mut s), json!(256));
}