fix(layers): preserve true colors

Closes #587
This commit is contained in:
Hakan Seven committed 2026-07-30 16:48:14 +03:00
1 parent 64d109a614
commit 1b1d9af2d5
5 files changed
+16 -69

No files matched your search

+1 -1
View File
@@ -64,7 +64,7 @@ impl OpenCADStudio {
.iter()
.map(|l| crate::ui::ribbon::LayerInfo {
name: l.name.clone(),
color: l.color,
color: crate::ui::window::layers::iced_color_from_acad(&l.color),
visible: l.visible,
frozen: l.frozen,
locked: l.locked,
+1 -1
View File
@@ -1708,7 +1708,7 @@ pub enum Message {
LayerRenameEdit(String),
LayerColorPickerToggle(usize),
LayerColorMorePalette,
LayerColorSet(u8),
LayerColorSet(acadrust::types::Color),
LayerLinetypeSet(String),
LayerLineweightSet(LineWeight),
LayerTransparencyEdit(usize, String),
+3 -6
View File
@@ -1,7 +1,6 @@
use super::{Message, OpenCADStudio};
use crate::scene::VIEWCUBE_DRAW_PX;
use crate::ui::PropertiesPanel;
use acadrust::types::Color as AcadColor;
use iced::time::Instant;
use iced::Task;
@@ -1998,22 +1997,20 @@ impl OpenCADStudio {
Task::none()
}
Message::LayerColorSet(aci) => {
Message::LayerColorSet(color) => {
let i = self.active_tab;
// Apply to every selected layer (multi-select), not just one.
let names = self.selected_layer_names(i);
if !names.is_empty() {
let undo = self.begin_layer_undo(i, "LAYER COLOR", &names);
use crate::ui::window::layers::iced_color_from_acad;
let new_color = iced_color_from_acad(&AcadColor::Index(aci));
for name in &names {
if let Some(dl) = self.tabs[i].scene.document.layers.get_mut(name) {
dl.color = AcadColor::Index(aci);
dl.color = color;
}
}
for pl in self.tabs[i].layers.layers.iter_mut() {
if names.contains(&pl.name) {
pl.color = new_color;
pl.color = color;
}
}
self.tabs[i].dirty = true;
+1 -8
View File
@@ -986,14 +986,7 @@ pub(super) fn on_text_style_dialog_open(&mut self) -> Task<Message> {
}
Some(crate::app::ColorPickTarget::Layer(idx)) => {
self.tabs[self.active_tab].layers.selected = Some(idx);
let index = match color {
acadrust::types::Color::Index(i) => i,
acadrust::types::Color::Rgb { r, g, b } => {
crate::ui::color_select::nearest_aci(r, g, b)
}
_ => 7,
};
Some(Message::LayerColorSet(index))
Some(Message::LayerColorSet(color))
}
Some(crate::app::ColorPickTarget::LayerState(idx)) => {
Some(Message::LayerStateEditorLayerColor(idx, color))
+10 -53
View File
@@ -84,7 +84,7 @@ pub struct Layer {
pub visible: bool,
pub frozen: bool,
pub locked: bool,
pub color: Color,
pub color: AcadColor,
pub linetype: String,
pub lineweight: LineWeight,
pub transparency: i32,
@@ -93,7 +93,7 @@ pub struct Layer {
}
impl Layer {
pub fn new(name: &str, color: Color) -> Self {
pub fn new(name: &str, color: AcadColor) -> Self {
Self {
name: name.to_string(),
visible: true,
@@ -143,7 +143,7 @@ impl Default for LayerPanel {
fn default() -> Self {
Self {
visible: false,
layers: vec![Layer::new("0", Color::WHITE)],
layers: vec![Layer::new("0", AcadColor::Index(7))],
selected: None,
selected_multi: Vec::new(),
editing: None,
@@ -212,7 +212,7 @@ impl LayerPanel {
visible: !l.flags.off,
frozen: l.flags.frozen,
locked: l.flags.locked,
color: iced_color_from_acad(&l.color),
color: l.color,
linetype: if l.line_type.is_empty() {
"Continuous".to_string()
} else {
@@ -526,7 +526,8 @@ fn layer_header_button_style(theme: &Theme, status: button::Status) -> button::S
}
/// Packed RGB key for ordering colours deterministically by hue-ish bytes.
fn color_sort_key(c: Color) -> u32 {
fn color_sort_key(c: AcadColor) -> u32 {
let c = iced_color_from_acad(&c);
let q = |v: f32| (v.clamp(0.0, 1.0) * 255.0).round() as u32;
(q(c.r) << 16) | (q(c.g) << 8) | q(c.b)
}
@@ -763,26 +764,20 @@ fn layer_row<'a>(
};
// Color cell — looks like a combo_box input; click opens swatch dropdown below row.
let aci = iced_to_aci(layer.color);
let cur_color_name = color_label_aci(aci).to_string();
let _ = cur_color_name;
// Shared colour selector. Layers carry a concrete colour (no ByLayer /
// ByBlock); the chosen index is applied to this row.
// ByBlock); true colours stay RGB instead of being collapsed to ACI 7.
let color_cell: Element<'_, Message> = container(crate::ui::color_select::color_selector(
acadrust::types::Color::Index(aci),
layer.color,
color_picker_open,
crate::ui::color_select::ColorExtras {
by_layer: false,
by_block: false,
},
|c| match c {
acadrust::types::Color::Index(i) => Message::LayerColorSet(i),
_ => Message::LayerColorSet(7),
},
Message::LayerColorSet,
Message::LayerColorPickerToggle(index),
Message::OpenColorWindow(
crate::app::ColorPickTarget::Layer(index),
acadrust::types::Color::Index(aci),
layer.color,
),
))
.width(Length::Fixed(COL_COLOR))
@@ -940,44 +935,6 @@ fn combo_input_style(
// ── Display helpers ───────────────────────────────────────────────────────
#[allow(dead_code)]
fn aci_color_display(i: u8) -> (Color, &'static str) {
let (r, g, b) = aci_to_rgb(i).unwrap_or((200, 200, 200));
(
Color::from_rgb(r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0),
"",
)
}
fn iced_to_aci(c: Color) -> u8 {
let r = (c.r * 255.0) as u8;
let g = (c.g * 255.0) as u8;
let b = (c.b * 255.0) as u8;
for i in 1u8..=255 {
if let Some((ar, ag, ab)) = aci_to_rgb(i) {
if ar == r && ag == g && ab == b {
return i;
}
}
}
7
}
fn color_label_aci(i: u8) -> &'static str {
match i {
1 => "red",
2 => "yellow",
3 => "green",
4 => "cyan",
5 => "blue",
6 => "magenta",
7 => "white",
8 => "dark gray",
9 => "gray",
_ => "white",
}
}
pub fn iced_color_from_acad(c: &AcadColor) -> Color {
match c {
AcadColor::Index(i) => {