1
1
package solve.rendering.canvas
2
2
3
3
import javafx.beans.InvalidationListener
4
+ import javafx.event.EventHandler
5
+ import javafx.scene.input.MouseButton
6
+ import javafx.scene.input.MouseEvent
7
+ import javafx.scene.input.ScrollEvent
4
8
import org.joml.Vector2f
9
+ import org.joml.Vector2i
5
10
import solve.rendering.engine.rendering.renderers.FramesRenderer
6
11
import solve.rendering.engine.scene.Scene
12
+ import solve.rendering.engine.utils.minus
13
+ import solve.rendering.engine.utils.toFloatVector
7
14
import solve.scene.SceneFacade
8
15
import solve.scene.controller.SceneController
9
16
import solve.utils.ServiceLocator
10
- import tornadofx.*
17
+ import kotlin.math.pow
18
+ import kotlin.math.sign
11
19
12
20
class SceneCanvas : OpenGLCanvas () {
13
21
private var sceneController: SceneController ? = null
14
22
private var framesRenderer: FramesRenderer ? = null
15
23
private var canvasScene: Scene ? = null
16
24
25
+ private var mousePosition = Vector2i ()
26
+
27
+ private var isDraggingScene = false
28
+ private var dragStartCameraPosition = Vector2f ()
29
+ private var dragStartPoint = Vector2i ()
30
+
17
31
private val projectChangedEventHandler = InvalidationListener {
18
32
val controller = sceneController ? : return @InvalidationListener
19
33
framesRenderer?.setNewSceneFrames(controller.scene.frames)
@@ -23,12 +37,37 @@ class SceneCanvas : OpenGLCanvas() {
23
37
framesRenderer?.setFramesSelection(controller.scene.frames)
24
38
}
25
39
40
+ private val wheelScrolledEventHandler = EventHandler <ScrollEvent > { event ->
41
+ val scrollValueSign = event.deltaY.sign.toInt()
42
+ onWheelScrolled(scrollValueSign)
43
+ }
44
+ private val mouseMovedEventHandler = EventHandler <MouseEvent > { event ->
45
+ mousePosition = extrudeEventMousePosition(event)
46
+ }
47
+ private val mouseDraggedEventHandler = EventHandler <MouseEvent > { event ->
48
+ val mousePosition = extrudeEventMousePosition(event)
49
+ if (event.button == MouseButton .MIDDLE )
50
+ onMouseDragged(mousePosition)
51
+ }
52
+ private val wheelPressedEventHandler = EventHandler <MouseEvent > { event ->
53
+ if (event.button != MouseButton .MIDDLE )
54
+ return @EventHandler
55
+ dragStartCameraPosition = window.camera.position
56
+ dragStartPoint = fromScreenToCameraPoint(mousePosition)
57
+ isDraggingScene = true
58
+ }
59
+ private val wheelReleasedEventHandler = EventHandler <MouseEvent > { event ->
60
+ if (event.button != MouseButton .MIDDLE )
61
+ return @EventHandler
62
+ isDraggingScene = false
63
+ }
64
+
26
65
init {
27
66
initializeCanvasEvents()
28
67
}
29
68
30
69
override fun onInit () {
31
- moveCamerToLeftUpperCorner ()
70
+ moveCameraToLeftUpperCorner ()
32
71
33
72
val controller = ServiceLocator .getService<SceneController >() ? : return
34
73
sceneController = controller
@@ -48,18 +87,52 @@ class SceneCanvas : OpenGLCanvas() {
48
87
removeBindings()
49
88
}
50
89
51
- private fun moveCamerToLeftUpperCorner () {
90
+ private fun onMouseDragged (mousePosition : Vector2i ) {
91
+ val mousePoint = fromScreenToCameraPoint(mousePosition)
92
+ if (isDraggingScene) {
93
+ val dragVector = mousePoint - dragStartPoint
94
+ window.camera.position = dragStartCameraPosition - dragVector.toFloatVector() / window.camera.scaledZoom
95
+ }
96
+ }
97
+
98
+ private fun onWheelScrolled (scrollValueSign : Int ) {
99
+ val pointPosition = fromScreenToCameraPoint(mousePosition)
100
+ val zoomMultiplier = OnWheelScrolledZoomMultiplier .pow(scrollValueSign)
101
+ window.camera.zoomToPoint(pointPosition, zoomMultiplier)
102
+ }
103
+
104
+ private fun extrudeEventMousePosition (event : MouseEvent ) = Vector2i (event.x.toInt(), event.y.toInt())
105
+
106
+ private fun fromScreenToCameraPoint (screenPoint : Vector2i ) = screenPoint - (window.size / 2 )
107
+
108
+ private fun moveCameraToLeftUpperCorner () {
52
109
window.camera.position =
53
110
Vector2f (window.width.toFloat(), window.height.toFloat()) / (2f * window.camera.scaledZoom)
54
111
}
55
112
56
113
private fun addBindings () {
57
114
SceneFacade .lastVisualizationKeepSettingsProperty.addListener(projectChangedEventHandler)
58
115
sceneController?.sceneProperty?.addListener(framesChangedEventHandler)
116
+
117
+ canvas.onMouseMoved = mouseMovedEventHandler
118
+ canvas.onMouseDragged = mouseDraggedEventHandler
119
+ canvas.onMousePressed = wheelPressedEventHandler
120
+ canvas.onMouseReleased = wheelReleasedEventHandler
121
+ canvas.onScroll = wheelScrolledEventHandler
59
122
}
60
123
61
124
private fun removeBindings () {
62
125
SceneFacade .lastVisualizationKeepSettingsProperty.removeListener(projectChangedEventHandler)
63
126
sceneController?.sceneProperty?.removeListener(framesChangedEventHandler)
127
+
128
+ canvas.removeEventHandler(MouseEvent .MOUSE_MOVED , mouseMovedEventHandler)
129
+ canvas.removeEventHandler(MouseEvent .MOUSE_DRAGGED , mouseDraggedEventHandler)
130
+ canvas.removeEventHandler(MouseEvent .MOUSE_PRESSED , wheelPressedEventHandler)
131
+ canvas.removeEventHandler(MouseEvent .MOUSE_RELEASED , wheelReleasedEventHandler)
132
+ canvas.removeEventHandler(ScrollEvent .SCROLL , wheelScrolledEventHandler)
133
+ }
134
+
135
+ companion object {
136
+ private const val OnWheelScrolledZoomMultiplier = 1.1f
64
137
}
65
138
}
0 commit comments