forked from 1b-agent/opencadstudio-upstream
feat(points): point style commands + DDPTYPE dialog, viewport-aware size
Points could only render as a 1px dot — no way to change PDMODE/PDSIZE. - PDMODE / PDSIZE commands set the header value and rebuild the glyphs. - DDPTYPE opens a Point Style dialog: a 5x4 grid of rendered glyphs (shape x enclosure), a size field, and relative/absolute radios. - Relative (<=0) PDSIZE now sizes from the current world-per-pixel so the marker stays a roughly constant on-screen size across zoom, rebuilding on zoom via the existing camera-generation cache key. Absolute (>0) scales with the world as before. Switching to absolute with a zero size seeds a positive value from the on-screen size so it stays representable. Part of the #100 extensibility epic (point style surfaced in #106). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
a3b8acb59e
commit
96ec672d5b
14 files changed
+456
-45
No files matched your search
@@ -178,6 +178,50 @@ impl OpenCADStudio {
|
||||
self.disabled_plugins.clone()
|
||||
}
|
||||
|
||||
/// Write PDSIZE from the dialog buffer with the current relative/absolute
|
||||
/// sign. A relative size is stored negative; absolute positive. Switching to
|
||||
/// absolute with an empty/zero size seeds a positive value from the current
|
||||
/// on-screen size so the point stays representable (PDSIZE 0 always reads as
|
||||
/// relative, so absolute needs a non-zero magnitude).
|
||||
fn apply_point_size(&mut self) {
|
||||
let i = self.active_tab;
|
||||
let mut mag = self
|
||||
.point_size_buf
|
||||
.trim()
|
||||
.parse::<f64>()
|
||||
.unwrap_or(0.0)
|
||||
.abs();
|
||||
if !self.point_size_relative && mag == 0.0 {
|
||||
let wpp = self.tabs[i].scene.world_per_pixel().unwrap_or(0.0);
|
||||
mag = if wpp > 0.0 {
|
||||
crate::entities::point::relative_world_size(0.0, wpp)
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
self.point_size_buf = format!("{mag:.4}");
|
||||
}
|
||||
let next = if self.point_size_relative { -mag } else { mag };
|
||||
self.push_undo_snapshot(i, "PDSIZE");
|
||||
self.tabs[i].scene.document.header.point_display_size = next;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
|
||||
/// Replace the `mask` bits of PDMODE with `value`, rebuild the point glyphs
|
||||
/// and mark the document dirty. Used by the Point Style (DDPTYPE) dialog.
|
||||
fn set_point_mode_bits(&mut self, mask: i16, value: i16) {
|
||||
let i = self.active_tab;
|
||||
let cur = self.tabs[i].scene.document.header.point_display_mode;
|
||||
let next = (cur & !mask) | (value & mask);
|
||||
if next == cur {
|
||||
return;
|
||||
}
|
||||
self.push_undo_snapshot(i, "PDMODE");
|
||||
self.tabs[i].scene.document.header.point_display_mode = next;
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.tabs[i].dirty = true;
|
||||
}
|
||||
|
||||
/// Write preferences to disk only when they differ from the last write,
|
||||
/// so a toggle persists immediately without thrashing the file.
|
||||
fn persist_settings_if_changed(&mut self) {
|
||||
@@ -5499,6 +5543,28 @@ impl OpenCADStudio {
|
||||
self.persist_settings_if_changed();
|
||||
Task::none()
|
||||
}
|
||||
Message::PointStyleSetMode(mode) => {
|
||||
self.set_point_mode_bits(!0, mode);
|
||||
Task::none()
|
||||
}
|
||||
Message::PointStyleSizeRelative(relative) => {
|
||||
self.point_size_relative = relative;
|
||||
self.apply_point_size();
|
||||
Task::none()
|
||||
}
|
||||
Message::PointStyleSizeInput(s) => {
|
||||
self.point_size_buf = s;
|
||||
Task::none()
|
||||
}
|
||||
Message::PointStyleApplySize => {
|
||||
self.apply_point_size();
|
||||
Task::none()
|
||||
}
|
||||
Message::PointStyleOk => {
|
||||
self.apply_point_size();
|
||||
self.close_active_modal();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::EnterViewport(handle) => {
|
||||
let i = self.active_tab;
|
||||
|
||||
Reference in new issue
Block a user