3import QGroundControl.Viewer3D
5/// Gazebo-style input handling for the 3D viewer. Forwards mouse/touch gestures
6/// to a Viewer3DCameraController:
7/// - Left drag: pan (picked ground point stays under the cursor)
8/// - Middle drag or Shift+left drag: orbit around the point under the cursor
9/// - Right drag: zoom toward/away from the pressed point (up = in, down = out)
10/// - Wheel: zoom toward/away from the point under the cursor
11/// - Pinch: zoom toward the gesture centroid
12/// - Two-finger twist: rotate heading around the point under the centroid
13/// - Two-finger vertical swipe: tilt around the point under the centroid
17 property Viewer3DCameraController controller
22 acceptedButtons: Qt.LeftButton
23 acceptedModifiers: Qt.NoModifier
26 root.controller.beginPan(centroid.pressPosition)
27 // Event compression can collapse the whole drag into the
28 // activating event with no centroid change afterwards, so
29 // apply the movement accumulated so far right away
30 root.controller.panTo(centroid.position)
35 root.controller.panTo(centroid.position)
43 acceptedButtons: Qt.MiddleButton
44 // acceptedButtons does not filter touch points (they have no
45 // buttons), so keep touch away from the button-driven handlers
46 acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
49 root.controller.beginOrbit(centroid.pressPosition)
50 root.controller.orbitTo(centroid.position)
55 root.controller.orbitTo(centroid.position)
60 // Gazebo-style right-drag zoom: drag up zooms in, down zooms out
64 acceptedButtons: Qt.RightButton
65 acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
66 property real _lastY: 0
69 _lastY = centroid.pressPosition.y
70 root.controller.zoom((_lastY - centroid.position.y) * 3, centroid.pressPosition)
71 _lastY = centroid.position.y
76 root.controller.zoom((_lastY - centroid.position.y) * 3, centroid.pressPosition)
77 _lastY = centroid.position.y
82 // Trackpad-friendly orbit: macOS trackpads have no easy right-drag
86 acceptedButtons: Qt.LeftButton
87 acceptedModifiers: Qt.ShiftModifier
90 root.controller.beginOrbit(centroid.pressPosition)
91 root.controller.orbitTo(centroid.position)
96 root.controller.orbitTo(centroid.position)
104 onWheel: (event) => {
105 root.controller.zoom(event.angleDelta.y, Qt.point(event.x, event.y))
109 // The PinchHandler owns all two-finger gestures: scale zooms, twist
110 // rotates, and vertical centroid movement tilts (Google Earth style:
111 // swipe up tilts toward the horizon, gain full height = 180 deg). A
112 // separate two-finger DragHandler for tilt would race the PinchHandler
113 // for the exclusive grab, randomly making tilt swipes unresponsive.
117 property real _lastScale: 1.0
118 property real _lastRotation: 0.0
119 property real _lastY: 0
124 // Apply the movement consumed before activation right away:
125 // touch-move compression can leave no centroid change between
126 // activation and release, so waiting for onCentroidChanged
127 // would drop the whole swipe
128 _lastY = centroid.pressPosition.y
129 root.controller.tiltBy(((_lastY - centroid.position.y) / root.height) * 180, centroid.position)
130 _lastY = centroid.position.y
135 root.controller.tiltBy(((_lastY - centroid.position.y) / root.height) * 180, centroid.position)
136 _lastY = centroid.position.y
139 onActiveScaleChanged: {
140 if (active && (activeScale > 0)) {
141 root.controller.zoomBy(_lastScale / activeScale, centroid.position)
142 _lastScale = activeScale
145 // Two-finger twist: the world follows the fingers. activeRotation is
146 // positive for a visually clockwise twist (y-down screen), which
147 // matches a heading increase, so it feeds through directly.
148 onActiveRotationChanged: {
150 root.controller.rotateBy(activeRotation - _lastRotation, centroid.position)
151 _lastRotation = activeRotation