forked from 1b-agent/opencadstudio-upstream
fix(cursor): restore default geometry
Keep CURSORSIZE 5 and PICKBOX 3 mapped to the pre-option 60 px arms, 15 px box, and 8 px selection aperture.\n\nRefs #413
This commit is contained in:
1 parent
1738f9a79b
commit
8847724127
4 files changed
+63
-20
No files matched your search
+2
-2
@@ -448,9 +448,9 @@ pub(super) struct OpenCADStudio {
|
||||
zoom_wheel_reversed: bool,
|
||||
/// Mouse-wheel zoom sensitivity, clamped to 3..=100 (ZOOMFACTOR).
|
||||
zoom_factor: i32,
|
||||
/// Crosshair reach as a viewport percentage (CURSORSIZE, 1..=100).
|
||||
/// Crosshair size setting (CURSORSIZE, 1..=100).
|
||||
cursor_size: i32,
|
||||
/// Selection-box half-size and click aperture in pixels (PICKBOX, 0..=50).
|
||||
/// Selection-box size setting (PICKBOX, 0..=50).
|
||||
pick_box: i32,
|
||||
/// Drawing viewport cursor style (CURSORTYPE).
|
||||
cursor_type: settings::CursorType,
|
||||
|
||||
+2
-2
@@ -156,9 +156,9 @@ pub struct UserSettings {
|
||||
pub polar_increment_deg: f32,
|
||||
pub zoom_wheel_reversed: bool,
|
||||
pub zoom_factor: i32,
|
||||
/// CURSORSIZE: crosshair arm reach as a percentage of the viewport.
|
||||
/// CURSORSIZE: normalized crosshair reach; 5 retains the original 60 px arms.
|
||||
pub cursor_size: i32,
|
||||
/// PICKBOX: visible selection-box half-size and click aperture in pixels.
|
||||
/// PICKBOX: normalized visible-box and click-aperture size.
|
||||
pub pick_box: i32,
|
||||
/// CURSORTYPE: crosshair or the platform pointer over the drawing.
|
||||
pub cursor_type: CursorType,
|
||||
|
||||
+12
-12
@@ -1778,7 +1778,7 @@ impl OpenCADStudio {
|
||||
eye,
|
||||
bounds,
|
||||
self.tabs[i].scene.document.header.lineweight_display,
|
||||
self.pick_box.max(1) as f32,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box),
|
||||
)
|
||||
.and_then(|s| Scene::handle_from_wire_name(s))
|
||||
.or_else(|| {
|
||||
@@ -2941,7 +2941,7 @@ impl OpenCADStudio {
|
||||
view_rot2,
|
||||
eye2,
|
||||
bounds,
|
||||
self.pick_box.max(1) as f32 * 2.0,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box) * 2.0,
|
||||
);
|
||||
let include_fills = self.tabs[i]
|
||||
.active_cmd
|
||||
@@ -2962,7 +2962,7 @@ impl OpenCADStudio {
|
||||
eye2,
|
||||
bounds,
|
||||
self.tabs[i].scene.document.header.lineweight_display,
|
||||
self.pick_box.max(1) as f32,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box),
|
||||
)
|
||||
.and_then(|s| Scene::handle_from_wire_name(s))
|
||||
.or_else(|| {
|
||||
@@ -3491,7 +3491,7 @@ impl OpenCADStudio {
|
||||
view_rot,
|
||||
eye,
|
||||
bounds,
|
||||
self.pick_box.max(1) as f32 * 2.0,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box) * 2.0,
|
||||
);
|
||||
let candidate_handles = self.tabs[i]
|
||||
.scene
|
||||
@@ -3511,7 +3511,7 @@ impl OpenCADStudio {
|
||||
eye,
|
||||
bounds,
|
||||
self.tabs[i].scene.document.header.lineweight_display,
|
||||
self.pick_box.max(1) as f32,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box),
|
||||
)
|
||||
.into_iter()
|
||||
.filter_map(|s| Scene::handle_from_wire_name(s))
|
||||
@@ -3533,7 +3533,7 @@ impl OpenCADStudio {
|
||||
eye,
|
||||
bounds,
|
||||
self.tabs[i].scene.document.header.lineweight_display,
|
||||
self.pick_box.max(1) as f32,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box),
|
||||
)
|
||||
.and_then(|s| Scene::handle_from_wire_name(s))
|
||||
.or_else(|| {
|
||||
@@ -3875,7 +3875,7 @@ impl OpenCADStudio {
|
||||
view_rot,
|
||||
eye,
|
||||
bounds,
|
||||
self.pick_box.max(1) as f32 * 2.0,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box) * 2.0,
|
||||
);
|
||||
let candidate_handles = self.tabs[i]
|
||||
.scene
|
||||
@@ -3890,7 +3890,7 @@ impl OpenCADStudio {
|
||||
eye,
|
||||
bounds,
|
||||
self.tabs[i].scene.document.header.lineweight_display,
|
||||
self.pick_box.max(1) as f32,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box),
|
||||
)
|
||||
.and_then(|s| Scene::handle_from_wire_name(s))
|
||||
.or_else(|| {
|
||||
@@ -3995,7 +3995,7 @@ impl OpenCADStudio {
|
||||
view_rot,
|
||||
eye,
|
||||
bounds,
|
||||
self.pick_box.max(1) as f32 * 2.0,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box) * 2.0,
|
||||
);
|
||||
scene::pick::hit_test::click_hit(
|
||||
p,
|
||||
@@ -4004,7 +4004,7 @@ impl OpenCADStudio {
|
||||
eye,
|
||||
bounds,
|
||||
self.tabs[i].scene.document.header.lineweight_display,
|
||||
self.pick_box.max(1) as f32,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box),
|
||||
)
|
||||
.and_then(|s| Scene::handle_from_wire_name(s))
|
||||
.and_then(|h| {
|
||||
@@ -4410,7 +4410,7 @@ impl OpenCADStudio {
|
||||
view_rot,
|
||||
eye,
|
||||
bounds,
|
||||
self.pick_box.max(1) as f32 * 2.0,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box) * 2.0,
|
||||
);
|
||||
let candidate_ms = candidate_started.elapsed().as_secs_f64() * 1000.0;
|
||||
let candidate_count = hover_candidates.len();
|
||||
@@ -4430,7 +4430,7 @@ impl OpenCADStudio {
|
||||
eye,
|
||||
bounds,
|
||||
self.tabs[i].scene.document.header.lineweight_display,
|
||||
self.pick_box.max(1) as f32,
|
||||
crate::ui::overlay::pick_box_aperture_px(self.pick_box),
|
||||
)
|
||||
.and_then(Scene::handle_from_wire_name);
|
||||
let wire_ms = wire_started.elapsed().as_secs_f64() * 1000.0;
|
||||
|
||||
+47
-4
@@ -12,6 +12,51 @@ use crate::scene::SelectionState;
|
||||
|
||||
use crate::snap::SnapType;
|
||||
|
||||
/// Original crosshair geometry retained at the default setting values.
|
||||
pub const CROSSHAIR_SQ: f32 = 7.5;
|
||||
pub const CROSSHAIR_ARM: f32 = 60.0;
|
||||
const DEFAULT_CURSOR_SIZE: i32 = 5;
|
||||
const DEFAULT_PICK_BOX: i32 = 3;
|
||||
const DEFAULT_PICK_APERTURE: f32 = 8.0;
|
||||
|
||||
/// Convert CURSORSIZE to a screen-space arm length while keeping the original
|
||||
/// 60 px cursor at the default value and the full-viewport result at 100.
|
||||
pub(crate) fn crosshair_arm_px(bounds: iced::Rectangle, value: i32) -> f32 {
|
||||
let value = value.clamp(1, 100);
|
||||
if value <= DEFAULT_CURSOR_SIZE {
|
||||
return CROSSHAIR_ARM * value as f32 / DEFAULT_CURSOR_SIZE as f32;
|
||||
}
|
||||
|
||||
let full = bounds.width.hypot(bounds.height).max(CROSSHAIR_ARM);
|
||||
let scale = (value - DEFAULT_CURSOR_SIZE) as f32 / (100 - DEFAULT_CURSOR_SIZE) as f32;
|
||||
CROSSHAIR_ARM + (full - CROSSHAIR_ARM) * scale
|
||||
}
|
||||
|
||||
/// Convert PICKBOX to the visible half-size while retaining the original
|
||||
/// 15 x 15 px center box at the default value.
|
||||
pub(crate) fn pick_box_half_px(value: i32) -> f32 {
|
||||
let value = value.clamp(0, 50);
|
||||
if value <= DEFAULT_PICK_BOX {
|
||||
return CROSSHAIR_SQ * value as f32 / DEFAULT_PICK_BOX as f32;
|
||||
}
|
||||
|
||||
let scale = (value - DEFAULT_PICK_BOX) as f32 / (50 - DEFAULT_PICK_BOX) as f32;
|
||||
CROSSHAIR_SQ + (50.0 - CROSSHAIR_SQ) * scale
|
||||
}
|
||||
|
||||
/// Convert PICKBOX to the real click/hover aperture. A zero setting hides the
|
||||
/// box but retains the one-pixel minimum needed for direct hits.
|
||||
pub(crate) fn pick_box_aperture_px(value: i32) -> f32 {
|
||||
let value = value.clamp(0, 50);
|
||||
let aperture = if value <= DEFAULT_PICK_BOX {
|
||||
DEFAULT_PICK_APERTURE * value as f32 / DEFAULT_PICK_BOX as f32
|
||||
} else {
|
||||
let scale = (value - DEFAULT_PICK_BOX) as f32 / (50 - DEFAULT_PICK_BOX) as f32;
|
||||
DEFAULT_PICK_APERTURE + (50.0 - DEFAULT_PICK_APERTURE) * scale
|
||||
};
|
||||
aperture.max(1.0)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct CrosshairOptions {
|
||||
pub size_percent: i32,
|
||||
@@ -964,10 +1009,8 @@ impl canvas::Program<Message> for SelectionCanvas {
|
||||
style: canvas::Style::Solid(color),
|
||||
..Default::default()
|
||||
};
|
||||
let sq = self.crosshair.pick_box.clamp(0, 50) as f32;
|
||||
let arm = bounds.width.hypot(bounds.height)
|
||||
* self.crosshair.size_percent.clamp(1, 100) as f32
|
||||
/ 100.0;
|
||||
let sq = pick_box_half_px(self.crosshair.pick_box);
|
||||
let arm = crosshair_arm_px(bounds, self.crosshair.size_percent);
|
||||
let base_angles: [f64; 2] = if self.crosshair.isometric {
|
||||
self.crosshair.iso_plane.angles()
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user