forked from 1b-agent/opencadstudio-upstream
feat: annotation scale system (CANNOSCALE, PSLTSCALE, MultiLeader, Leader)
- Scale popup dropdown replaces cycle behavior; paper-space viewport scale editable when a viewport is active/selected - CANNOSCALE persisted via DXF $USERR1 (read on open, write on save) - PSLTSCALE: linetype dash lengths scaled by viewport anno_scale so dashes appear uniform physical size in paper space - MultiLeader: arrow size, dogleg length, and text height scale with anno_scale; leader line paths (world coords) stay fixed - Leader: arrow size and hookline length scale with anno_scale; also corrects world_offset subtraction that was previously deferred to the TruckObject::Lines path Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
543c626feb
commit
0e5dec0948
9 files changed
+471
-162
No files matched your search
@@ -39,6 +39,7 @@ pub(super) struct H7CAD {
|
||||
vp_size: (f32, f32),
|
||||
snapper: Snapper,
|
||||
snap_popup_open: bool,
|
||||
scale_popup_open: bool,
|
||||
/// Whether Tangent snap was enabled before a tangent-pick command started.
|
||||
pre_cmd_tangent: Option<bool>,
|
||||
/// Orthogonal drawing constraint (F8): constrains picks to 0°/90°/180°/270°.
|
||||
@@ -322,6 +323,14 @@ pub enum Message {
|
||||
TogglePolar,
|
||||
/// Set polar tracking angle increment (right-click POLAR button).
|
||||
SetPolarAngle(f32),
|
||||
/// Set the model-space annotation scale (CANNOSCALE equivalent).
|
||||
SetAnnotationScale(f32),
|
||||
/// Set the active viewport's custom_scale (paper space).
|
||||
SetViewportScale(f64),
|
||||
/// Toggle the scale picker popup open/closed.
|
||||
ToggleScalePopup,
|
||||
/// Close the scale picker popup.
|
||||
CloseScalePopup,
|
||||
/// Toggle dynamic input overlay (F12).
|
||||
ToggleDynInput,
|
||||
/// Toggle object snap tracking (F11).
|
||||
@@ -606,6 +615,7 @@ impl H7CAD {
|
||||
vp_size: (1280.0, 720.0),
|
||||
snapper: Snapper::default(),
|
||||
snap_popup_open: false,
|
||||
scale_popup_open: false,
|
||||
pre_cmd_tangent: None,
|
||||
ortho_mode: false,
|
||||
polar_mode: false,
|
||||
|
||||
@@ -60,6 +60,8 @@ impl H7CAD {
|
||||
|
||||
self.tabs[i].current_path = Some(path.clone());
|
||||
self.tabs[i].scene.document = doc;
|
||||
let stored = self.tabs[i].scene.document.header.user_real1;
|
||||
self.tabs[i].scene.annotation_scale = if stored > 1e-9 { stored as f32 } else { 1.0 };
|
||||
|
||||
// Auto-resolve XREFs relative to the opened file's directory.
|
||||
if let Some(base_dir) = path.parent() {
|
||||
@@ -407,6 +409,7 @@ impl H7CAD {
|
||||
let i = self.active_tab;
|
||||
if let Some(path) = &self.tabs[i].current_path {
|
||||
let path = path.clone();
|
||||
self.tabs[i].scene.document.header.user_real1 = self.tabs[i].scene.annotation_scale as f64;
|
||||
match crate::io::save(&self.tabs[i].scene.document, &path) {
|
||||
Ok(()) => {
|
||||
self.command_line
|
||||
@@ -468,6 +471,7 @@ impl H7CAD {
|
||||
let (_, version) = crate::io::parse_save_format(&self.save_dialog_format);
|
||||
let close = self.close_save_dialog_window();
|
||||
let i = self.active_tab;
|
||||
self.tabs[i].scene.document.header.user_real1 = self.tabs[i].scene.annotation_scale as f64;
|
||||
match crate::io::save_as_version(&self.tabs[i].scene.document, &path, version) {
|
||||
Ok(()) => {
|
||||
self.command_line.push_output(&format!("Saved: {}", path.display()));
|
||||
@@ -2019,6 +2023,23 @@ impl H7CAD {
|
||||
self.ortho_mode = false;
|
||||
Task::none()
|
||||
}
|
||||
Message::SetAnnotationScale(scale) => {
|
||||
self.scale_popup_open = false;
|
||||
if let Some(tab) = self.tabs.get_mut(self.active_tab) {
|
||||
tab.scene.annotation_scale = scale;
|
||||
tab.scene.bump_geometry();
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::SetViewportScale(scale) => {
|
||||
self.scale_popup_open = false;
|
||||
if let Some(tab) = self.tabs.get_mut(self.active_tab) {
|
||||
tab.scene.set_viewport_scale(scale);
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::ToggleScalePopup => { self.scale_popup_open ^= true; Task::none() }
|
||||
Message::CloseScalePopup => { self.scale_popup_open = false; Task::none() }
|
||||
Message::ToggleSnap(t) => { self.snapper.toggle(t); Task::none() }
|
||||
Message::ToggleSnapPopup => { self.snap_popup_open ^= true; Task::none() }
|
||||
Message::CloseSnapPopup => { self.snap_popup_open = false; Task::none() }
|
||||
|
||||
+38
-18
@@ -344,23 +344,32 @@ impl H7CAD {
|
||||
}
|
||||
col.push(center_stack)
|
||||
.push(self.command_line.view())
|
||||
.push(self.status_bar.view(
|
||||
&self.snapper,
|
||||
self.snap_popup_open,
|
||||
self.ortho_mode,
|
||||
self.polar_mode,
|
||||
self.polar_increment_deg,
|
||||
self.show_grid,
|
||||
self.dyn_input,
|
||||
self.snapper.otrack_enabled,
|
||||
tab.scene.layout_names(),
|
||||
tab.scene.current_layout.clone(),
|
||||
self.layout_rename_state.as_ref(),
|
||||
tab.scene.first_viewport_scale(),
|
||||
tab.scene.viewport_count(),
|
||||
tab.scene.active_viewport.is_some(),
|
||||
self.show_layout_tabs,
|
||||
))
|
||||
.push({
|
||||
let is_model = tab.scene.current_layout == "Model";
|
||||
let scale_pill_enabled = is_model
|
||||
|| tab.scene.active_viewport.is_some()
|
||||
|| tab.scene.has_selected_viewport();
|
||||
self.status_bar.view(
|
||||
&self.snapper,
|
||||
self.snap_popup_open,
|
||||
self.ortho_mode,
|
||||
self.polar_mode,
|
||||
self.polar_increment_deg,
|
||||
self.show_grid,
|
||||
self.dyn_input,
|
||||
self.snapper.otrack_enabled,
|
||||
tab.scene.layout_names(),
|
||||
tab.scene.current_layout.clone(),
|
||||
self.layout_rename_state.as_ref(),
|
||||
tab.scene.first_viewport_scale(),
|
||||
tab.scene.viewport_count(),
|
||||
tab.scene.active_viewport.is_some(),
|
||||
self.show_layout_tabs,
|
||||
tab.scene.annotation_scale,
|
||||
self.scale_popup_open,
|
||||
scale_pill_enabled,
|
||||
)
|
||||
})
|
||||
.width(Fill)
|
||||
.height(Fill)
|
||||
})
|
||||
@@ -377,6 +386,17 @@ impl H7CAD {
|
||||
iced::widget::Space::new().width(0).height(0).into()
|
||||
};
|
||||
|
||||
let scale_layer: Element<'_, Message> = if self.scale_popup_open {
|
||||
let is_model = tab.scene.current_layout == "Model";
|
||||
crate::ui::scale_popup::scale_popup_overlay(
|
||||
is_model,
|
||||
tab.scene.annotation_scale,
|
||||
tab.scene.first_viewport_scale(),
|
||||
)
|
||||
} else {
|
||||
iced::widget::Space::new().width(0).height(0).into()
|
||||
};
|
||||
|
||||
let dropdown_layer: Element<'_, Message> = self
|
||||
.ribbon
|
||||
.dropdown_overlay(
|
||||
@@ -406,7 +426,7 @@ impl H7CAD {
|
||||
}
|
||||
};
|
||||
|
||||
stack![main_ui, self.app_menu.view(), snap_layer, dropdown_layer, layout_ctx_layer, viewport_ctx_layer].into()
|
||||
stack![main_ui, self.app_menu.view(), snap_layer, scale_layer, dropdown_layer, layout_ctx_layer, viewport_ctx_layer].into()
|
||||
}
|
||||
|
||||
pub fn subscription(&self) -> Subscription<Message> {
|
||||
|
||||
Reference in new issue
Block a user