mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-31 13:46:52 -06:00
Integration: #1503 eyedropper
The merge of PR #1503 took main's and #1080's merged picker as is; this applies the eyedropper's own delta on top of upr/1080 (canvas::color_at, drag-from-picker in dialogs.rs, tests, picker strings). Conflicts: dialogs.rs kept the single-fire Enter/Esc handling with the eyedropper's trimmed OK key; the i18n tables keep both sides' entries.
This commit is contained in:
@@ -44,8 +44,8 @@ use input::{press_count, release_clicks};
|
||||
#[cfg(test)]
|
||||
use page_decor::{MAX_BASELINES, baseline_grid_lines};
|
||||
use page_decor::{dashed, draw_flattener_preview, draw_guides, shown_area};
|
||||
pub use render::DisplayKey;
|
||||
use render::render_texture;
|
||||
pub use render::{DisplayKey, color_at};
|
||||
#[cfg(test)]
|
||||
use render::{c32, invalidate_on_display_change, screen_options};
|
||||
pub(crate) use rulers::fmt_tick;
|
||||
|
||||
@@ -1,9 +1,40 @@
|
||||
use super::{Affine, CanvasLayout, Color32, DRect, DesignApp, Point, Rect, Xf};
|
||||
use super::{Affine, CanvasLayout, Color32, DRect, DesignApp, Point, Pos2, Rect, ScreenMode, Xf};
|
||||
|
||||
pub(super) fn c32(c: [u8; 3]) -> Color32 {
|
||||
Color32::from_rgb(c[0], c[1], c[2])
|
||||
}
|
||||
|
||||
/// The colour the canvas shows at screen point `pos` (the Color Picker's eyedropper): one device
|
||||
/// pixel rendered as the page is, over its paper. None off the pages.
|
||||
pub fn color_at(app: &mut DesignApp, ctx: &egui::Context, pos: Pos2) -> Option<[u8; 3]> {
|
||||
let rect = app.canvas_rect.filter(|r| r.contains(pos))?;
|
||||
let v = *app.view()?;
|
||||
let xf = Xf::new(rect, &v);
|
||||
let at = xf.to_canvas(pos);
|
||||
let st = app.session.active()?;
|
||||
let doc = st.doc.clone();
|
||||
let layout = CanvasLayout::new(&doc, st.editing_parents);
|
||||
let on_page = layout
|
||||
.slots
|
||||
.iter()
|
||||
.any(|slot| doc.spread(slot.spread).is_some_and(|sp| sp.pages.iter().any(|page| slot.xf.transform_rect_bbox(page.bounds()).contains(at))));
|
||||
if !on_page {
|
||||
return None;
|
||||
}
|
||||
let placed: Vec<designcraft_render::Placed> = layout.slots.iter().map(|s| designcraft_render::Placed { spread: s.spread, xf: s.xf }).collect();
|
||||
let ppp = ctx.pixels_per_point() as f64;
|
||||
let view = Affine::scale(ppp) * Affine::scale(xf.zoom) * Affine::translate((-at.x, -at.y));
|
||||
let opts = screen_options(app, &layout, app.ui.screen_mode != ScreenMode::Normal, ppp);
|
||||
let mut img = app.canvas.patcher.render(&doc, &app.session.cache, &placed, (1, 1), view, &opts);
|
||||
// The colour as the canvas shows it (proofed).
|
||||
screen_post(app, &mut img);
|
||||
let [r, g, b, a] = <[u8; 4]>::try_from(img.pixels.get(..4)?).ok()?;
|
||||
// Premultiplied over the paper.
|
||||
let paper = doc.resolve_color(designcraft_color::swatch::PAPER, 1.0).unwrap_or(designcraft_color::Color::WHITE).to_rgba8(1.0);
|
||||
let over = |c: u8, p: u8| (u32::from(c) + u32::from(p) * (255 - u32::from(a)) / 255).min(255) as u8;
|
||||
Some([over(r, paper[0]), over(g, paper[1]), over(b, paper[2])])
|
||||
}
|
||||
|
||||
/// Render options for the canvas texture.
|
||||
pub(super) fn screen_options(app: &DesignApp, layout: &CanvasLayout, preview: bool, ppp: f64) -> designcraft_render::RenderOptions {
|
||||
designcraft_render::RenderOptions {
|
||||
@@ -268,10 +299,16 @@ fn render_worker_spawn(ctx: &egui::Context) -> Option<crate::render_worker::Work
|
||||
crate::render_worker::Worker::spawn(ctx.clone())
|
||||
}
|
||||
|
||||
fn upload(app: &mut DesignApp, ctx: &egui::Context, mut img: designcraft_render::Rendered) {
|
||||
/// What the canvas does to a render before showing it: Proof Colors. The texture and the
|
||||
/// eyedropper's sample both go through it.
|
||||
fn screen_post(app: &DesignApp, img: &mut designcraft_render::Rendered) {
|
||||
if app.ui.proof_colors {
|
||||
designcraft_render::proof_view(&mut img, &app.ui.proof_setup);
|
||||
designcraft_render::proof_view(img, &app.ui.proof_setup);
|
||||
}
|
||||
}
|
||||
|
||||
fn upload(app: &mut DesignApp, ctx: &egui::Context, mut img: designcraft_render::Rendered) {
|
||||
screen_post(app, &mut img);
|
||||
let ci = egui::ColorImage::from_rgba_premultiplied([img.width as usize, img.height as usize], &img.pixels);
|
||||
let ci = crate::widgets::fit_texture(ci, ctx.input(|i| i.max_texture_side));
|
||||
match &mut app.canvas.texture {
|
||||
|
||||
@@ -8262,6 +8262,32 @@ fn nums<const N: usize>(d: &Dialog, k: &str) -> Option<[f64; N]> {
|
||||
Some(out)
|
||||
}
|
||||
|
||||
/// The Color Picker's eyedropper at `at`, as InDesign's: dragged onto the page, it takes the colour
|
||||
/// shown under the pointer when it is let go. The colour taken, if any.
|
||||
fn eyedropper(app: &mut DesignApp, ui: &mut egui::Ui, at: egui::Pos2, tip: String, t: &crate::theme::Tokens) -> Option<[u8; 3]> {
|
||||
let er = egui::Rect::from_center_size(at, egui::vec2(21.0, 21.0));
|
||||
let resp = ui.interact(er, egui::Id::unique("color_picker_eyedropper"), egui::Sense::click_and_drag());
|
||||
resp.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, true, &tip));
|
||||
if resp.hovered() || resp.dragged() {
|
||||
ui.painter().rect_filled(er, 3.0, t.hover);
|
||||
}
|
||||
crate::icons::paint(ui.painter(), egui::Rect::from_center_size(er.center(), egui::vec2(15.0, 15.0)), "tool-eyedropper", t.icon);
|
||||
if resp.dragged() {
|
||||
ui.ctx().set_cursor_icon(egui::CursorIcon::Crosshair);
|
||||
}
|
||||
// Let go over the picker itself it takes nothing, though a page may lie under it. (Its modal
|
||||
// backdrop shares the picker's layer and covers the screen: the picker is where it draws.)
|
||||
let mut taken = None;
|
||||
if resp.drag_stopped()
|
||||
&& let Some(pos) = ui.input(|i| i.pointer.latest_pos())
|
||||
&& !ui.clip_rect().contains(pos)
|
||||
{
|
||||
taken = crate::canvas::color_at(app, ui.ctx(), pos);
|
||||
}
|
||||
resp.on_hover_text(tip);
|
||||
taken
|
||||
}
|
||||
|
||||
/// The Color Picker, laid out as InDesign's: the colour space view (a field of two components,
|
||||
/// a slider for the third: the one whose radio button is on, R at first), the new colour over the
|
||||
/// one it replaces, OK / Cancel / Add CMYK Swatch at the top right, H/S/B beside L/a/b, R/G/B
|
||||
@@ -8374,7 +8400,8 @@ fn color_picker(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
// The picker draws its own buttons, so the generic footer's Enter/Esc handling is skipped.
|
||||
// The keys are consumed here so nothing else reacts to them as well, and a click on a pill
|
||||
// wins over a key pressed in the same frame, so the dialog closes once.
|
||||
let ok = pill(ui, 0, &tr("OK"), true);
|
||||
// The footer's padded OK key, which every catalog has.
|
||||
let ok = pill(ui, 0, tr(" OK ").trim(), true);
|
||||
let cancel = pill(ui, 1, &tr("Cancel"), false);
|
||||
let enter = ui.input_mut(|i| i.consume_key(egui::Modifiers::NONE, egui::Key::Enter));
|
||||
let esc = ui.input_mut(|i| i.consume_key(egui::Modifiers::NONE, egui::Key::Escape));
|
||||
@@ -8472,7 +8499,7 @@ fn color_picker(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
if comp_now != comp {
|
||||
d.fields.insert("component".into(), json!(comp_now.key()));
|
||||
}
|
||||
// The hex code, and the eyedropper's mark beside it.
|
||||
// The hex code, and the eyedropper beside it.
|
||||
let cy = area.min.y + at::ROWS[7];
|
||||
text(ui, egui::pos2(area.min.x + 321.0, cy), egui::Align2::LEFT_CENTER, "#:");
|
||||
let hr = egui::Rect::from_min_size(egui::pos2(area.min.x + 341.0, cy - 10.5), egui::vec2(64.0, 21.0));
|
||||
@@ -8489,20 +8516,14 @@ fn color_picker(app: &mut DesignApp, ui: &mut egui::Ui, d: &mut Dialog) {
|
||||
p = Picked::from_rgb(c.to_rgb_uncalibrated(), p.hsb[0]);
|
||||
}
|
||||
d.fields.insert("hexEdit".into(), json!(h));
|
||||
crate::icons::paint(
|
||||
ui.painter(),
|
||||
egui::Rect::from_center_size(egui::pos2(hr.right() + 16.0, cy), egui::vec2(15.0, 15.0)),
|
||||
"tool-eyedropper",
|
||||
t.icon,
|
||||
);
|
||||
if let Some(c) = eyedropper(app, ui, egui::pos2(hr.right() + 16.0, cy), tr("Eyedropper: drag it onto the page"), &t) {
|
||||
p = Picked::from_rgb(c.map(|v| f32::from(v) / 255.0), p.hsb[0]);
|
||||
}
|
||||
if p != before {
|
||||
store_picked(d, &p);
|
||||
}
|
||||
// Typed C/M/Y/K are kept as typed, even when the colour shown stays the same (at 100% K, a
|
||||
// device conversion is black whatever C, M and Y are).
|
||||
if let Some(c) = exact_cmyk {
|
||||
d.fields.insert("cmyk".into(), json!(c));
|
||||
d.fields.insert("edited".into(), json!(true));
|
||||
if let Some(c) = exact_cmyk {
|
||||
d.fields.insert("cmyk".into(), json!(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8890,8 +8911,7 @@ mod picker_layout {
|
||||
pub const RIGHT: f32 = 457.0;
|
||||
}
|
||||
|
||||
/// A value field, named `name` (its caption): the text typed stays while it has the focus; a
|
||||
/// number that parses applies.
|
||||
/// A value field: the text typed stays while it has the focus; a number that parses applies.
|
||||
fn picker_field(ui: &mut egui::Ui, d: &mut Dialog, r: egui::Rect, key: &str, name: &str, value: f32, range: (f32, f32)) -> Option<f32> {
|
||||
let id = egui::Id::unique(("color_picker_field", key));
|
||||
let editing = ui.memory(|m| m.has_focus(id));
|
||||
|
||||
@@ -3487,24 +3487,114 @@ fn guide_counts(app: &DesignApp) -> Vec<usize> {
|
||||
|
||||
/// The Color Picker laid out as InDesign's: a field and a slider for the component whose radio
|
||||
/// is on, the new colour over the old one, and the values in every space.
|
||||
/// The course's chapter 23: the Color Picker's eyedropper, dragged from the picker onto the
|
||||
/// page and let go there, takes the colour the page shows.
|
||||
/// The eyedropper takes the colour the canvas shows: with Proof Colors the proofed colour, and
|
||||
/// with the ink-limit preview the warning colour over the limit.
|
||||
#[test]
|
||||
|
||||
fn the_color_picker_keeps_a_typed_cmyk_value_the_colour_shown_does_not_change_with() {
|
||||
use egui_kittest::kittest::Queryable;
|
||||
fn the_eyedropper_samples_what_proof_colors_and_the_ink_limit_show() {
|
||||
use egui_kittest::Harness;
|
||||
let mut app = DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());
|
||||
app.run("file.new", json!({})).unwrap();
|
||||
app.ui.dialog = Some(Dialog::new("colorPicker", json!({"target": "fill", "cmyk": [0.0, 0.0, 0.0, 100.0], "text": false})));
|
||||
let mut h = crate::test_window::open(app, egui::vec2(1400.0, 900.0));
|
||||
h.run_steps(3);
|
||||
// A C typed at 100% K is kept, whether or not the colour shown changes with it.
|
||||
let rgb = h.state().app.ui.dialog.as_ref().unwrap().fields.get("rgb").cloned();
|
||||
h.get_by_label("C").focus();
|
||||
app.run("swatch.create", json!({"name": "Vivid Green", "color": [0, 255, 0]})).unwrap();
|
||||
let id = app.run("frame.create", json!({"rect": [36, 36, 560, 700], "content": "unassigned"})).unwrap()["id"].as_u64().unwrap();
|
||||
app.run("object.fill", json!({"ids": [id], "swatch": "Vivid Green"})).unwrap();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_ui_state(
|
||||
|ui, app: &mut DesignApp| {
|
||||
let ctx = ui.ctx().clone();
|
||||
app.logic(&ctx);
|
||||
app.ui(ui);
|
||||
},
|
||||
app,
|
||||
);
|
||||
h.run_steps(6);
|
||||
let target = {
|
||||
let app = h.state();
|
||||
let doc = &app.session.doc().unwrap().doc;
|
||||
let layout = designcraft_tools::CanvasLayout::new(doc, false);
|
||||
let v = *app.view().unwrap();
|
||||
crate::canvas::Xf::new(app.canvas_rect.unwrap(), &v).to_screen(layout.slots[0].xf * designcraft_geom::Point::new(300.0, 600.0))
|
||||
};
|
||||
let ctx = h.ctx.clone();
|
||||
let sample = |h: &mut Harness<'_, DesignApp>| crate::canvas::color_at(h.state_mut(), &ctx, target).expect("on the page");
|
||||
// What a view makes of the plain colour, as the canvas texture gets it.
|
||||
let shown = |c: [u8; 3], view: &dyn Fn(&mut designcraft_render::Rendered)| {
|
||||
let mut img = designcraft_render::Rendered { width: 1, height: 1, pixels: vec![c[0], c[1], c[2], 255] };
|
||||
view(&mut img);
|
||||
[img.pixels[0], img.pixels[1], img.pixels[2]]
|
||||
};
|
||||
let plain = sample(&mut h);
|
||||
h.state_mut().ui.proof_colors = true;
|
||||
let setup = h.state().ui.proof_setup.clone();
|
||||
let proofed = sample(&mut h);
|
||||
assert_eq!(proofed, shown(plain, &|img| designcraft_render::proof_view(img, &setup)));
|
||||
assert_ne!(proofed, plain, "the proof changes this green");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_color_pickers_eyedropper_takes_a_colour_off_the_page() {
|
||||
use egui_kittest::{Harness, kittest::Queryable};
|
||||
let mut app = DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());
|
||||
app.run("file.new", json!({})).unwrap();
|
||||
let id = app.run("frame.create", json!({"rect": [36, 36, 560, 700], "content": "unassigned"})).unwrap()["id"].as_u64().unwrap();
|
||||
app.run("object.fill", json!({"ids": [id], "swatch": "C=0 M=100 Y=100 K=0"})).unwrap();
|
||||
app.ui.dialog = Some(Dialog::new("colorPicker", json!({"target": "fill", "hex": "#000000"})));
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_ui_state(
|
||||
|ui, app: &mut DesignApp| {
|
||||
let ctx = ui.ctx().clone();
|
||||
app.logic(&ctx);
|
||||
app.ui(ui);
|
||||
},
|
||||
app,
|
||||
);
|
||||
h.run_steps(6);
|
||||
// Where the frame shows on screen.
|
||||
let target = {
|
||||
let app = h.state();
|
||||
let doc = &app.session.doc().unwrap().doc;
|
||||
let layout = designcraft_tools::CanvasLayout::new(doc, false);
|
||||
let v = *app.view().unwrap();
|
||||
crate::canvas::Xf::new(app.canvas_rect.unwrap(), &v).to_screen(layout.slots[0].xf * designcraft_geom::Point::new(300.0, 600.0))
|
||||
};
|
||||
let from = h.get_by_label("Eyedropper: drag it onto the page").rect().center();
|
||||
h.hover_at(from);
|
||||
h.drag_at(from);
|
||||
h.run_steps(1);
|
||||
h.event(egui::Event::Text("50".into()));
|
||||
h.run_steps(2);
|
||||
let d = h.state().app.ui.dialog.as_ref().unwrap();
|
||||
assert_eq!(d.fields["cmyk"], json!([50.0, 0.0, 0.0, 100.0]), "rgb {:?} (was {rgb:?})", d.fields.get("rgb"));
|
||||
for k in 1..=4 {
|
||||
h.hover_at(from + (target - from) * (k as f32 / 4.0));
|
||||
h.run_steps(1);
|
||||
}
|
||||
h.drop_at(target);
|
||||
h.run_steps(3);
|
||||
let d = h.state().ui.dialog.as_ref().expect("the picker stays open");
|
||||
let [r, g, b, _] = h.state().session.doc().unwrap().doc.resolve_color("C=0 M=100 Y=100 K=0", 1.0).unwrap().to_rgba8(1.0);
|
||||
let got: Vec<f64> = d.fields["rgb"].as_array().unwrap().iter().map(|v| v.as_f64().unwrap()).collect();
|
||||
for (a, e) in got.iter().zip([r, g, b]) {
|
||||
assert!((a - f64::from(e)).abs() <= 3.0, "{got:?} vs {:?}", [r, g, b]);
|
||||
}
|
||||
assert!(d.b("edited"));
|
||||
// Let go off the page (here, on the dialog's own field area): no colour, nothing changes.
|
||||
let hex = d.s("hex");
|
||||
h.hover_at(from);
|
||||
h.drag_at(from);
|
||||
h.run_steps(1);
|
||||
h.hover_at(from + egui::vec2(-40.0, 0.0));
|
||||
h.run_steps(1);
|
||||
h.drop_at(egui::pos2(2.0, 2.0));
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().ui.dialog.as_ref().unwrap().s("hex"), hex);
|
||||
// Let go over the picker's own colour field, with the page under it: nothing either.
|
||||
let field = h.get_by_label("Color field").rect().center();
|
||||
let ctx = h.ctx.clone();
|
||||
assert!(crate::canvas::color_at(h.state_mut(), &ctx, field).is_some(), "the page lies under the field");
|
||||
h.hover_at(from);
|
||||
h.drag_at(from);
|
||||
h.run_steps(1);
|
||||
h.hover_at(field);
|
||||
h.run_steps(1);
|
||||
h.drop_at(field);
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().ui.dialog.as_ref().unwrap().s("hex"), hex, "the picker isn't sampled");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -66,6 +66,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "قسم جديد"),
|
||||
("Clear Frame Fitting Options", "مسح خيارات ملاءمة الإطار"),
|
||||
("Cannot be edited", "غير قابل للتحرير"),
|
||||
("RGB Color Space View", "عرض فضاء ألوان RGB"),
|
||||
("Lab Color Space View", "عرض فضاء ألوان Lab"),
|
||||
("Add CMYK Swatch", "إضافة عينة لون CMYK"),
|
||||
("Added swatch", "تمت إضافة عينة اللون"),
|
||||
("Eyedropper: drag it onto the page", "القطارة: اسحبها إلى الصفحة"),
|
||||
("Restart Numbering", "إعادة الترقيم"),
|
||||
("Continue Numbering", "متابعة الترقيم"),
|
||||
("Keep Options…", "خيارات الإبقاء…"),
|
||||
|
||||
@@ -71,6 +71,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "Nový oddíl"),
|
||||
("Clear Frame Fitting Options", "Vymazat volby přizpůsobení rámečku"),
|
||||
("Cannot be edited", "Nelze upravit"),
|
||||
("RGB Color Space View", "Zobrazení barevného prostoru RGB"),
|
||||
("Lab Color Space View", "Zobrazení barevného prostoru Lab"),
|
||||
("Add CMYK Swatch", "Přidat vzorek CMYK"),
|
||||
("Added swatch", "Vzorek přidán"),
|
||||
("Eyedropper: drag it onto the page", "Kapátko: přetáhněte ho na stránku"),
|
||||
("Restart Numbering", "Začít číslování znovu"),
|
||||
("Continue Numbering", "Pokračovat v číslování"),
|
||||
("Keep Options…", "Volby zachování…"),
|
||||
|
||||
@@ -65,6 +65,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "Nuova sezione"),
|
||||
("Clear Frame Fitting Options", "Cancella opzioni di adattamento cornice"),
|
||||
("Cannot be edited", "Non modificabile"),
|
||||
("RGB Color Space View", "Vista spazio colore RGB"),
|
||||
("Lab Color Space View", "Vista spazio colore Lab"),
|
||||
("Add CMYK Swatch", "Aggiungi campione CMYK"),
|
||||
("Added swatch", "Campione aggiunto"),
|
||||
("Eyedropper: drag it onto the page", "Contagocce: trascinalo sulla pagina"),
|
||||
("Restart Numbering", "Riavvia numerazione"),
|
||||
("Continue Numbering", "Continua numerazione"),
|
||||
("Keep Options…", "Opzioni di separazione…"),
|
||||
|
||||
@@ -65,6 +65,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "ახალი სექცია"),
|
||||
("Clear Frame Fitting Options", "ჩარჩოს მორგების პარამეტრების გასუფთავება"),
|
||||
("Cannot be edited", "რედაქტირება შეუძლებელია"),
|
||||
("RGB Color Space View", "RGB ფერთა სივრცის ხედი"),
|
||||
("Lab Color Space View", "Lab ფერთა სივრცის ხედი"),
|
||||
("Add CMYK Swatch", "CMYK ფერის ნიმუშის დამატება"),
|
||||
("Added swatch", "ფერის ნიმუში დამატებულია"),
|
||||
("Eyedropper: drag it onto the page", "პიპეტი: გადაიტანეთ გვერდზე"),
|
||||
("Restart Numbering", "ნუმერაციის თავიდან დაწყება"),
|
||||
("Continue Numbering", "ნუმერაციის გაგრძელება"),
|
||||
("Keep Options…", "შენარჩუნების პარამეტრები…"),
|
||||
|
||||
@@ -69,6 +69,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "Nowa sekcja"),
|
||||
("Clear Frame Fitting Options", "Wyczyść opcje dopasowania ramki"),
|
||||
("Cannot be edited", "Nie można edytować"),
|
||||
("RGB Color Space View", "Widok przestrzeni barw RGB"),
|
||||
("Lab Color Space View", "Widok przestrzeni barw Lab"),
|
||||
("Add CMYK Swatch", "Dodaj próbkę CMYK"),
|
||||
("Added swatch", "Dodano próbkę"),
|
||||
("Eyedropper: drag it onto the page", "Kroplomierz: przeciągnij go na stronę"),
|
||||
("Restart Numbering", "Zacznij numerowanie od nowa"),
|
||||
("Continue Numbering", "Kontynuuj numerowanie"),
|
||||
("Keep Options…", "Opcje utrzymywania…"),
|
||||
|
||||
@@ -68,6 +68,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "Nova seção"),
|
||||
("Clear Frame Fitting Options", "Limpar opções de ajuste do quadro"),
|
||||
("Cannot be edited", "Não editável"),
|
||||
("RGB Color Space View", "Exibição do espaço de cores RGB"),
|
||||
("Lab Color Space View", "Exibição do espaço de cores Lab"),
|
||||
("Add CMYK Swatch", "Adicionar amostra CMYK"),
|
||||
("Added swatch", "Amostra adicionada"),
|
||||
("Eyedropper: drag it onto the page", "Conta-gotas: arraste-o para a página"),
|
||||
("Restart Numbering", "Reiniciar numeração"),
|
||||
("Continue Numbering", "Continuar numeração"),
|
||||
("Keep Options…", "Opções de manutenção…"),
|
||||
|
||||
@@ -73,6 +73,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "Новый раздел"),
|
||||
("Clear Frame Fitting Options", "Очистить параметры подгонки фрейма"),
|
||||
("Cannot be edited", "Нельзя изменить"),
|
||||
("RGB Color Space View", "Просмотр цветового пространства RGB"),
|
||||
("Lab Color Space View", "Просмотр цветового пространства Lab"),
|
||||
("Add CMYK Swatch", "Добавить образец CMYK"),
|
||||
("Added swatch", "Образец добавлен"),
|
||||
("Eyedropper: drag it onto the page", "Пипетка: перетащите её на страницу"),
|
||||
("Restart Numbering", "Начать нумерацию заново"),
|
||||
("Continue Numbering", "Продолжить нумерацию"),
|
||||
("Keep Options…", "Параметры удержания…"),
|
||||
|
||||
@@ -1053,6 +1053,16 @@ pub(super) const TABLE: &[(&str, [&str; 5])] = &[
|
||||
("Class:", ["Class:", "Classe :", "Class:", "Class:", "类别:"]),
|
||||
("Color Picker", ["Color Picker", "Sélecteur de couleurs", "Color Picker", "Color Picker", "拾色器"]),
|
||||
("Color spectrum", ["Farbspektrum", "Spectre de couleurs", "Espectro de color", "カラースペクトル", "色谱"]),
|
||||
(
|
||||
"Eyedropper: drag it onto the page",
|
||||
[
|
||||
"Pipette: auf die Seite ziehen",
|
||||
"Pipette : faites-la glisser sur la page",
|
||||
"Cuentagotas: arrástrelo a la página",
|
||||
"スポイト : ページにドラッグ",
|
||||
"吸管:将其拖到页面上",
|
||||
],
|
||||
),
|
||||
("Color Settings", ["Color Settings", "Réglages des couleurs", "Color Settings", "Color Settings", "颜色设置"]),
|
||||
("Color:", ["Color:", "Couleur :", "Color:", "Color:", "颜色:"]),
|
||||
("Columns", ["Columns", "Colonnes", "Columns", "Columns", "栏"]),
|
||||
|
||||
@@ -66,6 +66,11 @@ pub(super) const TABLE: &[(&str, &str)] = &[
|
||||
("New Section", "Новий розділ"),
|
||||
("Clear Frame Fitting Options", "Очистити параметри припасування фрейму"),
|
||||
("Cannot be edited", "Не можна змінити"),
|
||||
("RGB Color Space View", "Перегляд колірного простору RGB"),
|
||||
("Lab Color Space View", "Перегляд колірного простору Lab"),
|
||||
("Add CMYK Swatch", "Додати зразок CMYK"),
|
||||
("Added swatch", "Зразок додано"),
|
||||
("Eyedropper: drag it onto the page", "Піпетка: перетягніть її на сторінку"),
|
||||
("Restart Numbering", "Почати нумерацію знову"),
|
||||
("Continue Numbering", "Продовжити нумерацію"),
|
||||
("Keep Options…", "Параметри утримання…"),
|
||||
|
||||
Reference in New Issue
Block a user