Skip to content

Commit

Permalink
Allow awaiting the "init" event of ui.map and ui.scene (#2606)
Browse files Browse the repository at this point in the history
* allow awaiting the "init" event of `ui.map` and `ui.scene`

* add leaflet wait_for_init example

* began scene wait_for_init example

* review

---------

Co-authored-by: Rodja Trappe <rodja@zauberzeug.com>
  • Loading branch information
falkoschindler and rodja authored Feb 26, 2024
1 parent 3e41652 commit f222bd0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 0 deletions.
8 changes: 8 additions & 0 deletions nicegui/elements/leaflet.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
from pathlib import Path
from typing import Any, Dict, List, Tuple, Union, cast

Expand Down Expand Up @@ -74,6 +75,13 @@ def _handle_init(self, e: GenericEventArguments) -> None:
for layer in self.layers:
self.run_method('add_layer', layer.to_dict(), layer.id)

async def initialized(self) -> None:
"""Wait until the map is initialized."""
event = asyncio.Event()
self.on('init', event.set, [])
await self.client.connected()
await event.wait()

def _handle_moveend(self, e: GenericEventArguments) -> None:
self.center = e.args['center']

Expand Down
8 changes: 8 additions & 0 deletions nicegui/elements/scene.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
from dataclasses import dataclass
from typing import Any, Callable, Dict, List, Optional, Union

Expand Down Expand Up @@ -120,6 +121,13 @@ def _handle_init(self, e: GenericEventArguments) -> None:
for obj in self.objects.values():
obj.send()

async def initialized(self) -> None:
"""Wait until the scene is initialized."""
event = asyncio.Event()
self.on('init', event.set, [])
await self.client.connected()
await event.wait()

def run_method(self, name: str, *args: Any, timeout: float = 1, check_interval: float = 0.01) -> AwaitableResponse:
if not self.is_initialized:
return NullResponse()
Expand Down
16 changes: 16 additions & 0 deletions website/documentation/content/leaflet_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,20 @@ def run_layer_methods() -> None:
ui.button('Change icon', on_click=lambda: marker.run_method(':setIcon', icon))


@doc.demo('Wait for Initialization', '''
You can wait for the map to be initialized with the `initialized` method.
This is necessary when you want to run methods like fitting the bounds of the map right after the map is created.
''')
async def wait_for_init() -> None:
m = ui.leaflet(zoom=5)
central_park = m.generic_layer(name='polygon', args=[[
(40.767809, -73.981249),
(40.800273, -73.958291),
(40.797011, -73.949683),
(40.764704, -73.973741),
]])
await m.initialized()
bounds = await central_park.run_method('getBounds')
m.run_map_method('fitBounds', [[bounds['_southWest'], bounds['_northEast']]])

doc.reference(ui.leaflet)
11 changes: 11 additions & 0 deletions website/documentation/content/scene_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,15 @@ def point_clouds() -> None:
scene.point_cloud(points=points, colors=points, point_size=0.1)


@doc.demo('Wait for Initialization', '''
You can wait for the scene to be initialized with the `initialized` method.
This demo animates a camera movement after the scene has been fully loaded.
''')
async def wait_for_init() -> None:
with ui.scene(width=285, height=220) as scene:
scene.sphere()
await scene.initialized()
scene.move_camera(x=1, y=-1, z=1.5, duration=2)


doc.reference(ui.scene)

0 comments on commit f222bd0

Please sign in to comment.