forked from 1b-agent/opencadstudio-upstream
fix(view): pause hover during navigation
This commit is contained in:
1 parent
afcf7baead
commit
67a767e23b
4 files changed
+78
-11
No files matched your search
@@ -7,6 +7,7 @@ impl OpenCADStudio {
|
||||
// path when there is no middle mouse button (trackpad / web).
|
||||
"PAN" => {
|
||||
self.tabs[i].pan_mode = true;
|
||||
self.clear_navigation_hover(i);
|
||||
self.command_line
|
||||
.push_output(crate::t!("PAN: drag with the left mouse button. Press Esc to exit.").as_ref());
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ impl OpenCADStudio {
|
||||
match cmd {
|
||||
"3DORBIT" => {
|
||||
self.tabs[i].orbit_mode = true;
|
||||
self.clear_navigation_hover(i);
|
||||
}
|
||||
|
||||
// ── Selection utilities ───────────────────────────────────────
|
||||
|
||||
@@ -2680,6 +2680,8 @@ impl OpenCADStudio {
|
||||
// End of a Shift+MMB orbit — drop the captured pivot so the next
|
||||
// gesture recomputes it against the current selection. (#229)
|
||||
sel.orbit_pivot = None;
|
||||
drop(sel);
|
||||
self.arm_hover_after_navigation(i);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
@@ -2698,6 +2700,7 @@ impl OpenCADStudio {
|
||||
|
||||
Message::ViewCubeHome => {
|
||||
let i = self.active_tab;
|
||||
self.clear_navigation_hover(i);
|
||||
let r_ucs = self.tabs[i].scene.viewcube_ucs_mat();
|
||||
if self.tabs[i].scene.active_viewport.is_some() {
|
||||
self.tabs[i]
|
||||
@@ -2713,6 +2716,7 @@ impl OpenCADStudio {
|
||||
|
||||
Message::ViewCubeRoll(cw) => {
|
||||
let i = self.active_tab;
|
||||
self.clear_navigation_hover(i);
|
||||
let ang = if cw {
|
||||
std::f32::consts::FRAC_PI_2
|
||||
} else {
|
||||
@@ -2738,6 +2742,7 @@ impl OpenCADStudio {
|
||||
NudgeDir::Right => (true, true),
|
||||
};
|
||||
let i = self.active_tab;
|
||||
self.clear_navigation_hover(i);
|
||||
if self.tabs[i].scene.active_viewport.is_some() {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
|
||||
+71
-11
@@ -663,17 +663,22 @@ impl OpenCADStudio {
|
||||
VIEWCUBE_PX,
|
||||
));
|
||||
|
||||
// Multi-functional grip hover: detect cursor sitting on a
|
||||
// selected entity's grip and, after a dwell, open the
|
||||
// popup menu. See scene::model::object::GripMenuItem.
|
||||
self.update_grip_hover(i, p);
|
||||
let navigating = self.tabs[i].scene.selection.borrow().middle_down;
|
||||
if navigating {
|
||||
self.clear_navigation_hover(i);
|
||||
} else {
|
||||
// Multi-functional grip hover: detect cursor sitting on a
|
||||
// selected entity's grip and, after a dwell, open the
|
||||
// popup menu. See scene::model::object::GripMenuItem.
|
||||
self.update_grip_hover(i, p);
|
||||
|
||||
// UCS icon hover highlight (suppressed mid grip-drag).
|
||||
self.ucs_icon_hover = self.ucs_grip_drag.is_none()
|
||||
&& self
|
||||
.ucs_icon_hit_info(i, svw, svh)
|
||||
.map(|h| over_ucs_icon(p, &h))
|
||||
.unwrap_or(false);
|
||||
// UCS icon hover highlight (suppressed mid grip-drag).
|
||||
self.ucs_icon_hover = self.ucs_grip_drag.is_none()
|
||||
&& self
|
||||
.ucs_icon_hit_info(i, svw, svh)
|
||||
.map(|h| over_ucs_icon(p, &h))
|
||||
.unwrap_or(false);
|
||||
}
|
||||
|
||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||
sel.last_move_pos = Some(p);
|
||||
@@ -2213,6 +2218,7 @@ impl OpenCADStudio {
|
||||
// Interactive navigation tools reuse the middle-button movement path,
|
||||
// so no selection/pick logic runs while the left button drives them.
|
||||
if self.tabs[i].orbit_mode || self.tabs[i].pan_mode {
|
||||
self.clear_navigation_hover(i);
|
||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||
sel.middle_down = true;
|
||||
sel.middle_last_pos = Some(p);
|
||||
@@ -2388,6 +2394,8 @@ impl OpenCADStudio {
|
||||
sel.middle_down = false;
|
||||
sel.middle_last_pos = None;
|
||||
sel.orbit_pivot = None;
|
||||
drop(sel);
|
||||
self.arm_hover_after_navigation(i);
|
||||
return Task::none();
|
||||
}
|
||||
|
||||
@@ -3952,8 +3960,52 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
/// Remove cursor-derived highlights and cancel a queued rollover pick before
|
||||
/// moving the camera. A later idle cursor move re-arms hover normally.
|
||||
pub(in crate::app) fn clear_navigation_hover(&mut self, i: usize) {
|
||||
if i >= self.tabs.len() {
|
||||
return;
|
||||
}
|
||||
self.tabs[i].scene.set_hover_highlight(None);
|
||||
self.hover_dwell = None;
|
||||
self.grip_hover = None;
|
||||
self.ucs_icon_hover = false;
|
||||
}
|
||||
|
||||
/// Queue a fresh rollover pick at the stationary cursor after camera motion
|
||||
/// ends. Repeated wheel events replace this timestamp, so the pick runs only
|
||||
/// after the final zoom step settles.
|
||||
pub(in crate::app) fn arm_hover_after_navigation(&mut self, i: usize) {
|
||||
if i >= self.tabs.len() || self.tabs[i].active_cmd.is_some() {
|
||||
return;
|
||||
}
|
||||
let (cursor, canvas_size) = {
|
||||
let selection = self.tabs[i].scene.selection.borrow();
|
||||
(selection.last_move_pos, selection.vp_size)
|
||||
};
|
||||
let Some(cursor) = cursor else {
|
||||
return;
|
||||
};
|
||||
let tile = self.tabs[i]
|
||||
.scene
|
||||
.viewport_edit_frame(canvas_size)
|
||||
.map(|(_, rect)| rect)
|
||||
.unwrap_or_else(|| {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.active_model_tile_bounds(canvas_size.0, canvas_size.1)
|
||||
});
|
||||
self.hover_dwell = Some(crate::app::HoverDwell {
|
||||
last_move_at: Instant::now(),
|
||||
point: Point::new(cursor.x - tile.x, cursor.y - tile.y),
|
||||
tile_size: (tile.width, tile.height),
|
||||
tab: i,
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn on_viewport_middle_press(&mut self) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
self.clear_navigation_hover(i);
|
||||
self.ribbon.close_dropdown();
|
||||
let now = Instant::now();
|
||||
let is_double = {
|
||||
@@ -3988,6 +4040,7 @@ impl OpenCADStudio {
|
||||
mouse::ScrollDelta::Pixels { y, .. } => y * 0.01,
|
||||
};
|
||||
let i = self.active_tab;
|
||||
self.clear_navigation_hover(i);
|
||||
let cursor = self.tabs[i].scene.selection.borrow().last_move_pos;
|
||||
let (vw, vh) = self.tabs[i].scene.selection.borrow().vp_size;
|
||||
let bounds = iced::Rectangle {
|
||||
@@ -4040,6 +4093,7 @@ impl OpenCADStudio {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.record_nav_perf(crate::scene::NavPerfOp::Zoom, nav_started);
|
||||
self.arm_hover_after_navigation(i);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
@@ -4149,6 +4203,7 @@ impl OpenCADStudio {
|
||||
|
||||
fn snap_view_region(&mut self, region: CubeRegion, r_ucs: glam::Mat4) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
self.clear_navigation_hover(i);
|
||||
let mut region = region;
|
||||
// "Already there → flip to opposite" check: compare the
|
||||
// current gaze direction with the region's target gaze.
|
||||
@@ -4204,10 +4259,15 @@ impl OpenCADStudio {
|
||||
let i = dwell.tab;
|
||||
// Re-check the gate — drag / command may have started
|
||||
// between the move that armed the dwell and this tick.
|
||||
if i >= self.tabs.len() || self.tabs[i].active_cmd.is_some() {
|
||||
if i >= self.tabs.len() {
|
||||
self.hover_dwell = None;
|
||||
return Task::none();
|
||||
}
|
||||
let navigating = self.tabs[i].scene.selection.borrow().middle_down;
|
||||
if self.tabs[i].active_cmd.is_some() || navigating {
|
||||
self.clear_navigation_hover(i);
|
||||
return Task::none();
|
||||
}
|
||||
let bounds = iced::Rectangle {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
|
||||
Reference in new issue
Block a user