Select Color: frameless gradient button, hex beside H/S/B, all Options swatches

- The gradient mode button is just its gradient, without a frame.
- In the gradient view H, S and B sit on the left and Hex on the right
  of one row; the nearest index colour moves to the row below.
- Every colour swatch in Options opens the Select Color panel: the six
  theme colours, crosshair, snap marker and command line text join the
  three viewport backgrounds. BgTarget becomes UiColor, and one
  color_swatch helper replaces the four hand-built swatches.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
This commit is contained in:
Claude committed 2026-10-12 18:33:23 +00:00
1 parent 0a28163ef5
commit c8c5f667f7
6 files changed
+102 -125

No files matched your search

+12 -7
View File
@@ -1577,12 +1577,17 @@ pub struct SaveOutcome {
refreshed_preview: Option<Option<codec::Preview>>,
result: Result<(), crate::io::SaveFailure>,
}
/// Which viewport background the interface colour picker is editing.
/// Which Options colour the interface colour picker is editing.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BgTarget {
Model,
Paper,
Desk,
pub enum UiColor {
ModelBackground,
PaperBackground,
DeskBackground,
/// One of the six theme colours, by its row in Options.
Theme(usize),
Crosshair,
SnapMarker,
CommandText,
}
/// Where a colour chosen in the standalone palette window should be applied.
@@ -1607,8 +1612,8 @@ pub enum ColorPickTarget {
LayerState(usize),
/// The MText editor's selection (or global) colour.
MText,
/// An Options viewport background (interface colour, true colour only).
Background(BgTarget),
/// An Options interface colour (true colour only).
Interface(UiColor),
}
/// Table records the clipboard entities depend on, snapshotted from the source
+1 -1
View File
@@ -11061,7 +11061,7 @@ impl OpenCADStudio {
// the recent list.
if !matches!(
self.color_picker.as_ref().map(|picker| &picker.target),
Some(crate::app::ColorPickTarget::Background(_))
Some(crate::app::ColorPickTarget::Interface(_))
) {
self.note_recent_color(color);
}
+12 -7
View File
@@ -1136,7 +1136,7 @@ impl OpenCADStudio {
}
pub(super) fn on_color_window_pick(&mut self, color: codec::types::Color) -> Task<Message> {
if let Some(crate::app::ColorPickTarget::Background(target)) = self
if let Some(crate::app::ColorPickTarget::Interface(target)) = self
.color_picker
.as_ref()
.map(|picker| picker.target.clone())
@@ -1146,13 +1146,18 @@ impl OpenCADStudio {
return Task::none();
};
// Hand the result to the same handler the typed hex field uses, so
// the picker and the field cannot drift apart on validation,
// persistence or the MatchTheme fallback.
// the picker and the field cannot drift apart on validation or
// persistence.
let hex = crate::app::config::rgb_to_hex([r, g, b]);
use crate::app::UiColor;
return Task::done(match target {
crate::app::BgTarget::Model => Message::ModelSpaceBgChanged(hex),
crate::app::BgTarget::Paper => Message::PaperSpaceBgChanged(hex),
crate::app::BgTarget::Desk => Message::DeskSpaceBgChanged(hex),
UiColor::ModelBackground => Message::ModelSpaceBgChanged(hex),
UiColor::PaperBackground => Message::PaperSpaceBgChanged(hex),
UiColor::DeskBackground => Message::DeskSpaceBgChanged(hex),
UiColor::Theme(index) => Message::OptionsThemeColorChanged(index, hex),
UiColor::Crosshair => Message::CrosshairColorChanged(hex),
UiColor::SnapMarker => Message::SnapMarkerColorChanged(hex),
UiColor::CommandText => Message::CommandTextColorChanged(hex),
});
}
if matches!(
@@ -1208,7 +1213,7 @@ impl OpenCADStudio {
}
// Handled before this match.
Some(
crate::app::ColorPickTarget::PlotStyle | crate::app::ColorPickTarget::Background(_),
crate::app::ColorPickTarget::PlotStyle | crate::app::ColorPickTarget::Interface(_),
) => None,
None => None,
};