forked from 1b-agent/opencadstudio-upstream
Clean up Graphic Attributes palette
- Revert formatting, import/module reordering and unrelated rewrites outside the feature (command.rs, style.rs, paper.rs, view/mod.rs, properties.rs, dialog.rs, ValuePromptCommand); the new SVG icons stay. - Move the palette logic out of dialog.rs into update/graphic_attributes.rs. - Replace 14 loose app fields and ~50 Message variants by GraphicAttributesState (one Menu enum for the open drop-down) and a nested GraphicAttributesMsg / GradientMsg, like BlockPaletteMsg. - Share the selection -> line/fill handles -> unlocked edit path, reuse valid_block_name, the ribbon lineweight handler and fill_handles, and drop the unused GradientColorToggle, color_open and LineLinetypeScaleInput. - Linetype scale accepts any positive value (e.g. ISO pen widths 0.13, 0.18, 0.25, 0.35) instead of rounding to 0.1 with a 0.1 minimum. - Closing open boundaries and creating the fill is one undo step. - The close prompt also answers typed Y/N + Enter, a bare Enter (Yes) and Escape (cancel), not only the option buttons. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VgkJN8DEojuPTumAXLHotu
This commit is contained in:
17 files changed
+3478
-3992
No files matched your search
+7
-27
@@ -2004,11 +2004,9 @@ impl Scene {
|
||||
let range = boundary.len()..boundary.len() + ring.len();
|
||||
boundary.extend(ring);
|
||||
local_boundary.extend(local_ring.iter().map(|&[x, y]| [x as f32, y as f32]));
|
||||
if path
|
||||
.edges
|
||||
.iter()
|
||||
.any(|edge| matches!(edge, acadrust::entities::BoundaryEdge::Spline(_)))
|
||||
{
|
||||
if path.edges.iter().any(|edge| {
|
||||
matches!(edge, acadrust::entities::BoundaryEdge::Spline(_))
|
||||
}) {
|
||||
spline_paths.push((path, local_ring, range));
|
||||
}
|
||||
boundary_exterior.push(depth == 0);
|
||||
@@ -2057,14 +2055,7 @@ impl Scene {
|
||||
.colors
|
||||
.get(i)
|
||||
.and_then(|e| e.color.rgb())
|
||||
.map(|(r, g, b)| {
|
||||
[
|
||||
r as f32 / 255.0,
|
||||
g as f32 / 255.0,
|
||||
b as f32 / 255.0,
|
||||
color[3],
|
||||
]
|
||||
})
|
||||
.map(|(r, g, b)| [r as f32 / 255.0, g as f32 / 255.0, b as f32 / 255.0, color[3]])
|
||||
};
|
||||
gradient_color1 = stop(0);
|
||||
let color1 = gradient_color1.unwrap_or(color);
|
||||
@@ -2221,21 +2212,13 @@ impl Scene {
|
||||
}
|
||||
let project = |point: [f64; 2]| {
|
||||
let [x, y] = to_xy(point[0], point[1]);
|
||||
[
|
||||
(x - world_origin[0]) as f32 as f64,
|
||||
(y - world_origin[1]) as f32 as f64,
|
||||
]
|
||||
[(x - world_origin[0]) as f32 as f64, (y - world_origin[1]) as f32 as f64]
|
||||
};
|
||||
for (path, ring, range) in spline_paths.into_iter().rev() {
|
||||
if range.end > boundary.len() {
|
||||
continue;
|
||||
}
|
||||
let curves = || {
|
||||
path.edges
|
||||
.iter()
|
||||
.filter_map(crate::entities::hatch::edge_curve)
|
||||
.collect()
|
||||
};
|
||||
let curves = || path.edges.iter().filter_map(crate::entities::hatch::edge_curve).collect();
|
||||
if let Some(refined) =
|
||||
cadkernel::geom2d::refine_spline_boundary(&ring, curves, &project)
|
||||
{
|
||||
@@ -2243,10 +2226,7 @@ impl Scene {
|
||||
continue;
|
||||
}
|
||||
boundary.splice(range.clone(), refined.iter().map(|p| to_xy(p[0], p[1])));
|
||||
local_boundary.splice(
|
||||
range,
|
||||
refined.into_iter().map(|[x, y]| [x as f32, y as f32]),
|
||||
);
|
||||
local_boundary.splice(range, refined.into_iter().map(|[x, y]| [x as f32, y as f32]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,7 +221,8 @@ fn valid_samples_are_unchanged_and_invalid_samples_stay_rejected() {
|
||||
|p| p
|
||||
)
|
||||
.is_none());
|
||||
assert!(refine_spline_boundary(&vec![[0.0; 2]; 513],
|
||||
assert!(refine_spline_boundary(
|
||||
&vec![[0.0; 2]; 513],
|
||||
|| panic!("size cap ignored"),
|
||||
|p| p
|
||||
)
|
||||
|
||||
@@ -362,8 +362,9 @@ impl HatchModel {
|
||||
self.pattern_segments_with_dot_length(Some(0.0))
|
||||
}
|
||||
|
||||
fn pattern_segments_with_dot_length(&self,
|
||||
plot_dot_length: Option<f64>
|
||||
fn pattern_segments_with_dot_length(
|
||||
&self,
|
||||
plot_dot_length: Option<f64>,
|
||||
) -> Vec<[[f64; 2]; 2]> {
|
||||
let HatchPattern::Pattern(families) = &self.pattern else {
|
||||
return Vec::new();
|
||||
|
||||
+22
-20
@@ -2,7 +2,8 @@
|
||||
use super::*;
|
||||
|
||||
impl Scene {
|
||||
pub(super) fn paper_viewport_handles(&self
|
||||
pub(super) fn paper_viewport_handles(
|
||||
&self,
|
||||
) -> (Handle, Handle, Arc<Vec<Handle>>) {
|
||||
{
|
||||
let cache = self.paper_viewport_cache.borrow();
|
||||
@@ -11,7 +12,7 @@ impl Scene {
|
||||
return (
|
||||
cache.layout_block,
|
||||
cache.sheet,
|
||||
Arc::clone(&cache.content)
|
||||
Arc::clone(&cache.content),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -122,8 +123,7 @@ impl Scene {
|
||||
) -> Vec<ViewportInstance> {
|
||||
if self.current_layout == "Model" {
|
||||
let tiles = self.model_tiles.borrow();
|
||||
let active = self.active_model_tile.get()
|
||||
.min(tiles.len().saturating_sub(1));
|
||||
let active = self.active_model_tile.get().min(tiles.len().saturating_sub(1));
|
||||
return tiles
|
||||
.iter()
|
||||
.enumerate()
|
||||
@@ -298,7 +298,9 @@ impl Scene {
|
||||
hatches.push(sheet);
|
||||
}
|
||||
hatches.extend(
|
||||
self.paper_canvas_hatches(tint_selected).iter().cloned()
|
||||
self.paper_canvas_hatches(tint_selected)
|
||||
.iter()
|
||||
.cloned(),
|
||||
);
|
||||
let hatches = Arc::new(hatches);
|
||||
let wipeouts = self.paper_canvas_wipeouts();
|
||||
@@ -375,8 +377,9 @@ impl Scene {
|
||||
|
||||
/// Physical sheet bounds in canvas pixels. Uses the same forced top-down
|
||||
/// paper transform as the GPU sheet viewport, ignoring stored camera twist.
|
||||
pub fn paper_sheet_screen_rect(&self,
|
||||
canvas_px: (f32, f32)
|
||||
pub fn paper_sheet_screen_rect(
|
||||
&self,
|
||||
canvas_px: (f32, f32),
|
||||
) -> Option<iced::Rectangle> {
|
||||
let ((x0, y0), (x1, y1)) = self.paper_limits()?;
|
||||
let (canvas_w, canvas_h) = canvas_px;
|
||||
@@ -474,13 +477,13 @@ impl Scene {
|
||||
)
|
||||
.is_some() =>
|
||||
{
|
||||
Self::hatch_model_from_dxf(dxf, model.color).unwrap_or_else(|| model.clone())
|
||||
Self::hatch_model_from_dxf(dxf, model.color)
|
||||
.unwrap_or_else(|| model.clone())
|
||||
}
|
||||
_ => model.clone(),
|
||||
};
|
||||
let style = self.render_style(entity);
|
||||
if matches!(
|
||||
m.pattern, model::hatch_model::HatchPattern::Gradient { .. }) {
|
||||
if matches!(m.pattern, model::hatch_model::HatchPattern::Gradient { .. }) {
|
||||
m.set_alpha(style.0[3]);
|
||||
} else {
|
||||
m.color = style.0;
|
||||
@@ -601,15 +604,13 @@ impl Scene {
|
||||
)
|
||||
.is_some() =>
|
||||
{
|
||||
Self::hatch_model_from_dxf(dxf, model.color).unwrap_or_else(|| model.clone())
|
||||
Self::hatch_model_from_dxf(dxf, model.color)
|
||||
.unwrap_or_else(|| model.clone())
|
||||
}
|
||||
_ => model.clone(),
|
||||
};
|
||||
let style = self.render_style(entity);
|
||||
if matches!(
|
||||
hatch.pattern,
|
||||
model::hatch_model::HatchPattern::Gradient { .. }
|
||||
) {
|
||||
if matches!(hatch.pattern, model::hatch_model::HatchPattern::Gradient { .. }) {
|
||||
hatch.set_alpha(style.0[3]);
|
||||
} else {
|
||||
hatch.color = style.0;
|
||||
@@ -722,9 +723,9 @@ impl Scene {
|
||||
// from a big symbol library) has viewports legitimately aimed at that
|
||||
// second cluster; testing only the dense one wrongly auto-fits them onto
|
||||
// the library. Fall back to the cluster box when no extents are known.
|
||||
let full_bounds = self.model_space_extents()
|
||||
.map(|(mn, mx)|
|
||||
(mn.x as f64, mn.y as f64, mx.x as f64, mx.y as f64));
|
||||
let full_bounds = self.model_space_extents().map(|(mn, mx)| {
|
||||
(mn.x as f64, mn.y as f64, mx.x as f64, mx.y as f64)
|
||||
});
|
||||
// Absolute drawing centre. Geometry now reaches the scene at absolute
|
||||
// (UTM) coordinates — the old code centred the overlap test and the
|
||||
// auto-fit on the origin, which was right only while world_offset
|
||||
@@ -741,8 +742,9 @@ impl Scene {
|
||||
(self.local_center[0], self.local_center[1])
|
||||
} else {
|
||||
self.model_space_extents()
|
||||
.map(|(mn, mx)|
|
||||
(((mn.x + mx.x) * 0.5) as f64, ((mn.y + mx.y) * 0.5) as f64))
|
||||
.map(|(mn, mx)| {
|
||||
(((mn.x + mx.x) * 0.5) as f64, ((mn.y + mx.y) * 0.5) as f64)
|
||||
})
|
||||
.unwrap_or((0.0, 0.0))
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user