Selaa lähdekoodia

introduce drag events

Falko Schindler 1 vuosi sitten
vanhempi
säilyke
c1bb5806eb
3 muutettua tiedostoa jossa 51 lisäystä ja 6 poistoa
  1. 13 2
      nicegui/elements/scene.js
  2. 27 3
      nicegui/elements/scene.py
  3. 11 1
      nicegui/events.py

+ 13 - 2
nicegui/elements/scene.js

@@ -120,8 +120,19 @@ export default {
     }
     }
     this.controls = new OrbitControls(this.camera, this.renderer.domElement);
     this.controls = new OrbitControls(this.camera, this.renderer.domElement);
     this.drag_controls = new DragControls(this.draggable_objects, this.camera, this.renderer.domElement);
     this.drag_controls = new DragControls(this.draggable_objects, this.camera, this.renderer.domElement);
-    this.drag_controls.addEventListener("dragstart", () => (this.controls.enabled = false));
-    this.drag_controls.addEventListener("dragend", () => (this.controls.enabled = true));
+    const handle_drag = (event) => {
+      this.$emit(event.type, {
+        type: event.type,
+        object_id: event.object.object_id,
+        object_name: event.object.name,
+        x: event.object.position.x,
+        y: event.object.position.y,
+        z: event.object.position.z,
+      });
+      this.controls.enabled = event.type == "dragend";
+    };
+    this.drag_controls.addEventListener("dragstart", handle_drag);
+    this.drag_controls.addEventListener("dragend", handle_drag);
 
 
     const render = () => {
     const render = () => {
       requestAnimationFrame(() => setTimeout(() => render(), 1000 / 20));
       requestAnimationFrame(() => setTimeout(() => render(), 1000 / 20));

+ 27 - 3
nicegui/elements/scene.py

@@ -3,7 +3,8 @@ from typing import Any, Callable, Dict, List, Optional, Union
 
 
 from .. import binding, globals
 from .. import binding, globals
 from ..element import Element
 from ..element import Element
-from ..events import GenericEventArguments, SceneClickEventArguments, SceneClickHit, handle_event
+from ..events import (GenericEventArguments, SceneClickEventArguments, SceneClickHit, SceneDragEventArguments,
+                      handle_event)
 from ..helpers import KWONLY_SLOTS
 from ..helpers import KWONLY_SLOTS
 from .scene_object3d import Object3D
 from .scene_object3d import Object3D
 
 
@@ -58,10 +59,12 @@ class Scene(Element,
                  height: int = 300,
                  height: int = 300,
                  grid: bool = True,
                  grid: bool = True,
                  on_click: Optional[Callable[..., Any]] = None,
                  on_click: Optional[Callable[..., Any]] = None,
+                 on_drag_start: Optional[Callable[..., Any]] = None,
+                 on_drag_end: Optional[Callable[..., Any]] = None,
                  ) -> None:
                  ) -> None:
         """3D Scene
         """3D Scene
 
 
-        Display a 3d scene using `three.js <https://threejs.org/>`_.
+        Display a 3D scene using `three.js <https://threejs.org/>`_.
         Currently NiceGUI supports boxes, spheres, cylinders/cones, extrusions, straight lines, curves and textured meshes.
         Currently NiceGUI supports boxes, spheres, cylinders/cones, extrusions, straight lines, curves and textured meshes.
         Objects can be translated, rotated and displayed with different color, opacity or as wireframes.
         Objects can be translated, rotated and displayed with different color, opacity or as wireframes.
         They can also be grouped to apply joint movements.
         They can also be grouped to apply joint movements.
@@ -69,7 +72,9 @@ class Scene(Element,
         :param width: width of the canvas
         :param width: width of the canvas
         :param height: height of the canvas
         :param height: height of the canvas
         :param grid: whether to display a grid
         :param grid: whether to display a grid
-        :param on_click: callback to execute when a 3d object is clicked
+        :param on_click: callback to execute when a 3D object is clicked
+        :param on_drag_start: callback to execute when a 3D object is dragged
+        :param on_drag_end: callback to execute when a 3D object is dropped
         """
         """
         super().__init__()
         super().__init__()
         self._props['width'] = width
         self._props['width'] = width
@@ -79,9 +84,13 @@ class Scene(Element,
         self.stack: List[Union[Object3D, SceneObject]] = [SceneObject()]
         self.stack: List[Union[Object3D, SceneObject]] = [SceneObject()]
         self.camera: SceneCamera = SceneCamera()
         self.camera: SceneCamera = SceneCamera()
         self.on_click = on_click
         self.on_click = on_click
+        self.on_drag_start = on_drag_start
+        self.on_drag_end = on_drag_end
         self.is_initialized = False
         self.is_initialized = False
         self.on('init', self.handle_init)
         self.on('init', self.handle_init)
         self.on('click3d', self.handle_click)
         self.on('click3d', self.handle_click)
+        self.on('dragstart', self.handle_drag)
+        self.on('dragend', self.handle_drag)
 
 
     def handle_init(self, e: GenericEventArguments) -> None:
     def handle_init(self, e: GenericEventArguments) -> None:
         self.is_initialized = True
         self.is_initialized = True
@@ -115,6 +124,21 @@ class Scene(Element,
         )
         )
         handle_event(self.on_click, arguments)
         handle_event(self.on_click, arguments)
 
 
+    def handle_drag(self, e: GenericEventArguments) -> None:
+        arguments = SceneDragEventArguments(
+            sender=self,
+            client=self.client,
+            type=e.args['type'],
+            object_id=e.args['object_id'],
+            object_name=e.args['object_name'],
+            x=e.args['x'],
+            y=e.args['y'],
+            z=e.args['z'],
+        )
+        if arguments.type == 'dragend':
+            self.objects[arguments.object_id].move(arguments.x, arguments.y, arguments.z)
+        handle_event(self.on_drag_start if arguments.type == 'dragstart' else self.on_drag_end, arguments)
+
     def __len__(self) -> int:
     def __len__(self) -> int:
         return len(self.objects)
         return len(self.objects)
 
 

+ 11 - 1
nicegui/events.py

@@ -1,6 +1,6 @@
 from dataclasses import dataclass
 from dataclasses import dataclass
 from inspect import Parameter, signature
 from inspect import Parameter, signature
-from typing import TYPE_CHECKING, Any, Awaitable, BinaryIO, Callable, Dict, List, Optional
+from typing import TYPE_CHECKING, Any, Awaitable, BinaryIO, Callable, Dict, List, Literal, Optional
 
 
 from . import background_tasks, globals
 from . import background_tasks, globals
 from .helpers import KWONLY_SLOTS
 from .helpers import KWONLY_SLOTS
@@ -53,6 +53,16 @@ class SceneClickEventArguments(ClickEventArguments):
     hits: List[SceneClickHit]
     hits: List[SceneClickHit]
 
 
 
 
+@dataclass(**KWONLY_SLOTS)
+class SceneDragEventArguments(ClickEventArguments):
+    type: Literal['dragstart', 'dragend']
+    object_id: str
+    object_name: str
+    x: float
+    y: float
+    z: float
+
+
 @dataclass(**KWONLY_SLOTS)
 @dataclass(**KWONLY_SLOTS)
 class ColorPickEventArguments(EventArguments):
 class ColorPickEventArguments(EventArguments):
     color: str
     color: str