Select Color: aligned views, smaller mode buttons, compact interface picker

- The gradient view no longer shows the nearest index colour.
- Mode buttons are 44 x 24 and the pipette button matches their height.
- Slider rows are 14 px apart and the gradient field is 108 px tall, so
  the hex value sits on the same row in the HSB, RGB and gradient views.
- The interface colour picker (Options) shrinks to its content, ending
  just below the hex row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013rGmDUNr1hUf4zo1X3dak8
This commit is contained in:
Claude committed 2026-10-12 18:53:51 +00:00
1 parent c8c5f667f7
commit 936c3b91aa
2 files changed
+33 -25

No files matched your search

+24 -17
View File
@@ -15,7 +15,12 @@ use iced::{Background, Border, Color, Element, Gradient, Length, Radians, Theme}
const ROW_HEIGHT: f32 = 26.0;
const TRACK: f32 = 18.0;
const STRIP_WIDTH: f32 = 22.0;
const FIELD_HEIGHT: f32 = 118.0;
/// Gap between slider rows. Together with `FIELD_HEIGHT` it puts the hex row
/// at the same height in every mode: 3 × 26 + 2 × 14 + 12 = 108 + 10.
const ROW_GAP: f32 = 14.0;
const FIELD_HEIGHT: f32 = 108.0;
const MODE_WIDTH: f32 = 44.0;
const MODE_HEIGHT: f32 = 24.0;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum EditorMode {
@@ -149,8 +154,8 @@ impl ColorEditor {
let active = self.mode == mode;
button(container(content).center(Length::Fill))
.on_press(msg(EditorMsg::Mode(mode)))
.width(52)
.height(28)
.width(MODE_WIDTH)
.height(MODE_HEIGHT)
.padding(0)
.style(move |theme: &Theme, status| {
super::picker::toggle_style(theme, active, status)
@@ -159,7 +164,7 @@ impl ColorEditor {
// The field button is only its gradient, without a frame; it takes
// colour when its mode is active and stays gray otherwise.
let field_active = self.mode == EditorMode::Field;
let field_button = button(Space::new().width(52).height(28))
let field_button = button(Space::new().width(MODE_WIDTH).height(MODE_HEIGHT))
.on_press(msg(EditorMsg::Mode(EditorMode::Field)))
.padding(0)
.style(move |_theme: &Theme, _status| {
@@ -182,8 +187,8 @@ impl ColorEditor {
}
});
let mut modes = row![
mode_button(text("HSB").size(12).into(), EditorMode::Hsb),
mode_button(text("RGB").size(12).into(), EditorMode::Rgb),
mode_button(text("HSB").size(11).into(), EditorMode::Hsb),
mode_button(text("RGB").size(11).into(), EditorMode::Rgb),
field_button,
Space::new().width(Length::Fill),
]
@@ -232,7 +237,7 @@ impl ColorEditor {
EditorMsg::Brightness,
),
]
.spacing(10)
.spacing(ROW_GAP)
.into(),
EditorMode::Rgb => {
let ends = |lo: (u8, u8, u8), hi: (u8, u8, u8)| {
@@ -310,23 +315,25 @@ impl ColorEditor {
.spacing(10)
.align_y(iced::Center),
]
// 108 + 10 matches the slider views' 3 × 26 + 2 × 14 + 12.
.spacing(10)
.into()
}
};
// Below the editor: the hex value (unless the field view already
// shows it) and, on the right, the nearest index colour.
let mut hex_row = row![].spacing(8).align_y(iced::Center);
// The field view shows the hex value beside H, S and B and leaves out
// the nearest index colour; the slider views end on a hex row.
let mut view = column![modes, editor].spacing(12);
if !field_mode {
hex_row = hex_row.push(hex_field());
let mut hex_row = row![hex_field(), Space::new().width(Length::Fill)]
.spacing(8)
.align_y(iced::Center);
if let Some(end) = hex_end {
hex_row = hex_row.push(end);
}
view = view.push(hex_row);
}
hex_row = hex_row.push(Space::new().width(Length::Fill));
if let Some(end) = hex_end {
hex_row = hex_row.push(end);
}
column![modes, editor, hex_row].spacing(12).into()
view.into()
}
}
+9 -8
View File
@@ -20,8 +20,6 @@ const PANEL_WIDTH: f32 = 400.0;
/// fields instead of the dialogs and command line underneath.
const PANEL_ID: &str = "select-color-panel";
const BODY_HEIGHT: f32 = 352.0;
/// The interface picker has no tabs or info line, only the editor.
const EDITOR_ONLY_HEIGHT: f32 = 258.0;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ColorPickerTab {
@@ -179,8 +177,11 @@ impl ColorPicker {
self.index_tab()
};
let mut body = column![body, Space::new().height(Length::Fill)].spacing(8);
// The interface picker shrinks to the editor; the CAD panel keeps one
// height across its tabs, with the info line at the bottom.
let mut body = column![body].spacing(8);
if !editor_only {
body = body.push(Space::new().height(Length::Fill));
let fill =
math::color_rgb(self.pending).map_or(Color::from_rgb8(128, 128, 128), rgb_color);
body = body
@@ -208,9 +209,9 @@ impl ColorPicker {
.padding(12)
.width(Length::Fill)
.height(if editor_only {
EDITOR_ONLY_HEIGHT
Length::Shrink
} else {
BODY_HEIGHT
Length::Fixed(BODY_HEIGHT)
})
.style(panel_style);
@@ -396,10 +397,10 @@ impl ColorPicker {
None
} else {
Some(
button(crate::ui::icons::themed(crate::ui::icons::EYEDROPPER, 16.0))
button(crate::ui::icons::themed(crate::ui::icons::EYEDROPPER, 14.0))
.on_press(picker_msg(ColorPickerMsg::Eyedropper(EyedropperMsg::Start)))
.height(28)
.padding([0, 8])
.height(24)
.padding([0, 7])
.style(|theme: &Theme, status| toggle_style(theme, false, status))
.into(),
)