mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-18 01:46:47 +08:00
[feat] add compact mobile virtual mouse controls
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import Foundation
|
||||
|
||||
/// Shared by the video surface and the virtual buttons. Coordinates always
|
||||
/// refer to the remote cursor, never to the floating controls' screen location.
|
||||
final class RemoteMouseInput {
|
||||
var send: ((Float, Float, Int, Int) -> Void)?
|
||||
var didCancel: (() -> Void)?
|
||||
var viewportSize = CGSize(width: 0, height: 0)
|
||||
private(set) var x: Float = 0.5
|
||||
private(set) var y: Float = 0.5
|
||||
private(set) var revision: UInt64 = 0
|
||||
private var gestureLeft = false
|
||||
private var virtualLeft = false
|
||||
private var virtualRight = false
|
||||
var hasVirtualButton: Bool { virtualLeft || virtualRight }
|
||||
|
||||
func position(x: Float, y: Float) {
|
||||
self.x = min(max(x, 0), 1)
|
||||
self.y = min(max(y, 0), 1)
|
||||
}
|
||||
|
||||
func drag(dx: Float, dy: Float) {
|
||||
guard hasVirtualButton, viewportSize.width > 0, viewportSize.height > 0 else { return }
|
||||
position(x: x + dx / Float(viewportSize.width) * 1.35,
|
||||
y: y + dy / Float(viewportSize.height) * 1.35)
|
||||
emit(0)
|
||||
}
|
||||
|
||||
func setGestureLeft(_ down: Bool) {
|
||||
guard !(down && hasVirtualButton), gestureLeft != down else { return }
|
||||
gestureLeft = down
|
||||
emit(down ? 1 : 2)
|
||||
}
|
||||
|
||||
func setVirtualButton(left: Bool, down: Bool) {
|
||||
guard (left ? virtualLeft : virtualRight) != down else { return }
|
||||
if down {
|
||||
setGestureLeft(false)
|
||||
revision &+= 1
|
||||
}
|
||||
if left { virtualLeft = down } else { virtualRight = down }
|
||||
emit(left ? (down ? 1 : 2) : (down ? 3 : 4))
|
||||
}
|
||||
|
||||
func scroll(_ direction: Int) {
|
||||
guard direction != 0 else { return }
|
||||
emit(7, wheel: direction > 0 ? 1 : -1)
|
||||
}
|
||||
|
||||
func releaseAll() {
|
||||
setGestureLeft(false)
|
||||
setVirtualButton(left: true, down: false)
|
||||
setVirtualButton(left: false, down: false)
|
||||
revision &+= 1
|
||||
didCancel?()
|
||||
}
|
||||
|
||||
private func emit(_ flag: Int, wheel: Int = 0) { send?(x, y, flag, wheel) }
|
||||
}
|
||||
Reference in New Issue
Block a user