Răsfoiți Sursa

allow creating scene objects without context

Falko Schindler 1 an în urmă
părinte
comite
59f16bb84c
3 a modificat fișierele cu 31 adăugiri și 4 ștergeri
  1. 10 0
      nicegui/elements/scene.py
  2. 3 4
      nicegui/elements/scene_object3d.py
  3. 18 0
      tests/test_scene.py

+ 10 - 0
nicegui/elements/scene.py

@@ -82,6 +82,16 @@ class Scene(Element,
         self.on('init', self.handle_init)
         self.on('click3d', self.handle_click)
 
+    def __enter__(self) -> 'Scene':
+        Object3D.current_scene = self
+        return super().__enter__()
+
+    def __getattribute__(self, name: str) -> Any:
+        attribute = super().__getattribute__(name)
+        if isinstance(attribute, type) and issubclass(attribute, Object3D):
+            Object3D.current_scene = self
+        return attribute
+
     def handle_init(self, e: GenericEventArguments) -> None:
         self.is_initialized = True
         with globals.socket_id(e.args['socket_id']):

+ 3 - 4
nicegui/elements/scene_object3d.py

@@ -1,20 +1,19 @@
 import math
 import uuid
-from typing import TYPE_CHECKING, Any, List, Optional, Union, cast
-
-from .. import globals
+from typing import TYPE_CHECKING, Any, List, Optional, Union
 
 if TYPE_CHECKING:
     from .scene import Scene, SceneObject
 
 
 class Object3D:
+    current_scene: Optional['Scene'] = None
 
     def __init__(self, type: str, *args: Any) -> None:
         self.type = type
         self.id = str(uuid.uuid4())
         self.name: Optional[str] = None
-        self.scene: 'Scene' = cast('Scene', globals.get_slot().parent)
+        self.scene: 'Scene' = self.current_scene
         self.scene.objects[self.id] = self
         self.parent: Union[Object3D, SceneObject] = self.scene.stack[-1]
         self.args: List = list(args)

+ 18 - 0
tests/test_scene.py

@@ -112,3 +112,21 @@ def test_rotation_matrix_from_euler():
     Rz = np.array([[np.cos(kappa), -np.sin(kappa), 0], [np.sin(kappa), np.cos(kappa), 0], [0, 0, 1]])
     R = Rz @ Ry @ Rx
     assert np.allclose(Object3D.rotation_matrix_from_euler(omega, phi, kappa), R)
+
+
+def test_object_creation_via_context(screen: Screen):
+    with ui.scene() as scene:
+        scene.box().with_name('box')
+
+    screen.open('/')
+    screen.wait(0.5)
+    assert screen.selenium.execute_script(f'return scene_c{scene.id}.children[4].name') == 'box'
+
+
+def test_object_creation_via_attribute(screen: Screen):
+    scene = ui.scene()
+    scene.box().with_name('box')
+
+    screen.open('/')
+    screen.wait(0.5)
+    assert screen.selenium.execute_script(f'return scene_c{scene.id}.children[4].type') == 'box'