forked from 1b-agent/opencadstudio-upstream
feat(hatch): editable gradient colors + background color
Gradient Type (One/Two color), Color 1 and Color 2 editable via a generic field-keyed colour picker path. Background colour editable and stored as HATCHBACKGROUNDCOLOR extended data (group 1071 true colour), rendered in OCS as a solid backdrop drawn behind the pattern. Hide Origin X/Y for gradients (pattern-only concept) and drop the redundant gradient rows from the pattern branch. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
22059e138c
commit
b5106c82b5
5 files changed
+190
-27
No files matched your search
@@ -1558,6 +1558,12 @@ pub enum Message {
|
||||
/// User picked an MTEXT background fill colour — sets `background_color`
|
||||
/// and switches the background mode to Fill so it shows immediately.
|
||||
PropBgColorChanged(AcadColor),
|
||||
/// Toggle the generic per-field colour picker (e.g. a hatch gradient colour)
|
||||
/// identified by its property field name.
|
||||
PropColorFieldToggle(String),
|
||||
/// User picked a colour for a generic per-field colour row (hatch gradient
|
||||
/// `Color 1` / `Color 2`), routed by the field name.
|
||||
PropColorFieldChanged { field: String, color: AcadColor },
|
||||
/// Collapse the inline color picker dropdown. Fired when another
|
||||
/// properties-panel dropdown (a combo_box) opens, so at most one panel
|
||||
/// dropdown is open at a time and they can't overlap. (#235)
|
||||
|
||||
+60
-7
@@ -2279,13 +2279,18 @@ impl OpenCADStudio {
|
||||
if !handles.is_empty() {
|
||||
self.push_undo_snapshot(i, "CHPROP");
|
||||
for &handle in &handles {
|
||||
if let Some(acadrust::EntityType::MText(m)) =
|
||||
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||
{
|
||||
m.background_color = color.clone();
|
||||
// Picking a colour turns the background on in Fill
|
||||
// mode (specific colour), preserving the frame bit.
|
||||
m.background_fill_flags = (m.background_fill_flags & !0x02) | 0x01;
|
||||
match self.tabs[i].scene.document.get_entity_mut(handle) {
|
||||
Some(acadrust::EntityType::MText(m)) => {
|
||||
m.background_color = color.clone();
|
||||
// Picking a colour turns the background on in Fill
|
||||
// mode (specific colour), preserving the frame bit.
|
||||
m.background_fill_flags =
|
||||
(m.background_fill_flags & !0x02) | 0x01;
|
||||
}
|
||||
Some(acadrust::EntityType::Hatch(h)) => {
|
||||
crate::entities::hatch::set_background_color(h, &color);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.invalidate_property_targets(i, &handles);
|
||||
@@ -2296,6 +2301,54 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::PropColorFieldToggle(field) => {
|
||||
let i = self.active_tab;
|
||||
let p = &mut self.tabs[i].properties;
|
||||
p.open_color_field = if p.open_color_field.as_deref() == Some(field.as_str()) {
|
||||
None
|
||||
} else {
|
||||
Some(field)
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::PropColorFieldChanged { field, color } => {
|
||||
let i = self.active_tab;
|
||||
let handles = self.property_target_handles(i);
|
||||
if !handles.is_empty() {
|
||||
self.push_undo_snapshot(i, "CHPROP");
|
||||
let idx = if field == "gradient_color_2" { 1 } else { 0 };
|
||||
for &handle in &handles {
|
||||
if let Some(acadrust::EntityType::Hatch(h)) =
|
||||
self.tabs[i].scene.document.get_entity_mut(handle)
|
||||
{
|
||||
while h.gradient_color.colors.len() <= idx {
|
||||
let value = if h.gradient_color.colors.is_empty() {
|
||||
0.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
h.gradient_color.colors.push(
|
||||
acadrust::entities::hatch::GradientColorEntry {
|
||||
value,
|
||||
color: acadrust::types::Color::Index(7),
|
||||
},
|
||||
);
|
||||
}
|
||||
h.gradient_color.colors[idx].color = color.clone();
|
||||
}
|
||||
}
|
||||
// Rebuild hatch seeds so the gradient fill picks up the new
|
||||
// colour (synced_hatch_models only patches the main colour).
|
||||
self.tabs[i].scene.populate_hatches_from_document();
|
||||
self.invalidate_property_targets(i, &handles);
|
||||
self.tabs[i].properties.open_color_field = None;
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::PropColorPickerClose => {
|
||||
let i = self.active_tab;
|
||||
self.tabs[i].properties.color_picker_open = false;
|
||||
|
||||
Reference in new issue
Block a user