Fixed tiling bug and multi map bug
This commit is contained in:
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
import dpg_map as dpgm
|
||||
import dpg_map.interaction as interaction_module
|
||||
from dpg_map.commands import CommandKind
|
||||
from dpg_map.interaction import (
|
||||
calculate_hit_rect,
|
||||
@@ -74,6 +75,43 @@ def test_polled_drag_starts_and_moves_while_button_is_down() -> None:
|
||||
assert state.center[1] < 0.0
|
||||
|
||||
|
||||
def test_renderer_poll_does_not_start_drag_for_inactive_map() -> None:
|
||||
state = create_map_state(tag="poll-no-start", 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,
|
||||
can_start=False,
|
||||
)
|
||||
|
||||
assert state.interaction.active_drag is False
|
||||
assert state.center == (0.0, 0.0)
|
||||
|
||||
|
||||
def test_drag_owner_prevents_second_map_from_tracking_first_map() -> None:
|
||||
with interaction_module._drag_owner_lock:
|
||||
interaction_module._drag_owner_map = None
|
||||
state_a = create_map_state(tag="drag-owner-a", center=(0.0, 0.0), zoom=3)
|
||||
state_b = create_map_state(tag="drag-owner-b", center=(0.0, 0.0), zoom=3)
|
||||
apply_size_measurement(state_a, SizeMeasurement(width=400, height=300, visible=True))
|
||||
apply_size_measurement(state_b, SizeMeasurement(width=400, height=300, visible=True))
|
||||
rect_a = calculate_hit_rect(state_a, (10.0, 20.0))
|
||||
rect_b = calculate_hit_rect(state_b, (10.0, 20.0))
|
||||
|
||||
handle_mouse_down(state_a, (20.0, 30.0), rect_a)
|
||||
handle_mouse_down(state_b, (20.0, 30.0), rect_b)
|
||||
handle_mouse_drag(state_a, (45.0, 30.0))
|
||||
handle_mouse_drag(state_b, (45.0, 30.0))
|
||||
|
||||
assert state_a.center[1] < 0.0
|
||||
assert state_b.center == (0.0, 0.0)
|
||||
handle_mouse_release(state_a)
|
||||
|
||||
|
||||
def test_wheel_zoom_keeps_cursor_latlon_stable() -> None:
|
||||
state = create_map_state(tag="wheel", center=(47.9029, 1.9093), zoom=8)
|
||||
apply_size_measurement(state, SizeMeasurement(width=800, height=600, visible=True))
|
||||
|
||||
@@ -3,11 +3,12 @@ from __future__ import annotations
|
||||
from typing import Any
|
||||
|
||||
import dpg_map as dpgm
|
||||
import dpg_map.renderer as renderer_module
|
||||
from dpg_map.commands import CommandKind, MapCommand
|
||||
from dpg_map.providers import TileProvider
|
||||
from dpg_map.renderer import MapRenderer, drain_renderer_commands
|
||||
from dpg_map.state import DirtyFlags, create_map_state
|
||||
from dpg_map.tiles import TileID, TileResult, TileStatus
|
||||
from dpg_map.tiles import TileID, TileResult, TileStatus, VisibleTile
|
||||
|
||||
|
||||
class FakeDpg:
|
||||
@@ -15,6 +16,7 @@ class FakeDpg:
|
||||
self.items: set[str | int] = set()
|
||||
self.deleted: list[tuple[str | int, bool]] = []
|
||||
self.drawn: list[tuple[str, str | int]] = []
|
||||
self.images: list[tuple[Any, Any, str | int]] = []
|
||||
|
||||
def does_item_exist(self, tag: str | int) -> bool:
|
||||
return tag in self.items
|
||||
@@ -33,6 +35,7 @@ class FakeDpg:
|
||||
def draw_image(self, *args: Any, parent: str | int, **kwargs: Any) -> None:
|
||||
_ = (args, kwargs)
|
||||
self.drawn.append(("image", parent))
|
||||
self.images.append((args[1], args[2], parent))
|
||||
|
||||
def draw_text(self, *args: Any, parent: str | int, **kwargs: Any) -> None:
|
||||
_ = (args, kwargs)
|
||||
@@ -47,6 +50,51 @@ class FakeDpg:
|
||||
self.drawn.append(("polyline", parent))
|
||||
|
||||
|
||||
class FrameCallbackDpg(FakeDpg):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.frame_count = 0
|
||||
self.callbacks: dict[int, Any] = {}
|
||||
|
||||
def get_frame_count(self) -> int:
|
||||
return self.frame_count
|
||||
|
||||
def set_frame_callback(self, frame: int, callback: Any) -> None:
|
||||
self.callbacks[frame] = callback
|
||||
|
||||
|
||||
def test_shared_frame_pump_renders_multiple_maps_from_one_frame_callback() -> None:
|
||||
with renderer_module._scheduler_lock:
|
||||
renderer_module._scheduled_renderers.clear()
|
||||
renderer_module._scheduler_frame_scheduled = False
|
||||
renderer_module._scheduler_dpg = None
|
||||
|
||||
state_a = create_map_state(tag="frame-pump-a")
|
||||
state_b = create_map_state(tag="frame-pump-b")
|
||||
fake = FrameCallbackDpg()
|
||||
fake.items.update({state_a.drawlist_tag, state_b.drawlist_tag})
|
||||
renderer_a = MapRenderer(state_a, fake)
|
||||
renderer_b = MapRenderer(state_b, fake)
|
||||
rendered: list[str] = []
|
||||
renderer_a.render_frame = lambda: rendered.append("a") # type: ignore[method-assign]
|
||||
renderer_b.render_frame = lambda: rendered.append("b") # type: ignore[method-assign]
|
||||
|
||||
renderer_a.schedule_next_frame()
|
||||
renderer_b.schedule_next_frame()
|
||||
assert list(fake.callbacks) == [1]
|
||||
|
||||
fake.frame_count = 1
|
||||
fake.callbacks[1]()
|
||||
|
||||
assert rendered == ["a", "b"]
|
||||
assert sorted(renderer_module._scheduled_renderers) == ["frame-pump-a", "frame-pump-b"]
|
||||
|
||||
with renderer_module._scheduler_lock:
|
||||
renderer_module._scheduled_renderers.clear()
|
||||
renderer_module._scheduler_frame_scheduled = False
|
||||
renderer_module._scheduler_dpg = None
|
||||
|
||||
|
||||
def test_renderer_command_drain_preserves_structural_order_and_coalesces() -> None:
|
||||
state = create_map_state(tag="renderer-drain")
|
||||
state.dirty = DirtyFlags.NONE
|
||||
@@ -109,6 +157,37 @@ def test_overlay_draw_clears_only_overlay_layer() -> None:
|
||||
assert ("text", "overlay-draw##layer-overlays") in fake.drawn
|
||||
|
||||
|
||||
def test_tile_draw_snaps_fractional_positions_to_integer_pixels() -> None:
|
||||
state = create_map_state(tag="tile-snap", center=(47.0, 2.0), zoom=8)
|
||||
tile_id = TileID("osm", 8, 129, 89)
|
||||
state.tile_manager._result_queue.put(
|
||||
TileResult(
|
||||
tile_id,
|
||||
generation=state.generation,
|
||||
status=TileStatus.READY,
|
||||
width=1,
|
||||
height=1,
|
||||
pixels=(1.0, 1.0, 1.0, 1.0),
|
||||
source="disk",
|
||||
)
|
||||
)
|
||||
state.tile_manager.drain_results(generation=state.generation, provider_name="osm")
|
||||
state.tile_manager.set_texture_tag(tile_id, "tile-texture")
|
||||
fake = FakeDpg()
|
||||
fake.items.add(state.drawlist_tag)
|
||||
renderer = MapRenderer(state, fake)
|
||||
|
||||
renderer._draw_tile_layer(
|
||||
visible_tiles=[VisibleTile(tile_id, 10.4, 20.6)],
|
||||
width=400,
|
||||
height=300,
|
||||
attribution="Tiles",
|
||||
tile_size=256,
|
||||
)
|
||||
|
||||
assert fake.images == [((10, 21), (266, 277), "tile-snap##layer-tiles")]
|
||||
|
||||
|
||||
def test_overlay_update_drain_sets_only_overlay_dirty() -> None:
|
||||
state = create_map_state(tag="overlay-dirty")
|
||||
state.dirty = DirtyFlags.NONE
|
||||
|
||||
Reference in New Issue
Block a user