Skip to content

Commit

Permalink
Updates Mouse to be InputState
Browse files Browse the repository at this point in the history
This deprecates a number of methods in favour of standardisation. It
fulfils some of #775 and finishes the work on #476
  • Loading branch information
hobnob committed Nov 8, 2024
1 parent 7a8dca8 commit c2da329
Show file tree
Hide file tree
Showing 11 changed files with 405 additions and 251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import indigo.shared.collections.Batch
import indigo.shared.constants.Key
import indigo.shared.datatypes._
import indigo.shared.events.GlobalEvent
import indigo.shared.events.MouseButton
import indigo.shared.scenegraph.Graphic
import indigo.shared.scenegraph.SceneNode
import indigo.shared.scenegraph.Text
Expand Down Expand Up @@ -217,10 +218,11 @@ final case class InputField(
rec(frameContext.inputState.keyboard.keysReleased.toList, this, false, None)
else Outcome(this)

if (frameContext.inputState.mouse.mouseReleased)
if (frameContext.inputState.pointers.isReleased)
bounds(frameContext.boundaryLocator) match
case Some(bounds) =>
if frameContext.inputState.mouse.wasMouseUpWithin(bounds) then updated.flatMap(_.giveFocus)
if frameContext.inputState.pointers.wasUpWithin(bounds, MouseButton.LeftMouseButton) then
updated.flatMap(_.giveFocus)
else updated.flatMap(_.loseFocus)
case _ =>
updated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import indigo.shared.datatypes.Depth
import indigo.shared.datatypes.Point
import indigo.shared.datatypes.Rectangle
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
Expand Down Expand Up @@ -318,33 +318,35 @@ final case class RadioButtonGroup(
rec(radioButtons, false, Nil)
}

/** Update all the option buttons according to the newest state of mouse input.
/** Update all the option buttons according to the newest state of pointer input.
*
* @param mouse
* The current mouse state
* @param pointer
* The current pointer state
* @return
* An Outcome[RadioButtonGroup] with this radio button's new state
*/
def update(mouse: Mouse): Outcome[RadioButtonGroup] = {
def update(pointer: PointerState): Outcome[RadioButtonGroup] = {
val indexedOptions = options.zipWithIndex

val selected: Option[Int] =
indexedOptions.flatMap {
case (o, i)
if mouse.isLeftDown && o.hitArea.getOrElse(hitArea).moveBy(o.position).isPointWithin(mouse.position) =>
Batch(i)
pointer.maybePosition.flatMap(pointerPos =>
indexedOptions.flatMap {
case (o, i)
if pointer.isLeftDown && o.hitArea.getOrElse(hitArea).moveBy(o.position).isPointWithin(pointerPos) =>
Batch(i)

case _ =>
Batch.empty
}.headOption
case _ =>
Batch.empty
}.headOption
)

val updatedOptions: Batch[Outcome[RadioButton]] =
indexedOptions.map {
// Selected already
case (o, _) if o.inSelectedState && selected.isEmpty =>
Outcome(o)

// Selected already after some mouse selection
// Selected already after some pointer selection
case (o, i) if o.inSelectedState && selected.isDefined && selected.contains(i) =>
Outcome(o)

Expand All @@ -356,15 +358,15 @@ final case class RadioButtonGroup(
case (o, i) if o.inSelectedState && selected.isDefined && !selected.contains(i) =>
Outcome(o.copy(state = RadioButtonState.Normal), o.onUnselected())

// Not selected, no mouse click, mouse within, should be in hover state.
// Not selected, no pointer click, pointer within, should be in hover state.
case (o, _)
if !o.inSelectedState && !mouse.isLeftDown && o.hitArea
if pointer.maybePosition != None && !o.inSelectedState && !pointer.isLeftDown && o.hitArea
.getOrElse(hitArea)
.moveBy(o.position)
.isPointWithin(mouse.position) =>
.isPointWithin(pointer.position) =>
Outcome(o.copy(state = RadioButtonState.Hover), o.onHoverOver())

// Hovered, but mouse outside so revert to normal
// Hovered, but pointer outside so revert to normal
case (o, _) if o.inHoverState =>
Outcome(o.copy(state = RadioButtonState.Normal), o.onHoverOut())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import indigo.shared.collections.Batch
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.MouseButton
import indigo.shared.events.PointerEvent
import indigo.shared.events.PointerType
import indigo.shared.input.Pointer
import indigo.shared.input.Pointers
import indigo.shared.materials.Material
import indigo.shared.scenegraph.Graphic

Expand Down Expand Up @@ -47,7 +50,10 @@ class RadioButtonGroupTests extends munit.FunSuite {
test("No mouse interaction") {

val mouse =
new Mouse(Batch.empty, Point(-10, -10), false)
new Pointers(
Batch(Pointer(Point(-10, -10), PointerType.Mouse)),
Batch.empty
)

val actual = radioButtons.update(mouse)

Expand All @@ -61,7 +67,10 @@ class RadioButtonGroupTests extends munit.FunSuite {
test("hover over unselected button") {

val mouse =
new Mouse(Batch.empty, Point(5, 25), false)
new Pointers(
Batch(Pointer(Point(5, 25), PointerType.Mouse)),
Batch.empty
)

val actual = radioButtons.update(mouse)

Expand All @@ -81,7 +90,10 @@ class RadioButtonGroupTests extends munit.FunSuite {
test("hover out unselected button") {

val mouse =
new Mouse(Batch.empty, Point(-5, 25), false)
new Pointers(
Batch(Pointer(Point(-5, 25), PointerType.Mouse)),
Batch.empty
)

val actual =
radioButtons
Expand Down Expand Up @@ -110,7 +122,10 @@ class RadioButtonGroupTests extends munit.FunSuite {
test("selecting a hovered button") {

val mouse =
new Mouse(Batch(MouseEvent.Click(5, 25)), Point(5, 25), true)
new Pointers(
Batch(Pointer(Point(5, 25), PointerType.Mouse, MouseButton.LeftMouseButton)),
Batch(PointerEvent.PointerClick(5, 25, PointerType.Mouse))
)

val actual =
radioButtons
Expand Down Expand Up @@ -138,7 +153,10 @@ class RadioButtonGroupTests extends munit.FunSuite {

test("selecting a hovered button, existing selected is de-selected") {
val mouse =
new Mouse(Batch(MouseEvent.Click(5, 25)), Point(5, 25), true)
new Pointers(
Batch(Pointer(Point(5, 25), PointerType.Mouse, MouseButton.LeftMouseButton)),
Batch(PointerEvent.PointerClick(5, 25, PointerType.Mouse))
)

val actual =
radioButtons
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -570,16 +570,24 @@ object PointerEvent:
button: Option[MouseButton]
) extends PointerEvent
object PointerDown:
def apply(position: Point): PointerDown =
PointerDown(position, MouseButton.LeftMouseButton, PointerType.Mouse)
def apply(x: Int, y: Int): PointerDown =
PointerDown(Point(x, y), MouseButton.LeftMouseButton, PointerType.Mouse)
def apply(position: Point, pointerType: PointerType): PointerDown =
PointerDown(position, MouseButton.LeftMouseButton, pointerType)
def apply(x: Int, y: Int, pointerType: PointerType): PointerDown =
PointerDown(Point(x, y), MouseButton.LeftMouseButton, pointerType)
def apply(position: Point, button: MouseButton): PointerDown =
PointerDown(position, button, PointerType.Mouse)
def apply(x: Int, y: Int, button: MouseButton): PointerDown =
PointerDown(Point(x, y), button, PointerType.Mouse)
def apply(x: Int, y: Int, button: MouseButton, pointerType: PointerType): PointerDown =
PointerDown(Point(x, y), button, pointerType)
def apply(position: Point, button: MouseButton, pointerType: PointerType): PointerDown =
PointerDown(
position = position,
buttons = Batch.empty,
buttons = Batch(button),
isAltKeyDown = false,
isCtrlKeyDown = false,
isMetaKeyDown = false,
Expand Down Expand Up @@ -624,10 +632,18 @@ object PointerEvent:
button: Option[MouseButton]
) extends PointerEvent
object PointerUp:
def apply(position: Point): PointerUp =
PointerUp(position, MouseButton.LeftMouseButton, PointerType.Mouse)
def apply(x: Int, y: Int): PointerUp =
PointerUp(Point(x, y), MouseButton.LeftMouseButton, PointerType.Mouse)
def apply(position: Point, pointerType: PointerType): PointerUp =
PointerUp(position, MouseButton.LeftMouseButton, pointerType)
def apply(x: Int, y: Int, pointerType: PointerType): PointerUp =
PointerUp(Point(x, y), MouseButton.LeftMouseButton, pointerType)
def apply(position: Point, button: MouseButton): PointerUp =
PointerUp(position, button, PointerType.Mouse)
def apply(x: Int, y: Int, button: MouseButton): PointerUp =
PointerUp(Point(x, y), button, PointerType.Mouse)
def apply(x: Int, y: Int, button: MouseButton, pointerType: PointerType): PointerUp =
PointerUp(Point(x, y), button, pointerType)
def apply(position: Point, button: MouseButton, pointerType: PointerType): PointerUp =
Expand Down Expand Up @@ -677,6 +693,41 @@ object PointerEvent:
button: Option[MouseButton]
) extends PointerEvent
object PointerClick:
def apply(position: Point): PointerClick =
PointerClick(position, MouseButton.LeftMouseButton, PointerType.Mouse)
def apply(x: Int, y: Int): PointerClick =
PointerClick(Point(x, y), MouseButton.LeftMouseButton, PointerType.Mouse)
def apply(position: Point, pointerType: PointerType): PointerClick =
PointerClick(position, MouseButton.LeftMouseButton, pointerType)
def apply(x: Int, y: Int, pointerType: PointerType): PointerClick =
PointerClick(Point(x, y), MouseButton.LeftMouseButton, pointerType)
def apply(position: Point, button: MouseButton): PointerClick =
PointerClick(position, button, PointerType.Mouse)
def apply(x: Int, y: Int, button: MouseButton): PointerClick =
PointerClick(Point(x, y), button, PointerType.Mouse)
def apply(x: Int, y: Int, button: MouseButton, pointerType: PointerType): PointerClick =
PointerClick(Point(x, y), button, pointerType)
def apply(position: Point, button: MouseButton, pointerType: PointerType): PointerClick =
PointerClick(
position = position,
buttons = Batch.empty,
isAltKeyDown = false,
isCtrlKeyDown = false,
isMetaKeyDown = false,
isShiftKeyDown = false,
movementPosition = Point.zero,
button = Some(button),
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: PointerClick): Option[Point] =
Option(e.position)

Expand All @@ -702,6 +753,33 @@ object PointerEvent:
isPrimary: Boolean
) extends PointerEvent
object PointerMove:
def apply(position: Point): PointerMove =
PointerMove(position, PointerType.Mouse)
def apply(x: Int, y: Int): PointerMove =
PointerMove(Point(x, y), PointerType.Mouse)
def apply(x: Int, y: Int, pointerType: PointerType): PointerMove =
PointerMove(Point(x, y), pointerType)
def apply(position: Point, pointerType: PointerType): PointerMove =
PointerMove(
position = position,
buttons = Batch.empty,
isAltKeyDown = false,
isCtrlKeyDown = false,
isMetaKeyDown = false,
isShiftKeyDown = false,
movementPosition = Point.zero,
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: PointerMove): Option[Point] =
Option(e.position)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ final case class InputMapping[A](oneOf: List[(Combo, A)]) {
oneOf
.find { c =>
c._1.mouseInputs.forall {
case MouseInput.MouseUp => mouse.mouseReleased
case MouseInput.MouseDown => mouse.mousePressed
case MouseInput.MouseClick => mouse.mouseClicked
case MouseInput.MouseAt(pt) => mouse.position == pt
case MouseInput.MouseUp => mouse.isReleased
case MouseInput.MouseDown => mouse.isPressed
case MouseInput.MouseClick => mouse.isClicked
case MouseInput.MouseAt(pt) => mouse.maybePosition == Some(pt)
case MouseInput.MouseButtonUp(button) => mouse.released(button)
case MouseInput.MouseButtonDown(button) => mouse.pressed(button)
case MouseInput.MouseWheelDown => mouse.scrolled.contains(MouseWheel.ScrollDown)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package indigo.shared.events

import indigo.shared.collections.Batch
import indigo.shared.events.MouseEvent
import indigo.shared.input.Gamepad
import indigo.shared.input.Keyboard
import indigo.shared.input.Mouse
Expand Down Expand Up @@ -38,10 +39,12 @@ object InputState {
events: Batch[InputEvent],
gamepadState: Gamepad
): InputState =
val pointers = Pointers.calculateNext(previous.pointers, events.collect { case e: PointerEvent => e });

InputState(
Mouse.calculateNext(previous.mouse, events.collect { case e: MouseEvent => e }),
Mouse(pointers, events.collect { case e: MouseEvent.Wheel => e }),
Keyboard.calculateNext(previous.keyboard, events.collect { case e: KeyboardEvent => e }),
gamepadState,
Pointers.calculateNext(previous.pointers, events.collect { case e: PointerEvent => e })
pointers
)
}
Loading

0 comments on commit c2da329

Please sign in to comment.