new touchpad widget: absolute mousepad
This commit is contained in:
@@ -118,9 +118,9 @@ import UIKit
|
||||
"OSCBACK"
|
||||
]
|
||||
|
||||
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "LSWHEEL", "RSWHEEL", "LTPAD", "RTPAD", "DS4TOUCH", "MOUSEPAD", "ABSMOUSE", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL", "DPAD", "TRACKBALL", "WASDPAD", "ARROWPAD"]
|
||||
@objc public static let mousePadWithButtonActions: [String] = ["MOUSEPAD", "ABSMOUSE"]
|
||||
@objc public static let mousePads: [String] = ["MOUSEPAD", "ABSMOUSE", "TRACKBALL"]
|
||||
@objc public static let touchPadCmds: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD", "LSWHEEL", "RSWHEEL", "LTPAD", "RTPAD", "DS4TOUCH", "MOUSEPAD", "ABSMOUSEPAD", "ABSMOUSE", "MOUSEWHEEL", "WHEEL", "DISCRETEWHEEL", "DSWHEEL", "DPAD", "TRACKBALL", "WASDPAD", "ARROWPAD"]
|
||||
@objc public static let mousePadWithButtonActions: [String] = ["MOUSEPAD", "ABSMOUSE", "ABSMOUSEPAD"]
|
||||
@objc public static let mousePads: [String] = ["MOUSEPAD", "ABSMOUSE", "TRACKBALL", "ABSMOUSEPAD"]
|
||||
@objc public static let directionPads: [String] = ["DPAD", "WASDPAD", "ARROWPAD"]
|
||||
@objc public static let stickTouchPads: [String] = ["LSVPAD", "RSVPAD", "LSPAD", "RSPAD"]
|
||||
@objc public static let nonVectorStickPads: [String] = ["LSPAD", "RSPAD"]
|
||||
|
||||
@@ -129,7 +129,8 @@ import ObjectiveC.runtime
|
||||
@objc public var initialCenter: CGPoint = .zero // location from persisted data
|
||||
@objc public var layoutChanges: [CGPoint] = []
|
||||
@objc public var mouseButtonAction: MouseButtonAction = .hovering;
|
||||
|
||||
@objc public var mouseButtonActionDelay: TimeInterval = 0.005;
|
||||
|
||||
//autoTapTimer
|
||||
@objc public var autoTapInterval: Int = 49;
|
||||
private var autoTapTimer: SafeTimer?
|
||||
@@ -279,7 +280,7 @@ import ObjectiveC.runtime
|
||||
// for mousePad
|
||||
private var touchBegan: Bool = false
|
||||
private var directionPadTouchBegan: Bool = false
|
||||
private var firstTouchMoved: Bool = false
|
||||
@objc private(set) var firstTouchMoved: Bool = false
|
||||
private var mousePointerMoved: Bool
|
||||
private var twoTouchesDetected: Bool
|
||||
private var allSpawnedTouchesCount: Int = 0
|
||||
@@ -329,6 +330,7 @@ import ObjectiveC.runtime
|
||||
@objc public var bulkMoveEnabled: Bool = false
|
||||
@objc public var sequenceSet: Set<Int16> = Set()
|
||||
@objc public var parentSequence: Int16 = -1
|
||||
@objc public var standardFoldingInterval: TimeInterval = 0.05
|
||||
static weak var capturer: OnScreenWidgetView?
|
||||
|
||||
@objc init(cmdString: String, buttonLabel: String, shape:String, profile:OSCProfile) {
|
||||
@@ -535,6 +537,10 @@ import ObjectiveC.runtime
|
||||
self.hasTrackPoint = true
|
||||
self.hasNonEditableLabel = (self.cmdString == "DISABLETOUCH"
|
||||
|| self.cmdString == "GAMEPADOVERLAY")
|
||||
|
||||
self.mouseButtonActionDelay = self.cmdString.contains("ABSMOUSEPAD") ? 0.005 : 0
|
||||
|
||||
self.standardFoldingInterval = widgetType == .touchPad ? 0.05 : 0.15;
|
||||
}
|
||||
|
||||
// ======================================================================================================
|
||||
@@ -2076,7 +2082,7 @@ import ObjectiveC.runtime
|
||||
}
|
||||
|
||||
if self.widgetType == WidgetTypeEnum.touchPad && CommandManager.mousePadWithButtonActions.contains(self.touchPadString) && allSpawnedTouchesCount == 1 && !twoTouchesDetected {
|
||||
self.handleMousePadButtonActionDown()
|
||||
self.handleMousePadButtonActionDown(touch: touch)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2433,6 +2439,10 @@ import ObjectiveC.runtime
|
||||
}
|
||||
self.updateTouchLocation(touch: touch)
|
||||
break
|
||||
case "ABSMOUSEPAD":
|
||||
let touchLocation = touch.location(in: self.superview)
|
||||
LiSendMousePositionEvent(Int16(touchLocation.x), Int16(touchLocation.y), Int16(self.superViewWidth), Int16(self.superViewHeight))
|
||||
break
|
||||
case "LSWHEEL", "RSWHEEL":
|
||||
self.handleStickWheelMove(touch: touch)
|
||||
case "LSPAD":
|
||||
@@ -2507,47 +2517,72 @@ import ObjectiveC.runtime
|
||||
}
|
||||
}
|
||||
|
||||
private func handleMousePadButtonActionUp(){
|
||||
switch self.mouseButtonAction{
|
||||
case .leftButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_LEFT)
|
||||
case .middleButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_MIDDLE)
|
||||
case .rightButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_RIGHT)
|
||||
case .hovering:
|
||||
if !self.mousePointerMoved && !self.quickDoubleTapDetected {self.sendLongMouseLeftButtonClickEvent()} // deal with single tap(click)
|
||||
if self.quickDoubleTapDetected { //deal with quick double tap
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_LEFT) //must release the button anyway, because the button is likely being held down since the long click turned into a dragging event.
|
||||
if !self.mousePointerMoved {self.sendShortMouseLeftButtonClickEvent()}
|
||||
self.quickDoubleTapDetected = false
|
||||
private func handleMousePadButtonActionUp(touch:UITouch?=nil){
|
||||
if let touch = touch {
|
||||
let touchLocation = touch.location(in: self.superview)
|
||||
switch touchPadString {
|
||||
case "ABSMOUSEPAD":
|
||||
LiSendMousePositionEvent(Int16(touchLocation.x), Int16(touchLocation.y), Int16(self.superViewWidth), Int16(self.superViewHeight))
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + self.mouseButtonActionDelay) {
|
||||
switch self.mouseButtonAction{
|
||||
case .leftButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_LEFT)
|
||||
case .middleButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_MIDDLE)
|
||||
case .rightButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_RIGHT)
|
||||
case .hovering:
|
||||
if !self.mousePointerMoved && !self.quickDoubleTapDetected {self.sendLongMouseLeftButtonClickEvent()} // deal with single tap(click)
|
||||
if self.quickDoubleTapDetected { //deal with quick double tap
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_RELEASE), BUTTON_LEFT) //must release the button anyway, because the button is likely being held down since the long click turned into a dragging event.
|
||||
if !self.mousePointerMoved {self.sendShortMouseLeftButtonClickEvent()}
|
||||
self.quickDoubleTapDetected = false
|
||||
}
|
||||
self.mousePointerMoved = false // reset this flag
|
||||
case .noClick:
|
||||
// quickDoubleTapDetected = false
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.mousePointerMoved = false // reset this flag
|
||||
case .noClick:
|
||||
// quickDoubleTapDetected = false
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private func handleMousePadButtonActionDown(){
|
||||
switch mouseButtonAction{
|
||||
case .leftButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), BUTTON_LEFT)
|
||||
case .middleButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), BUTTON_MIDDLE)
|
||||
case .rightButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), BUTTON_RIGHT)
|
||||
case .noClick:
|
||||
if quickDoubleTapDetected && !self.comboButtonStrings.isEmpty {
|
||||
self.showl3r3Indicator()
|
||||
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)
|
||||
|
||||
private func handleMousePadButtonActionDown(touch:UITouch?=nil){
|
||||
DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + self.mouseButtonActionDelay) {
|
||||
switch self.mouseButtonAction{
|
||||
case .leftButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), BUTTON_LEFT)
|
||||
case .middleButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), BUTTON_MIDDLE)
|
||||
case .rightButtonDown:
|
||||
LiSendMouseButtonEvent(CChar(BUTTON_ACTION_PRESS), BUTTON_RIGHT)
|
||||
case .noClick:
|
||||
if self.quickDoubleTapDetected && !self.comboButtonStrings.isEmpty {
|
||||
self.showl3r3Indicator()
|
||||
self.sendComboButtonsDownEvent(comboStrings: self.comboButtonStrings)
|
||||
}
|
||||
case .hovering:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
case .hovering:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let touch = touch {
|
||||
let touchLocation = touch.location(in: self.superview)
|
||||
switch touchPadString {
|
||||
case "ABSMOUSEPAD":
|
||||
LiSendMousePositionEvent(Int16(touchLocation.x), Int16(touchLocation.y), Int16(self.superViewWidth), Int16(self.superViewHeight))
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3460,7 +3495,7 @@ import ObjectiveC.runtime
|
||||
|| abs(widget.backgroundAlpha) < 0.1){
|
||||
widget.highlightBorder(highlighted: true, color: UIColor.systemBlue.cgColor)
|
||||
}
|
||||
let duration = OnScreenWidgetView.enableFolderAnimation ? (folder.buttonMode == .slideAndHold ? 0.05 : 0.15) : 0
|
||||
let duration = OnScreenWidgetView.enableFolderAnimation ? (folder.buttonMode == .slideAndHold ? 0.05 : widget.standardFoldingInterval) : 0
|
||||
UIView.animate(withDuration: duration, animations: {
|
||||
widget.center = folder.center
|
||||
},completion: { finished in
|
||||
@@ -3487,7 +3522,7 @@ import ObjectiveC.runtime
|
||||
|| abs(widget.backgroundAlpha) < 0.1){
|
||||
widget.highlightBorder(highlighted: true, color: UIColor.systemBlue.cgColor)
|
||||
}
|
||||
UIView.animate(withDuration: OnScreenWidgetView.enableFolderAnimation ? (folder.buttonMode == .slideAndHold ? 0.05 : 0.15) : 0, animations: {
|
||||
UIView.animate(withDuration: OnScreenWidgetView.enableFolderAnimation ? (folder.buttonMode == .slideAndHold ? 0.05 : widget.standardFoldingInterval) : 0, animations: {
|
||||
widget.center = widget.storedCenter
|
||||
},completion: { finished in
|
||||
widget.capturedTouches.removeAllObjects()
|
||||
|
||||
@@ -11,7 +11,7 @@ import UIKit
|
||||
@objc class UITouchUtil: NSObject {
|
||||
@objc public static func touches(in view: UIView, from event: UIEvent?) -> Set<UITouch> {
|
||||
guard (event?.allTouches) != nil else { return [] }
|
||||
return event?.allTouches?.filter({ $0.view == view && $0.type == .direct}) ?? []
|
||||
return event?.allTouches?.filter({ $0.view == view && ($0.type == .direct || $0.type == .pencil)}) ?? []
|
||||
}
|
||||
|
||||
@objc public static func distance(between touch1: UITouch?, and touch2: UITouch?, in view: UIView?) -> CGFloat {
|
||||
|
||||
@@ -1526,6 +1526,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Absolute MousePad" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "鼠标触控板(绝对坐标)"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑鼠觸控板(絕對座標)"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "滑鼠觸控板(絕對座標)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Absolute touch drag" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -1600,19 +1623,19 @@
|
||||
"localizations" : {
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"state" : "translated",
|
||||
"value" : "添加主机"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"state" : "translated",
|
||||
"value" : "新增主機"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "needs_review",
|
||||
"state" : "translated",
|
||||
"value" : "新增主機"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -2305,7 +2305,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
|
||||
view.sendSubviewToBack(selectedWidgetView)
|
||||
}
|
||||
}
|
||||
if !isToolbarHidden, let selectedWidgetView, layerIsOverlappingWithTrashcanButton(selectedWidgetView.layer) {
|
||||
if !isToolbarHidden, let selectedWidgetView, layerIsOverlappingWithTrashcanButton(selectedWidgetView.layer), selectedWidgetView.firstTouchMoved {
|
||||
OnScreenWidgetView.setFree(widget: selectedWidgetView)
|
||||
OnScreenWidgetView.removeWidgetFromMappings(key: selectedWidgetView.sequence)
|
||||
selectedWidgetView.removeFromSuperview()
|
||||
|
||||
@@ -638,7 +638,7 @@ struct VirtualKeyboardView: View {
|
||||
}
|
||||
|
||||
private func isPadLikeControl(_ key: Key) -> Bool {
|
||||
let padCommands: Set<String> = ["WHEEL", "MOUSEPAD", "TRACKBALL"]
|
||||
let padCommands: Set<String> = ["WHEEL", "MOUSEPAD", "TRACKBALL", "ABSMOUSEPAD"]
|
||||
if let cmd = key.cmdString(for: keyboardType) {
|
||||
return padCommands.contains(cmd)
|
||||
}
|
||||
@@ -1080,18 +1080,28 @@ struct VirtualKeyboardView: View {
|
||||
),
|
||||
height: keyHeight * 2 + spacing
|
||||
)
|
||||
|
||||
keyboardKeyView(
|
||||
Key(
|
||||
label: SwiftLocalizationHelper.localizedString(forKey: "Trackball"),
|
||||
width: unit * 2 + spacing,
|
||||
winCmdString: "TRACKBALL",
|
||||
macCmdString: "TRACKBALL",
|
||||
winKeyCode: 0xFF,
|
||||
macKeyCode: 0xFF
|
||||
),
|
||||
height: keyHeight * 2 + spacing
|
||||
)
|
||||
VStack(spacing: spacing) {
|
||||
keyboardKeyView(
|
||||
Key(
|
||||
label: SwiftLocalizationHelper.localizedString(forKey: "Absolute MousePad"),
|
||||
width: unit * 2 + spacing,
|
||||
winCmdString: "ABSMOUSEPAD",
|
||||
macCmdString: "ABSMOUSEPAD",
|
||||
winKeyCode: 0xFF,
|
||||
macKeyCode: 0xFF
|
||||
),
|
||||
)
|
||||
keyboardKeyView(
|
||||
Key(
|
||||
label: SwiftLocalizationHelper.localizedString(forKey: "Trackball"),
|
||||
width: unit * 2 + spacing,
|
||||
winCmdString: "TRACKBALL",
|
||||
macCmdString: "TRACKBALL",
|
||||
winKeyCode: 0xFF,
|
||||
macKeyCode: 0xFF
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1274,12 +1284,13 @@ struct VirtualKeyboardView: View {
|
||||
Key(label: SwiftLocalizationHelper.localizedString(forKey: "Wheel\nDown"), width: unit, winCmdString: "WHEELUP", macCmdString: "WHEELUP", winKeyCode: 0xFF, macKeyCode: 0xFF),
|
||||
Key(label: SwiftLocalizationHelper.localizedString(forKey: "WheelPad"), width: unit * 2 + spacing, winCmdString: "WHEEL", macCmdString: "WHEEL", winKeyCode: 0xFF, macKeyCode: 0xFF),
|
||||
Key(label: SwiftLocalizationHelper.localizedString(forKey: "MousePad"), width: unit * 2 + spacing, winCmdString: "MOUSEPAD", macCmdString: "MOUSEPAD", winKeyCode: 0xFF, macKeyCode: 0xFF),
|
||||
Key(label: SwiftLocalizationHelper.localizedString(forKey: "Absolute MousePad"), width: unit * 2 + spacing, winCmdString: "ABSMOUSEPAD", macCmdString: "ABSMOUSEPAD", winKeyCode: 0xFF, macKeyCode: 0xFF),
|
||||
Key(label: SwiftLocalizationHelper.localizedString(forKey: "Trackball"), width: unit * 2 + spacing, winCmdString: "TRACKBALL", macCmdString: "TRACKBALL", winKeyCode: 0xFF, macKeyCode: 0xFF)
|
||||
]
|
||||
if mode == .shortcutPicker {
|
||||
keys.removeAll { key in
|
||||
let command = key.cmdString(for: keyboardType) ?? ""
|
||||
return command == "WHEEL" || command == "MOUSEPAD" || command == "TRACKBALL"
|
||||
return command == "WHEEL" || command == "MOUSEPAD" || command == "TRACKBALL" || command == "ABSMOUSEPAD"
|
||||
}
|
||||
}
|
||||
return keys
|
||||
|
||||
@@ -1257,6 +1257,7 @@ struct WidgetPickerView: View {
|
||||
"ARROWPAD",
|
||||
"WHEEL",
|
||||
"MOUSEPAD",
|
||||
"ABSMOUSEPAD",
|
||||
"TRACKBALL"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user