diff --git a/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala b/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala index 82dfd3b..5dc56ac 100644 --- a/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala +++ b/src/main/scala/ocelot/desktop/ui/widget/IconButton.scala @@ -51,7 +51,8 @@ class IconButton( case _ => // the other modes are triggered on click. } - case ClickEvent(MouseEvent.Button.Left, _) => mode match { + case ClickEvent(MouseEvent.Button.Left, _) => + mode match { case Mode.Regular => // regular buttons are handled above. case Mode.Switch if model.pressed => handleRelease() @@ -62,12 +63,38 @@ class IconButton( handlePress() clickSoundSource.release.play() } + + onClicked() } + /** + * Called when the state is changed to pressed. + * + * UX note: override this for [[Mode.Switch]] and [[Mode.Radio]] buttons. + * + * @see [[onClicked]] for [[Mode.Regular]] buttons. + */ def onPressed(): Unit = {} + /** + * Called when the state is changed to released. + * + * UX note: override this for [[Mode.Switch]] and [[Mode.Radio]] buttons. + * + * @see [[onClicked]] for [[Mode.Regular]] buttons. + */ def onReleased(): Unit = {} + /** + * Called when the button is clicked (the mouse button has been released while it's within the button's bounds), + * regardless of the state. + * + * UX note: override this for [[Mode.Regular]] buttons. + * + * @see [[onPressed]] and [[onReleased]] for [[Mode.Switch]] and [[Mode.Radio]] buttons. + */ + def onClicked(): Unit = {} + private def onHoverEnter(): Unit = { updateColorAnimationTargets() @@ -178,22 +205,24 @@ object IconButton { sealed trait Mode object Mode { - - /** Your regular, run-of-the-mill button you love. + /** + * Your regular, run-of-the-mill button you love. * * When the LMB is depressed, [[IconButton.onPressed]] is called. * After it's released, [[IconButton.onReleased]] is called. */ case object Regular extends Mode - /** A toggleable button, or a switch. + /** + * A toggleable button, or a switch. * * Clicking the LMB while the button is pressed releases it, and [[IconButton.onReleased]] is called. * Clicking the LMB while the button is released depresses it, and [[IconButton.onPressed]] is called. */ case object Switch extends Mode - /** A radio button is like a switch except clicking on it while it's depressed doesn't do anything. + /** + * A radio button is like a switch except clicking on it while it's depressed doesn't do anything. * * [[IconButton.onReleased]] is never called (unless you do it yourself). * @@ -202,18 +231,21 @@ object IconButton { case object Radio extends Mode } - /** This is the visible button state. + /** + * This is the visible button state. * * When [[IconButton.update]] notices a state change, it runs its animations. * * Note that callbacks are run after running the setter regardless of whether it does anything. */ trait Model { - - /** Whether to display the pressed button state. */ + /** + * Whether to display the pressed button state. + */ def pressed: Boolean - /** This setter is used by [[IconButton]] to respond to user interaction. + /** + * This setter is used by [[IconButton]] to respond to user interaction. * * You may want to override this method to do nothing * if you're proxying another model and updating it in callbacks. @@ -221,10 +253,14 @@ object IconButton { def pressed_=(newValue: Boolean): Unit } - /** This is the default model that simply reads from a variable and writes to it. */ + /** + * This is the default model that simply reads from a variable and writes to it. + */ case class DefaultModel(override var pressed: Boolean) extends Model - /** This is a model that ignores user input (presumably you handle it in callbacks). */ + /** + * This is a model that ignores user input (presumably you handle it in callbacks). + */ class ReadOnlyModel(f: () => Boolean) extends Model { override def pressed: Boolean = f() @@ -232,8 +268,8 @@ object IconButton { } object ReadOnlyModel { - - /** A utility method to create a new instance of [[ReadOnlyModel]]. + /** + * A utility method to create a new instance of [[ReadOnlyModel]]. * * The value returned by [[ReadOnlyModel.pressed]] is obtained * by evaluating the provided expression '''every time'''.