diff --git a/indigo-plugin/indigo-plugin/src/indigoplugin/generators/ConfigGen.scala b/indigo-plugin/indigo-plugin/src/indigoplugin/generators/ConfigGen.scala index fd9c44d19..dc9c60eb1 100644 --- a/indigo-plugin/indigo-plugin/src/indigoplugin/generators/ConfigGen.scala +++ b/indigo-plugin/indigo-plugin/src/indigoplugin/generators/ConfigGen.scala @@ -36,7 +36,6 @@ object ConfigGen { | advanced = AdvancedGameConfig | .default | .withAntiAliasing(${indigoOptions.metadata.antiAliasing.toString}) - | ) | ) |""".stripMargin diff --git a/indigo/indigo-extras/src/main/scala/indigoextras/ui/Button.scala b/indigo/indigo-extras/src/main/scala/indigoextras/ui/Button.scala index d0cfe6374..a2ab8547a 100644 --- a/indigo/indigo-extras/src/main/scala/indigoextras/ui/Button.scala +++ b/indigo/indigo-extras/src/main/scala/indigoextras/ui/Button.scala @@ -7,7 +7,7 @@ import indigo.shared.datatypes.Point import indigo.shared.datatypes.Rectangle import indigo.shared.datatypes.Size import indigo.shared.events.GlobalEvent -import indigo.shared.input.Mouse +import indigo.shared.input.PointerState import indigo.shared.scenegraph.EntityNode import indigo.shared.scenegraph.Graphic import indigo.shared.scenegraph.Group @@ -51,52 +51,55 @@ final case class Button( def withDepth(newDepth: Depth): Button = this.copy(depth = newDepth) - def update(mouse: Mouse): Outcome[Button] = { - val mouseInBounds = bounds.isPointWithin(mouse.position) + def update(pointer: PointerState): Outcome[Button] = { + val pointerInBounds = pointer.positions.exists(p => bounds.isPointWithin(p)) + println( + s"Pointer in bounds: $pointerInBounds released: ${pointer.isReleased} clicked: ${pointer.isClicked} pressed: ${pointer.isPressed}" + ) val upEvents: Batch[GlobalEvent] = - if mouseInBounds && mouse.mouseReleased then onUp() + if pointerInBounds && pointer.released then onUp() else Batch.empty val clickEvents: Batch[GlobalEvent] = - if mouseInBounds && mouse.mouseClicked then onClick() + if pointerInBounds && pointer.isClicked then onClick() else Batch.empty val downEvents: Batch[GlobalEvent] = - if mouseInBounds && mouse.mousePressed then onDown() + if pointerInBounds && pointer.pressed then onDown() else Batch.empty - val mouseButtonEvents: Batch[GlobalEvent] = + val pointerButtonEvents: Batch[GlobalEvent] = downEvents ++ upEvents ++ clickEvents state match // Stay in Down state - case ButtonState.Down if mouseInBounds && mouse.isLeftDown => - Outcome(this).addGlobalEvents(onHoldDown() ++ mouseButtonEvents) + case ButtonState.Down if pointerInBounds && pointer.isLeftDown => + Outcome(this).addGlobalEvents(onHoldDown() ++ pointerButtonEvents) // Move to Down state - case ButtonState.Up if mouseInBounds && mouse.mousePressed => - Outcome(toDownState).addGlobalEvents(onHoverOver() ++ mouseButtonEvents) + case ButtonState.Up if pointerInBounds && pointer.pressed => + Outcome(toDownState).addGlobalEvents(onHoverOver() ++ pointerButtonEvents) - case ButtonState.Over if mouseInBounds && mouse.mousePressed => - Outcome(toDownState).addGlobalEvents(mouseButtonEvents) + case ButtonState.Over if pointerInBounds && pointer.pressed => + Outcome(toDownState).addGlobalEvents(pointerButtonEvents) // Out of Down state - case ButtonState.Down if mouseInBounds && !mouse.isLeftDown => - Outcome(toOverState).addGlobalEvents(onHoverOver() ++ mouseButtonEvents) + case ButtonState.Down if pointerInBounds && !pointer.isLeftDown => + Outcome(toOverState).addGlobalEvents(onHoverOver() ++ pointerButtonEvents) - case ButtonState.Down if !mouseInBounds && !mouse.isLeftDown => - Outcome(toUpState).addGlobalEvents(onHoverOut() ++ mouseButtonEvents) + case ButtonState.Down if !pointerInBounds && !pointer.isLeftDown => + Outcome(toUpState).addGlobalEvents(onHoverOut() ++ pointerButtonEvents) // - case ButtonState.Up if mouseInBounds => - Outcome(toOverState).addGlobalEvents(onHoverOver() ++ mouseButtonEvents) + case ButtonState.Up if pointerInBounds => + Outcome(toOverState).addGlobalEvents(onHoverOver() ++ pointerButtonEvents) - case ButtonState.Over if !mouseInBounds => - Outcome(toUpState).addGlobalEvents(onHoverOut() ++ mouseButtonEvents) + case ButtonState.Over if !pointerInBounds => + Outcome(toUpState).addGlobalEvents(onHoverOut() ++ pointerButtonEvents) case _ => - Outcome(this).addGlobalEvents(mouseButtonEvents) + Outcome(this).addGlobalEvents(pointerButtonEvents) } private def applyPositionAndDepth(sceneNode: SceneNode, pt: Point, d: Depth): SceneNode = diff --git a/indigo/indigo-extras/src/main/scala/indigoextras/ui/HitArea.scala b/indigo/indigo-extras/src/main/scala/indigoextras/ui/HitArea.scala index 2a1f821cb..041835293 100644 --- a/indigo/indigo-extras/src/main/scala/indigoextras/ui/HitArea.scala +++ b/indigo/indigo-extras/src/main/scala/indigoextras/ui/HitArea.scala @@ -20,35 +20,35 @@ final case class HitArea( onHoldDown: () => Batch[GlobalEvent] ) derives CanEqual: - def update(pointers: PointerState): Outcome[HitArea] = { - val pointerInBounds = pointers.positions.exists(p => area.contains(Vertex.fromPoint(p))) + def update(pointer: PointerState): Outcome[HitArea] = { + val pointerInBounds = pointer.positions.exists(p => area.contains(Vertex.fromPoint(p))) val upEvents: Batch[GlobalEvent] = - if pointerInBounds && pointers.released then onUp() + if pointerInBounds && pointer.released then onUp() else Batch.empty val clickEvents: Batch[GlobalEvent] = - if pointerInBounds && pointers.isClicked then onClick() + if pointerInBounds && pointer.isClicked then onClick() else Batch.empty val downEvents: Batch[GlobalEvent] = - if pointerInBounds && pointers.pressed then onDown() + if pointerInBounds && pointer.pressed then onDown() else Batch.empty val pointerButtonEvents: Batch[GlobalEvent] = downEvents ++ upEvents ++ clickEvents state match - case ButtonState.Down if pointerInBounds && pointers.isLeftDown => + case ButtonState.Down if pointerInBounds && pointer.isLeftDown => Outcome(this).addGlobalEvents(onHoldDown() ++ pointerButtonEvents) case ButtonState.Up if pointerInBounds => Outcome(toOverState).addGlobalEvents(onHoverOver() ++ pointerButtonEvents) - case ButtonState.Over if pointerInBounds && pointers.pressed => + case ButtonState.Over if pointerInBounds && pointer.pressed => Outcome(toDownState).addGlobalEvents(pointerButtonEvents) - case ButtonState.Down if pointerInBounds && !pointers.isLeftDown => + case ButtonState.Down if pointerInBounds && !pointer.isLeftDown => Outcome(toOverState).addGlobalEvents(onHoverOver() ++ pointerButtonEvents) case ButtonState.Over if !pointerInBounds => diff --git a/indigo/indigo-extras/src/test/scala/indigoextras/ui/ButtonTests.scala b/indigo/indigo-extras/src/test/scala/indigoextras/ui/ButtonTests.scala index e9b38531e..75ffe4c0b 100644 --- a/indigo/indigo-extras/src/test/scala/indigoextras/ui/ButtonTests.scala +++ b/indigo/indigo-extras/src/test/scala/indigoextras/ui/ButtonTests.scala @@ -1,5 +1,6 @@ package indigoextras.ui +import indigo.MouseButton import indigo.shared.assets.AssetName import indigo.shared.collections.Batch import indigo.shared.datatypes.Depth @@ -7,7 +8,13 @@ import indigo.shared.datatypes.Point import indigo.shared.datatypes.Rectangle import indigo.shared.events.GlobalEvent import indigo.shared.events.MouseEvent -import indigo.shared.input.Mouse +import indigo.shared.events.PointerEvent.PointerDown +import indigo.shared.events.PointerEvent.PointerId +import indigo.shared.events.PointerEvent.PointerUp +import indigo.shared.events.PointerType +import indigo.shared.input.Pointer +import indigo.shared.input.PointerState +import indigo.shared.input.Pointers import indigo.shared.materials.Material import indigo.shared.scenegraph.Graphic @@ -39,9 +46,13 @@ class ButtonTests extends munit.FunSuite { test("Transition from Up -> Over when mouse over.") { assertEquals(button.state.isUp, true) - - val mouse = - new Mouse(Batch.empty, Point(20, 20), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch.empty + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.update(mouse) @@ -50,8 +61,13 @@ class ButtonTests extends munit.FunSuite { test("Transition from Up -> Over when mouse over.Within the button: On mouse over, the over action is performed") { - val mouse = - new Mouse(Batch.empty, Point(20, 20), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch.empty + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.update(mouse) assert(actual.unsafeGlobalEvents.length == 1) @@ -59,8 +75,13 @@ class ButtonTests extends munit.FunSuite { } test("Transition from Over -> Up when mouse out.") { - val mouse = - new Mouse(Batch.empty, Point(0, 0), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(0, 0))), + Batch.empty + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toOverState.update(mouse) @@ -70,8 +91,13 @@ class ButtonTests extends munit.FunSuite { test( "Transition from Over -> Up when mouse out.Starting within the button: On mouse out, the out action is performed" ) { - val mouse = - new Mouse(Batch.empty, Point(0, 0), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(0, 0))), + Batch.empty + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toOverState.update(mouse) assert(actual.unsafeGlobalEvents.length == 1) @@ -79,8 +105,13 @@ class ButtonTests extends munit.FunSuite { } test("Transition from Over -> Down on mouse press.") { - val mouse = - new Mouse(Batch(MouseEvent.MouseDown(20, 20)), Point(20, 20), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerDown(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toOverState.update(mouse) @@ -89,8 +120,13 @@ class ButtonTests extends munit.FunSuite { test("Transition from Over -> Down on mouse press.Within the button: On mouse down, the down action is performed") { - val mouse = - new Mouse(Batch(MouseEvent.MouseDown(20, 20)), Point(20, 20), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerDown(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toOverState.update(mouse) @@ -99,17 +135,26 @@ class ButtonTests extends munit.FunSuite { } test("Transition from Up -> Down on mouse press.") { - val mouse = - new Mouse(Batch(MouseEvent.MouseDown(20, 20)), Point(20, 20), false) - + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerDown(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toUpState.update(mouse) assertEquals(actual.unsafeGet.state.isDown, true) } test("Transition from Up -> Down on mouse press.Within the button: On mouse down, the down action is performed") { - val mouse = - new Mouse(Batch(MouseEvent.MouseDown(20, 20)), Point(20, 20), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerDown(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toUpState.update(mouse) @@ -121,8 +166,13 @@ class ButtonTests extends munit.FunSuite { } test("Transition from Down -> Over on mouse release.") { - val mouse = - new Mouse(Batch(MouseEvent.MouseUp(20, 20)), Point(20, 20), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerUp(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toDownState.update(mouse) @@ -132,8 +182,13 @@ class ButtonTests extends munit.FunSuite { test( "Transition from Down -> Over on mouse release.Within the button: On mouse release, the up action is performed" ) { - val mouse = - new Mouse(Batch(MouseEvent.MouseUp(20, 20)), Point(20, 20), false) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerUp(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = button.toDownState.update(mouse) @@ -143,10 +198,31 @@ class ButtonTests extends munit.FunSuite { } test("If the button is down, and the mouse moves out, the button stays down until release.") { + val mouse1 = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerDown(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } + val mouse2 = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch(MouseButton.LeftMouseButton), Point(200, 200))), + Batch.empty + ) + val pointerType = Some(PointerType.Mouse) + } + val mouse3 = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(200, 200))), + Batch(PointerUp(200, 200, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = for { - buttonPressed <- button.update(new Mouse(Batch(MouseEvent.MouseDown(20, 20)), Point(20, 20), false)) - mouseOut <- buttonPressed.update(new Mouse(Batch.empty, Point(200, 200), true)) - mouseReleased <- mouseOut.update(new Mouse(Batch(MouseEvent.MouseUp(200, 200)), Point(200, 200), false)) + buttonPressed <- button.update(mouse1) + mouseOut <- buttonPressed.update(mouse2) + mouseReleased <- mouseOut.update(mouse3) } yield (buttonPressed.state, mouseOut.state, mouseReleased.state) assert(clue(actual.unsafeGet._1.isDown)) @@ -157,11 +233,31 @@ class ButtonTests extends munit.FunSuite { test( "If the button is down, and the mouse moves out, the button stays down until release.If the mouse is moved onto and pressed down on the button, dragged out and released, only the down action is performed." ) { - + val mouse1 = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(20, 20))), + Batch(PointerDown(20, 20, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } + val mouse2 = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(200, 200))), + Batch.empty + ) + val pointerType = Some(PointerType.Mouse) + } + val mouse3 = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch.empty, Point(200, 200))), + Batch(PointerUp(200, 200, PointerType.Mouse)) + ) + val pointerType = Some(PointerType.Mouse) + } val actual = for { - buttonPressed <- button.update(new Mouse(Batch(MouseEvent.MouseDown(20, 20)), Point(20, 20), false)) - mouseOut <- buttonPressed.update(new Mouse(Batch.empty, Point(200, 200), false)) - mouseReleased <- mouseOut.update(new Mouse(Batch(MouseEvent.MouseUp(200, 200)), Point(200, 200), false)) + buttonPressed <- button.update(mouse1) + mouseOut <- buttonPressed.update(mouse2) + mouseReleased <- mouseOut.update(mouse3) } yield (buttonPressed.state, mouseOut.state, mouseReleased.state) assert(clue(actual.unsafeGlobalEvents.length) == clue(3)) @@ -171,7 +267,13 @@ class ButtonTests extends munit.FunSuite { } test("If the button is down and we keep the mouse pressed, hold down actions are performed.") { - val mouse = new Mouse(Batch.empty, button.bounds.position, true) + val mouse = new PointerState { + val pointers = new Pointers( + Batch(Pointer(PointerId(1), PointerType.Mouse, Batch(MouseButton.LeftMouseButton), button.bounds.position)), + Batch.empty + ) + val pointerType = Some(PointerType.Mouse) + } val actual = for { holdDown <- button.toDownState.update(mouse) holdDownLonger <- holdDown.update(mouse) diff --git a/indigo/indigo-extras/src/test/scala/indigoextras/ui/HitAreaTests.scala b/indigo/indigo-extras/src/test/scala/indigoextras/ui/HitAreaTests.scala index b7bf0736b..df08bf545 100644 --- a/indigo/indigo-extras/src/test/scala/indigoextras/ui/HitAreaTests.scala +++ b/indigo/indigo-extras/src/test/scala/indigoextras/ui/HitAreaTests.scala @@ -12,7 +12,6 @@ import indigo.shared.events.MouseEvent import indigo.shared.events.PointerEvent.PointerDown import indigo.shared.events.PointerEvent.PointerId import indigo.shared.events.PointerType -import indigo.shared.input.Mouse import indigo.shared.input.Pointer import indigo.shared.input.PointerState import indigo.shared.input.Pointers @@ -52,7 +51,6 @@ class HitAreaTests extends munit.FunSuite { val pointerType = Some(PointerType.Mouse) } - val mouse2 = new Mouse(Batch.empty, bounds.position, false) val actual = hitArea.toDownState.update(mouse).unsafeGet assert(actual.state == ButtonState.Over) } @@ -62,26 +60,7 @@ class HitAreaTests extends munit.FunSuite { val pointers = new Pointers( Batch(Pointer(PointerId(1), PointerType.Mouse, Batch(MouseButton.LeftMouseButton), bounds.position)), Batch( - PointerDown( - bounds.position, - Batch(MouseButton.LeftMouseButton), - false, - false, - false, - false, - Point.zero, - PointerId(1), - 0, - 0, - 0, - 0, - Radians.zero, - Radians.zero, - Radians.zero, - PointerType.Mouse, - true, - Some(MouseButton.LeftMouseButton) - ) + PointerDown(bounds.position, MouseButton.LeftMouseButton, PointerType.Mouse) ) ) val pointerType = Some(PointerType.Mouse) diff --git a/indigo/indigo/src/main/scala/indigo/shared/events/GlobalEvent.scala b/indigo/indigo/src/main/scala/indigo/shared/events/GlobalEvent.scala index b06997766..3bb942c52 100644 --- a/indigo/indigo/src/main/scala/indigo/shared/events/GlobalEvent.scala +++ b/indigo/indigo/src/main/scala/indigo/shared/events/GlobalEvent.scala @@ -569,6 +569,91 @@ object PointerEvent: button: Option[MouseButton] ) extends PointerEvent object PointerDown: + def apply(position: Point, pointerType: PointerType): PointerDown = + PointerDown( + position = position, + buttons = Batch.empty, + isAltKeyDown = false, + isCtrlKeyDown = false, + isMetaKeyDown = false, + isShiftKeyDown = false, + movementPosition = Point.zero, + button = Some(MouseButton.LeftMouseButton), + pointerId = 0, + width = 0, + height = 0, + pressure = 0, + tangentialPressure = 0, + tiltX = Radians.zero, + tiltY = Radians.zero, + twist = Radians.zero, + pointerType = pointerType, + isPrimary = true + ) + def apply(x: Int, y: Int, pointerType: PointerType): PointerDown = + PointerDown( + position = Point(x, y), + buttons = Batch.empty, + isAltKeyDown = false, + isCtrlKeyDown = false, + isMetaKeyDown = false, + isShiftKeyDown = false, + movementPosition = Point.zero, + button = Some(MouseButton.LeftMouseButton), + pointerId = 0, + width = 0, + height = 0, + pressure = 0, + tangentialPressure = 0, + tiltX = Radians.zero, + tiltY = Radians.zero, + twist = Radians.zero, + pointerType = pointerType, + isPrimary = true + ) + def apply(position: Point, button: MouseButton, pointerType: PointerType): PointerDown = + PointerDown( + position = position, + buttons = Batch.empty, + isAltKeyDown = false, + isCtrlKeyDown = false, + isMetaKeyDown = false, + isShiftKeyDown = false, + movementPosition = Point.zero, + button = Some(MouseButton.LeftMouseButton), + pointerId = 0, + width = 0, + height = 0, + pressure = 0, + tangentialPressure = 0, + tiltX = Radians.zero, + tiltY = Radians.zero, + twist = Radians.zero, + pointerType = pointerType, + isPrimary = true + ) + def apply(x: Int, y: Int, button: MouseButton, pointerType: PointerType): PointerDown = + PointerDown( + position = Point(x, y), + buttons = Batch.empty, + isAltKeyDown = false, + isCtrlKeyDown = false, + isMetaKeyDown = false, + isShiftKeyDown = false, + movementPosition = Point.zero, + button = Some(MouseButton.LeftMouseButton), + pointerId = 0, + width = 0, + height = 0, + pressure = 0, + tangentialPressure = 0, + tiltX = Radians.zero, + tiltY = Radians.zero, + twist = Radians.zero, + pointerType = pointerType, + isPrimary = true + ) + def unapply(e: PointerDown): Option[Point] = Option(e.position) @@ -595,6 +680,70 @@ object PointerEvent: button: Option[MouseButton] ) extends PointerEvent object PointerUp: + def apply(position: Point, pointerType: PointerType): PointerUp = + PointerUp( + position = position, + buttons = Batch.empty, + isAltKeyDown = false, + isCtrlKeyDown = false, + isMetaKeyDown = false, + isShiftKeyDown = false, + movementPosition = Point.zero, + button = Some(MouseButton.LeftMouseButton), + pointerId = 0, + width = 0, + height = 0, + pressure = 0, + tangentialPressure = 0, + tiltX = Radians.zero, + tiltY = Radians.zero, + twist = Radians.zero, + pointerType = pointerType, + isPrimary = true + ) + def apply(x: Int, y: Int, pointerType: PointerType): PointerUp = + PointerUp( + position = Point(x, y), + buttons = Batch.empty, + isAltKeyDown = false, + isCtrlKeyDown = false, + isMetaKeyDown = false, + isShiftKeyDown = false, + movementPosition = Point.zero, + button = Some(MouseButton.LeftMouseButton), + pointerId = 0, + width = 0, + height = 0, + pressure = 0, + tangentialPressure = 0, + tiltX = Radians.zero, + tiltY = Radians.zero, + twist = Radians.zero, + pointerType = pointerType, + isPrimary = true + ) + def apply(x: Int, y: Int, button: MouseButton, pointerType: PointerType): PointerUp = + PointerUp( + position = Point(x, y), + buttons = Batch.empty, + isAltKeyDown = false, + isCtrlKeyDown = false, + isMetaKeyDown = false, + isShiftKeyDown = false, + movementPosition = Point.zero, + button = Some(MouseButton.LeftMouseButton), + pointerId = 0, + width = 0, + height = 0, + pressure = 0, + tangentialPressure = 0, + tiltX = Radians.zero, + tiltY = Radians.zero, + twist = Radians.zero, + pointerType = pointerType, + isPrimary = true + ) + def unapply(e: PointerUp): Option[Point] = Option(e.position)