fix(grip): open hover popup without requiring mouse motion
Dwell timing only advanced when `ViewportMove` fired; a perfectly still cursor never triggered the popup. Subscribe to animation frames while `grip_hover` is set and dispatch `GripDwellTick` from them so `update_grip_hover` re-checks the elapsed dwell each frame. Subscription auto-stops as soon as the hover clears or the popup opens.
This commit is contained in:
parent
6c1462932d
commit
595ee3e245
3 changed files with 29 additions and 0 deletions
|
|
@ -453,6 +453,9 @@ pub enum Message {
|
||||||
/// User picked an item in the multi-functional grip popup menu —
|
/// User picked an item in the multi-functional grip popup menu —
|
||||||
/// the index is into `grip_popup.items`.
|
/// the index is into `grip_popup.items`.
|
||||||
GripMenuPick(usize),
|
GripMenuPick(usize),
|
||||||
|
/// Timer pulse while the cursor is dwelling on a grip; drives the
|
||||||
|
/// dwell-to-popup transition without requiring further mouse motion.
|
||||||
|
GripDwellTick,
|
||||||
WindowResized(f32, f32),
|
WindowResized(f32, f32),
|
||||||
/// Enter pressed globally — finalises the active command (no text-input involvement).
|
/// Enter pressed globally — finalises the active command (no text-input involvement).
|
||||||
CommandFinalize,
|
CommandFinalize,
|
||||||
|
|
|
||||||
|
|
@ -3067,6 +3067,21 @@ impl OpenCADStudio {
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::GripDwellTick => {
|
||||||
|
let i = self.active_tab;
|
||||||
|
// Reuse the move-time logic — `p` is the last cursor
|
||||||
|
// position the viewport saw, which is also what the
|
||||||
|
// hover state was last set with.
|
||||||
|
let p = self.tabs[i]
|
||||||
|
.scene
|
||||||
|
.selection
|
||||||
|
.borrow()
|
||||||
|
.last_move_pos
|
||||||
|
.unwrap_or(self.cursor_pos);
|
||||||
|
self.update_grip_hover(i, p);
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
|
||||||
Message::GripMenuPick(idx) => {
|
Message::GripMenuPick(idx) => {
|
||||||
let i = self.active_tab;
|
let i = self.active_tab;
|
||||||
let Some(popup) = self.grip_popup.take() else {
|
let Some(popup) = self.grip_popup.take() else {
|
||||||
|
|
|
||||||
|
|
@ -932,9 +932,20 @@ impl OpenCADStudio {
|
||||||
} else {
|
} else {
|
||||||
Subscription::none()
|
Subscription::none()
|
||||||
};
|
};
|
||||||
|
// While the cursor sits over a grip, request animation frames
|
||||||
|
// so the multi-functional popup opens even when the user keeps
|
||||||
|
// the mouse perfectly still — `ViewportMove` alone would never
|
||||||
|
// fire again. Auto-stops once the hover clears or the popup is
|
||||||
|
// already open.
|
||||||
|
let grip_dwell = if self.grip_hover.is_some() && self.grip_popup.is_none() {
|
||||||
|
window::frames().map(|_| Message::GripDwellTick)
|
||||||
|
} else {
|
||||||
|
Subscription::none()
|
||||||
|
};
|
||||||
iced::Subscription::batch([
|
iced::Subscription::batch([
|
||||||
frames,
|
frames,
|
||||||
history_tick,
|
history_tick,
|
||||||
|
grip_dwell,
|
||||||
event::listen_with(|ev, status, win_id| {
|
event::listen_with(|ev, status, win_id| {
|
||||||
use iced::event::Status;
|
use iced::event::Status;
|
||||||
match ev {
|
match ev {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue