mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-20 02:59:19 +01:00
Make HoverEvent a CapturingEvent
This commit is contained in:
parent
448089ccb9
commit
99af664d84
@ -103,7 +103,7 @@ abstract class Node extends Widget with MouseHandler with HoverHandler with Pers
|
||||
override def update(): Unit = {
|
||||
super.update()
|
||||
|
||||
if (isHovered || isMoving) {
|
||||
if (mouseOver || isMoving) {
|
||||
root.get.statusBar.addMouseEntry(IconSource.Icons.RMB, "Menu")
|
||||
root.get.statusBar.addMouseEntry(IconSource.Icons.DragLMB, "Move node")
|
||||
|
||||
@ -245,7 +245,7 @@ abstract class Node extends Widget with MouseHandler with HoverHandler with Pers
|
||||
|
||||
private def stopMoving(): Unit = {
|
||||
isMoving = false
|
||||
if (isHovered)
|
||||
if (mouseOver)
|
||||
highlight.goto(HoveredHighlight)
|
||||
else
|
||||
highlight.goto(NoHighlight)
|
||||
|
||||
@ -50,7 +50,7 @@ class NodeTypeWidget(val nodeType: NodeType) extends Widget with MouseHandler wi
|
||||
|
||||
override def update(): Unit = {
|
||||
super.update()
|
||||
if (isHovered) {
|
||||
if (mouseOver) {
|
||||
root.get.statusBar.addMouseEntry(IconSource.Icons.LMB, "Add node")
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ trait ShiftClickNode extends Node {
|
||||
override def update(): Unit = {
|
||||
super.update()
|
||||
|
||||
if (isHovered || isMoving)
|
||||
if (mouseOver || isMoving)
|
||||
root.get.statusBar.addKeyMouseEntry(IconSource.Icons.LMB, "SHIFT", hoveredShiftStatusBarText)
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ trait WindowedNode[T <: Window] extends Node with Windowed[T] {
|
||||
}
|
||||
|
||||
override def update(): Unit = {
|
||||
if (isHovered || isMoving)
|
||||
if (mouseOver || isMoving)
|
||||
root.get.statusBar.addMouseEntry(IconSource.Icons.LMB, if (windowCreated && window.isOpen) "Close" else "Open")
|
||||
|
||||
super.update()
|
||||
|
||||
@ -26,7 +26,7 @@ abstract class NoteBlockNodeBase(entity: Entity with Environment) extends Entity
|
||||
|
||||
override def update(): Unit = {
|
||||
super.update()
|
||||
if (isHovered || isMoving) {
|
||||
if (mouseOver || isMoving) {
|
||||
root.get.statusBar.addMouseEntry(IconSource.Icons.LMB, "Play sample")
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import ocelot.desktop.geometry.{Rect2D, Size2D, Vector2D}
|
||||
import ocelot.desktop.graphics.Graphics
|
||||
import ocelot.desktop.ui.event.handlers.HoverHandler
|
||||
import ocelot.desktop.ui.event.sources.{BrainEvents, KeyEvents, MouseEvents, ScrollEvents}
|
||||
import ocelot.desktop.ui.event.{Capturing, CapturingEvent, Dispatchable, MouseEvent}
|
||||
import ocelot.desktop.ui.event.{Capturing, CapturingEvent, Dispatchable, HoverEvent, MouseEvent}
|
||||
import ocelot.desktop.ui.widget.{RootWidget, Widget}
|
||||
import ocelot.desktop.util._
|
||||
import ocelot.desktop.{OcelotDesktop, Settings}
|
||||
@ -28,7 +28,6 @@ import scala.collection.mutable.ArrayBuffer
|
||||
import scala.concurrent.duration.DurationInt
|
||||
import scala.util.Try
|
||||
|
||||
|
||||
object UiHandler extends Logging {
|
||||
var root: RootWidget = _
|
||||
var graphics: Graphics = _
|
||||
@ -506,12 +505,16 @@ object UiHandler extends Logging {
|
||||
}
|
||||
|
||||
hierarchy.reverseIterator.foreach {
|
||||
case handler: HoverHandler if !mouseTarget.contains(handler) => handler.setHovered(false)
|
||||
case h: HoverHandler if !mouseTarget.contains(h) && h._mouseOver.update(false) =>
|
||||
dispatchCapturing(h)(HoverEvent(HoverEvent.State.Leave))
|
||||
|
||||
case _ =>
|
||||
}
|
||||
|
||||
mouseTarget.foreach {
|
||||
case handler: HoverHandler => handler.setHovered(true)
|
||||
case h: HoverHandler if h._mouseOver.update(true) =>
|
||||
dispatchCapturing(h)(HoverEvent(HoverEvent.State.Enter))
|
||||
|
||||
case _ =>
|
||||
}
|
||||
|
||||
|
||||
@ -6,4 +6,4 @@ object HoverEvent {
|
||||
}
|
||||
}
|
||||
|
||||
case class HoverEvent(state: HoverEvent.State.Value) extends Event
|
||||
case class HoverEvent(state: HoverEvent.State.Value) extends CapturingEvent
|
||||
|
||||
@ -1,21 +1,11 @@
|
||||
package ocelot.desktop.ui.event.handlers
|
||||
|
||||
import ocelot.desktop.ui.event.HoverEvent
|
||||
import ocelot.desktop.ui.widget.Widget
|
||||
import ocelot.desktop.util.Register
|
||||
|
||||
trait HoverHandler extends Widget {
|
||||
private var wasHovered = false
|
||||
private var _isHovered: Boolean = false
|
||||
// must only be updated in UiHandler.
|
||||
val _mouseOver: Register.Writeable[Boolean] = Register.apply(false)
|
||||
|
||||
def isHovered: Boolean = _isHovered
|
||||
|
||||
def setHovered(v: Boolean): Unit = {
|
||||
_isHovered = v
|
||||
|
||||
if (_isHovered && !wasHovered)
|
||||
handleEvent(HoverEvent(HoverEvent.State.Enter))
|
||||
else if (!_isHovered && wasHovered)
|
||||
handleEvent(HoverEvent(HoverEvent.State.Leave))
|
||||
wasHovered = _isHovered
|
||||
}
|
||||
def mouseOver: Boolean = _mouseOver.value
|
||||
}
|
||||
|
||||
@ -114,8 +114,8 @@ class IconButton(
|
||||
protected def pressedActiveColor: Color = pressedColor.toRGBANorm.mapRgb(_ * (1 - darkenActiveColorFactor))
|
||||
protected def releasedActiveColor: Color = releasedColor.toRGBANorm.mapRgb(_ * (1 - darkenActiveColorFactor))
|
||||
|
||||
private def targetPressedColor: Color = if (isHovered) pressedActiveColor else pressedColor
|
||||
private def targetReleasedColor: Color = if (isHovered) releasedActiveColor else releasedColor
|
||||
private def targetPressedColor: Color = if (mouseOver) pressedActiveColor else pressedColor
|
||||
private def targetReleasedColor: Color = if (mouseOver) releasedActiveColor else releasedColor
|
||||
|
||||
private def targetIconMix: Float = if (model.pressed) 1f else 0f
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ abstract class Plot extends Widget {
|
||||
}
|
||||
}
|
||||
|
||||
if (panel.isHovered) {
|
||||
if (panel.mouseOver) {
|
||||
g.foreground = ColorScheme("PlotLine")
|
||||
val pos = UiHandler.mousePosition
|
||||
val x = xAxis.inversePos(pos.x - pBounds.x, pBounds.w)
|
||||
|
||||
@ -144,8 +144,8 @@ class ScrollView(val inner: Widget) extends Widget with Logging with HoverHandle
|
||||
|
||||
val mousePos = UiHandler.mousePosition
|
||||
|
||||
val vAnimDir = if (isHovered && vThumbHoverArea.contains(mousePos) || dragState.isVertical) 1 else -1
|
||||
val hAnimDir = if (isHovered && hThumbHoverArea.contains(mousePos) || dragState.isHorizontal) 1 else -1
|
||||
val vAnimDir = if (mouseOver && vThumbHoverArea.contains(mousePos) || dragState.isVertical) 1 else -1
|
||||
val hAnimDir = if (mouseOver && hThumbHoverArea.contains(mousePos) || dragState.isHorizontal) 1 else -1
|
||||
|
||||
vAnim = (vAnim + UiHandler.dt / 0.2f * vAnimDir).clamped()
|
||||
hAnim = (hAnim + UiHandler.dt / 0.2f * hAnimDir).clamped()
|
||||
|
||||
@ -149,7 +149,7 @@ abstract class Viewport3DWidget extends Widget with MouseHandler with HoverHandl
|
||||
|
||||
scene = createScene()
|
||||
|
||||
if (isHovered) {
|
||||
if (mouseOver) {
|
||||
root.get.statusBar.addMouseEntry(IconSource.Icons.LMB, "Rotate view")
|
||||
root.get.statusBar.addKeyMouseEntry(IconSource.Icons.LMB, "SHIFT", "Pan view")
|
||||
}
|
||||
|
||||
@ -584,7 +584,7 @@ class WorkspaceView extends Widget with Persistable with MouseHandler with Hover
|
||||
g.restore()
|
||||
|
||||
gridAlpha.update()
|
||||
if (KeyEvents.isControlDown && (isHovered || nodes.exists(_.isHovered))) {
|
||||
if (KeyEvents.isControlDown && (mouseOver || nodes.exists(_.mouseOver))) {
|
||||
gridAlpha.goto(0.1f)
|
||||
drawGrid(g)
|
||||
} else {
|
||||
@ -663,15 +663,15 @@ class WorkspaceView extends Widget with Persistable with MouseHandler with Hover
|
||||
nodes.foreach(_.update())
|
||||
particleSystem.update(UiHandler.dt)
|
||||
|
||||
if (isHovered) {
|
||||
if (mouseOver) {
|
||||
root.get.statusBar.addKeyEntry(Settings.get.keymap.name(Center), "Reset camera")
|
||||
}
|
||||
|
||||
if (isHovered || nodes.exists(_.isHovered)) {
|
||||
if (mouseOver || nodes.exists(_.mouseOver)) {
|
||||
root.get.statusBar.addKeyEntry("CTRL", "Show grid")
|
||||
}
|
||||
|
||||
if (isHovered && newConnection.isEmpty) {
|
||||
if (mouseOver && newConnection.isEmpty) {
|
||||
root.get.statusBar.addMouseEntry(
|
||||
IconSource.Icons.LMB,
|
||||
if (nodeSelector.isClosed) "Add node" else "Close selector",
|
||||
|
||||
@ -23,7 +23,7 @@ class ContextMenuSubmenu(
|
||||
super.update()
|
||||
if (
|
||||
!isClosing && !bounds.inflated(4).contains(UiHandler.mousePosition)
|
||||
&& !parentEntry.isHovered
|
||||
&& !parentEntry.mouseOver
|
||||
) close()
|
||||
}
|
||||
}
|
||||
@ -45,7 +45,7 @@ class ContextMenuSubmenu(
|
||||
}
|
||||
|
||||
override def update(): Unit = {
|
||||
if (!isHovered && submenu.isClosed) super.leave()
|
||||
if (!mouseOver && submenu.isClosed) super.leave()
|
||||
super.update()
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import ocelot.desktop.geometry.{Padding2D, Size2D}
|
||||
import ocelot.desktop.graphics.{Graphics, IconSource}
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.event.handlers.{HoverHandler, MouseHandler}
|
||||
import ocelot.desktop.ui.event.{ClickEvent, HoverEvent, MouseEvent}
|
||||
import ocelot.desktop.ui.event.{ClickEvent, MouseEvent}
|
||||
import ocelot.desktop.ui.layout.{AlignItems, LinearLayout}
|
||||
import ocelot.desktop.ui.widget._
|
||||
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry}
|
||||
@ -55,7 +55,7 @@ class StatusBar extends Widget {
|
||||
override def hThumbVisible: Boolean = false
|
||||
}
|
||||
|
||||
private lazy val hoverBoxWithPauseButton: HoverBox = new HoverBox(new IconButton(
|
||||
children :+= new HoverBox(new IconButton(
|
||||
IconSource.Icons.Pause,
|
||||
IconSource.Icons.Play,
|
||||
mode = IconButton.Mode.Switch,
|
||||
@ -64,23 +64,18 @@ class StatusBar extends Widget {
|
||||
tooltip = Some("Pause emulation"),
|
||||
model = new IconButton.ReadOnlyModel(() => OcelotDesktop.emulationPaused),
|
||||
) {
|
||||
eventHandlers += {
|
||||
case HoverEvent(HoverEvent.State.Enter) =>
|
||||
hoverBoxWithPauseButton.startHoverEnterAnimation()
|
||||
case HoverEvent(HoverEvent.State.Leave) =>
|
||||
hoverBoxWithPauseButton.startHoverLeaveAnimation()
|
||||
}
|
||||
override def onPressed(): Unit = {
|
||||
OcelotDesktop.emulationPaused = true
|
||||
labelTooltip.foreach(_.setText("Resume emulation"))
|
||||
}
|
||||
|
||||
override def onReleased(): Unit = {
|
||||
OcelotDesktop.emulationPaused = false
|
||||
labelTooltip.foreach(_.setText("Pause emulation"))
|
||||
}
|
||||
}, Padding2D(left = 2, right = 2))
|
||||
|
||||
private lazy val hoverBoxWithTpsLabel: HoverBox = new HoverBox(new Label with MouseHandler with HoverHandler {
|
||||
children :+= new HoverBox(new Label with MouseHandler with HoverHandler {
|
||||
override protected def receiveClickEvents: Boolean = true
|
||||
|
||||
eventHandlers += {
|
||||
@ -113,18 +108,12 @@ class StatusBar extends Widget {
|
||||
}
|
||||
|
||||
root.get.contextMenus.open(menu, pos)
|
||||
|
||||
case HoverEvent(HoverEvent.State.Enter) =>
|
||||
hoverBoxWithTpsLabel.startHoverEnterAnimation()
|
||||
|
||||
case HoverEvent(HoverEvent.State.Leave) =>
|
||||
hoverBoxWithTpsLabel.startHoverLeaveAnimation()
|
||||
}
|
||||
|
||||
override def update(): Unit = {
|
||||
super.update()
|
||||
|
||||
if (isHovered) {
|
||||
if (mouseOver) {
|
||||
root.get.statusBar.addMouseEntry(IconSource.Icons.RMB, "Change simulation speed")
|
||||
}
|
||||
}
|
||||
@ -136,9 +125,6 @@ class StatusBar extends Widget {
|
||||
override def text: String = f"TPS: ${OcelotDesktop.tpsCounter.fps}%02.1f"
|
||||
})
|
||||
|
||||
children :+= hoverBoxWithPauseButton
|
||||
children :+= new PaddingBox(hoverBoxWithTpsLabel, Padding2D(left = 8))
|
||||
|
||||
def addMouseEntry(icon: IconSource, text: String): Unit = {
|
||||
if (!keyMouseEntries.children.collect({ case e: MouseEntry => e.icon }).contains(icon)) {
|
||||
keyMouseEntries.children :+= new MouseEntry(icon, text)
|
||||
@ -165,17 +151,15 @@ class StatusBar extends Widget {
|
||||
keyMouseEntries.children = ArraySeq.empty
|
||||
}
|
||||
|
||||
private class HoverBox(widget: Widget, padding: Padding2D = Padding2D(left = 8, right = 8)) extends PaddingBox(widget, padding) with HoverAnimation {
|
||||
private class HoverBox(widget: Widget, padding: Padding2D = Padding2D(left = 8, right = 8))
|
||||
extends PaddingBox(widget, padding)
|
||||
with HoverAnimation {
|
||||
|
||||
override def receiveMouseEvents: Boolean = true
|
||||
|
||||
override protected val hoverAnimationColorActive: Color = ColorScheme("StatusBarActive")
|
||||
override protected val hoverAnimationColorDefault: Color = hoverAnimationColorActive.toRGBANorm.withAlpha(0)
|
||||
|
||||
// public re-exports
|
||||
override def startHoverEnterAnimation(): Unit = super.startHoverEnterAnimation()
|
||||
|
||||
override def startHoverLeaveAnimation(): Unit = super.startHoverLeaveAnimation()
|
||||
|
||||
override def draw(g: Graphics): Unit = {
|
||||
g.rect(bounds, hoverAnimation.color)
|
||||
super.draw(g)
|
||||
|
||||
@ -3,17 +3,18 @@ package ocelot.desktop.ui.widget.traits
|
||||
import ocelot.desktop.ColorScheme
|
||||
import ocelot.desktop.color.Color
|
||||
import ocelot.desktop.ui.Const._
|
||||
import ocelot.desktop.ui.event.{EventAware, HoverEvent}
|
||||
import ocelot.desktop.ui.event.{Capturing, EventAware, HoverEvent}
|
||||
import ocelot.desktop.ui.event.handlers.HoverHandler
|
||||
import ocelot.desktop.ui.widget.{Updatable, Widget}
|
||||
import ocelot.desktop.util.animation.ColorAnimation
|
||||
|
||||
/** Helper trait that manages color animations for UI widgets that should be highlighted on mouse hover. */
|
||||
|
||||
//noinspection ScalaWeakerAccess
|
||||
|
||||
/**
|
||||
* Helper trait that manages color animations for UI widgets that should be highlighted on mouse hover.
|
||||
*/
|
||||
trait HoverAnimation extends Widget with EventAware with HoverHandler with Updatable {
|
||||
//noinspection ScalaWeakerAccess
|
||||
protected val hoverAnimationSpeedEnter: Float = AnimationSpeedHoverEnter
|
||||
//noinspection ScalaWeakerAccess
|
||||
protected val hoverAnimationSpeedLeave: Float = AnimationSpeedHoverLeave
|
||||
protected val hoverAnimationColorDefault: Color = ColorScheme("ButtonBackground")
|
||||
protected val hoverAnimationColorActive: Color = ColorScheme("ButtonBackgroundActive")
|
||||
@ -22,19 +23,11 @@ trait HoverAnimation extends Widget with EventAware with HoverHandler with Updat
|
||||
new ColorAnimation(hoverAnimationColorDefault, hoverAnimationSpeedEnter)
|
||||
|
||||
eventHandlers += {
|
||||
case HoverEvent(HoverEvent.State.Enter) =>
|
||||
startHoverEnterAnimation()
|
||||
|
||||
case HoverEvent(HoverEvent.State.Leave) =>
|
||||
startHoverLeaveAnimation()
|
||||
}
|
||||
|
||||
protected def startHoverEnterAnimation(): Unit = {
|
||||
case Capturing(HoverEvent(HoverEvent.State.Enter)) =>
|
||||
hoverAnimation.speed = hoverAnimationSpeedEnter
|
||||
hoverAnimation.goto(hoverAnimationColorActive)
|
||||
}
|
||||
|
||||
protected def startHoverLeaveAnimation(): Unit = {
|
||||
case Capturing(HoverEvent(HoverEvent.State.Leave)) =>
|
||||
hoverAnimation.speed = hoverAnimationSpeedLeave
|
||||
hoverAnimation.goto(hoverAnimationColorDefault)
|
||||
}
|
||||
|
||||
@ -35,6 +35,12 @@ object Register {
|
||||
|
||||
changed
|
||||
}
|
||||
|
||||
def update(nextValue: T): Boolean = {
|
||||
this.nextValue = nextValue
|
||||
|
||||
update()
|
||||
}
|
||||
}
|
||||
|
||||
class Sampling[T](next: () => T) extends Register[T] {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user