mirror of
https://gitlab.com/cc-ru/ocelot/ocelot-desktop.git
synced 2025-12-19 18:49:19 +01:00
Select all text on triple-click
This commit is contained in:
parent
4cee456454
commit
c0eec1fffc
@ -2,4 +2,18 @@ package ocelot.desktop.ui.event
|
||||
|
||||
import ocelot.desktop.geometry.Vector2D
|
||||
|
||||
/**
|
||||
* A synthetic event dispatched by [[ocelot.desktop.ui.event.handlers.MouseHandler MouseHandler]] on mouse click.
|
||||
*/
|
||||
case class ClickEvent(button: MouseEvent.Button.Value, mousePos: Vector2D) extends Event
|
||||
|
||||
/**
|
||||
* A synthetic event dispatched by [[ocelot.desktop.ui.event.handlers.MouseHandler MouseHandler]] on double-click
|
||||
* in addition to (and after) [[ClickEvent]].
|
||||
*/
|
||||
case class DoubleClickEvent(button: MouseEvent.Button.Value, mousePos: Vector2D) extends Event
|
||||
/**
|
||||
* A synthetic event dispatched by [[ocelot.desktop.ui.event.handlers.MouseHandler MouseHandler]] on triple-click
|
||||
* in addition to (and after) [[ClickEvent]].
|
||||
*/
|
||||
case class TripleClickEvent(button: MouseEvent.Button.Value, mousePos: Vector2D) extends Event
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
package ocelot.desktop.ui.event
|
||||
|
||||
import ocelot.desktop.geometry.Vector2D
|
||||
|
||||
case class DoubleClickEvent(button: MouseEvent.Button.Value, mousePos: Vector2D) extends Event
|
||||
@ -2,8 +2,8 @@ package ocelot.desktop.ui.event.handlers
|
||||
|
||||
import ocelot.desktop.geometry.Vector2D
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.event.handlers.MouseHandler.{DoubleClickTimeMillis, Tolerance}
|
||||
import ocelot.desktop.ui.event.{ClickEvent, DoubleClickEvent, DragEvent, MouseEvent}
|
||||
import ocelot.desktop.ui.event.handlers.MouseHandler.{ClickInfo, withinTolerance}
|
||||
import ocelot.desktop.ui.event.{ClickEvent, DoubleClickEvent, DragEvent, MouseEvent, TripleClickEvent}
|
||||
import ocelot.desktop.ui.widget.Widget
|
||||
|
||||
import scala.collection.mutable
|
||||
@ -13,9 +13,7 @@ trait MouseHandler extends Widget {
|
||||
private val prevPositions = new mutable.HashMap[MouseEvent.Button.Value, Vector2D]()
|
||||
private val dragButtons = new mutable.HashSet[MouseEvent.Button.Value]()
|
||||
|
||||
private var lastClickPosition: Vector2D = Vector2D.Zero
|
||||
private var lastClickTime: Long = 0
|
||||
private var lastClickButton = MouseEvent.Button.Left
|
||||
private var lastClickInfo = Option.empty[ClickInfo]
|
||||
|
||||
override def receiveMouseEvents: Boolean = receiveClickEvents || receiveDragEvents
|
||||
|
||||
@ -59,24 +57,29 @@ trait MouseHandler extends Widget {
|
||||
}
|
||||
|
||||
if (clicked) {
|
||||
val time = System.currentTimeMillis()
|
||||
val info = ClickInfo(mousePos, time, button, 1)
|
||||
|
||||
for (lastInfo <- lastClickInfo if lastInfo.isConsecutive(info)) {
|
||||
if (lastInfo.count < 3) {
|
||||
info.count = lastInfo.count + 1
|
||||
}
|
||||
}
|
||||
|
||||
lastClickInfo = Some(info)
|
||||
|
||||
handleEvent(ClickEvent(button, mousePos))
|
||||
|
||||
val inTimeForDoubleClick = System.currentTimeMillis() - lastClickTime < DoubleClickTimeMillis
|
||||
val sameButton = lastClickButton == button
|
||||
val roughlySamePosition = withinTolerance(lastClickPosition, mousePos)
|
||||
if (inTimeForDoubleClick && sameButton && roughlySamePosition) {
|
||||
handleEvent(DoubleClickEvent(button, mousePos))
|
||||
info.count match {
|
||||
case 2 => handleEvent(DoubleClickEvent(button, mousePos))
|
||||
case 3 => handleEvent(TripleClickEvent(button, mousePos))
|
||||
case _ =>
|
||||
}
|
||||
lastClickTime = System.currentTimeMillis()
|
||||
lastClickPosition = mousePos
|
||||
lastClickButton = button
|
||||
}
|
||||
|
||||
startPositions.remove(button)
|
||||
}
|
||||
|
||||
private def withinTolerance(a: Vector2D, b: Vector2D): Boolean = (b - a).lengthSquared < Tolerance * Tolerance
|
||||
|
||||
override def update(): Unit = {
|
||||
super.update()
|
||||
|
||||
@ -112,5 +115,17 @@ trait MouseHandler extends Widget {
|
||||
|
||||
object MouseHandler {
|
||||
private val Tolerance = 8
|
||||
private val DoubleClickTimeMillis = 1e3f / 2
|
||||
private val ConsecutiveClickTimeMillis = 1e3f / 2
|
||||
|
||||
private def withinTolerance(a: Vector2D, b: Vector2D): Boolean = (b - a).lengthSquared < Tolerance * Tolerance
|
||||
|
||||
private case class ClickInfo(position: Vector2D, time: Long, button: MouseEvent.Button.Value, var count: Int) {
|
||||
def isConsecutive(prev: ClickInfo): Boolean = {
|
||||
val quickEnough = time - prev.time < ConsecutiveClickTimeMillis
|
||||
val sameButton = button == prev.button
|
||||
val closeEnough = withinTolerance(position, prev.position)
|
||||
|
||||
quickEnough && sameButton && closeEnough
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import ocelot.desktop.graphics.{Font, Graphics, IconSource}
|
||||
import ocelot.desktop.ui.UiHandler
|
||||
import ocelot.desktop.ui.event.handlers.MouseHandler
|
||||
import ocelot.desktop.ui.event.sources.KeyEvents
|
||||
import ocelot.desktop.ui.event.{DoubleClickEvent, DragEvent, KeyEvent, MouseEvent}
|
||||
import ocelot.desktop.ui.event.{DoubleClickEvent, DragEvent, KeyEvent, MouseEvent, TripleClickEvent}
|
||||
import ocelot.desktop.ui.widget.TextInput.{Cursor, Selection, Text}
|
||||
import ocelot.desktop.ui.widget.contextmenu.{ContextMenu, ContextMenuEntry}
|
||||
import ocelot.desktop.ui.widget.traits.HoverAnimation
|
||||
@ -183,6 +183,9 @@ class TextInput(val initialText: String = "") extends Widget with MouseHandler w
|
||||
case DoubleClickEvent(MouseEvent.Button.Left, _) if isFocused && mouseInBounds =>
|
||||
selectWord()
|
||||
|
||||
case TripleClickEvent(MouseEvent.Button.Left, _) if isFocused && mouseInBounds =>
|
||||
selectAll()
|
||||
|
||||
case DragEvent(DragEvent.State.Start | DragEvent.State.Drag, MouseEvent.Button.Left, mouse) if isFocused =>
|
||||
val pos = if (mouse.y < bounds.y) {
|
||||
0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user