forked from 1b-agent/opencadstudio-upstream
fix(ui): explain silent anno-scale toggles, theme xref empty state
AnnoObjectScaleToggle had three silent no-op paths (no target, locked layer, unknown scale); each now pushes command-line info mirroring the open-path guards. Xref empty-state hardcoded grey now uses muted_style. DD_BOUNDS eviction and attr-clamp changes investigated and deliberately dropped (no reachable defect in either). Tests: anno_scale_toggle_tests cover all three paths (RED: silence). Full suite: 2032 passed / 0 failed / 25 ignored, zero warnings.
This commit is contained in:
1 parent
15cfabdb0f
commit
7bbc5b0319
2 files changed
+109
-27
No files matched your search
+108
-21
@@ -4588,28 +4588,39 @@ impl OpenCADStudio {
|
|||||||
}
|
}
|
||||||
Message::AnnoObjectScaleToggle(name) => {
|
Message::AnnoObjectScaleToggle(name) => {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
if let Some(entity) = self.anno_object_scale_target {
|
let Some(entity) = self.anno_object_scale_target else {
|
||||||
if self.tabs[i].scene.is_layer_locked(entity) {
|
self.command_line.push_info(
|
||||||
return Task::none();
|
crate::t!("Select one object first, then run OBJECTSCALE.").as_ref(),
|
||||||
}
|
);
|
||||||
if let Some(sh) = self.tabs[i].scene.scale_handle_ensuring(&name) {
|
return Task::none();
|
||||||
self.push_undo_snapshot(i, "OBJECTSCALE");
|
};
|
||||||
let doc = &mut self.tabs[i].scene.document;
|
if self.tabs[i].scene.is_layer_locked(entity) {
|
||||||
let is_member =
|
self.command_line.push_info(
|
||||||
crate::scene::annotative::object_scale_memberships(doc, entity)
|
crate::t!("The object is on a locked layer.").as_ref(),
|
||||||
.iter()
|
);
|
||||||
.any(|(_, h)| *h == sh);
|
return Task::none();
|
||||||
if is_member {
|
}
|
||||||
crate::scene::annotative::remove_annotation_context_for_scale(
|
if let Some(sh) = self.tabs[i].scene.scale_handle_ensuring(&name) {
|
||||||
doc, entity, sh,
|
self.push_undo_snapshot(i, "OBJECTSCALE");
|
||||||
);
|
let doc = &mut self.tabs[i].scene.document;
|
||||||
} else {
|
let is_member =
|
||||||
crate::scene::annotative::create_annotation_context(doc, entity, sh);
|
crate::scene::annotative::object_scale_memberships(doc, entity)
|
||||||
}
|
.iter()
|
||||||
self.tabs[i].dirty = true;
|
.any(|(_, h)| *h == sh);
|
||||||
self.invalidate_property_targets(i, &[entity]);
|
if is_member {
|
||||||
self.refresh_properties();
|
crate::scene::annotative::remove_annotation_context_for_scale(
|
||||||
|
doc, entity, sh,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
crate::scene::annotative::create_annotation_context(doc, entity, sh);
|
||||||
}
|
}
|
||||||
|
self.tabs[i].dirty = true;
|
||||||
|
self.invalidate_property_targets(i, &[entity]);
|
||||||
|
self.refresh_properties();
|
||||||
|
} else {
|
||||||
|
self.command_line.push_info(
|
||||||
|
crate::tf!("Unknown annotation scale '{name}'.").as_ref(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
@@ -11139,6 +11150,82 @@ mod prop_pointer_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod anno_scale_toggle_tests {
|
||||||
|
// #59: silent no-op toggles must explain themselves on the command line.
|
||||||
|
use super::Message;
|
||||||
|
use crate::app::OpenCADStudio;
|
||||||
|
|
||||||
|
fn app_with_target() -> (OpenCADStudio, usize) {
|
||||||
|
let mut app = OpenCADStudio::new_for_test();
|
||||||
|
app.automation_op(r#"{"op":"new"}"#);
|
||||||
|
let i = app.active_tab;
|
||||||
|
let mut line = codec::entities::Line::new();
|
||||||
|
line.start = codec::types::Vector3::ZERO;
|
||||||
|
line.end = codec::types::Vector3::new(1.0, 0.0, 0.0);
|
||||||
|
let h = app
|
||||||
|
.commit_entity_handle(codec::EntityType::Line(line))
|
||||||
|
.expect("line commits");
|
||||||
|
app.anno_object_scale_target = Some(h);
|
||||||
|
(app, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn locked_layer_toggle_explains_itself() {
|
||||||
|
let (mut app, i) = app_with_target();
|
||||||
|
app.tabs[i]
|
||||||
|
.scene
|
||||||
|
.document
|
||||||
|
.layers
|
||||||
|
.get_mut("0")
|
||||||
|
.expect("layer 0 exists")
|
||||||
|
.flags
|
||||||
|
.locked = true;
|
||||||
|
let before = app.command_line.history.len();
|
||||||
|
let _ = app.update(Message::AnnoObjectScaleToggle("1:50".to_string()));
|
||||||
|
let new: Vec<String> = app.command_line.history[before..]
|
||||||
|
.iter()
|
||||||
|
.map(|e| e.text.clone())
|
||||||
|
.collect();
|
||||||
|
assert!(
|
||||||
|
new.iter().any(|t| t.to_lowercase().contains("locked")),
|
||||||
|
"locked-layer toggle must say so, got {new:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unknown_scale_toggle_explains_itself() {
|
||||||
|
let (mut app, _i) = app_with_target();
|
||||||
|
let before = app.command_line.history.len();
|
||||||
|
let _ = app.update(Message::AnnoObjectScaleToggle("NOPE".to_string()));
|
||||||
|
let new: Vec<String> = app.command_line.history[before..]
|
||||||
|
.iter()
|
||||||
|
.map(|e| e.text.clone())
|
||||||
|
.collect();
|
||||||
|
assert!(
|
||||||
|
!new.is_empty(),
|
||||||
|
"unknown-scale toggle must say something, got silence"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn missing_target_toggle_explains_itself() {
|
||||||
|
let mut app = OpenCADStudio::new_for_test();
|
||||||
|
app.automation_op(r#"{"op":"new"}"#);
|
||||||
|
app.anno_object_scale_target = None;
|
||||||
|
let before = app.command_line.history.len();
|
||||||
|
let _ = app.update(Message::AnnoObjectScaleToggle("1:50".to_string()));
|
||||||
|
let new: Vec<String> = app.command_line.history[before..]
|
||||||
|
.iter()
|
||||||
|
.map(|e| e.text.clone())
|
||||||
|
.collect();
|
||||||
|
assert!(
|
||||||
|
!new.is_empty(),
|
||||||
|
"target-less toggle must say something, got silence"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod free_text_entry_tests {
|
mod free_text_entry_tests {
|
||||||
//! The free-form text prompts (table cell content, TEXT / MTEXT bodies)
|
//! The free-form text prompts (table cell content, TEXT / MTEXT bodies)
|
||||||
|
|||||||
@@ -879,12 +879,7 @@ impl XrefManagerPanel {
|
|||||||
container(
|
container(
|
||||||
text(crate::t!("XREF No external references in this drawing."))
|
text(crate::t!("XREF No external references in this drawing."))
|
||||||
.size(12)
|
.size(12)
|
||||||
.color(iced::Color {
|
.style(muted_style),
|
||||||
r: 0.55,
|
|
||||||
g: 0.55,
|
|
||||||
b: 0.55,
|
|
||||||
a: 1.0,
|
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
.center_x(Fill)
|
.center_x(Fill)
|
||||||
.center_y(Fill)
|
.center_y(Fill)
|
||||||
|
|||||||
Reference in new issue
Block a user