forked from 1b-agent/opencadstudio-upstream
feat(model-space): theme-aware model space canvas and CAD selection/grip sysvars
Model space appearance now follows the active UI theme instead of a hardcoded dark background. Canvas mode is user-selectable (Match Theme / Classic CAD Dark / Custom RGB), with matching controls for the paper sheet and desk surround backgrounds and grid opacity. Implements industry-standard CAD system variables, all settable via command name, SETVAR, and the Options dialog: - COLORTHEME (0/1 dark/light UI scheme, preserves custom palettes) - COLORSCHEME (interactive named-theme selection) - BACKGROUND (THEME/CLASSIC/DEFAULT/DESK presets, RGB triplets) - SELECTIONAREA, SELECTIONAREAOPACITY (translucent marquee fill) - WINDOWSAREACOLOR/WINDOWAREACOLOR, CROSSINGAREACOLOR (ACI or theme) - SELECTIONEFFECT, SELECTIONEFFECTCOLOR (GPU highlight pass, driven by selection_generation invalidation — no retessellation) - SELECTIONPREVIEW (bit 0 = idle rollover, bit 1 = in-command hover) - GRIPSIZE, GRIPCOLOR, GRIPHOT, GRIPHOVER (grip overlay styling)
This commit is contained in:
1 parent
89b1a22850
commit
688785a6cf
18 files changed
+1949
-316
No files matched your search
+61
-45
@@ -375,56 +375,72 @@ impl OpenCADStudio {
|
||||
}
|
||||
|
||||
// ── Color Scheme / Theme selector ─────────────────────────────
|
||||
cmd if cmd == "COLORSCHEME" || cmd.starts_with("COLORSCHEME ") => {
|
||||
use iced::Theme;
|
||||
let sub = cmd
|
||||
.split_once(' ')
|
||||
.map(|(_, r)| r.trim())
|
||||
.unwrap_or("")
|
||||
.to_uppercase();
|
||||
// Map name to Theme variant.
|
||||
let theme: Option<Theme> = match sub.as_str() {
|
||||
"DARK" => Some(Theme::Dark),
|
||||
"LIGHT" => Some(Theme::Light),
|
||||
"DRACULA" => Some(Theme::Dracula),
|
||||
"NORD" => Some(Theme::Nord),
|
||||
"SOLARIZED_LIGHT" | "SOLARIZEDLIGHT" => Some(Theme::SolarizedLight),
|
||||
"SOLARIZED_DARK" | "SOLARIZEDDARK" => Some(Theme::SolarizedDark),
|
||||
"GRUVBOX_LIGHT" | "GRUVBOXLIGHT" => Some(Theme::GruvboxLight),
|
||||
"GRUVBOX_DARK" | "GRUVBOXDARK" => Some(Theme::GruvboxDark),
|
||||
"TOKYONIGHT" | "TOKYO_NIGHT" => Some(Theme::TokyoNight),
|
||||
"TOKYONIGHTSTORM" | "TOKYO_NIGHT_STORM" => Some(Theme::TokyoNightStorm),
|
||||
"TOKYONIGHTLIGHT" | "TOKYO_NIGHT_LIGHT" => Some(Theme::TokyoNightLight),
|
||||
"KANAGAWAWAVE" | "KANAGAWA_WAVE" => Some(Theme::KanagawaWave),
|
||||
"KANAGAWADRAGON" | "KANAGAWA_DRAGON" => Some(Theme::KanagawaDragon),
|
||||
"KANAGAWALOTUS" | "KANAGAWA_LOTUS" => Some(Theme::KanagawaLotus),
|
||||
"MOONFLY" => Some(Theme::Moonfly),
|
||||
"NIGHTFLY" => Some(Theme::Nightfly),
|
||||
"OXOCARBON" => Some(Theme::Oxocarbon),
|
||||
"FERRA" => Some(Theme::Ferra),
|
||||
"" | "LIST" | "?" => {
|
||||
self.command_line.push_output(
|
||||
"Available themes: DARK LIGHT DRACULA NORD SOLARIZED_LIGHT SOLARIZED_DARK \
|
||||
GRUVBOX_LIGHT GRUVBOX_DARK TOKYONIGHT TOKYONIGHTSTORM TOKYONIGHTLIGHT \
|
||||
KANAGAWAWAVE KANAGAWADRAGON KANAGAWALOTUS MOONFLY NIGHTFLY OXOCARBON FERRA"
|
||||
);
|
||||
return Some(Task::none());
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"COLORSCHEME: unknown theme '{}'. Type COLORSCHEME LIST for options.",
|
||||
sub
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
};
|
||||
cmd if cmd.eq_ignore_ascii_case("COLORSCHEME") => {
|
||||
use crate::command::ValuePromptCommand;
|
||||
let c = ValuePromptCommand::new(
|
||||
"COLORSCHEME",
|
||||
"COLORSCHEME Enter theme name (or ? to list):",
|
||||
);
|
||||
self.command_line.push_output(
|
||||
"Available themes: DARK LIGHT DRACULA NORD SOLARIZED_LIGHT SOLARIZED_DARK \
|
||||
GRUVBOX_LIGHT GRUVBOX_DARK TOKYONIGHT TOKYONIGHTSTORM TOKYONIGHTLIGHT \
|
||||
KANAGAWAWAVE KANAGAWADRAGON KANAGAWALOTUS MOONFLY NIGHTFLY OXOCARBON FERRA",
|
||||
);
|
||||
self.command_line.push_info(&format!(
|
||||
"Current color scheme: <{}>",
|
||||
self.ui_theme.name
|
||||
));
|
||||
self.command_line.push_info(&c.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(c));
|
||||
return Some(Task::none());
|
||||
}
|
||||
cmd if cmd.to_ascii_uppercase().starts_with("COLORSCHEME ") => {
|
||||
let sub = cmd.split_once(' ').map(|(_, r)| r.trim()).unwrap_or("");
|
||||
let upper_sub = sub.to_ascii_uppercase();
|
||||
if upper_sub.is_empty() {
|
||||
self.command_line.push_output(&format!(
|
||||
"Current color scheme: <{}>",
|
||||
self.ui_theme.name
|
||||
));
|
||||
return Some(Task::none());
|
||||
}
|
||||
if upper_sub == "LIST" || upper_sub == "?" {
|
||||
self.command_line.push_output(
|
||||
"Available themes: DARK LIGHT DRACULA NORD SOLARIZED_LIGHT SOLARIZED_DARK \
|
||||
GRUVBOX_LIGHT GRUVBOX_DARK TOKYONIGHT TOKYONIGHTSTORM TOKYONIGHTLIGHT \
|
||||
KANAGAWAWAVE KANAGAWADRAGON KANAGAWALOTUS MOONFLY NIGHTFLY OXOCARBON FERRA",
|
||||
);
|
||||
return Some(Task::none());
|
||||
}
|
||||
if sub == "0" || sub == "1" {
|
||||
self.command_line.push_error(
|
||||
"COLORSCHEME: 0 and 1 are COLORTHEME options. Enter a theme name (e.g. DARK, LIGHT, DRACULA) or use COLORTHEME.",
|
||||
);
|
||||
return Some(Task::none());
|
||||
}
|
||||
let theme = crate::app::config::parse_theme_name(sub);
|
||||
if let Some(t) = theme {
|
||||
if self.ui_theme.name == "Custom" {
|
||||
self.saved_custom_palette = Some(self.ui_theme.palette);
|
||||
}
|
||||
let name = format!("{:?}", t);
|
||||
self.ui_theme.name = t.to_string();
|
||||
self.ui_theme.palette =
|
||||
crate::app::config::UiThemePalette::from_iced(t.seed());
|
||||
self.theme_color_inputs = self.ui_theme.palette.hex_values();
|
||||
self.active_theme = t.clone();
|
||||
self.sync_model_space_theme(true);
|
||||
self.persist_settings_if_changed();
|
||||
self.command_line
|
||||
.push_output(crate::tf!("Color scheme set to '{name}'.").as_ref());
|
||||
return Some(Task::done(Message::SetTheme(t)));
|
||||
return Some(Task::none());
|
||||
} else {
|
||||
self.command_line.push_error(crate::tf!(
|
||||
"COLORSCHEME: unknown theme '{}'. Type COLORSCHEME LIST for options.",
|
||||
sub
|
||||
).as_ref());
|
||||
return Some(Task::none());
|
||||
}
|
||||
return Some(Task::none());
|
||||
}
|
||||
|
||||
// ── Layout Manager GUI ─────────────────────────────────────────
|
||||
|
||||
Reference in new issue
Block a user