forked from 1b-agent/opencadstudio-upstream
feat(ui): shared colour selector used across all style editors (#94)
Add a reusable color_selector widget (ui/color_select.rs): a main-colour dropdown plus a "more colours" button that expands the full 255-entry ACI palette — the same design the properties panel uses. Replace the flat ACI swatch rows added earlier in the dimension, multileader and table style editors with it, wired through each editor's existing colour edit message (the chosen colour is encoded as an ACI string) plus a per-field palette-open toggle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
3ccda2f129
commit
8cdb17a6b4
8 files changed
+280
-121
No files matched your search
@@ -352,6 +352,8 @@ pub(super) struct OpenCADStudio {
|
||||
|
||||
// ── MLeaderStyle Dialog ───────────────────────────────────────────────
|
||||
mleaderstyle_selected: String,
|
||||
/// Colour field whose expanded palette is open (line/text/block).
|
||||
mls_color_open: Option<&'static str>,
|
||||
mls_landing_distance: String,
|
||||
mls_landing_gap: String,
|
||||
mls_arrowhead_size: String,
|
||||
@@ -381,6 +383,9 @@ pub(super) struct OpenCADStudio {
|
||||
/// General table-style description buffer.
|
||||
ts_description: String,
|
||||
/// Per-cell edit buffers, indexed 0=Data, 1=Header, 2=Title.
|
||||
/// Table cell colour field (row class, "textcolor"/"fillcolor") whose
|
||||
/// expanded palette is open.
|
||||
ts_color_open: Option<(u8, &'static str)>,
|
||||
ts_cell_textstyle: [String; 3],
|
||||
ts_cell_height: [String; 3],
|
||||
ts_cell_textcolor: [String; 3],
|
||||
@@ -467,6 +472,8 @@ pub(super) struct OpenCADStudio {
|
||||
// ── DimStyle Dialog ───────────────────────────────────────────────────
|
||||
/// Name of the style currently shown in the dialog.
|
||||
dimstyle_selected: String,
|
||||
/// Which colour field currently has its expanded palette open (if any).
|
||||
ds_color_open: Option<DsField>,
|
||||
/// Active tab: 0=Lines, 1=Arrows, 2=Text, 3=Scale/Units, 4=Tolerances.
|
||||
dimstyle_tab: u8,
|
||||
// Edit buffers (strings while typing):
|
||||
@@ -1171,6 +1178,8 @@ pub enum Message {
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
/// Toggle the expanded colour palette for a table cell colour field.
|
||||
TableColorMore(u8, &'static str),
|
||||
/// Toggle background fill on a cell style.
|
||||
TableStyleCellToggleFill(u8),
|
||||
/// Set the alignment of a cell style from the dropdown.
|
||||
@@ -1223,6 +1232,8 @@ pub enum Message {
|
||||
field: &'static str,
|
||||
value: String,
|
||||
},
|
||||
/// Toggle the expanded colour palette for an MLeaderStyle colour field.
|
||||
MLeaderColorMore(&'static str),
|
||||
MLeaderStyleToggle(&'static str),
|
||||
MLeaderStyleSetEnum {
|
||||
field: &'static str,
|
||||
@@ -1254,6 +1265,8 @@ pub enum Message {
|
||||
// Field edit messages:
|
||||
DsEdit(DsField, String),
|
||||
DsToggle(DsField),
|
||||
/// Toggle the expanded colour palette for a DimStyle colour field.
|
||||
DsColorMore(DsField),
|
||||
/// Set a block/linetype Handle field on the selected dim style from a
|
||||
/// dropdown of available block-records / linetypes (by name).
|
||||
DsSetHandle {
|
||||
@@ -1429,6 +1442,7 @@ impl OpenCADStudio {
|
||||
ts_hmargin: "1.5".to_string(),
|
||||
ts_vmargin: "1.5".to_string(),
|
||||
ts_description: String::new(),
|
||||
ts_color_open: None,
|
||||
ts_cell_textstyle: Default::default(),
|
||||
ts_cell_height: Default::default(),
|
||||
ts_cell_textcolor: Default::default(),
|
||||
@@ -1443,6 +1457,7 @@ impl OpenCADStudio {
|
||||
mlstyle_selected: "Standard".to_string(),
|
||||
// MLeaderStyle dialog
|
||||
mleaderstyle_selected: "Standard".to_string(),
|
||||
mls_color_open: None,
|
||||
mls_landing_distance: String::new(),
|
||||
mls_landing_gap: String::new(),
|
||||
mls_arrowhead_size: String::new(),
|
||||
@@ -1465,6 +1480,7 @@ impl OpenCADStudio {
|
||||
mls_block_scale_z: String::new(),
|
||||
// DimStyle dialog
|
||||
dimstyle_selected: "Standard".to_string(),
|
||||
ds_color_open: None,
|
||||
dimstyle_tab: 0,
|
||||
ds_dimdle: "0".to_string(),
|
||||
ds_dimdli: "3.75".to_string(),
|
||||
|
||||
@@ -6535,6 +6535,14 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::TableColorMore(row, field) => {
|
||||
self.ts_color_open = if self.ts_color_open == Some((row, field)) {
|
||||
None
|
||||
} else {
|
||||
Some((row, field))
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::TableStyleCellEdit { row, field, value } => {
|
||||
let r = row as usize;
|
||||
if r < 3 {
|
||||
@@ -6985,6 +6993,14 @@ impl OpenCADStudio {
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderColorMore(field) => {
|
||||
self.mls_color_open = if self.mls_color_open == Some(field) {
|
||||
None
|
||||
} else {
|
||||
Some(field)
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleSetEnum { field, value } => {
|
||||
use acadrust::objects::{
|
||||
BlockContentConnectionType, LeaderContentType, LeaderDrawOrderType,
|
||||
@@ -7294,6 +7310,14 @@ impl OpenCADStudio {
|
||||
self.apply_ds_toggle(field);
|
||||
Task::none()
|
||||
}
|
||||
Message::DsColorMore(field) => {
|
||||
self.ds_color_open = if self.ds_color_open.as_ref() == Some(&field) {
|
||||
None
|
||||
} else {
|
||||
Some(field)
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::DsSetHandle { field, value } => {
|
||||
let i = self.active_tab;
|
||||
let name = self.dimstyle_selected.clone();
|
||||
|
||||
@@ -136,6 +136,7 @@ impl OpenCADStudio {
|
||||
&self.ts_border_spacing,
|
||||
self.style_rename.as_deref(),
|
||||
&self.style_rename_buf,
|
||||
self.ts_color_open,
|
||||
);
|
||||
}
|
||||
if Some(window_id) == self.mlstyle_window {
|
||||
@@ -286,6 +287,7 @@ impl OpenCADStudio {
|
||||
block_content_name,
|
||||
rename_active: self.style_rename.as_deref(),
|
||||
rename_buf: &self.style_rename_buf,
|
||||
color_open: self.mls_color_open,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -457,6 +459,7 @@ impl OpenCADStudio {
|
||||
dimltex2_name,
|
||||
block_opts,
|
||||
lt_opts,
|
||||
color_open: self.ds_color_open.clone(),
|
||||
},
|
||||
self.style_rename.as_deref(),
|
||||
&self.style_rename_buf,
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
//! Shared colour selector: a main-colour dropdown plus a "more colours" button
|
||||
//! that expands the full ACI palette. Used by the properties panel and every
|
||||
//! style editor so colour selection looks and behaves the same everywhere.
|
||||
|
||||
use crate::app::Message;
|
||||
use crate::ui::properties::acad_color_display;
|
||||
use acadrust::types::Color as AcadColor;
|
||||
use iced::widget::{button, column, container, pick_list, row, scrollable, text};
|
||||
use iced::{Background, Border, Color, Element, Theme};
|
||||
|
||||
/// Which "logical" entries the main dropdown offers besides the standard ACI
|
||||
/// colours.
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct ColorExtras {
|
||||
pub by_layer: bool,
|
||||
pub by_block: bool,
|
||||
}
|
||||
|
||||
/// Encode a colour as the ACI integer string the style editors store
|
||||
/// (ByBlock=0, ByLayer=256, indexed 1-255; RGB has no ACI slot → ByLayer).
|
||||
pub fn color_to_aci_string(c: AcadColor) -> String {
|
||||
match c {
|
||||
AcadColor::ByBlock => "0".to_string(),
|
||||
AcadColor::ByLayer => "256".to_string(),
|
||||
AcadColor::Index(i) => i.to_string(),
|
||||
AcadColor::Rgb { .. } => "256".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Decode an ACI integer string back into an `AcadColor`.
|
||||
pub fn aci_string_to_color(s: &str) -> AcadColor {
|
||||
match s.trim().parse::<i16>().unwrap_or(256) {
|
||||
0 => AcadColor::ByBlock,
|
||||
256 => AcadColor::ByLayer,
|
||||
n if (1..=255).contains(&n) => AcadColor::Index(n as u8),
|
||||
_ => AcadColor::ByLayer,
|
||||
}
|
||||
}
|
||||
|
||||
/// A dropdown option wrapping an `AcadColor`, displayed by its colour name.
|
||||
#[derive(Clone, PartialEq)]
|
||||
struct ColorChoice(AcadColor);
|
||||
|
||||
impl std::fmt::Display for ColorChoice {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let (_, name) = acad_color_display(self.0);
|
||||
write!(f, "{name}")
|
||||
}
|
||||
}
|
||||
|
||||
const PICKER_BG: Color = Color {
|
||||
r: 0.12,
|
||||
g: 0.12,
|
||||
b: 0.12,
|
||||
a: 1.0,
|
||||
};
|
||||
const BORDER: Color = Color {
|
||||
r: 0.35,
|
||||
g: 0.35,
|
||||
b: 0.35,
|
||||
a: 1.0,
|
||||
};
|
||||
|
||||
/// Build a colour selector.
|
||||
///
|
||||
/// * `current` — the currently selected colour (shown in the dropdown).
|
||||
/// * `palette_open` — whether the expanded 255-colour grid is shown.
|
||||
/// * `extras` — whether ByLayer / ByBlock appear in the dropdown.
|
||||
/// * `on_select` — called with the chosen colour (dropdown item or grid swatch).
|
||||
/// * `on_more` — toggles the expanded palette.
|
||||
pub fn color_selector<'a>(
|
||||
current: AcadColor,
|
||||
palette_open: bool,
|
||||
extras: ColorExtras,
|
||||
on_select: impl Fn(AcadColor) -> Message + 'a,
|
||||
on_more: Message,
|
||||
) -> Element<'a, Message> {
|
||||
// Standard ACI 1-7 plus the requested extras, and the current colour if it
|
||||
// isn't already one of them (so a non-standard index still shows).
|
||||
let mut opts: Vec<ColorChoice> = Vec::new();
|
||||
if extras.by_layer {
|
||||
opts.push(ColorChoice(AcadColor::ByLayer));
|
||||
}
|
||||
if extras.by_block {
|
||||
opts.push(ColorChoice(AcadColor::ByBlock));
|
||||
}
|
||||
for i in 1u8..=7 {
|
||||
opts.push(ColorChoice(AcadColor::Index(i)));
|
||||
}
|
||||
let cur_choice = ColorChoice(current);
|
||||
if !opts.contains(&cur_choice) {
|
||||
opts.push(cur_choice.clone());
|
||||
}
|
||||
|
||||
// Expanded ACI palette. Built before the dropdown closure so it can borrow
|
||||
// `on_select`; the dropdown then moves it.
|
||||
let grid: Option<Element<'a, Message>> = if palette_open {
|
||||
const COLS: u16 = 16;
|
||||
let mut rows = column![].spacing(1);
|
||||
let mut idx: u16 = 1;
|
||||
while idx <= 255 {
|
||||
let mut r = row![].spacing(1);
|
||||
for _ in 0..COLS {
|
||||
if idx > 255 {
|
||||
break;
|
||||
}
|
||||
let ci = idx as u8;
|
||||
let (bg, _) = acad_color_display(AcadColor::Index(ci));
|
||||
let msg = on_select(AcadColor::Index(ci));
|
||||
r = r.push(
|
||||
button(text("").width(12).height(12))
|
||||
.on_press(msg)
|
||||
.style(move |_: &Theme, status| button::Style {
|
||||
background: Some(Background::Color(bg)),
|
||||
border: Border {
|
||||
color: if matches!(status, button::Status::Hovered) {
|
||||
Color::WHITE
|
||||
} else {
|
||||
Color {
|
||||
r: 0.0,
|
||||
g: 0.0,
|
||||
b: 0.0,
|
||||
a: 0.4,
|
||||
}
|
||||
},
|
||||
width: if matches!(status, button::Status::Hovered) {
|
||||
1.5
|
||||
} else {
|
||||
1.0
|
||||
},
|
||||
radius: 1.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.padding(0),
|
||||
);
|
||||
idx += 1;
|
||||
}
|
||||
rows = rows.push(r);
|
||||
}
|
||||
Some(
|
||||
container(scrollable(rows).height(150))
|
||||
.style(|_: &Theme| container::Style {
|
||||
background: Some(Background::Color(PICKER_BG)),
|
||||
border: Border {
|
||||
color: BORDER,
|
||||
width: 1.0,
|
||||
radius: 0.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
.padding(4)
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let dropdown = pick_list(opts, Some(cur_choice), move |c| on_select(c.0))
|
||||
.text_size(11)
|
||||
.width(150);
|
||||
let more = button(text(if palette_open { "×" } else { "⋯" }).size(11))
|
||||
.on_press(on_more)
|
||||
.padding([2, 7]);
|
||||
let top = row![dropdown, more].spacing(4).align_y(iced::Center);
|
||||
|
||||
match grid {
|
||||
Some(g) => column![top, g].spacing(2).into(),
|
||||
None => top.into(),
|
||||
}
|
||||
}
|
||||
+19
-36
@@ -126,6 +126,8 @@ pub struct DimStyleValues<'a> {
|
||||
// Dropdown option lists shared by the arrowhead / linetype fields.
|
||||
pub block_opts: Vec<String>,
|
||||
pub lt_opts: Vec<String>,
|
||||
/// Colour field whose expanded palette is currently open.
|
||||
pub color_open: Option<DsField>,
|
||||
}
|
||||
|
||||
fn tab_btn_style(active: bool) -> impl Fn(&Theme, button::Status) -> button::Style {
|
||||
@@ -290,43 +292,24 @@ pub fn view_window<'a>(
|
||||
("6", "Windows desktop"),
|
||||
];
|
||||
|
||||
// ACI colour swatches (1-9) + ByLayer; reuses the existing DsEdit path
|
||||
// (the chosen index is sent as the field's string value).
|
||||
let color_row = move |label: &'static str, fld: DsField, val: &'a str| -> Element<'a, Message> {
|
||||
let cur: i16 = val.trim().parse().unwrap_or(256);
|
||||
let mut swatches = row![].spacing(2).align_y(iced::Center);
|
||||
for aci in 1u8..=9 {
|
||||
let c = acadrust::types::Color::from_index(aci as i16);
|
||||
let (bg, _) = crate::ui::properties::acad_color_display(c);
|
||||
let sel = cur == aci as i16;
|
||||
swatches = swatches.push(
|
||||
button(text("").width(16).height(14))
|
||||
.on_press(Message::DsEdit(fld.clone(), aci.to_string()))
|
||||
.style(move |_: &Theme, _| button::Style {
|
||||
background: Some(Background::Color(bg)),
|
||||
border: Border {
|
||||
color: if sel { Color::WHITE } else { Color::BLACK },
|
||||
width: if sel { 2.0 } else { 1.0 },
|
||||
radius: 2.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
}
|
||||
// ByLayer (256) chip.
|
||||
swatches = swatches.push(
|
||||
button(text("ByLayer").size(10))
|
||||
.on_press(Message::DsEdit(fld.clone(), "256".to_string()))
|
||||
.style(move |_: &Theme, _| button::Style {
|
||||
border: Border {
|
||||
color: if cur == 256 { Color::WHITE } else { BORDER },
|
||||
width: if cur == 256 { 2.0 } else { 1.0 },
|
||||
radius: 2.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
// Shared colour selector (main dropdown + "more" palette), reusing the
|
||||
// existing DsEdit path (the chosen colour is sent as an ACI string).
|
||||
let color_open = vals.color_open.clone();
|
||||
let color_row = move |label: &'static str, fld: DsField, _val: &'a str| -> Element<'a, Message> {
|
||||
let cur = crate::ui::color_select::aci_string_to_color(_val);
|
||||
let open = color_open.as_ref() == Some(&fld);
|
||||
let f_sel = fld.clone();
|
||||
let selector = crate::ui::color_select::color_selector(
|
||||
cur,
|
||||
open,
|
||||
crate::ui::color_select::ColorExtras {
|
||||
by_layer: true,
|
||||
by_block: true,
|
||||
},
|
||||
move |c| Message::DsEdit(f_sel.clone(), crate::ui::color_select::color_to_aci_string(c)),
|
||||
Message::DsColorMore(fld.clone()),
|
||||
);
|
||||
row![lbl(label), swatches]
|
||||
row![lbl(label), selector]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
|
||||
+27
-44
@@ -102,6 +102,8 @@ pub struct MLeaderStyleView<'a> {
|
||||
pub rename_active: Option<&'a str>,
|
||||
/// Edit buffer for the inline rename text input.
|
||||
pub rename_buf: &'a str,
|
||||
/// Colour field whose expanded palette is currently open.
|
||||
pub color_open: Option<&'static str>,
|
||||
}
|
||||
|
||||
fn section<'a>(label: &'static str) -> Element<'a, Message> {
|
||||
@@ -126,48 +128,29 @@ fn num_row<'a>(
|
||||
.into()
|
||||
}
|
||||
|
||||
/// ACI colour swatch row (1-9 + ByLayer). Reuses MLeaderStyleEdit by sending
|
||||
/// the chosen index as the field's string value.
|
||||
fn color_row<'a>(label: &'static str, value: &'a str, field: &'static str) -> Element<'a, Message> {
|
||||
let cur: i16 = value.trim().parse().unwrap_or(256);
|
||||
let mut swatches = row![].spacing(2).align_y(iced::Center);
|
||||
for aci in 1u8..=9 {
|
||||
let c = acadrust::types::Color::from_index(aci as i16);
|
||||
let (bg, _) = crate::ui::properties::acad_color_display(c);
|
||||
let sel = cur == aci as i16;
|
||||
swatches = swatches.push(
|
||||
button(text("").width(16).height(14))
|
||||
.on_press(Message::MLeaderStyleEdit {
|
||||
field,
|
||||
value: aci.to_string(),
|
||||
})
|
||||
.style(move |_: &Theme, _| button::Style {
|
||||
background: Some(Background::Color(bg)),
|
||||
border: Border {
|
||||
color: if sel { Color::WHITE } else { Color::BLACK },
|
||||
width: if sel { 2.0 } else { 1.0 },
|
||||
radius: 2.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
}
|
||||
swatches = swatches.push(
|
||||
button(text("ByLayer").size(10))
|
||||
.on_press(Message::MLeaderStyleEdit {
|
||||
field,
|
||||
value: "256".to_string(),
|
||||
})
|
||||
.style(move |_: &Theme, _| button::Style {
|
||||
border: Border {
|
||||
color: if cur == 256 { Color::WHITE } else { BORDER },
|
||||
width: if cur == 256 { 2.0 } else { 1.0 },
|
||||
radius: 2.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
/// Shared colour selector row. Reuses MLeaderStyleEdit by sending the chosen
|
||||
/// colour as an ACI string; `open` shows the expanded palette.
|
||||
fn color_row<'a>(
|
||||
label: &'static str,
|
||||
value: &'a str,
|
||||
field: &'static str,
|
||||
open: bool,
|
||||
) -> Element<'a, Message> {
|
||||
let cur = crate::ui::color_select::aci_string_to_color(value);
|
||||
let selector = crate::ui::color_select::color_selector(
|
||||
cur,
|
||||
open,
|
||||
crate::ui::color_select::ColorExtras {
|
||||
by_layer: true,
|
||||
by_block: true,
|
||||
},
|
||||
move |c| Message::MLeaderStyleEdit {
|
||||
field,
|
||||
value: crate::ui::color_select::color_to_aci_string(c),
|
||||
},
|
||||
Message::MLeaderColorMore(field),
|
||||
);
|
||||
row![text(label).size(11).color(DIM).width(150), swatches]
|
||||
row![text(label).size(11).color(DIM).width(150), selector]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
@@ -260,7 +243,7 @@ pub fn view_window<'a>(v: MLeaderStyleView<'a>) -> Element<'a, Message> {
|
||||
format!("{:?}", s.path_type),
|
||||
"path_type"
|
||||
),
|
||||
color_row("Line color (ACI):", v.line_color, "line_color"),
|
||||
color_row("Line color (ACI):", v.line_color, "line_color", v.color_open == Some("line_color")),
|
||||
num_row("Line weight:", "-2", v.line_weight, "line_weight"),
|
||||
handle_row(
|
||||
"Line type:",
|
||||
@@ -336,7 +319,7 @@ pub fn view_window<'a>(v: MLeaderStyleView<'a>) -> Element<'a, Message> {
|
||||
"text_style_handle"
|
||||
),
|
||||
num_row("Text height:", "0.18", v.text_height, "text_height"),
|
||||
color_row("Text color (ACI):", v.text_color, "text_color"),
|
||||
color_row("Text color (ACI):", v.text_color, "text_color", v.color_open == Some("text_color")),
|
||||
enum_row(
|
||||
"Text angle:",
|
||||
opts(&["ParallelToLastLeaderLine", "Horizontal", "Optimized"]),
|
||||
@@ -389,7 +372,7 @@ pub fn view_window<'a>(v: MLeaderStyleView<'a>) -> Element<'a, Message> {
|
||||
v.block_content_name.clone(),
|
||||
"block_content_handle"
|
||||
),
|
||||
color_row("Block color (ACI):", v.block_color, "block_color"),
|
||||
color_row("Block color (ACI):", v.block_color, "block_color", v.color_open == Some("block_color")),
|
||||
enum_row(
|
||||
"Block connection:",
|
||||
opts(&["BlockExtents", "BasePoint"]),
|
||||
|
||||
@@ -4,6 +4,7 @@ pub const ROW_H: f32 = 26.0;
|
||||
|
||||
pub mod about;
|
||||
pub mod app_menu;
|
||||
pub mod color_select;
|
||||
pub mod command_line;
|
||||
pub mod cycle_popup;
|
||||
pub mod dimstyle;
|
||||
|
||||
+19
-41
@@ -84,6 +84,7 @@ pub fn view_window<'a>(
|
||||
border_spacing: &'a [[String; 6]; 3],
|
||||
rename_active: Option<&'a str>,
|
||||
rename_buf: &'a str,
|
||||
color_open: Option<(u8, &'static str)>,
|
||||
) -> Element<'a, Message> {
|
||||
// ── Right: Details panel ──────────────────────────────────────────────
|
||||
let info_row = |label: &'static str, val: String| -> Element<'_, Message> {
|
||||
@@ -121,49 +122,26 @@ pub fn view_window<'a>(
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
};
|
||||
// ACI swatch row — sends the chosen index through the same cell edit.
|
||||
// Shared colour selector — sends the chosen colour through the same
|
||||
// cell edit as an ACI string.
|
||||
let cell_color = |label: &'static str, value: &'a str, field: &'static str| -> Element<'a, Message> {
|
||||
let cur: i16 = value.trim().parse().unwrap_or(256);
|
||||
let mut sw = row![].spacing(2).align_y(iced::Center);
|
||||
for aci in 1u8..=9 {
|
||||
let c = acadrust::types::Color::from_index(aci as i16);
|
||||
let (bg, _) = crate::ui::properties::acad_color_display(c);
|
||||
let sel = cur == aci as i16;
|
||||
sw = sw.push(
|
||||
button(text("").width(16).height(14))
|
||||
.on_press(Message::TableStyleCellEdit {
|
||||
row,
|
||||
field,
|
||||
value: aci.to_string(),
|
||||
})
|
||||
.style(move |_: &Theme, _| button::Style {
|
||||
background: Some(Background::Color(bg)),
|
||||
border: Border {
|
||||
color: if sel { Color::WHITE } else { Color::BLACK },
|
||||
width: if sel { 2.0 } else { 1.0 },
|
||||
radius: 2.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
}
|
||||
sw = sw.push(
|
||||
button(text("ByLayer").size(10))
|
||||
.on_press(Message::TableStyleCellEdit {
|
||||
row,
|
||||
field,
|
||||
value: "256".to_string(),
|
||||
})
|
||||
.style(move |_: &Theme, _| button::Style {
|
||||
border: Border {
|
||||
color: if cur == 256 { Color::WHITE } else { BORDER },
|
||||
width: if cur == 256 { 2.0 } else { 1.0 },
|
||||
radius: 2.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
}),
|
||||
let cur = crate::ui::color_select::aci_string_to_color(value);
|
||||
let open = color_open == Some((row, field));
|
||||
let selector = crate::ui::color_select::color_selector(
|
||||
cur,
|
||||
open,
|
||||
crate::ui::color_select::ColorExtras {
|
||||
by_layer: true,
|
||||
by_block: true,
|
||||
},
|
||||
move |c| Message::TableStyleCellEdit {
|
||||
row,
|
||||
field,
|
||||
value: crate::ui::color_select::color_to_aci_string(c),
|
||||
},
|
||||
Message::TableColorMore(row, field),
|
||||
);
|
||||
row![text(label).size(11).color(DIM).width(150), sw]
|
||||
row![text(label).size(11).color(DIM).width(150), selector]
|
||||
.spacing(8)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
|
||||
Reference in new issue
Block a user