mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-15 21:57:04 +00:00
Merge pull request #7775 from dotCooCoo/feat/recolor-new-row
Recolor Artwork: New Row adds a row that current colors can be merged into
This commit is contained in:
@@ -34,7 +34,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Recolor Artwork",
|
||||
["Edit", "Edit Colors"],
|
||||
None,
|
||||
"{map: rows [{from: [colour keys (recolor.colors) or \"#rrggbb\" (every colour shown as that hex)], to: colour (hex, key, {c,m,y,k} or {l,a,b}) | null (in from, to and groupColors, #rrggbbaa and #rgba are refused), exclude?: false (the row's colours are kept), tint?: 100 (percent; with limitTo, art linked to the global or spot swatch the new color is takes this share of its tint)}] | {\"key or #rrggbb\": colour, …} (one row per colour), method?: \"exact\" (default)|\"preserveTints\"|\"scaleTints\"|\"tintsShades\"|\"hueShift\" (how a row's colours take its new colour, relative to the row's darkest, average or most saturated colour), limitTo?: swatch library id or name; or \"document\" (the document's swatches): new colours snap to its nearest colour, group?: colour group to rewrite, groupColors?: [colour] (what `group` is rewritten with; default: the rows' new colours, in order, excluded rows left out), rename?: the group's new name, includeImages?: true, includePatterns?: true, globalAdjust?: {saturation?: 0, brightness?: 0, temperature?: 0, luminosity?: 0} (Global Adjust: percent from -100 to 100, 0 changes nothing; every colour a row that isn't excluded recolours, and the group's new colours, take the same change after the row's new colour: saturation scales HSB saturation by 1 + saturation/100, brightness moves HSB brightness that share of the way to full or to black, temperature adds 0.2 × temperature/100 to red and takes it from blue, luminosity moves Lab lightness that share of the way to 100 or 0 keeping a and b; with limitTo each row's new colour takes the change before it snaps to the library)} recolour the selection (gradients, text, meshes, image pixels and pattern tiles included; each new colour keeps the model of the one it replaces (model?: \"keep\" default | \"new\" (the new colour's own model, so a CMYK colour replacing RGB art gives CMYK art) | \"document\" (the document's colour mode)), except a library swatch's with limitTo: art takes the swatch itself, linked to a global or spot colour at its tints, and the swatch joins the document's swatches; art linked to a global swatch of `group` that is rewritten with its row's new color stays linked to it, at its tint, unless the row converts the color into the art's model; other recolored art, and art in a row linked to a global swatch of `group` that is rewritten with another color, keeps its row's new color and loses its swatch link) and the group, as one undo step (none when nothing changes). On a path directly in a graph series, the graph also stores the new paint of the topmost visible fill and stroke, and on a graph label the new paint of its characters and rows for every label of its kind (docs/mcp.md) → {changed, swatches: [names added to the document's swatches], relinked?: with group, the other paints linked to its global swatches that took their new colors, note?: set when a colour kept a model other than its new colour's (see model), notChanged: {locked, hidden} (as edit.colors.invert), warning?: set when notChanged counts any object}",
|
||||
"{map: rows [{from: [colour keys (recolor.colors) or \"#rrggbb\" (every colour shown as that hex); may be empty: an empty row recolours nothing, adds no library swatch and gives `group` no colour], to: colour (hex, key, {c,m,y,k} or {l,a,b}) | null (in from, to and groupColors, #rrggbbaa and #rgba are refused), exclude?: false (the row's colours are kept), tint?: 100 (percent; with limitTo, art linked to the global or spot swatch the new color is takes this share of its tint)}] | {\"key or #rrggbb\": colour, …} (one row per colour), method?: \"exact\" (default)|\"preserveTints\"|\"scaleTints\"|\"tintsShades\"|\"hueShift\" (how a row's colours take its new colour, relative to the row's darkest, average or most saturated colour), limitTo?: swatch library id or name; or \"document\" (the document's swatches): new colours snap to its nearest colour, group?: colour group to rewrite, groupColors?: [colour] (what `group` is rewritten with; default: the rows' new colours, in order, excluded and empty rows left out), rename?: the group's new name, includeImages?: true, includePatterns?: true, globalAdjust?: {saturation?: 0, brightness?: 0, temperature?: 0, luminosity?: 0} (Global Adjust: percent from -100 to 100, 0 changes nothing; every colour a row that isn't excluded recolours, and the group's new colours, take the same change after the row's new colour: saturation scales HSB saturation by 1 + saturation/100, brightness moves HSB brightness that share of the way to full or to black, temperature adds 0.2 × temperature/100 to red and takes it from blue, luminosity moves Lab lightness that share of the way to 100 or 0 keeping a and b; with limitTo each row's new colour takes the change before it snaps to the library)} recolour the selection (gradients, text, meshes, image pixels and pattern tiles included; each new colour keeps the model of the one it replaces (model?: \"keep\" default | \"new\" (the new colour's own model, so a CMYK colour replacing RGB art gives CMYK art) | \"document\" (the document's colour mode)), except a library swatch's with limitTo: art takes the swatch itself, linked to a global or spot colour at its tints, and the swatch joins the document's swatches; art linked to a global swatch of `group` that is rewritten with its row's new color stays linked to it, at its tint, unless the row converts the color into the art's model; other recolored art, and art in a row linked to a global swatch of `group` that is rewritten with another color, keeps its row's new color and loses its swatch link) and the group, as one undo step (none when nothing changes). On a path directly in a graph series, the graph also stores the new paint of the topmost visible fill and stroke, and on a graph label the new paint of its characters and rows for every label of its kind (docs/mcp.md) → {changed, swatches: [names added to the document's swatches], relinked?: with group, the other paints linked to its global swatches that took their new colors, note?: set when a colour kept a model other than its new colour's (see model), notChanged: {locked, hidden} (as edit.colors.invert), warning?: set when notChanged counts any object}",
|
||||
has_doc,
|
||||
apply
|
||||
),
|
||||
@@ -1614,8 +1614,11 @@ fn apply(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
Some(k) => super::swatchlib::library_swatches(s, k).unwrap_or_default(),
|
||||
None => vec![],
|
||||
};
|
||||
let row_swatches: Vec<Option<Swatch>> =
|
||||
rows.iter().map(|r| r.new_color().and_then(|c| lib_swatches.iter().find(|w| w.paint.color() == Some(c)).cloned())).collect();
|
||||
// A row with no current colors recolors nothing, so its swatch does not join the document.
|
||||
let row_swatches: Vec<Option<Swatch>> = rows
|
||||
.iter()
|
||||
.map(|r| r.new_color().filter(|_| !r.from.is_empty()).and_then(|c| lib_swatches.iter().find(|w| w.paint.color() == Some(c)).cloned()))
|
||||
.collect();
|
||||
// While an object of a dynamic symbol instance's art is selected, the selection is refused, as
|
||||
// `selected_roots` refuses it.
|
||||
super::edit::refuse_symbol_part(s)?;
|
||||
@@ -1657,7 +1660,8 @@ fn apply(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
.ok_or_else(|| bad(C, format!("bad colour {v} in groupColors")))
|
||||
})
|
||||
.collect::<Result<_>>()?,
|
||||
None => rows.iter().filter_map(Row::new_color).map(|c| mapped_adjust.apply(c)).collect(),
|
||||
// A row with no current colors gives the group no color.
|
||||
None => rows.iter().filter(|r| !r.from.is_empty()).filter_map(Row::new_color).map(|c| mapped_adjust.apply(c)).collect(),
|
||||
};
|
||||
let rename = text_param(p, "rename", C)?;
|
||||
let colorized_ok = super::paint::check_colorized(&s.doc()?.doc).is_ok();
|
||||
|
||||
@@ -303,6 +303,62 @@ fn methods_and_bad_params() {
|
||||
assert!(s.execute("recolor.apply", &json!({"map": {}})).is_err(), "needs art or a group");
|
||||
}
|
||||
|
||||
/// A row with no current colors (Recolor Artwork's New Row) recolors nothing, and records no
|
||||
/// undo step on its own; beside it the other rows recolor as before, and the weights and
|
||||
/// randomize keep it. A row without `from`, or with a bad current color, is still refused.
|
||||
#[test]
|
||||
fn an_empty_row_recolors_nothing() {
|
||||
let mut s = session();
|
||||
let red = rect(&mut s, json!("#ff0000"));
|
||||
let blue = rect(&mut s, json!("#0000ff"));
|
||||
select_all(&mut s);
|
||||
let undo = s.doc().unwrap().history.undo.len();
|
||||
let empty = json!({"from": [], "to": "rgb 0 255 0"});
|
||||
let r = run(&mut s, "recolor.apply", json!({"map": [empty]}));
|
||||
assert_eq!(r["changed"], json!(0));
|
||||
assert_eq!(s.doc().unwrap().history.undo.len(), undo, "no undo step");
|
||||
let map = json!([empty, {"from": ["rgb 0 0 255"], "to": "rgb 255 255 0"}]);
|
||||
let w = run(&mut s, "recolor.weigh", json!({"map": map}));
|
||||
assert_eq!(w["map"], map, "the rows as given");
|
||||
assert_eq!(w["shares"], json!([0.0, 100.0]));
|
||||
let shuffled = run(&mut s, "recolor.randomize", json!({"map": map, "seed": 1}));
|
||||
assert_eq!(shuffled["map"][0]["from"], json!([]));
|
||||
run(&mut s, "recolor.apply", json!({"map": map}));
|
||||
assert_eq!((fill(&s, red).to_hex(), fill(&s, blue).to_hex()), ("#ff0000".into(), "#ffff00".into()));
|
||||
assert_eq!(s.doc().unwrap().history.undo.len(), undo + 1);
|
||||
for bad in [json!([{"to": "rgb 0 255 0"}]), json!([{"from": ["nonsense"], "to": "rgb 0 255 0"}])] {
|
||||
assert!(s.execute("recolor.apply", &json!({"map": bad})).is_err(), "{bad}");
|
||||
}
|
||||
}
|
||||
|
||||
/// An empty row adds no library swatch with `limitTo`, and gives a rewritten group no color: the
|
||||
/// group keeps one color per row that holds current colors.
|
||||
#[test]
|
||||
fn an_empty_row_adds_no_swatch_and_no_group_color() {
|
||||
let mut s = session();
|
||||
rect(&mut s, json!("#ff0000"));
|
||||
rect(&mut s, json!("#0000ff"));
|
||||
select_all(&mut s);
|
||||
let undo = s.doc().unwrap().history.undo.len();
|
||||
let swatches = s.doc().unwrap().doc.swatches.len();
|
||||
let r = run(&mut s, "recolor.apply", json!({"map": [{"from": [], "to": "#ff0033"}], "limitTo": "web-safe-216"}));
|
||||
assert_eq!(r["swatches"], json!([]), "{r}");
|
||||
assert_eq!(s.doc().unwrap().doc.swatches.len(), swatches);
|
||||
assert_eq!(s.doc().unwrap().history.undo.len(), undo, "no undo step");
|
||||
run(&mut s, "swatch.newGroup", json!({"name": "Pair", "colors": ["#ff0000", "#0000ff"]}));
|
||||
select_all(&mut s);
|
||||
let map = json!([
|
||||
{"from": [], "to": "rgb 0 255 0"},
|
||||
{"from": ["rgb 255 0 0"], "to": "rgb 255 0 0"},
|
||||
{"from": ["rgb 0 0 255"], "to": "rgb 0 0 255"},
|
||||
]);
|
||||
run(&mut s, "recolor.apply", json!({"map": map, "group": "Pair"}));
|
||||
let d = &s.doc().unwrap().doc;
|
||||
let g = d.swatch_groups.iter().find(|g| g.name == "Pair").unwrap();
|
||||
let hexes: Vec<String> = g.swatches.iter().map(|w| w.paint.color().unwrap().to_hex()).collect();
|
||||
assert_eq!(hexes, ["#ff0000", "#0000ff"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn randomize_shuffles_new_colours_and_skips_excluded_rows() {
|
||||
let mut s = session();
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
//! whose OK sets it in the model it was picked in), the color mode menu and its sliders (HSB, RGB,
|
||||
//! CMYK or Lab, and Tint when the new color is a spot color of the library), which edit the
|
||||
//! first selected row's new color (once they have, OK gives the art each new color in its own
|
||||
//! model), Merge and Separate, Randomize order or
|
||||
//! model), New Row (a row with no current colors above the first selected row, or at the top,
|
||||
//! with that row's new color; it recolors nothing until Merge moves colors into it), Merge and
|
||||
//! Separate, Randomize order or
|
||||
//! saturation and brightness, Reset, the Method and Limit to Library (its folder button imports a
|
||||
//! library file and limits to it; a library's colours apply as its swatches: a spot colour stays a
|
||||
//! spot colour, and joins the document's swatches). Edit tab: a hue and
|
||||
@@ -566,9 +568,11 @@ fn selection(d: &Dialog) -> Vec<usize> {
|
||||
fn apply_params(d: &Dialog) -> Value {
|
||||
let rs = rows(d);
|
||||
let group = d.fields.get("group").and_then(Value::as_str).map(|g| {
|
||||
let rest =
|
||||
d.fields.get("__assign").and_then(Value::as_array).filter(|_| d.bool("__art")).map_or(&[][..], |a| a.get(rs.len()..).unwrap_or_default());
|
||||
let colors: Vec<&Value> = rs.iter().map(|r| &r["to"]).chain(rest).collect();
|
||||
// A row made with New Row that holds no current colors gives the group no color.
|
||||
let filled: Vec<&Value> = rs.iter().filter(|r| !r["from"].as_array().is_some_and(Vec::is_empty)).map(|r| &r["to"]).collect();
|
||||
let assign = d.fields.get("__assign").and_then(Value::as_array).filter(|_| d.bool("__art"));
|
||||
let rest = assign.map_or(&[][..], |a| a.get(filled.len()..).unwrap_or_default());
|
||||
let colors: Vec<&Value> = filled.into_iter().chain(rest).collect();
|
||||
let name = d.str("groupName");
|
||||
let rename = (!name.trim().is_empty() && name != g).then_some(name);
|
||||
json!({"group": g, "groupColors": colors, "rename": rename})
|
||||
@@ -778,6 +782,10 @@ fn assign_tab(app: &mut VectorcraftApp, ui: &mut Ui, d: &mut Dialog, rows: &mut
|
||||
let x = cur.left() + j as f32 * w;
|
||||
chip(ui, Rect::from_min_max(pos2(x, cur.top()), pos2(x + w - if w > 4.0 { 2.0 } else { 0.0 }, cur.bottom())), *c, false);
|
||||
}
|
||||
// A row made with New Row shows an empty slot until colors are merged into it.
|
||||
if from.is_empty() {
|
||||
ui.painter().rect_stroke(cur, 1.0, egui::Stroke::new(1.0, t.border), egui::StrokeKind::Inside);
|
||||
}
|
||||
if cr.clicked() {
|
||||
clicked = Some(i);
|
||||
}
|
||||
@@ -826,6 +834,14 @@ fn assign_tab(app: &mut VectorcraftApp, ui: &mut Ui, d: &mut Dialog, rows: &mut
|
||||
}
|
||||
ui.add_space(4.0);
|
||||
ui.horizontal(|ui| {
|
||||
// New Row is available only with art.
|
||||
if widgets::icon_button_enabled(ui, "plus", tl!("New Row"), false, d.bool("__art"), 24.0).clicked() {
|
||||
let at = new_row(rows, &sel);
|
||||
d.fields.insert("__sel".into(), json!([at]));
|
||||
// The slider edit was kept for a row index that now names another row.
|
||||
d.fields.remove(COMPS);
|
||||
changed = true;
|
||||
}
|
||||
let can_merge = sel.len() > 1;
|
||||
if widgets::icon_button_enabled(ui, "combine", tl!("Merge colors into one row"), false, can_merge, 24.0).clicked() {
|
||||
merge(rows, &sel);
|
||||
@@ -1218,6 +1234,16 @@ fn separate(rows: &mut Vec<Value>, sel: &[usize]) {
|
||||
*rows = out;
|
||||
}
|
||||
|
||||
/// New Row: insert a row with no current colors above the first selected row, or at the top
|
||||
/// when none is selected, and return its index. Its new color is the new color of the row it goes
|
||||
/// above (black without one). It recolors nothing until current colors are merged into it.
|
||||
fn new_row(rows: &mut Vec<Value>, sel: &[usize]) -> usize {
|
||||
let at = sel.iter().copied().filter(|i| *i < rows.len()).min().unwrap_or(0);
|
||||
let to = rows.get(at).and_then(to_color).unwrap_or_default();
|
||||
rows.insert(at, json!({"from": [], "to": key(&to)}));
|
||||
at
|
||||
}
|
||||
|
||||
/// The rows the Edit tab shows: those with a new colour, not excluded.
|
||||
fn active_rows(rows: &[Value]) -> Vec<usize> {
|
||||
(0..rows.len()).filter(|i| !excluded(&rows[*i]) && to_color(&rows[*i]).is_some()).collect()
|
||||
@@ -1540,6 +1566,35 @@ mod tests {
|
||||
assert_eq!(r.len(), 2);
|
||||
}
|
||||
|
||||
/// New Row goes above the first selected row with that row's new color, or at the top; it has
|
||||
/// no current colors, and a merge with it as the first selected row fills it.
|
||||
#[test]
|
||||
fn a_new_row_goes_above_the_selection_and_takes_merged_colors() {
|
||||
let mut r = rows();
|
||||
assert_eq!(new_row(&mut r, &[2, 1]), 1);
|
||||
assert_eq!(r.len(), 4);
|
||||
assert_eq!(r[1], json!({"from": [], "to": "rgb 0 0 255"}));
|
||||
assert_eq!(r[2]["from"], json!(["rgb 0 0 255", "rgb 0 0 128"]), "the selected row moved down");
|
||||
merge(&mut r, &[1, 3]);
|
||||
assert_eq!(r[1], json!({"from": ["rgb 0 255 0"], "to": "rgb 0 0 255"}));
|
||||
assert_eq!(new_row(&mut r, &[]), 0);
|
||||
assert_eq!(r[0], json!({"from": [], "to": "rgb 255 0 0"}));
|
||||
let mut none = vec![];
|
||||
assert_eq!(new_row(&mut none, &[5]), 0);
|
||||
assert_eq!(none, vec![json!({"from": [], "to": key(&Color::BLACK)})]);
|
||||
}
|
||||
|
||||
/// Opened on a color group, OK rewrites it with the new colors of the rows that hold current
|
||||
/// colors, then the group's colors no such row took: an empty row gives it no color.
|
||||
#[test]
|
||||
fn an_empty_row_gives_the_group_no_color() {
|
||||
let mut r = rows();
|
||||
new_row(&mut r, &[]);
|
||||
let fields = json!({"rows": r, "group": "Trio", "__art": true, "__assign": ["rgb 255 0 0", "rgb 0 0 255", "rgb 0 255 0", "rgb 9 9 9"]});
|
||||
let p = apply_params(&Dialog::new("recolor", fields));
|
||||
assert_eq!(p["groupColors"], json!(["rgb 255 0 0", "rgb 0 0 255", "rgb 0 255 0", "rgb 9 9 9"]));
|
||||
}
|
||||
|
||||
/// Randomize after a seed past `u64::MAX` keeps the largest seed.
|
||||
#[test]
|
||||
fn next_seed_holds_at_the_largest() {
|
||||
@@ -1825,6 +1880,35 @@ mod tests {
|
||||
assert_eq!(app.session.doc().unwrap().history.undo.len(), undo, "the art is unchanged: no undo step");
|
||||
}
|
||||
|
||||
/// A row made with New Row recolors nothing while it is empty, and OK keeps it; the blue art's
|
||||
/// color merged into it takes its new color, in the preview and at OK.
|
||||
#[test]
|
||||
fn colors_merged_into_a_new_row_take_its_new_color() {
|
||||
let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), Default::default());
|
||||
let ctx = egui::Context::default();
|
||||
let [red, blue] = theme_setup(&mut app, &ctx);
|
||||
let undo = app.session.doc().unwrap().history.undo.len();
|
||||
let set_rows = |app: &mut VectorcraftApp, rs: Vec<Value>| {
|
||||
app.ui.dialog.as_mut().unwrap().fields.insert("rows".into(), Value::Array(rs));
|
||||
};
|
||||
let mut rs = super::rows(app.ui.dialog.as_ref().unwrap());
|
||||
let at = new_row(&mut rs, &[]);
|
||||
rs[at]["to"] = json!("rgb 0 255 0");
|
||||
set_rows(&mut app, rs.clone());
|
||||
frame(&mut app, &ctx, 0.1, vec![], 0);
|
||||
assert_eq!((fill_hex(&app, red), fill_hex(&app, blue)), ("#ff0000".into(), "#0000ff".into()), "an empty row recolors nothing");
|
||||
let b = rs.iter().position(|r| r["from"] == json!([BLUE])).unwrap();
|
||||
merge(&mut rs, &[at, b]);
|
||||
// A second empty row stays empty and is sent at OK too.
|
||||
new_row(&mut rs, &[]);
|
||||
set_rows(&mut app, rs);
|
||||
frame(&mut app, &ctx, 0.2, vec![], 0);
|
||||
assert_eq!(fill_hex(&app, blue), "#00ff00", "the art previews the merge");
|
||||
crate::dialogs::confirm(&mut app).unwrap();
|
||||
assert_eq!((fill_hex(&app, red), fill_hex(&app, blue)), ("#ff0000".into(), "#00ff00".into()));
|
||||
assert_eq!(app.session.doc().unwrap().history.undo.len(), undo + 1, "one undo step");
|
||||
}
|
||||
|
||||
const RED: &str = "rgb 255 0 0";
|
||||
const PURPLE: &str = "rgb 128 0 204";
|
||||
const BLUE: &str = "rgb 0 0 255";
|
||||
|
||||
@@ -1981,6 +1981,7 @@ font-technology Variable Променливи
|
||||
Menu Dialog Диалогов прозорец на менюто
|
||||
Merge Сливане
|
||||
Merge colors into one row Сливане на цветовете в един ред
|
||||
New Row Нов ред
|
||||
Merge Graphic Styles Сливане на графични стилове
|
||||
Merge Graphic Styles… Сливане на графични стилове…
|
||||
Merge Layers Сливане на слоеве
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2893,6 +2893,7 @@ digits Malayalam Malajalam
|
||||
Limit to Library: Ograniči na biblioteku:
|
||||
Link harmony colors Poveži boje harmonije
|
||||
Merge colors into one row Spoji boje u jedan red
|
||||
New Row Novi red
|
||||
No colors to recolor (preserved colors are left out). Nema boja za ponovno bojenje (sačuvane boje su izostavljene).
|
||||
Preserve: Očuvaj:
|
||||
Randomly change color order Nasumično promijeni redoslijed boja
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2595,6 +2595,7 @@ digits Malayalam Malaiàlam
|
||||
Menu Dialog Diàleg de menú
|
||||
Merge Fusiona
|
||||
Merge colors into one row Fusiona els colors en una fila
|
||||
New Row Fila nova
|
||||
Merge Graphic Styles Fusiona els estils gràfics
|
||||
Merge Graphic Styles… Fusiona els estils gràfics…
|
||||
Merge Layers Fusiona les capes
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2971,6 +2971,7 @@ digits Malayalam Malajálamské
|
||||
Limit to Library: Omezit na knihovnu:
|
||||
Link harmony colors Propojit barvy harmonie
|
||||
Merge colors into one row Sloučit barvy do jednoho řádku
|
||||
New Row Nový řádek
|
||||
No colors to recolor (preserved colors are left out). Žádné barvy k přebarvení (zachované barvy jsou vynechány).
|
||||
Preserve: Zachovat:
|
||||
Randomly change color order Náhodně změnit pořadí barev
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -3363,6 +3363,7 @@ digits Malayalam Malayalam
|
||||
Limit to Library: Begræns til bibliotek:
|
||||
Link harmony colors Sammenkæd harmonifarver
|
||||
Merge colors into one row Flet farver til én række
|
||||
New Row Ny række
|
||||
No colors to recolor (preserved colors are left out). Ingen farver at omfarve (bevarede farver er udeladt).
|
||||
Preserve: Bevar:
|
||||
Randomly change color order Ændr farverækkefølgen tilfældigt
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2057,6 +2057,7 @@ file-filter Templates Vorlagen
|
||||
Menu Dialog Menüdialog
|
||||
Merge Zusammenfügen
|
||||
Merge colors into one row Farben in einer Zeile zusammenführen
|
||||
New Row Neue Zeile
|
||||
Merge Graphic Styles Grafikstile zusammenfügen
|
||||
Merge Graphic Styles… Grafikstile zusammenfügen…
|
||||
Merge Layers Ebenen zusammenfügen
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -3034,6 +3034,7 @@ theme Appearance Εμφάνιση
|
||||
Menu Dialog Παράθυρο μενού
|
||||
Merge Συγχώνευση
|
||||
Merge colors into one row Συγχώνευση χρωμάτων σε μία γραμμή
|
||||
New Row Νέα γραμμή
|
||||
Merge Graphic Styles Συγχώνευση στυλ γραφικών
|
||||
Merge Graphic Styles… Συγχώνευση στυλ γραφικών…
|
||||
Merge Selected Συγχώνευση επιλεγμένων
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2051,6 +2051,7 @@ font-technology Variable Variables
|
||||
Menu Dialog Cuadro de diálogo de menú
|
||||
Merge Combinar
|
||||
Merge colors into one row Combinar colores en una fila
|
||||
New Row Nueva fila
|
||||
Merge Graphic Styles Combinar estilos gráficos
|
||||
Merge Graphic Styles… Combinar estilos gráficos…
|
||||
Merge Layers Combinar capas
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2915,6 +2915,7 @@ digits Malayalam Malajalam
|
||||
Limit to Library: Rajoita kirjastoon:
|
||||
Link harmony colors Linkitä harmoniavärit
|
||||
Merge colors into one row Yhdistä värit yhdelle riville
|
||||
New Row Uusi rivi
|
||||
No colors to recolor (preserved colors are left out). Ei uudelleenväritettäviä värejä (säilytetyt värit jätetään pois).
|
||||
Preserve: Säilytä:
|
||||
Randomly change color order Muuta värijärjestystä satunnaisesti
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -2045,6 +2045,7 @@ font-technology Variable Variables
|
||||
Menu Dialog Boîte de dialogue du menu
|
||||
Merge Fusionner
|
||||
Merge colors into one row Fusionner les couleurs sur une ligne
|
||||
New Row Nouvelle ligne
|
||||
Merge Graphic Styles Fusionner les styles graphiques
|
||||
Merge Graphic Styles… Fusionner les styles graphiques…
|
||||
Merge Layers Fusionner les calques
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2142,6 +2142,7 @@
|
||||
Merge Shared Edge શેર કરેલી કિનાર મર્જ કરો
|
||||
Merge Swatches સ્વેચ મર્જ કરો
|
||||
Merge colors into one row રંગોને એક હરોળમાં મર્જ કરો
|
||||
New Row નવી હરોળ
|
||||
Merge only with selection માત્ર પસંદગી સાથે મર્જ કરો
|
||||
Merged PRs મર્જ થયેલા PR
|
||||
Mesh Point Color મેશ બિંદુનો રંગ
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 72 and column 5.
|
@@ -2853,6 +2853,7 @@ antiAlias Sharp शार्प
|
||||
Menu Dialog मेन्यू डायलॉग
|
||||
Merge मर्ज करें
|
||||
Merge colors into one row रंगों को एक पंक्ति में मिलाएं
|
||||
New Row नई पंक्ति
|
||||
Merge Graphic Styles मर्ज ग्राफिक स्टाइल्स
|
||||
Merge Graphic Styles… मर्ज ग्राफिक स्टाइल्स…
|
||||
Merge Layers लेयर्स मर्ज करें
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2563,6 +2563,7 @@ file-filter Templates Sablonok
|
||||
Menu Dialog Menü párbeszédablaka
|
||||
Merge Összeolvasztás
|
||||
Merge colors into one row Színek egyesítése egy sorba
|
||||
New Row Új sor
|
||||
Merge Graphic Styles Grafikai stílusok egyesítése
|
||||
Merge Graphic Styles… Grafikai stílusok egyesítése…
|
||||
Merge Layers Rétegek egyesítése
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2711,6 +2711,7 @@ digits Malayalam Malayalam
|
||||
Limit to Library: Batasi ke pustaka:
|
||||
Link harmony colors Tautkan warna harmoni
|
||||
Merge colors into one row Gabungkan warna ke dalam satu baris
|
||||
New Row Baris baru
|
||||
No colors to recolor (preserved colors are left out). Tidak ada warna untuk diwarnai ulang (warna yang dipertahankan dikesampingkan).
|
||||
Preserve: Pertahankan:
|
||||
Randomly change color order Ubah urutan warna secara acak
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2459 and column 5.
|
@@ -2089,6 +2089,7 @@ file-filter Templates Modelli
|
||||
Menu Dialog Finestra di dialogo menu
|
||||
Merge Fondi
|
||||
Merge colors into one row Unisci colori in una riga
|
||||
New Row Nuova riga
|
||||
Merge Graphic Styles Unisci stili grafici
|
||||
Merge Graphic Styles… Unisci stili grafici…
|
||||
Merge Layers Unisci livelli
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2322,6 +2322,7 @@ antiAlias Sharp シャープ
|
||||
Merge Selected 選択レイヤーを結合
|
||||
Merge Swatches スウォッチを統合
|
||||
Merge colors into one row カラーを 1 行に統合
|
||||
New Row 新規行
|
||||
Mesh Tool メッシュツール
|
||||
Message: メッセージ:
|
||||
Metadata: メタデータ:
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2669,6 +2669,7 @@ digits Malayalam მალაიალამური
|
||||
Limit to Library: ბიბლიოთეკით შეზღუდვა:
|
||||
Link harmony colors ჰარმონიის ფერების დაკავშირება
|
||||
Merge colors into one row ფერების ერთ სტრიქონში შერწყმა
|
||||
New Row ახალი სტრიქონი
|
||||
No colors to recolor (preserved colors are left out). ხელახლა შესაფერადებელი ფერები არ არის (შენარჩუნებული ფერები გამოტოვებულია).
|
||||
Preserve: შენარჩუნება:
|
||||
Randomly change color order ფერების რიგის შემთხვევითი შეცვლა
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2312,6 +2312,7 @@ antiAlias Sharp 날카롭게
|
||||
Merge Selected 선택 항목 병합
|
||||
Merge Swatches 견본 병합
|
||||
Merge colors into one row 색상을 한 행으로 병합
|
||||
New Row 새 행
|
||||
Mesh Tool 메시 도구
|
||||
Message: 메시지:
|
||||
Metadata: 메타데이터:
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -3271,6 +3271,7 @@ digits Malayalam Malayalam
|
||||
Limit to Library: Beperken tot bibliotheek:
|
||||
Link harmony colors Harmoniekleuren koppelen
|
||||
Merge colors into one row Kleuren samenvoegen in één rij
|
||||
New Row Nieuwe rij
|
||||
No colors to recolor (preserved colors are left out). Geen kleuren om opnieuw te kleuren (behouden kleuren zijn weggelaten).
|
||||
Preserve: Behouden:
|
||||
Randomly change color order Kleurvolgorde willekeurig wijzigen
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2880,6 +2880,7 @@ digits Malayalam Malajalam
|
||||
Limit to Library: Ogranicz do biblioteki:
|
||||
Link harmony colors Połącz kolory harmonii
|
||||
Merge colors into one row Scal kolory w jeden wiersz
|
||||
New Row Nowy wiersz
|
||||
No colors to recolor (preserved colors are left out). Brak kolorów do zmiany (zachowane kolory są pomijane).
|
||||
Preserve: Zachowaj:
|
||||
Randomly change color order Losowo zmień kolejność kolorów
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1727,6 +1727,7 @@ antiAlias Sharp Nítido
|
||||
Merge Layers Mesclar Camadas
|
||||
Merge Swatches Mesclar Amostras
|
||||
Merge colors into one row Mesclar cores em uma linha
|
||||
New Row Nova linha
|
||||
Mesh Tool Ferramenta Malha
|
||||
Message: Mensagem:
|
||||
Metadata: Metadados:
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2078,6 +2078,7 @@ file-filter Templates Шаблоны
|
||||
Menu Dialog Диалоговое окно меню
|
||||
Merge Объединить
|
||||
Merge colors into one row Объединить цвета в одну строку
|
||||
New Row Новая строка
|
||||
Merge Graphic Styles Объединить графические стили
|
||||
Merge Graphic Styles… Объединить графические стили…
|
||||
Merge Layers Объединить слои
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1992,6 +1992,7 @@ font-technology Variable Variabla
|
||||
Menu Dialog Menydialog
|
||||
Merge Sammanfoga
|
||||
Merge colors into one row Sammanfoga färger till en rad
|
||||
New Row Ny rad
|
||||
Merge Graphic Styles Sammanfoga grafikstilar
|
||||
Merge Graphic Styles… Sammanfoga grafikstilar…
|
||||
Merge Layers Sammanfoga lager
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -1883,6 +1883,7 @@ font-technology Variable Değişken
|
||||
Menu Dialog Menü İletişim Kutusu
|
||||
Merge Birleştir
|
||||
Merge colors into one row Renkleri tek satırda birleştirme
|
||||
New Row Yeni satır
|
||||
Merge Graphic Styles Grafik Stillerini Birleştir
|
||||
Merge Graphic Styles… Grafik Stillerini Birleştir…
|
||||
Merge Layers Katmanları Birleştir
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2083,6 +2083,7 @@ file-filter Templates Шаблони
|
||||
Menu Dialog Діалогове вікно меню
|
||||
Merge Об’єднати
|
||||
Merge colors into one row Об’єднати кольори в один рядок
|
||||
New Row Новий рядок
|
||||
Merge Graphic Styles Об’єднати графічні стилі
|
||||
Merge Graphic Styles… Об’єднати графічні стилі…
|
||||
Merge Layers Об’єднати шари
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -2388,6 +2388,7 @@ digits Hindi Hindi
|
||||
Menu Dialog Hộp thoại menu
|
||||
Merge Hợp nhất
|
||||
Merge colors into one row Hợp nhất màu vào một hàng
|
||||
New Row Hàng mới
|
||||
Merge Graphic Styles Hợp nhất kiểu đồ họa
|
||||
Merge Graphic Styles… Hợp nhất kiểu đồ họa…
|
||||
Merge Layers Hợp nhất lớp
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 204 and column 5.
|
@@ -1960,6 +1960,7 @@ file-filter Templates 模板
|
||||
Menu Dialog 菜单对话框
|
||||
Merge 合并
|
||||
Merge colors into one row 将颜色合并为一行
|
||||
New Row 新建行
|
||||
Merge Graphic Styles 合并图形样式
|
||||
Merge Graphic Styles… 合并图形样式…
|
||||
Merge Layers 合并图层
|
||||
|
||||
|
Can't render this file because it is too large.
|
@@ -3147,6 +3147,7 @@ file-filter Templates 範本
|
||||
Menu Dialog 選單對話框
|
||||
Merge 合併
|
||||
Merge colors into one row 將顏色合併為一列
|
||||
New Row 新增列
|
||||
Merge Graphic Styles 合併繪圖樣式
|
||||
Merge Graphic Styles… 合併繪圖樣式…
|
||||
Merge Layers 合併圖層
|
||||
|
||||
|
Can't render this file because it is too large.
|
+5
-1
@@ -4432,7 +4432,11 @@ stay tints), `scaleTints` (every colour becomes a tint as light, relative to the
|
||||
darker than the row's average become tints and shades) or `hueShift` (the most saturated colour takes the new colour,
|
||||
the others turn by the same hue). `limitTo` snaps new colours to a swatch library's nearest colour;
|
||||
`recolor.randomize {map, order?, saturationBrightness?, seed?}` shuffles or varies new colours; a row with
|
||||
`exclude: true` keeps its colours. With `limitTo`, a row's `tint` (a percentage, default 100) gives the art
|
||||
`exclude: true` keeps its colours. A row's `from` may be an empty list: the row recolors nothing, adds no library swatch with
|
||||
`limitTo` and gives `group` no color, and `recolor.randomize` and `recolor.weigh` keep it. A row without `from`, or with
|
||||
a current color that is not a color, is refused. With art selected, the Recolor Artwork dialog's New Row button (beside
|
||||
Merge) adds such a row above the first selected row, or at the top, with that row's new color, and selects it; Shift-click another row and Merge to move its colors into it. An
|
||||
empty row does not count toward Colors. With `limitTo`, a row's `tint` (a percentage, default 100) gives the art
|
||||
linked to the global or spot swatch its new color is that share of its tint; `tint` must be a number. `recolor.randomize`
|
||||
moves a row's `tint` with its new color and removes it from a color it changes, and moves a row's `model` with its new color. `swatch.editGroup {group, colors, rename?}` rewrites a colour group in one undo
|
||||
step (art linked to its global swatches follows), and `recolor.apply` with `group` recolours the art and rewrites the
|
||||
|
||||
@@ -1601,6 +1601,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- **Document Color Mode for effects and graphs:** File › Document Color Mode and `document.open {colorMode}` convert the colors of effects (Drop Shadow, Inner Glow, Outer Glow and the other effects with a color, on objects, their fills and strokes and in graphic styles) and the series paints and label styles that a graph keeps, so a graph drawn again from new data keeps the converted colors; File › Document Color Mode also converts the fill and stroke that new art takes. Undo restores the original new-art fill and stroke and Redo applies the conversion again.
|
||||
- **Recolor Artwork layout (#3416):** the Edit chip list uses the modal scroll helper and its actual remaining height; the tab's minimum-height space scrolls with the chips. `tests_recolor` covers 5/20/200/400 colors, window resizing, 100/125/150/200% UI scaling, scrolling to and editing the final chip, Preview, Cancel, Confirm and Undo, alongside the existing #1733 drag regressions. Scores and estimates unchanged.
|
||||
- **Recolor Artwork Edit displays:** buttons beside the Edit tab's wheel show the colors on a smooth color wheel, a segmented color wheel or as color bars ([Edit colors using Recolor Artwork](https://helpx.adobe.com/illustrator/desktop/manage-colors/modify-colors/edit-colors-using-edit-colors-dialog.html)). The segmented wheel draws 24 hues by 5 saturations as solid patches, and its markers move freely as on the smooth wheel. The bars show one solid bar per recolored color in row order: a click selects a bar for the color sliders, and a drag moves its row without changing a color ([Advanced recolor options overview](https://helpx.adobe.com/illustrator/desktop/manage-colors/learn-color-basics/edit-colors-dialog-overview.html)). The dialog opens on the smooth wheel; `display` (`smooth`, `segmented`, `bars`) is the dialog field. `tests_recolor` covers switching, the dialog height, segmented dragging and Brightness, and bar selection, editing, reordering, scrolling, Preview, Cancel and OK. Scores and estimates unchanged.
|
||||
- **Recolor Artwork New Row:** the Assign tab's New Row button adds a row with no current colors, so current colors can be moved into it and take its new color ([Advanced recolor options overview](https://helpx.adobe.com/illustrator/desktop/manage-colors/learn-color-basics/edit-colors-dialog-overview.html), [Assign new colors to selected artworks](https://helpx.adobe.com/illustrator/desktop/manage-colors/modify-colors/assign-new-colors-to-selected-artwork.html)). VectorCraft's own rules: the row goes above the first selected row (at the top when none is selected) with that row's new color and becomes the selection, and Merge with it as the first selected row moves the other rows' colors into it. The button needs selected art. An empty row recolors nothing, does not count toward Colors, adds no library swatch and gives a rewritten color group no color. Tests: `a_new_row_goes_above_the_selection_and_takes_merged_colors`, `an_empty_row_gives_the_group_no_color` and `colors_merged_into_a_new_row_take_its_new_color` in `crates/ui-egui/src/dialogs/recolor.rs`, `an_empty_row_recolors_nothing` and `an_empty_row_adds_no_swatch_and_no_group_color` in `crates/engine/src/tests/recolor.rs`.
|
||||
- **Edit Colors parameters:** `edit.colors.saturate` needs a number `intensity`, the value from -100% to 100% that Saturate takes ([Adjusting colors](https://web.archive.org/web/20230128232631/https://helpx.adobe.com/illustrator/using/adjusting-colors.html)), and answers "missing number `intensity`" without one; a number outside the range counts as its nearest end. A value that is not a number, such as `"40"`, is refused with `` `intensity` must be a number, not "40" ``, as in every command that needs a number (`tests::params::a_malformed_required_number_is_not_reported_as_missing`). `edit.colors.adjustBalance` refuses a channel and `color.harmony` refuses `steps` or `amount` that is not a number; both read `null` as a value left out. `tests::editcolors` and `tests::colorguide` cover them.
|
||||
- **Convert to Indexed Color:** Edit › Edit Colors › Convert to Indexed Color… (`edit.colors.toIndexed`) stores the embedded images in the selection as indexed-color PNGs of at most 256 colors. The palette is chosen as for a PNG-8 export, as evenly spaced levels of red, green and blue, or from the document's swatches, with diffusion, pattern or noise dithering; pixels under half opacity become transparent. The dialog previews live, and OK is one undo step. This is VectorCraft's own command and counts toward no score. `tests::editcolors` and `encode::tests_palette` cover it. Scores and estimates unchanged.
|
||||
- **Working RGB numeric controls:** the Color panel and Color Picker read RGB, HSB, hex and Web Safe RGB values in the active working RGB space. Editing one RGB channel preserves the other native channels, including colors outside display sRGB. Regressions cover sRGB, Display P3, Wide Gamut RGB and ProPhoto RGB, picker initialization, native numeric round trips, and a slider click with one Undo step. Scores and estimates unchanged.
|
||||
|
||||
Reference in New Issue
Block a user