forked from 1b-agent/opencadstudio-upstream
fix(ui): add non-color marker to CLI info entries and drop dead desk parameter
- Add 'i ' prefix to EntryKind::Info and coordinate set_step_prompt deduplication to satisfy WCAG 1.4.1 across all 22 themes - Drop unused _desk parameter from crosshair_background and clean up its call sites - Document AutoCAD-standard context-based crosshair drafting surface architecture in crosshair_background - Add doc comments documenting deliberate alpha omission in canvas_is_light and backlog scope in is_wide
This commit is contained in:
1 parent
b53cd580f6
commit
a9fda66ac0
3 files changed
+46
-11
No files matched your search
+9
-8
@@ -36,9 +36,12 @@ pub(in crate::app) const VIEWPORT_CAPTURE_BOUNDS_ID: &str = "viewport-capture-bo
|
||||
|
||||
const VIEWCUBE_HIT_SIZE: f32 = VIEWCUBE_REGION_PX;
|
||||
|
||||
/// Base surface directly under the crosshair and selection marquee.
|
||||
/// In paper space, the drafting surface is the white sheet (`tab.scene.paper_bg_color`).
|
||||
fn crosshair_background(tab: &DocumentTab, is_paper: bool, _desk: [f32; 4]) -> [f32; 4] {
|
||||
/// Base surface directly under the crosshair, selection marquee, and grid overlay.
|
||||
/// In paper space, drafting surface context is unconditionally the white sheet (`tab.scene.paper_bg_color`),
|
||||
/// matching AutoCAD's model (where crosshairs and overlays adapt per context — model vs. sheet/layout —
|
||||
/// rather than per-pixel cursor sampling). This avoids flicker across sheet edges and provides a clean
|
||||
/// dark crosshair that maintains ~5.85:1 contrast against the default medium-gray desk margin (#8A8A8A).
|
||||
fn crosshair_background(tab: &DocumentTab, is_paper: bool) -> [f32; 4] {
|
||||
if !is_paper {
|
||||
return tab.scene.bg_color;
|
||||
}
|
||||
@@ -395,8 +398,7 @@ impl OpenCADStudio {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let desk_bg = self.model_space.resolve_desk_bg();
|
||||
let bg = crosshair_background(tab, is_paper, desk_bg);
|
||||
let bg = crosshair_background(tab, is_paper);
|
||||
let bg_lum = 0.299 * bg[0] + 0.587 * bg[1] + 0.114 * bg[2];
|
||||
let grid_style = crate::ui::overlay::GridStyle {
|
||||
opacity: self.model_space.grid_opacity,
|
||||
@@ -751,7 +753,7 @@ impl OpenCADStudio {
|
||||
tab.pan_mode || tab.orbit_mode || tab.zoom_dynamic_mode,
|
||||
self.ribbon.open_dropdown.is_some(),
|
||||
hover_locked,
|
||||
crosshair_background(tab, is_paper, self.model_space.resolve_desk_bg()),
|
||||
crosshair_background(tab, is_paper),
|
||||
crate::ui::overlay::CrosshairOptions {
|
||||
size_percent: self.cursor_size,
|
||||
pick_box: self.pick_box,
|
||||
@@ -3915,8 +3917,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_crosshair_background_paper_space() {
|
||||
let tab = crate::app::document::DocumentTab::new_drawing(1);
|
||||
let desk_bg = [0.1, 0.1, 0.1, 1.0]; // Dark themed desk background
|
||||
let bg = crosshair_background(&tab, true, desk_bg);
|
||||
let bg = crosshair_background(&tab, true);
|
||||
assert_eq!(bg, tab.scene.paper_bg_color);
|
||||
assert!(crate::ui::style::common::canvas_is_light(bg));
|
||||
}
|
||||
|
||||
+34
-3
@@ -326,7 +326,12 @@ impl CommandLine {
|
||||
self.push(EntryKind::Error, text);
|
||||
}
|
||||
pub fn push_info(&mut self, msg: &str) {
|
||||
self.push(EntryKind::Info, msg.to_string());
|
||||
let text = if msg.starts_with("i ") {
|
||||
msg.to_string()
|
||||
} else {
|
||||
format!("i {msg}")
|
||||
};
|
||||
self.push(EntryKind::Info, text);
|
||||
}
|
||||
fn push(&mut self, kind: EntryKind, text: String) {
|
||||
self.history.push(HistoryEntry {
|
||||
@@ -356,10 +361,15 @@ impl CommandLine {
|
||||
e.created_at = Instant::now();
|
||||
}
|
||||
if let Some(p) = &prompt {
|
||||
let formatted = if p.starts_with("i ") {
|
||||
p.clone()
|
||||
} else {
|
||||
format!("i {p}")
|
||||
};
|
||||
// Reuse the prompt line dispatch/step-transition just pushed;
|
||||
// otherwise add it.
|
||||
if self.history.last().map(|e| &e.text) != Some(p) {
|
||||
self.push(EntryKind::Info, p.clone());
|
||||
if self.history.last().map(|e| &e.text) != Some(&formatted) {
|
||||
self.push(EntryKind::Info, formatted);
|
||||
}
|
||||
if let Some(last) = self.history.last_mut() {
|
||||
last.pinned = true;
|
||||
@@ -1059,4 +1069,25 @@ mod tests {
|
||||
Some("MOVE 0,0 10,0")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn info_entries_carry_prefix_marker() {
|
||||
let mut line = CommandLine::new();
|
||||
line.push_info("Object selected.");
|
||||
assert_eq!(line.history.last().map(|e| e.text.as_str()), Some("i Object selected."));
|
||||
assert_eq!(line.history.last().map(|e| &e.kind), Some(&super::EntryKind::Info));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_step_prompt_reuses_push_info_entry() {
|
||||
let mut line = CommandLine::new();
|
||||
let initial_len = line.history.len();
|
||||
line.push_info("Specify first point:");
|
||||
assert_eq!(line.history.len(), initial_len + 1);
|
||||
line.set_step_prompt(Some("Specify first point:".to_string()));
|
||||
assert_eq!(line.history.len(), initial_len + 1, "prompt must reuse push_info entry without duplicating");
|
||||
let last = line.history.last().unwrap();
|
||||
assert!(last.pinned);
|
||||
assert_eq!(last.text, "i Specify first point:");
|
||||
}
|
||||
}
|
||||
@@ -70,11 +70,14 @@ pub(crate) fn accessible_accent(accent: Color, bg: Color, fallback: Color) -> Co
|
||||
}
|
||||
|
||||
/// Returns true if the given canvas background color has a WCAG relative luminance > 0.5 (light surface).
|
||||
/// Ignores alpha assuming canvas backgrounds are opaque (or composited against default viewport clear).
|
||||
pub(crate) fn canvas_is_light(bg: [f32; 4]) -> bool {
|
||||
wcag_luminance(Color::from_rgb(bg[0], bg[1], bg[2])) > 0.5
|
||||
}
|
||||
|
||||
/// True if a character is East Asian Wide or Fullwidth (CJK ideographs, kana, hangul, fullwidth forms).
|
||||
/// Approximation of East Asian Wide/Fullwidth; not exhaustive (e.g. emoji ranges and CJK Extension B+
|
||||
/// beyond 0x2FA1F omitted for the backlog).
|
||||
pub(crate) fn is_wide(c: char) -> bool {
|
||||
let u = c as u32;
|
||||
matches!(
|
||||
|
||||
Reference in new issue
Block a user