forked from 1b-agent/opencadstudio-upstream
feat(ui): shared dropdown popup width calculation with wide-character support
- Add dropdown_popup_width helper in common.rs replacing magic formula heuristics - Implement is_wide range table to count East Asian Wide/Fullwidth (CJK) glyphs double for localized strings - Calibrate unit scale factor to 0.68 * font_size preserving existing width behavior at font size 11 - Apply shared calculation across viewport controls and ribbon dropdowns - Update unit tests to verify width calculation on standard and CJK labels
This commit is contained in:
1 parent
a7e3cf3a6d
commit
b53cd580f6
3 files changed
+69
-9
No files matched your search
@@ -131,12 +131,13 @@ pub(super) fn viewport_controls<'a>(
|
||||
);
|
||||
|
||||
let preview_mode = render_mode_preview.unwrap_or(render_mode);
|
||||
let max_label_len = render_modes
|
||||
.iter()
|
||||
.map(|c| c.to_string().chars().count())
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
let dropdown_w = (max_label_len as f32 * 7.5 + 46.0).max(180.0);
|
||||
let mode_names: Vec<String> = render_modes.iter().map(|c| c.to_string()).collect();
|
||||
let dropdown_w = crate::ui::style::common::dropdown_popup_width(
|
||||
mode_names.iter().map(|s| s.as_str()),
|
||||
11.0,
|
||||
46.0,
|
||||
180.0,
|
||||
);
|
||||
|
||||
let mut choices = column![].spacing(2).width(Length::Fill);
|
||||
for choice in render_modes {
|
||||
@@ -445,13 +446,30 @@ mod tests {
|
||||
.map(|c| c.label.chars().count())
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
let dropdown_w = (max_label_len as f32 * 7.5 + 46.0).max(180.0);
|
||||
let dropdown_w = crate::ui::style::common::dropdown_popup_width(
|
||||
crate::modules::view::visual_style::VISUAL_STYLES
|
||||
.iter()
|
||||
.map(|c| c.label),
|
||||
11.0,
|
||||
46.0,
|
||||
180.0,
|
||||
);
|
||||
|
||||
// Longest default label is "Gouraud Shaded + Edges" (22 chars)
|
||||
assert_eq!(max_label_len, 22);
|
||||
// Computed width should easily fit the 22-char label + checkmark + padding
|
||||
assert!(dropdown_w >= 210.0);
|
||||
|
||||
// CJK labels count wide characters double
|
||||
let cjk_labels = ["二维线框", "着色+边"];
|
||||
let cjk_w = crate::ui::style::common::dropdown_popup_width(
|
||||
cjk_labels.iter().copied(),
|
||||
11.0,
|
||||
46.0,
|
||||
180.0,
|
||||
);
|
||||
assert_eq!(cjk_w, 180.0);
|
||||
|
||||
for style in crate::modules::view::visual_style::VISUAL_STYLES {
|
||||
assert!(!style.label.contains('\n'), "Label should be a single line");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user