fix drag polling during overlay updates
This commit is contained in:
@@ -196,6 +196,31 @@ def handle_mouse_wheel(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def update_drag_from_button_state(
|
||||||
|
state: MapState,
|
||||||
|
*,
|
||||||
|
mouse_pos: tuple[float, float],
|
||||||
|
hit_rect: HitRect,
|
||||||
|
is_down: bool,
|
||||||
|
) -> None:
|
||||||
|
"""Poll left-button state and keep drag interaction moving."""
|
||||||
|
|
||||||
|
with state.lock:
|
||||||
|
active_drag = state.interaction.active_drag
|
||||||
|
|
||||||
|
if not is_down:
|
||||||
|
if active_drag:
|
||||||
|
handle_mouse_release(state)
|
||||||
|
return
|
||||||
|
|
||||||
|
if active_drag:
|
||||||
|
handle_mouse_drag(state, mouse_pos)
|
||||||
|
return
|
||||||
|
|
||||||
|
if hit_rect.contains(mouse_pos[0], mouse_pos[1]):
|
||||||
|
handle_mouse_down(state, mouse_pos, hit_rect)
|
||||||
|
|
||||||
|
|
||||||
def wheel_delta_from_app_data(app_data: Any) -> float:
|
def wheel_delta_from_app_data(app_data: Any) -> float:
|
||||||
"""Normalize Dear PyGui mouse wheel callback data."""
|
"""Normalize Dear PyGui mouse wheel callback data."""
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from typing import Any
|
|||||||
|
|
||||||
from .commands import CommandKind, MapCommand
|
from .commands import CommandKind, MapCommand
|
||||||
from .draw_layers import DrawLayerTags, clear_draw_layer, ensure_draw_layers
|
from .draw_layers import DrawLayerTags, clear_draw_layer, ensure_draw_layers
|
||||||
from .interaction import HitRect, calculate_hit_rect
|
from .interaction import HitRect, calculate_hit_rect, update_drag_from_button_state
|
||||||
from .overlays import MarkerOverlay, Overlay, PolylineOverlay, TrajectoryOverlay
|
from .overlays import MarkerOverlay, Overlay, PolylineOverlay, TrajectoryOverlay
|
||||||
from .projection import latlon_to_world
|
from .projection import latlon_to_world
|
||||||
from .sizing import SizeMeasurement, apply_size_measurement
|
from .sizing import SizeMeasurement, apply_size_measurement
|
||||||
@@ -53,6 +53,7 @@ class MapRenderer:
|
|||||||
commands = drain_renderer_commands(self.state)
|
commands = drain_renderer_commands(self.state)
|
||||||
self.last_drained_commands = tuple(commands)
|
self.last_drained_commands = tuple(commands)
|
||||||
self._update_size_from_dpg()
|
self._update_size_from_dpg()
|
||||||
|
self._poll_mouse_drag()
|
||||||
|
|
||||||
with self.state.lock:
|
with self.state.lock:
|
||||||
dirty = self.state.dirty
|
dirty = self.state.dirty
|
||||||
@@ -132,6 +133,21 @@ class MapRenderer:
|
|||||||
with self.state.lock:
|
with self.state.lock:
|
||||||
self.last_hit_rect = calculate_hit_rect(self.state, (draw_pos[0], draw_pos[1]))
|
self.last_hit_rect = calculate_hit_rect(self.state, (draw_pos[0], draw_pos[1]))
|
||||||
|
|
||||||
|
def _poll_mouse_drag(self) -> None:
|
||||||
|
if self.last_hit_rect is None:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
is_down = bool(self._dpg.is_mouse_button_down(self._dpg.mvMouseButton_Left))
|
||||||
|
mouse_pos = self._dpg.get_mouse_pos(local=False)
|
||||||
|
except Exception:
|
||||||
|
return
|
||||||
|
update_drag_from_button_state(
|
||||||
|
self.state,
|
||||||
|
mouse_pos=(float(mouse_pos[0]), float(mouse_pos[1])),
|
||||||
|
hit_rect=self.last_hit_rect,
|
||||||
|
is_down=is_down,
|
||||||
|
)
|
||||||
|
|
||||||
def _measure_child_content(self) -> tuple[int, int]:
|
def _measure_child_content(self) -> tuple[int, int]:
|
||||||
try:
|
try:
|
||||||
width, height = self._dpg.get_item_rect_size(self.state.child_window_tag)
|
width, height = self._dpg.get_item_rect_size(self.state.child_window_tag)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from dpg_map.interaction import (
|
|||||||
handle_mouse_release,
|
handle_mouse_release,
|
||||||
handle_mouse_wheel,
|
handle_mouse_wheel,
|
||||||
pan_state_by_pixels,
|
pan_state_by_pixels,
|
||||||
|
update_drag_from_button_state,
|
||||||
)
|
)
|
||||||
from dpg_map.sizing import SizeMeasurement, apply_size_measurement
|
from dpg_map.sizing import SizeMeasurement, apply_size_measurement
|
||||||
from dpg_map.state import DirtyFlags, create_map_state, get_map_state
|
from dpg_map.state import DirtyFlags, create_map_state, get_map_state
|
||||||
@@ -60,6 +61,19 @@ def test_mouse_drag_uses_active_drag_state() -> None:
|
|||||||
assert state.center[1] < 0.0
|
assert state.center[1] < 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_polled_drag_starts_and_moves_while_button_is_down() -> None:
|
||||||
|
state = create_map_state(tag="polled-drag", center=(0.0, 0.0), zoom=3)
|
||||||
|
apply_size_measurement(state, SizeMeasurement(width=400, height=300, visible=True))
|
||||||
|
rect = calculate_hit_rect(state, (10.0, 20.0))
|
||||||
|
|
||||||
|
update_drag_from_button_state(state, mouse_pos=(20.0, 30.0), hit_rect=rect, is_down=True)
|
||||||
|
update_drag_from_button_state(state, mouse_pos=(45.0, 30.0), hit_rect=rect, is_down=True)
|
||||||
|
update_drag_from_button_state(state, mouse_pos=(45.0, 30.0), hit_rect=rect, is_down=False)
|
||||||
|
|
||||||
|
assert state.interaction.active_drag is False
|
||||||
|
assert state.center[1] < 0.0
|
||||||
|
|
||||||
|
|
||||||
def test_wheel_zoom_keeps_cursor_latlon_stable() -> None:
|
def test_wheel_zoom_keeps_cursor_latlon_stable() -> None:
|
||||||
state = create_map_state(tag="wheel", center=(47.9029, 1.9093), zoom=8)
|
state = create_map_state(tag="wheel", center=(47.9029, 1.9093), zoom=8)
|
||||||
apply_size_measurement(state, SizeMeasurement(width=800, height=600, visible=True))
|
apply_size_measurement(state, SizeMeasurement(width=800, height=600, visible=True))
|
||||||
|
|||||||
Reference in New Issue
Block a user