forked from 1b-agent/opencadstudio-upstream
feat(block-editor): wire Rotation, Alignment and Flip parameter placement
Enable the existing palette rows and BPARAMETER choices. Rotation accepts a center, picked or numeric radius, and picked or numeric default angle. Alignment places a tangent direction from its base point. Flip places a reflection line and state label, with native grip and state expressions. Extend shared graph append/capacity checks for Flip's additional state node while preserving existing subgraphs. Keep Polar/Rotation angle labels unique in either placement order. Add editor graphics, extents and definition reframing through the existing overlay/history/save paths. This milestone implements native parameter placement and persistence. Rotate/Flip action association, reference alignment/grip editing, parameter property editing and parameter sets remain separate work. Validation covers command and palette placement, cancellation, local/parent undo, save/discard, native DWG/DXF objects, existing graph preservation and the 17 research fixtures. Broader block/dock regressions and editor renders are also checked.
This commit is contained in:
1 parent
6dab5a7229
commit
72c762e944
19 files changed
+1483
-25
No files matched your search
@@ -1019,6 +1019,7 @@ pub(crate) fn selection_overlay<'a>(
|
||||
|
||||
pub(crate) struct AuthoringDimension {
|
||||
pub lines: Vec<[Point; 2]>,
|
||||
pub round_grips: Vec<Point>,
|
||||
pub dimensions: Vec<[Point; 2]>,
|
||||
pub labels: Vec<(Point, String)>,
|
||||
pub grips: Vec<(Point, Option<Point>)>,
|
||||
@@ -2410,6 +2411,9 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
for point in &dimension.round_grips {
|
||||
frame.fill(&canvas::Path::circle(*point, 3.5), color);
|
||||
}
|
||||
for (point, base) in &dimension.grips {
|
||||
let marker = if let Some(base) = base {
|
||||
let dx = point.x - base.x;
|
||||
|
||||
@@ -192,6 +192,7 @@ fn catalog(
|
||||
tab: Tab,
|
||||
visibility_error: Option<&'static str>,
|
||||
point_error: Option<&'static str>,
|
||||
flip_error: Option<&'static str>,
|
||||
) -> Element<'static, Message> {
|
||||
let (entries, unavailable) = match tab {
|
||||
Tab::Parameters => (
|
||||
@@ -209,7 +210,9 @@ fn catalog(
|
||||
let visibility = tab == Tab::Parameters && *label == "Visibility";
|
||||
let point = tab == Tab::Parameters && *label == "Point";
|
||||
let distance = tab == Tab::Parameters && matches!(*label, "Linear" | "Polar" | "XY");
|
||||
let enabled = (visibility && visibility_error.is_none()) || ((point || distance) && point_error.is_none());
|
||||
let orientation = tab == Tab::Parameters && matches!(*label,"Rotation"|"Alignment"|"Flip");
|
||||
let orientation_error = if *label=="Flip" {flip_error} else {point_error};
|
||||
let enabled = (orientation && orientation_error.is_none()) || (visibility && visibility_error.is_none()) || ((point || distance) && point_error.is_none());
|
||||
let base = if enabled {
|
||||
icons::semantic(icon, 28.0)
|
||||
} else {
|
||||
@@ -244,6 +247,12 @@ fn catalog(
|
||||
.into_owned()
|
||||
} else if distance {
|
||||
crate::t!(point_error.unwrap_or("Place the base point, endpoint, and dimension label. Creates one end grip; associate an action to change geometry.")).into_owned()
|
||||
} else if orientation {
|
||||
crate::t!(orientation_error.unwrap_or(match *label {
|
||||
"Rotation" => "Place the center, specify a radius, then the default rotation angle.",
|
||||
"Alignment" => "Place the alignment base point and tangent direction.",
|
||||
_ => "Place a reflection line and its flip-state label. Associate a Flip action to mirror geometry.",
|
||||
})).into_owned()
|
||||
} else {
|
||||
unavailable.to_string()
|
||||
};
|
||||
@@ -254,6 +263,8 @@ fn catalog(
|
||||
container(entry).id("authoring-tool-point").into()
|
||||
} else if distance {
|
||||
container(entry).id(match *label { "Linear" => "authoring-tool-linear", "Polar" => "authoring-tool-polar", _ => "authoring-tool-xy" }).into()
|
||||
} else if orientation {
|
||||
container(entry).id(match *label {"Rotation"=>"authoring-tool-rotation","Alignment"=>"authoring-tool-alignment",_=>"authoring-tool-flip"}).into()
|
||||
} else {
|
||||
entry
|
||||
}
|
||||
@@ -366,6 +377,7 @@ pub fn view(
|
||||
chrome: Chrome,
|
||||
visibility_error: Option<&'static str>,
|
||||
point_error: Option<&'static str>,
|
||||
flip_error: Option<&'static str>,
|
||||
) -> Element<'static, Message> {
|
||||
let tabs = column(Tab::ALL.into_iter().map(|category| {
|
||||
let label = category.label();
|
||||
@@ -415,9 +427,14 @@ pub fn view(
|
||||
chrome,
|
||||
),
|
||||
row![
|
||||
scrollable(catalog(selected_tab, visibility_error, point_error))
|
||||
.width(Fill)
|
||||
.height(Fill),
|
||||
scrollable(catalog(
|
||||
selected_tab,
|
||||
visibility_error,
|
||||
point_error,
|
||||
flip_error
|
||||
))
|
||||
.width(Fill)
|
||||
.height(Fill),
|
||||
tabs
|
||||
]
|
||||
.spacing(4)
|
||||
|
||||
Reference in new issue
Block a user