feat: per-viewport background color (BACKGROUND command)

- DocumentTab: bg_color / paper_bg_color Optional<[f32;4]> fields
- view.rs: use custom color when set, fall back to defaults
- BACKGROUND <r> <g> <b>: set model or paper-space background (0–255 RGB)
- BACKGROUND RESET: restore default dark grey / paper grey

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-04-06 23:26:26 +03:00
commit 41a5d98b33
3 changed files with 43 additions and 2 deletions

View file

@ -31,6 +31,37 @@ impl H7CAD {
"CLEAR"|"CLR" => return Task::done(Message::ClearScene),
"WIREFRAME"|"VW" => return Task::done(Message::SetWireframe(true)),
"SOLID"|"VS" => return Task::done(Message::SetWireframe(false)),
// ── Background color ───────────────────────────────────────────
// Usage: BACKGROUND <r> <g> <b> (0255 each)
// BACKGROUND RESET (restore default)
cmd if cmd == "BACKGROUND" || cmd.starts_with("BACKGROUND ") => {
let args = cmd.split_whitespace().skip(1).collect::<Vec<_>>();
let is_paper = self.tabs[i].scene.current_layout != "Model";
if args.first().map(|s| s.eq_ignore_ascii_case("RESET")).unwrap_or(false) {
if is_paper {
self.tabs[i].paper_bg_color = None;
} else {
self.tabs[i].bg_color = None;
}
self.command_line.push_output("Background reset to default.");
} else if args.len() >= 3 {
let r = args[0].parse::<u8>().unwrap_or(0) as f32 / 255.0;
let g = args[1].parse::<u8>().unwrap_or(0) as f32 / 255.0;
let b = args[2].parse::<u8>().unwrap_or(0) as f32 / 255.0;
if is_paper {
self.tabs[i].paper_bg_color = Some([r, g, b, 1.0]);
} else {
self.tabs[i].bg_color = Some([r, g, b, 1.0]);
}
self.command_line
.push_output(&format!("Background: rgb({}, {}, {})", args[0], args[1], args[2]));
} else {
self.command_line.push_info(
"Usage: BACKGROUND <r> <g> <b> (0255) | BACKGROUND RESET"
);
}
}
"ORTHO" => return Task::done(Message::SetProjection(true)),
"PERSP" => return Task::done(Message::SetProjection(false)),
"LAYERS"|"LA" => return Task::done(Message::ToggleLayers),

View file

@ -31,6 +31,10 @@ pub(super) struct DocumentTab {
pub(super) active_layer: String,
/// Currently active UCS. `None` means WCS (identity transform).
pub(super) active_ucs: Option<Ucs>,
/// Custom model-space background color. `None` = default dark grey.
pub(super) bg_color: Option<[f32; 4]>,
/// Custom paper-space background color. `None` = default off-white grey.
pub(super) paper_bg_color: Option<[f32; 4]>,
}
impl DocumentTab {
@ -56,6 +60,8 @@ impl DocumentTab {
history: HistoryState::default(),
active_layer: "0".to_string(),
active_ucs: None,
bg_color: None,
paper_bg_color: None,
}
}

View file

@ -126,9 +126,13 @@ impl H7CAD {
.height(Fill);
let bg_color = if is_paper {
Color { r: 0.22, g: 0.24, b: 0.28, a: 1.0 }
tab.paper_bg_color
.map(|[r, g, b, a]| Color { r, g, b, a })
.unwrap_or(Color { r: 0.22, g: 0.24, b: 0.28, a: 1.0 })
} else {
Color { r: 0.11, g: 0.11, b: 0.11, a: 1.0 }
tab.bg_color
.map(|[r, g, b, a]| Color { r, g, b, a })
.unwrap_or(Color { r: 0.11, g: 0.11, b: 0.11, a: 1.0 })
};
let viewport_stack = stack![