M3.27: Color Picker reads colours with the engine's color_value (one parser; CMYK and grey in percent as the paint commands take them) instead of its own copy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
c071dcd4d0
commit
ad82e6e9a9
|
|
@ -240,7 +240,7 @@ pub fn matrix_param(p: &Value, key: &str) -> Option<Affine> {
|
|||
Some(Affine::new(c))
|
||||
}
|
||||
/// A colour from `"#rrggbb"`, `[r,g,b]` (0..1), `{"c":..,"m":..,"y":..,"k":..}` or `{"gray":..}`.
|
||||
pub(crate) fn color_value(v: &Value) -> Option<Color> {
|
||||
pub fn color_value(v: &Value) -> Option<Color> {
|
||||
match v {
|
||||
Value::String(s) => Color::from_hex(s),
|
||||
Value::Array(a) if a.len() >= 3 => Some(Color::rgb(a[0].as_f64()? as f32, a[1].as_f64()? as f32, a[2].as_f64()? as f32)),
|
||||
|
|
|
|||
|
|
@ -12,10 +12,11 @@ use serde_json::{Value, json};
|
|||
use vectorcraft_color::cms::{self, Lab};
|
||||
use vectorcraft_color::{Color, Paint};
|
||||
use vectorcraft_doc::ColorMode;
|
||||
use vectorcraft_engine::cmd::color_value;
|
||||
|
||||
use super::DialogSpec;
|
||||
use crate::panels::color::{GAMUT_WARNING, WEB_WARNING, gamut_fix, hex_digits, is_web_safe, parse_hex, warning_chip, web_safe};
|
||||
use crate::panels::{c32, color_from_json, color_json};
|
||||
use crate::panels::{c32, color_json};
|
||||
use crate::state::Dialog;
|
||||
use crate::theme::Tokens;
|
||||
use crate::{VectorcraftApp, widgets};
|
||||
|
|
@ -132,7 +133,7 @@ fn picked(d: &Dialog) -> Picked {
|
|||
let hex = d.str("hex");
|
||||
let color = match parse_hex(&hex) {
|
||||
Some(c) if hex != d.str("__hex") => c,
|
||||
_ => d.fields.get("color").and_then(color_from_json).unwrap_or(Color::WHITE),
|
||||
_ => d.fields.get("color").and_then(color_value).unwrap_or(Color::WHITE),
|
||||
};
|
||||
let hsb = d.fields.get("__hsb").and_then(|v| serde_json::from_value::<[f32; 3]>(v.clone()).ok());
|
||||
let p = match hsb {
|
||||
|
|
@ -165,7 +166,7 @@ fn proxy_color(app: &VectorcraftApp, stroke: bool) -> Color {
|
|||
pub fn open(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
|
||||
let stroke = p.get("stroke").and_then(Value::as_bool).unwrap_or(!app.session.fill_active);
|
||||
let color = match p.get("color") {
|
||||
Some(v) => color_from_json(v).ok_or_else(|| format!("bad color {v}"))?,
|
||||
Some(v) => color_value(v).ok_or_else(|| format!("bad color {v}"))?,
|
||||
None => proxy_color(app, stroke),
|
||||
};
|
||||
let mut d = Dialog::new(
|
||||
|
|
@ -182,7 +183,7 @@ fn body(app: &mut VectorcraftApp, ui: &mut Ui, d: &mut Dialog) -> bool {
|
|||
let web = d.bool("webOnly");
|
||||
let swatches = d.bool("swatches");
|
||||
let p = picked(d);
|
||||
let original = d.fields.get("original").and_then(color_from_json).unwrap_or(p.color);
|
||||
let original = d.fields.get("original").and_then(color_value).unwrap_or(p.color);
|
||||
let gamut = gamut_fix(app, ui.ctx(), "picker-gamut", &p.color);
|
||||
let mut pick: Option<Picked> = None;
|
||||
let mut new_channel = None;
|
||||
|
|
@ -481,6 +482,10 @@ mod tests {
|
|||
super::super::confirm(&mut app).unwrap();
|
||||
assert!(matches!(crate::panels::current_paints(&app).0.color(), Some(Color::Cmyk { .. })), "CMYK is kept");
|
||||
assert!(app.run("ui.colorPicker", json!({"color": "nope"})).is_err());
|
||||
// Colours take every form the paint commands take (CMYK in percent too).
|
||||
app.run("ui.colorPicker", json!({"stroke": false, "color": {"c": 0, "m": 100, "y": 100, "k": 0}})).unwrap();
|
||||
super::super::confirm(&mut app).unwrap();
|
||||
assert_eq!(crate::panels::current_paints(&app).0.color(), Some(Color::cmyk(0.0, 1.0, 1.0, 0.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -282,19 +282,6 @@ pub(crate) fn recent_colors_row(app: &mut VectorcraftApp, ui: &mut Ui) {
|
|||
}
|
||||
}
|
||||
|
||||
/// A colour from command JSON: `"#rrggbb"`, `[r,g,b]`, `{c,m,y,k}`, `{gray}` (inverse of
|
||||
/// [`color_json`]) or a serialized colour.
|
||||
pub(crate) fn color_from_json(v: &Value) -> Option<Color> {
|
||||
let f = |v: Option<&Value>| v.and_then(Value::as_f64).map(|x| x as f32);
|
||||
match v {
|
||||
Value::String(s) => color::parse_hex(s),
|
||||
Value::Array(a) if a.len() == 3 => Some(Color::rgb(f(a.first())?, f(a.get(1))?, f(a.get(2))?)),
|
||||
Value::Object(o) if o.contains_key("gray") => Some(Color::gray(f(o.get("gray"))?)),
|
||||
Value::Object(o) if !o.contains_key("model") => Some(Color::cmyk(f(o.get("c"))?, f(o.get("m"))?, f(o.get("y"))?, f(o.get("k"))?)),
|
||||
_ => serde_json::from_value(v.clone()).ok(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A colour as command JSON, keeping its model.
|
||||
pub(crate) fn color_json(c: &Color) -> Value {
|
||||
match *c {
|
||||
|
|
|
|||
Loading…
Reference in New Issue