Clarify integer and float bit-depth labels (#324) (#428)

* Clarify integer and float bit-depth labels

Add type-specific labels to New Document and Image Mode with translations and focused UI/catalog tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d

* Fix bit-depth labels and tooltips

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc

* Keep the reference menu names for the depth commands and preference

The Image > Mode items keep their menu-catalogue labels, so the engine
labels (command palette, MCP, Keyboard Shortcuts) and the preference
choice stay "8/16/32 Bits/Channel" to match; the integer / floating point
hint comes from the new tooltips.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Copilot-Session: f77709e9-6475-4953-ab57-b78347b4499d
Copilot-Session: e5e4c3e6-e406-4010-b05d-5042f9f4e4fc
This commit is contained in:
authored and GitHub committed 2026-10-07 07:09:51 -04:00
1 parent 2c02d41eaf
commit 50d52a0848
10 files changed
+82 -3

No files matched your search

+16 -2
View File
@@ -190,8 +190,9 @@ pub fn properties(app: &mut PhotocraftApp, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
ui.add_space(label_w + 8.0);
let mut d = depth;
let opts: Vec<(SampleType, &str)> = DEPTHS.iter().map(|(d, l, _)| (*d, *l)).collect();
if widgets::dropdown(ui, "doc-props-depth", &mut d, &opts, 150.0)
let opts: Vec<(SampleType, &str, &str)> =
DEPTHS.iter().map(|(d, l, _)| (*d, *l, if *d == SampleType::F32 { "Floating point" } else { "Integer" })).collect();
if widgets::dropdown_with_tooltips(ui, "doc-props-depth", &mut d, &opts, 150.0)
&& let Some((_, _, id)) = DEPTHS.iter().find(|(x, _, _)| *x == d)
{
run.push(((*id).to_string(), Value::Null));
@@ -315,4 +316,17 @@ mod tests {
assert!(photocraft_engine::commands::find(id).is_some(), "{id} is not an engine command");
}
}
#[test]
fn image_mode_depth_labels_match_sample_types_and_are_translated() {
assert_eq!(
DEPTHS.iter().map(|(sample, label, _)| (*sample, *label)).collect::<Vec<_>>(),
[(SampleType::U8, "8 Bits/Channel"), (SampleType::U16, "16 Bits/Channel"), (SampleType::F32, "32 Bits/Channel"),]
);
for lang in crate::i18n::Lang::all().filter(|lang| lang.code() != "en") {
for (_, label, id) in DEPTHS {
assert_ne!(crate::i18n::tr_id(lang, id, label), *label, "{}: {label}", lang.code());
}
}
}
}
+5
View File
@@ -181,8 +181,13 @@
Lab Color Barvy Lab
Multichannel Vícekanálový
8 Bits/Channel 8 bitů/kanál
8 bit 8 bitů
Integer Celé číslo
16 Bits/Channel 16 bitů/kanál
16 bit 16 bitů
32 Bits/Channel 32 bitů/kanál
32 bit (float) 32 bitů (float)
Floating point Číslo s plovoucí desetinnou čárkou
Color Table… Tabulka barev…
Bitmap… Bitmapa…
Duotone… Dvoutón…
Can't render this file because it contains an unexpected character in line 6 and column 47.
+5
View File
@@ -173,8 +173,13 @@
Lab Color Color Lab
Multichannel Multicanal
8 Bits/Channel 8 bits/canal
8 bit 8 bits
Integer Entero
16 Bits/Channel 16 bits/canal
16 bit 16 bits
32 Bits/Channel 32 bits/canal
32 bit (float) 32 bits (float)
Floating point Punto flotante
Color Table… Tabla de colores…
Bitmap… Mapa de bits…
Duotone… Duotono…
Can't render this file because it contains an unexpected character in line 4 and column 47.
+5
View File
@@ -177,8 +177,13 @@
Lab Color Lab カラー
Multichannel マルチチャンネル
8 Bits/Channel 8 ビット/チャンネル
8 bit 8 ビット
Integer 整数
16 Bits/Channel 16 ビット/チャンネル
16 bit 16 ビット
32 Bits/Channel 32 ビット/チャンネル
32 bit (float) 32 ビット(float)
Floating point 浮動小数点
Color Table… カラーテーブル…
Bitmap… ビットマップ…
Duotone… ダブルトーン…
Can't render this file because it contains an unexpected character in line 6 and column 47.
+5
View File
@@ -106,6 +106,11 @@
16 Bits/Channel 16 бит/канал
32 Bits/Channel 32 бита/канал
8 Bits/Channel 8 бит/канал
8 bit 8 бит
Integer Целое число
16 bit 16 бит
32 bit (float) 32 бит (float)
Floating point С плавающей точкой
Mode Режим
Grayscale Градации серого
RGB Color RGB
Can't render this file because it contains an unexpected character in line 6 and column 47.
+5
View File
@@ -175,8 +175,13 @@
Lab Color Lab 颜色
Multichannel 多通道
8 Bits/Channel 8 位/通道
8 bit 8 位
Integer 整数
16 Bits/Channel 16 位/通道
16 bit 16 位
32 Bits/Channel 32 位/通道
32 bit (float) 32 位(浮点)
Floating point 浮点数
Color Table… 颜色表…
Bitmap… 位图…
Duotone… 双色调…
1 # Simplified Chinese (zh-hans) catalog. UTF-8, TAB-separated columns:
175
176
177
178
179
180
181
182
183
184
185
186
187
+5
View File
@@ -181,8 +181,13 @@
Lab Color Lab 色彩
Multichannel 多重色版
8 Bits/Channel 8 位元/色版
8 bit 8 位元
Integer 整數
16 Bits/Channel 16 位元/色版
16 bit 16 位元
32 Bits/Channel 32 位元/色版
32 bit (float) 32 位元(浮點)
Floating point 浮點數
Color Table… 色彩表…
Bitmap… 點陣圖…
Duotone… 雙色調…
Can't render this file because it contains an unexpected character in line 6 and column 47.
+5
View File
@@ -844,6 +844,11 @@ fn render_level_rows(ui: &mut egui::Ui, items: &[&MenuItem], depth: usize, click
}
let hit = nav.row(ui, depth - 1, it.enabled, Some(&it.id), |ui, _| {
let r = ui.add_enabled(it.enabled, b);
let r = match it.id.as_str() {
"image.mode.bits8" | "image.mode.bits16" => r.on_hover_text(crate::i18n::tr(lang, "Integer")),
"image.mode.bits32" => r.on_hover_text(crate::i18n::tr(lang, "Floating point")),
_ => r,
};
let hit = r.clicked();
(r, hit)
});
+14 -1
View File
@@ -73,6 +73,8 @@ pub const CATEGORIES: &[(&str, &[Preset])] = &[
),
];
const DEPTH_OPTIONS: &[(u64, &str, &str)] = &[(8, "8 bit", "Integer"), (16, "16 bit", "Integer"), (32, "32 bit (float)", "Floating point")];
/// Width/Height units: (key, label, units per inch; 0 = pixels).
pub const UNITS: &[(&str, &str, f32)] =
&[("px", "Pixels", 0.0), ("in", "Inches", 1.0), ("cm", "Centimeters", 2.54), ("mm", "Millimeters", 25.4), ("pt", "Points", 72.0), ("pica", "Picas", 6.0)];
@@ -280,7 +282,8 @@ pub fn body(ui: &mut egui::Ui, f: &mut Map<String, Value>) {
f.insert("mode".into(), json!(mode));
}
let mut depth = f.get("depth").and_then(Value::as_u64).unwrap_or(8);
if widgets::dropdown(ui, "nd-depth", &mut depth, &[(8u64, "8 bit"), (16, "16 bit"), (32, "32 bit")], 120.0) {
let depth_options: Vec<(u64, &str, &str)> = DEPTH_OPTIONS.iter().map(|(bits, label, tooltip)| (*bits, *label, *tooltip)).collect();
if widgets::dropdown_with_tooltips(ui, "nd-depth", &mut depth, &depth_options, 120.0) {
f.insert("depth".into(), json!(depth));
}
});
@@ -312,6 +315,16 @@ mod tests {
assert_eq!(to_unit(640.0, "px", 72.0), 640.0);
}
#[test]
fn new_document_depth_labels_and_tooltips_are_translated() {
for lang in crate::i18n::Lang::all().filter(|lang| lang.code() != "en") {
for (_, label, tooltip) in DEPTH_OPTIONS {
assert_ne!(crate::i18n::tr(lang, label), *label, "{}: {label}", lang.code());
assert_ne!(crate::i18n::tr(lang, tooltip), *tooltip, "{}: {tooltip}", lang.code());
}
}
}
#[test]
fn preset_sets_size_resolution_and_create_params_drop_ui_keys() {
let mut f = crate::state::UiState::new_document_fields();
+17
View File
@@ -417,6 +417,23 @@ pub fn swatch_popup(swatch: &Response) -> egui::Popup<'static> {
.align_alternatives(&[egui::RectAlign::TOP_START])
}
pub fn dropdown_with_tooltips<T: PartialEq + Clone>(ui: &mut Ui, id: &str, current: &mut T, options: &[(T, &str, &str)], width: f32) -> bool {
let label = options.iter().find(|(v, _, _)| v == current).map(|(_, l, _)| tl!(l)).unwrap_or("—");
let mut changed = false;
let response = egui::ComboBox::from_id_salt(id).selected_text(label).width(width).height(420.0).icon(chevron_icon).show_ui(ui, |ui| {
for (v, l, tip) in options {
if ui.selectable_label(v == current, tl!(l)).on_hover_text(tl!(tip)).clicked() {
*current = v.clone();
changed = true;
}
}
});
if let Some((_, _, tip)) = options.iter().find(|(v, _, _)| v == current) {
let _ = response.response.on_hover_text(tl!(tip));
}
changed
}
/// Paint a small checkerboard (transparency) in `rect`.
pub fn checker(painter: &egui::Painter, rect: Rect, cell: f32) {
painter.rect_filled(rect, 0.0, Color32::from_gray(250));