forked from 1b-agent/opencadstudio-upstream
fix(color): show color book identity
This commit is contained in:
1 parent
7ea4f338f6
commit
6d6defa0ad
19 files changed
+142
-30
No files matched your search
Generated
+1
-1
@@ -72,7 +72,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
|
||||
[[package]]
|
||||
name = "acadrust"
|
||||
version = "0.4.1"
|
||||
source = "git+https://[email protected]/HakanSeven12/cadcodec.git?rev=c91a1c1de89a0fbc006dc360ddb0251ac8c207d1#c91a1c1de89a0fbc006dc360ddb0251ac8c207d1"
|
||||
source = "git+https://[email protected]/HakanSeven12/cadcodec.git?rev=a0f7d444f1607bc4b2c881060cbe7ea1014253cb#a0f7d444f1607bc4b2c881060cbe7ea1014253cb"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"anyhow",
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ glam = { version = "0.33", features = ["bytemuck"] }
|
||||
rfd = "0.17"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
env_logger = "0.11"
|
||||
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "c91a1c1de89a0fbc006dc360ddb0251ac8c207d1", features = ["serde"] }
|
||||
acadrust = { git = "https://github.com/HakanSeven12/cadcodec.git", rev = "a0f7d444f1607bc4b2c881060cbe7ea1014253cb", features = ["serde"] }
|
||||
cadkernel = { git = "https://github.com/HakanSeven12/cadkernel.git", rev = "48c634995fa60d3928c37bae49b12b421c56c886", features = ["acis", "offset"] }
|
||||
dwg-thumbnailer = { path = "crates/dwg-thumbnailer" }
|
||||
flate2 = "1"
|
||||
@@ -61,7 +61,7 @@ iced_core = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aa
|
||||
iced_widget = { git = "https://github.com/iced-rs/iced.git", rev = "23604ff22ab0aad9e00b9327cb7b8546ed84db39" }
|
||||
|
||||
[patch."https://github.com/HakanSeven12/cadcodec.git"]
|
||||
acadrust = { git = "https://[email protected]/HakanSeven12/cadcodec.git", rev = "c91a1c1de89a0fbc006dc360ddb0251ac8c207d1" }
|
||||
acadrust = { git = "https://[email protected]/HakanSeven12/cadcodec.git", rev = "a0f7d444f1607bc4b2c881060cbe7ea1014253cb" }
|
||||
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
|
||||
@@ -2466,6 +2466,7 @@ impl OpenCADStudio {
|
||||
dst_common.linetype_handle = common.linetype_handle;
|
||||
dst_common.linetype_scale = common.linetype_scale;
|
||||
dst_common.transparency = common.transparency.clone();
|
||||
dst_common.color_name = common.color_name.clone();
|
||||
dst_common.color_book_handle = common.color_book_handle;
|
||||
dst_common.full_visual_style_handle =
|
||||
common.full_visual_style_handle;
|
||||
|
||||
@@ -128,6 +128,8 @@ impl OpenCADStudio {
|
||||
if let Some(l) = self.tabs[i].scene.document.layers.get_mut(&layer_name)
|
||||
{
|
||||
l.color = acadrust::types::Color::from_index(idx);
|
||||
l.color_name = None;
|
||||
l.book_name = None;
|
||||
self.push_undo_snapshot(i, "LAYER COLOR");
|
||||
self.tabs[i].dirty = true;
|
||||
// By-layer colour is baked into every wire on
|
||||
|
||||
@@ -616,6 +616,8 @@ impl OpenCADStudio {
|
||||
}
|
||||
"COLOR" => {
|
||||
common.color = color_val.unwrap();
|
||||
common.color_name = None;
|
||||
common.color_book_handle = None;
|
||||
changed += 1;
|
||||
}
|
||||
"TRANSPARENCY" => {
|
||||
@@ -661,6 +663,8 @@ impl OpenCADStudio {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(*handle) {
|
||||
let common = entity.common_mut();
|
||||
common.color = acadrust::types::Color::ByLayer;
|
||||
common.color_name = None;
|
||||
common.color_book_handle = None;
|
||||
common.linetype = "ByLayer".to_string();
|
||||
common.line_weight = acadrust::types::LineWeight::ByLayer;
|
||||
changed += 1;
|
||||
|
||||
+48
-19
@@ -509,37 +509,59 @@ impl OpenCADStudio {
|
||||
{
|
||||
let doc = &self.tabs[i].scene.document;
|
||||
let common = entity.common();
|
||||
if let Some(acadrust::objects::ObjectType::BookColor(book)) = common
|
||||
let named_color = common
|
||||
.color_book_handle
|
||||
.filter(|handle| handle.is_valid())
|
||||
.and_then(|handle| doc.objects.get(&handle))
|
||||
{
|
||||
.and_then(|object| match object {
|
||||
acadrust::objects::ObjectType::BookColor(book) => Some((
|
||||
book.color,
|
||||
book.book_name.clone(),
|
||||
book.color_name.clone(),
|
||||
)),
|
||||
_ => None,
|
||||
})
|
||||
.or_else(|| {
|
||||
let identity = common.color_name.as_deref()?;
|
||||
let (book_name, color_name) = identity
|
||||
.split_once('$')
|
||||
.map(|(book, color)| (book.to_string(), color.to_string()))
|
||||
.unwrap_or_else(|| (String::new(), identity.to_string()));
|
||||
Some((common.color, book_name, color_name))
|
||||
});
|
||||
if let Some((color, book_name, color_name)) = named_color {
|
||||
for section in sections.iter_mut() {
|
||||
if let Some(row) =
|
||||
section.props.iter_mut().find(|row| row.field == "color")
|
||||
{
|
||||
row.value =
|
||||
crate::scene::model::object::PropValue::ColorChoice(
|
||||
book.color,
|
||||
);
|
||||
row.value = crate::scene::model::object::PropValue::NamedColorChoice {
|
||||
color,
|
||||
name: color_name.clone(),
|
||||
};
|
||||
}
|
||||
}
|
||||
use crate::entities::common::ro_prop;
|
||||
let mut props = Vec::new();
|
||||
if !book_name.is_empty() {
|
||||
props.push(ro_prop(
|
||||
t!("Book").as_ref(),
|
||||
"book_color_book",
|
||||
book_name,
|
||||
));
|
||||
}
|
||||
props.push(ro_prop(
|
||||
t!("Color Name").as_ref(),
|
||||
"book_color_name",
|
||||
color_name,
|
||||
));
|
||||
props.push(ro_prop(
|
||||
t!("Color").as_ref(),
|
||||
"book_color_value",
|
||||
format!("{:?}", color),
|
||||
));
|
||||
sections.push(crate::scene::model::object::PropSection {
|
||||
title: t!("Color Book").into_owned(),
|
||||
props: vec![
|
||||
ro_prop(t!("Book").as_ref(), "book_color_book", book.book_name.clone()),
|
||||
ro_prop(
|
||||
t!("Color Name").as_ref(),
|
||||
"book_color_name",
|
||||
book.color_name.clone(),
|
||||
),
|
||||
ro_prop(
|
||||
t!("Color").as_ref(),
|
||||
"book_color_value",
|
||||
format!("{:?}", book.color),
|
||||
),
|
||||
],
|
||||
props,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2916,6 +2938,7 @@ fn make_sections_read_only(
|
||||
acadrust::types::Color::Index(index) => index.to_string(),
|
||||
acadrust::types::Color::Rgb { r, g, b } => format!("{r},{g},{b}"),
|
||||
},
|
||||
PropValue::NamedColorChoice { name, .. } => name.clone(),
|
||||
PropValue::ColorVaries
|
||||
| PropValue::LwVaries
|
||||
| PropValue::FieldLwVaries { .. } => VARIES_LABEL.to_string(),
|
||||
@@ -3075,6 +3098,9 @@ fn merge_prop_value(
|
||||
PropValue::LayerChoice(VARIES_LABEL.into())
|
||||
}
|
||||
(PropValue::ColorChoice(_), PropValue::ColorChoice(_))
|
||||
| (PropValue::NamedColorChoice { .. }, PropValue::NamedColorChoice { .. })
|
||||
| (PropValue::ColorChoice(_), PropValue::NamedColorChoice { .. })
|
||||
| (PropValue::NamedColorChoice { .. }, PropValue::ColorChoice(_))
|
||||
| (PropValue::ColorVaries, _)
|
||||
| (_, PropValue::ColorVaries) => PropValue::ColorVaries,
|
||||
(PropValue::LwChoice(_), PropValue::LwChoice(_))
|
||||
@@ -3261,6 +3287,9 @@ fn update_row_color(
|
||||
};
|
||||
match &mut row.value {
|
||||
PropValue::ColorChoice(current) => *current = color,
|
||||
PropValue::NamedColorChoice { .. } => {
|
||||
row.value = PropValue::ColorChoice(color)
|
||||
}
|
||||
PropValue::ReadOnly(current) => *current = label,
|
||||
PropValue::ReadOnlyWithTooltip { value: current, .. } => *current = label,
|
||||
_ => {}
|
||||
|
||||
@@ -3226,6 +3226,8 @@ fn apply_attr_row(a: &mut acadrust::entities::AttributeEntity, row: &AttrRow) ->
|
||||
}
|
||||
if a.common.color != row.color {
|
||||
a.common.color = row.color;
|
||||
a.common.color_name = None;
|
||||
a.common.color_book_handle = None;
|
||||
ch = true;
|
||||
}
|
||||
if a.common.linetype != row.linetype {
|
||||
|
||||
@@ -2633,11 +2633,15 @@ impl OpenCADStudio {
|
||||
for name in &names {
|
||||
if let Some(dl) = self.tabs[i].scene.document.layers.get_mut(name) {
|
||||
dl.color = color;
|
||||
dl.color_name = None;
|
||||
dl.book_name = None;
|
||||
}
|
||||
}
|
||||
for pl in self.tabs[i].layers.layers.iter_mut() {
|
||||
if names.contains(&pl.name) {
|
||||
pl.color = color;
|
||||
pl.color_name = None;
|
||||
pl.book_name = None;
|
||||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
|
||||
@@ -1750,6 +1750,8 @@ pub(crate) fn block_content_insert(
|
||||
insert.normal = ml.context.block_content_normal;
|
||||
insert.common = ml.common.clone();
|
||||
insert.common.color = ml.block_content_color.clone();
|
||||
insert.common.color_name = None;
|
||||
insert.common.color_book_handle = None;
|
||||
Some(insert)
|
||||
}
|
||||
|
||||
|
||||
@@ -215,6 +215,8 @@ pub fn merge_layer(scene: &mut Scene, from: &str, to: &str, force_bylayer: bool)
|
||||
common.layer = to.to_string();
|
||||
if force_bylayer {
|
||||
common.color = acadrust::Color::ByLayer;
|
||||
common.color_name = None;
|
||||
common.color_book_handle = None;
|
||||
common.linetype = String::new();
|
||||
common.linetype_handle = None;
|
||||
common.line_weight = acadrust::LineWeight::ByLayer;
|
||||
|
||||
@@ -260,6 +260,8 @@ fn blend_common(source: &EntityCommon) -> EntityCommon {
|
||||
let mut common = EntityCommon::new();
|
||||
common.layer = source.layer.clone();
|
||||
common.color = source.color;
|
||||
common.color_name = source.color_name.clone();
|
||||
common.color_book_handle = source.color_book_handle;
|
||||
common.line_weight = source.line_weight;
|
||||
common.linetype = source.linetype.clone();
|
||||
common.linetype_handle = source.linetype_handle;
|
||||
|
||||
@@ -714,6 +714,8 @@ fn dim_common(base: &acadrust::entities::EntityCommon, clr: i16, lw: i16) -> aca
|
||||
c.handle = Handle::NULL;
|
||||
if clr != 0 && clr != 256 {
|
||||
c.color = acadrust::types::Color::from_index(clr);
|
||||
c.color_name = None;
|
||||
c.color_book_handle = None;
|
||||
}
|
||||
if lw >= 0 {
|
||||
c.line_weight = acadrust::types::LineWeight::from_value(lw);
|
||||
@@ -1223,6 +1225,8 @@ fn explode_dimension(dim: &Dimension, doc: &CadDocument) -> Vec<EntityType> {
|
||||
// Apply the text colour / lineweight (DIMCLRT) onto the entity.
|
||||
let tc = dim_common(&base.common, met.dimclrt, -2);
|
||||
tent.common_mut().color = tc.color;
|
||||
tent.common_mut().color_name = tc.color_name;
|
||||
tent.common_mut().color_book_handle = tc.color_book_handle;
|
||||
tent.common_mut().line_weight = tc.line_weight;
|
||||
result.push(tent);
|
||||
}
|
||||
|
||||
Vendored
+13
-1
@@ -17,6 +17,18 @@ pub fn general_section(entity: &EntityType) -> PropSection {
|
||||
((alpha as f64 / 255.0 * 100.0).round() as u32).to_string()
|
||||
}
|
||||
};
|
||||
let color_value = common.color_name.as_deref().map_or_else(
|
||||
|| PropValue::ColorChoice(common.color),
|
||||
|identity| PropValue::NamedColorChoice {
|
||||
color: common.color,
|
||||
name: identity
|
||||
.split_once('$')
|
||||
.map(|(_, color_name)| color_name)
|
||||
.filter(|color_name| !color_name.is_empty())
|
||||
.unwrap_or(identity)
|
||||
.to_string(),
|
||||
},
|
||||
);
|
||||
|
||||
// Hyperlink is stored in XDATA under the "PE_URL" application.
|
||||
let hyperlink = common
|
||||
@@ -36,7 +48,7 @@ pub fn general_section(entity: &EntityType) -> PropSection {
|
||||
Property {
|
||||
label: t!("Color").into_owned(),
|
||||
field: "color",
|
||||
value: PropValue::ColorChoice(common.color),
|
||||
value: color_value,
|
||||
},
|
||||
Property {
|
||||
label: t!("Layer").into_owned(),
|
||||
|
||||
@@ -30,6 +30,8 @@ pub enum PropValue {
|
||||
},
|
||||
/// ACI/RGB/ByLayer/ByBlock color — rendered as a color picker.
|
||||
ColorChoice(AcadColor),
|
||||
/// Color-book color with its file-provided display name.
|
||||
NamedColorChoice { color: AcadColor, name: String },
|
||||
/// Color varies across the current multi-selection.
|
||||
ColorVaries,
|
||||
/// Line weight — rendered as a combo_box.
|
||||
|
||||
+10
-2
@@ -568,7 +568,8 @@ impl Scene {
|
||||
}
|
||||
QSelectValueEditor::Choice(values)
|
||||
}
|
||||
PropValue::ColorChoice(_) => QSelectValueEditor::Choice(vec![
|
||||
PropValue::ColorChoice(_)
|
||||
| PropValue::NamedColorChoice { .. } => QSelectValueEditor::Choice(vec![
|
||||
"ByLayer".into(),
|
||||
"ByBlock".into(),
|
||||
]),
|
||||
@@ -659,7 +660,13 @@ impl Scene {
|
||||
match field {
|
||||
"handle" => Some(entity.common().handle.value().to_string()),
|
||||
"layer" => Some(entity.common().layer.clone()),
|
||||
"color" => Some(Self::format_color(entity.common().color)),
|
||||
"color" => Some(
|
||||
entity
|
||||
.common()
|
||||
.color_name
|
||||
.clone()
|
||||
.unwrap_or_else(|| Self::format_color(entity.common().color)),
|
||||
),
|
||||
"linetype" => Some(if entity.common().linetype.is_empty() {
|
||||
"ByLayer".to_string()
|
||||
} else {
|
||||
@@ -732,6 +739,7 @@ impl Scene {
|
||||
PropValue::Choice { selected, .. } => selected,
|
||||
PropValue::EditChoice { value, .. } => value,
|
||||
PropValue::ColorChoice(c) => Self::format_color(c),
|
||||
PropValue::NamedColorChoice { name, .. } => name,
|
||||
PropValue::LwChoice(lw)
|
||||
| PropValue::FieldLwChoice { value: lw, .. } => {
|
||||
Self::format_lineweight(lw)
|
||||
|
||||
@@ -296,7 +296,9 @@ pub fn toggle_invisible(entity: &mut EntityType) {
|
||||
|
||||
pub fn apply_color(entity: &mut EntityType, color: AcadColor) {
|
||||
entity.as_entity_mut().set_color(color);
|
||||
entity.common_mut().color_book_handle = None;
|
||||
let common = entity.common_mut();
|
||||
common.color_name = None;
|
||||
common.color_book_handle = None;
|
||||
}
|
||||
|
||||
pub fn apply_line_weight(entity: &mut EntityType, lw: LineWeight) {
|
||||
|
||||
+23
-1
@@ -124,9 +124,31 @@ pub fn color_selector<'a>(
|
||||
on_select: impl Fn(AcadColor) -> Message + 'a,
|
||||
on_toggle: Message,
|
||||
on_more: Message,
|
||||
) -> Element<'a, Message> {
|
||||
color_selector_with_name(
|
||||
current,
|
||||
None,
|
||||
open,
|
||||
extras,
|
||||
on_select,
|
||||
on_toggle,
|
||||
on_more,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn color_selector_with_name<'a>(
|
||||
current: AcadColor,
|
||||
display_name: Option<&'a str>,
|
||||
open: bool,
|
||||
extras: ColorExtras,
|
||||
on_select: impl Fn(AcadColor) -> Message + 'a,
|
||||
on_toggle: Message,
|
||||
on_more: Message,
|
||||
) -> Element<'a, Message> {
|
||||
let (cur_bg, _) = acad_color_display(current);
|
||||
let cur_name = color_display_name(current);
|
||||
let cur_name = display_name
|
||||
.map(str::to_string)
|
||||
.unwrap_or_else(|| color_display_name(current));
|
||||
let on_dismiss = on_toggle.clone();
|
||||
|
||||
// Closed button: current swatch + name + caret.
|
||||
|
||||
@@ -776,7 +776,12 @@ impl PropertiesPanel {
|
||||
label: &'a str,
|
||||
) -> Element<'a, Message> {
|
||||
match &prop.value {
|
||||
PropValue::ColorChoice(color) => self.render_color_row(label, prop.field, *color),
|
||||
PropValue::ColorChoice(color) => {
|
||||
self.render_color_row(label, prop.field, *color, None)
|
||||
}
|
||||
PropValue::NamedColorChoice { color, name } => {
|
||||
self.render_color_row(label, prop.field, *color, Some(name))
|
||||
}
|
||||
PropValue::ColorVaries => self.render_color_varies_row(label),
|
||||
PropValue::LayerChoice(layer) => self.render_layer_row(label, layer),
|
||||
PropValue::LwChoice(lw) => self.render_lw_row(label, *lw),
|
||||
@@ -848,6 +853,7 @@ impl PropertiesPanel {
|
||||
label: &'a str,
|
||||
field: &'static str,
|
||||
color: AcadColor,
|
||||
display_name: Option<&'a str>,
|
||||
) -> Element<'a, Message> {
|
||||
// MTEXT background colour uses its own picker state + messages so it
|
||||
// routes to `background_color`, not the entity's main colour.
|
||||
@@ -929,8 +935,9 @@ impl PropertiesPanel {
|
||||
);
|
||||
return prop_row_widget(label, selector);
|
||||
}
|
||||
let selector = crate::ui::color_select::color_selector(
|
||||
let selector = crate::ui::color_select::color_selector_with_name(
|
||||
color,
|
||||
display_name,
|
||||
self.color_picker_open,
|
||||
crate::ui::color_select::ColorExtras {
|
||||
by_layer: true,
|
||||
|
||||
@@ -90,6 +90,8 @@ pub struct Layer {
|
||||
pub locked: bool,
|
||||
pub plottable: bool,
|
||||
pub color: AcadColor,
|
||||
pub color_name: Option<String>,
|
||||
pub book_name: Option<String>,
|
||||
pub linetype: String,
|
||||
pub lineweight: LineWeight,
|
||||
pub transparency: i32,
|
||||
@@ -106,6 +108,8 @@ impl Layer {
|
||||
locked: false,
|
||||
plottable: true,
|
||||
color,
|
||||
color_name: None,
|
||||
book_name: None,
|
||||
linetype: "Continuous".to_string(),
|
||||
lineweight: LineWeight::Default,
|
||||
transparency: 0,
|
||||
@@ -220,6 +224,8 @@ impl LayerPanel {
|
||||
locked: l.flags.locked,
|
||||
plottable: l.is_plottable,
|
||||
color: l.color,
|
||||
color_name: l.color_name.clone(),
|
||||
book_name: l.book_name.clone(),
|
||||
linetype: if l.line_type.is_empty() {
|
||||
"Continuous".to_string()
|
||||
} else {
|
||||
@@ -808,8 +814,9 @@ fn layer_row<'a>(
|
||||
// Color cell — looks like a combo_box input; click opens swatch dropdown below row.
|
||||
// Shared colour selector. Layers carry a concrete colour (no ByLayer /
|
||||
// ByBlock); true colours stay RGB instead of being collapsed to ACI 7.
|
||||
let color_cell: Element<'_, Message> = container(crate::ui::color_select::color_selector(
|
||||
let color_cell: Element<'_, Message> = container(crate::ui::color_select::color_selector_with_name(
|
||||
layer.color,
|
||||
layer.color_name.as_deref(),
|
||||
color_picker_open,
|
||||
crate::ui::color_select::ColorExtras {
|
||||
by_layer: false,
|
||||
|
||||
Reference in new issue
Block a user