- feat: new on-screen widget lsWheel/rsWheel, direction wheel for RPG games.

- feat: direct walkmode test for lsWheel/rsWheel
- feat: direction minimum offset test for all on-screen widgets, gyro->stick mapping & physical controller.
This commit is contained in:
TrueZhuanjia committed 2025-12-26 16:17:55 +08:00
1 parent 2912a3a5cb
commit d8528fdc81
28 files changed
+977 -102

No files matched your search

+247 -44
View File
@@ -7,6 +7,7 @@
//
import UIKit
import SVGKit
@objc class OnScreenWidgetView: UIView, OscInstanceReceiverDelegate {
// receiving the OnScreenControls instance from delegate
@@ -68,18 +69,27 @@ import UIKit
@objc public var logicallyDown: Bool = false
@objc public var widthFactor: CGFloat = 1.0
@objc public var heightFactor: CGFloat = 1.0
@objc public var componentSizeFactor: CGFloat = 2.88
@objc public var buttonMode: Int = 0
@objc private var tapToToggleFlag: Bool = true
@objc public var sizeReference: Int = WidgetSizeReference.longSide.rawValue
@objc public var deNormalizedWidthFactor: CGFloat = 1.0
@objc public var deNormalizedHeightFactor: CGFloat = 1.0
@objc public var baselineDiameter:CGFloat = 0
private var baselineWidth:CGFloat = 0
private var baselineHeight:CGFloat = 0
private var baselineWidthLargeSquare:CGFloat = 0
private var baselineHeightLargeSquare:CGFloat = 0
@objc public var denormalizedWidthFactor: CGFloat = 1.0
@objc public var denormalizedHeightFactor: CGFloat = 1.0
@objc public var denormalizedComponentSizeFactor: CGFloat = 1.0
@objc public var borderWidth: CGFloat = 0.0
@objc public var backgroundAlpha: CGFloat = 0.5
@objc public var componentAlpha: CGFloat = 1
@objc public var labelAlpha: CGFloat = 0.82
@objc public var borderAlpha: CGFloat = 0.19
@objc public var borderAlpha: CGFloat = 0.1
@objc public var vibrationStyle: Int = 6
@objc public var latestTouchLocation: CGPoint
@objc public var selfViewOnTheRight: Bool = false
@@ -107,6 +117,7 @@ import UIKit
// for all touchPad or buttons hybrid with touchPads
@objc public var hasMinStickOffset: Bool = false
@objc public var hasStickIndicator: Bool = false
@objc public var hasComponent: Bool = false
@objc public var hasSensitivityX: Bool = false
@objc public var sensitivityXMin: CGFloat = 0
@objc public var sensitivityXMax: CGFloat = 8
@@ -133,10 +144,13 @@ import UIKit
@objc public var hasHapticFeedback: Bool = false
@objc public var isDirectionPad: Bool = false
@objc public var hasL3R3Indicator: Bool = false
@objc public var isStickWheel: Bool = false
// for all stick pads
@objc public var minStickOffset: CGFloat = 0
public let stickMaxOffset: CGFloat = 0x7FFE
public var stickOffsetVector: CGVector = CGVector(dx: 0, dy: 0)
// for LSVPAD, RSVPAD
@@ -157,6 +171,12 @@ import UIKit
private let stickBallMaxOffset = 18.0
@objc public var crossMarkLayer = CAShapeLayer()
// LSWHEEL/RSWHEEL
@objc public var stickWheelLayer = CALayer()
@objc public var stickWheelLayerSmall = CALayer()
@objc public var stickWheelAxis = CALayer()
@objc public var dWheelWalkModeThreshold: CGFloat
// this is for all stick pads and mouse Pad
@objc public var sensitivityFactorX: CGFloat = 1.0
@objc public var sensitivityFactorY: CGFloat = 1.0
@@ -195,7 +215,7 @@ import UIKit
private var previousButtonMask = Direction.initialStatus.rawValue
// OnScreenControls instance
private var onScreenControls: OnScreenControls
@objc public var onScreenControls: OnScreenControls
// key / button label
private let label: UILabel
@@ -336,6 +356,7 @@ import UIKit
self.oscProfile = oscProfileMan.getSelectedProfile()
self.tempSettings = dataMan.getSettings()
self.inertialScroller = InertialScroller()
dWheelWalkModeThreshold = stickMaxOffset*0.5
super.init(frame: .zero)
// helps widget panel to hide/show stacks
@@ -354,7 +375,20 @@ import UIKit
}
}
self.tweakBorderAlpha(alpha: 0.19) // fix default borderAlpha offset
if self.widgetType == WidgetTypeEnum.touchPad {
if self.isStickWheel {
self.widthFactor = 2
self.heightFactor = 2.6
self.backgroundAlpha = 1
self.componentAlpha = self.backgroundAlpha
self.borderAlpha = 0.05
self.sensitivityFactorX = 0.42
self.sensitivityFactorY = 0.42
self.componentSizeFactor = 2.8
}
}
self.tweakBorderAlpha(alpha: self.borderAlpha) // fix default borderAlpha offset
setupView()
@@ -365,10 +399,11 @@ import UIKit
}
@objc public func accessWidgetAttributes(){
self.hasMinStickOffset = CommandManager.stickTouchPads.contains(self.touchPadString)
self.hasMinStickOffset = (CommandManager.stickTouchPads.contains(self.touchPadString)
|| CommandManager.stickWheels.contains(self.touchPadString))
self.hasStickIndicator = CommandManager.nonVectorStickPads.contains(self.touchPadString) && widgetType == WidgetTypeEnum.touchPad
self.hasSensitivityX = CommandManager.touchPadCmds.contains(self.touchPadString) && !CommandManager.verticalTouchPads.contains(self.touchPadString)
self.hasSensitivityY = CommandManager.touchPadCmds.contains(self.touchPadString)
self.hasSensitivityY = CommandManager.touchPadCmds.contains(self.touchPadString) && !CommandManager.stickWheels.contains(self.touchPadString)
self.hasSlideThreshold = CommandManager.mousePad.contains(self.touchPadString)
if CommandManager.bidirectionalVerticalTouchPads.contains(self.touchPadString){
@@ -391,7 +426,10 @@ import UIKit
self.isFuncationalButton = self.functionalButtonString != ""
self.hasHapticFeedback = !self.comboButtonStrings.isEmpty || CommandManager.directionPads.contains(self.touchPadString)
self.isDirectionPad = self.widgetType == WidgetTypeEnum.touchPad && CommandManager.directionPads.contains(self.touchPadString)
self.hasL3R3Indicator = !self.isDirectionPad && self.widgetType == WidgetTypeEnum.touchPad
self.isStickWheel = self.widgetType == WidgetTypeEnum.touchPad && CommandManager.stickWheels.contains(self.touchPadString)
self.hasComponent = self.isStickWheel
self.hasL3R3Indicator = !self.isStickWheel && !self.isDirectionPad && self.widgetType == WidgetTypeEnum.touchPad
}
// ======================================================================================================
@@ -458,8 +496,20 @@ import UIKit
}
@objc public func adjustTransparency(alpha: CGFloat, tweakBorderAlpha:Bool){
CATransaction.begin()
CATransaction.setDisableActions(true)
self.backgroundAlpha = alpha
self.tweakAlpha(tweakBorderAlpha: tweakBorderAlpha)
if self.hasComponent {
self.componentAlpha = self.backgroundAlpha
self.tweakAlpha(tweakBorderAlpha: false)
if self.isStickWheel {self.setupStickWheelLayers()}
}
else{
self.tweakAlpha(tweakBorderAlpha: tweakBorderAlpha)
}
CATransaction.commit()
}
@objc public func adjustBorder(width: CGFloat){
@@ -471,7 +521,8 @@ import UIKit
@objc public func resizeWidgetView(){
guard let superview = superview else { return }
CATransaction.begin()
CATransaction.setDisableActions(true)
// Deactivate existing constraints if necessary
NSLayoutConstraint.deactivate(self.constraints)
@@ -498,6 +549,17 @@ import UIKit
// Re-setup widgetView style
setupView()
CATransaction.commit()
}
@objc public func resizeComponent(){
CATransaction.begin()
CATransaction.setDisableActions(true)
if widgetType == WidgetTypeEnum.touchPad, CommandManager.stickWheels.contains(touchPadString) {
setupStickWheelLayers()
}
CATransaction.commit()
}
@objc public func tweakLabelAlpha(alpha:CGFloat){
@@ -551,45 +613,79 @@ import UIKit
// print("referenceLen \(referenceLen), \(CACurrentMediaTime())")
return nearestEven(sizeFactor/10000*referenceLen);
}
private func changeAndActivateContraints(){
let isNormalizedSizeFactor = self.widthFactor > 6;
let isNormalizedHeightFactor = self.heightFactor > 6;
private func getBaselineLenths(){
let longSideLen = max(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
let shortSideLen = min(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
let baselineDiameter:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 60 : 60*shortSideLen/longSideLen
print("baselineDiameter \(baselineDiameter), \(CACurrentMediaTime())")
baselineDiameter = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 60 : 60*shortSideLen/longSideLen
let baselineWidth:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 70 : 70*shortSideLen/longSideLen
let baselineHeight:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 65 : 65*shortSideLen/longSideLen
let baselineWidthLargeSquare:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 170 : 170*shortSideLen/longSideLen
let baselineHeightLargeSquare:CGFloat = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 150 : 150*shortSideLen/longSideLen
baselineWidth = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 70 : 70*shortSideLen/longSideLen
baselineHeight = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 65 : 65*shortSideLen/longSideLen
baselineWidthLargeSquare = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 170 : 170*shortSideLen/longSideLen
baselineHeightLargeSquare = self.sizeReference == WidgetSizeReference.longSide.rawValue ? 150 : 150*shortSideLen/longSideLen
}
private func getDiameter(lengthFactor:CGFloat) -> CGFloat {
self.getBaselineLenths()
let isNormalizedSizeFactor = lengthFactor > 6;
return isNormalizedSizeFactor ? denormalizeSize(sizeFactor:lengthFactor) : CGFloat(Int(baselineDiameter * lengthFactor / 2) * 2)
}
private func getRecSize(widthFactor:CGFloat, heightFactor:CGFloat) -> CGSize {
let isNormalizedSizeFactor = widthFactor > 6;
let isNormalizedHeightFactor = heightFactor > 6;
self.getBaselineLenths()
let width = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:widthFactor) : CGFloat(Int(baselineWidth * widthFactor / 2) * 2)
let height = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:heightFactor) : CGFloat(Int(baselineHeight * heightFactor / 2) * 2)
return CGSize(width:width, height: height)
}
private func getLargeRecSize(widthFactor:CGFloat, heightFactor:CGFloat) -> CGSize {
let isNormalizedSizeFactor = self.widthFactor > 6;
let isNormalizedHeightFactor = self.heightFactor > 6;
self.getBaselineLenths()
let width = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineWidthLargeSquare * self.widthFactor / 2) * 2)
let height = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(baselineHeightLargeSquare * self.heightFactor / 2) * 2)
return CGSize(width:width, height: height)
}
private func changeAndActivateContraints(){
if self.shape == "round"{ // we'll make custom osc buttons round & smaller
let diameter = getDiameter(lengthFactor: self.widthFactor)
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineDiameter * self.widthFactor / 2) * 2)),
self.heightAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineDiameter * self.widthFactor / 2) * 2)),])
self.widthAnchor.constraint(equalToConstant: diameter),
self.heightAnchor.constraint(equalToConstant: diameter),])
// 实时调整大小时isNormalized 为 false。加载数据时 isNormalized 为 true
// baselineDiameter 仅在 实时调整大小时生效,从存储恢复时总是会恢复denormalizeSize()尺寸
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineDiameter : self.widthFactor;
self.deNormalizedHeightFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineDiameter : self.widthFactor;
self.denormalizedWidthFactor = diameter/baselineDiameter;
self.denormalizedHeightFactor = diameter/baselineDiameter;
//此处的 deNormalized 用于slider显示值
}
if self.shape == "square" {
let widgetSize = getRecSize(widthFactor: self.widthFactor, heightFactor: self.heightFactor)
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant: isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineWidth * self.widthFactor / 2) * 2)),
self.heightAnchor.constraint(equalToConstant: isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(baselineHeight * self.heightFactor / 2) * 2)),])
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineWidth : self.widthFactor;
self.deNormalizedHeightFactor = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor)/baselineHeight : self.heightFactor;
self.widthAnchor.constraint(equalToConstant: widgetSize.width),
self.heightAnchor.constraint(equalToConstant: widgetSize.height),])
self.denormalizedWidthFactor = widgetSize.width/baselineWidth;
self.denormalizedHeightFactor = widgetSize.height/baselineHeight;
}
if self.shape == "largeSquare" { // override all shape strings
let widgetSize = getLargeRecSize(widthFactor: self.widthFactor, heightFactor: self.heightFactor)
NSLayoutConstraint.activate([
self.widthAnchor.constraint(equalToConstant:isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor) : CGFloat(Int(baselineWidthLargeSquare * self.widthFactor / 2) * 2)),
self.heightAnchor.constraint(equalToConstant:isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor) : CGFloat(Int(baselineHeightLargeSquare * self.heightFactor / 2) * 2)),])
self.deNormalizedWidthFactor = isNormalizedSizeFactor ? denormalizeSize(sizeFactor:self.widthFactor)/baselineWidthLargeSquare : self.widthFactor;
self.deNormalizedHeightFactor = isNormalizedHeightFactor ? denormalizeSize(sizeFactor:self.heightFactor)/150 : self.heightFactor;
self.widthAnchor.constraint(equalToConstant:widgetSize.width),
self.heightAnchor.constraint(equalToConstant:widgetSize.height),])
self.denormalizedWidthFactor = widgetSize.width/baselineWidthLargeSquare;
self.denormalizedHeightFactor = widgetSize.height/baselineHeightLargeSquare;
}
NSLayoutConstraint.activate([
@@ -643,6 +739,7 @@ import UIKit
else {self.layer.borderWidth = self.borderWidth}
if OnScreenWidgetView.editMode { //display label in edit mode to make the pad more visible
label.text = self.widgetLabel
if CommandManager.stickWheels.contains(self.touchPadString) {label.isHidden = true}
}
else{
label.isHidden = self.widgetLabel.uppercased() == self.touchPadString // allow touchPad label to be display if it's different from touchPad cmdString
@@ -685,6 +782,9 @@ import UIKit
if self.crossMarkLayer.superlayer == nil {self.crossMarkLayer = createCrossMark()}
if self.lrudIndicatorBall.superlayer == nil {self.lrudIndicatorBall = createStickBall()}
}
if self.isStickWheel {
self.setupStickWheelLayers()
}
}
@objc public func setupL3R3Indicator() {
@@ -902,7 +1002,97 @@ import UIKit
}
//================================================================================================
/// stickWheel
private func
setupStickWheelLayers(){
let diameter = self.getDiameter(lengthFactor: self.componentSizeFactor)
self.denormalizedComponentSizeFactor = diameter/baselineDiameter
// let tintColor = UIColor(red: 0.5, green: 0.5, blue: 1.0, alpha: 1)
let tintColor = UIColor(
red: 0x48 / 255.0,
green: 0xF5 / 255.0,
blue: 0xFF / 255.0,
alpha: componentAlpha
)
let axisdiameter = self.getDiameter(lengthFactor: 0.5)
let axisSize = CGSize(width: axisdiameter, height: axisdiameter)
self.stickWheelAxis = GraphicUtils.makeCenteredSVGLayer(from: "StickWheelAxis.svg", in: self.layer, targetSize: axisSize)
self.stickWheelAxis.removeFromSuperlayer()
self.layer.insertSublayer(self.stickWheelAxis, at: 0)
// GraphicUtils.changeColor(layer: self.stickWheelAxis, color: .white.withAlphaComponent(1))
self.stickWheelAxis.isHidden = false
self.stickWheelLayer = GraphicUtils.makeCenteredSVGLayer(from: "StickWheel.svg", in: self.layer, targetSize: CGSize(width: diameter, height: diameter))
self.stickWheelLayer.removeFromSuperlayer()
self.layer.insertSublayer(self.stickWheelLayer, at: 0)
GraphicUtils.changeColor(layer: self.stickWheelLayer, color: tintColor)
self.stickWheelLayer.setAffineTransform(.identity)
self.stickWheelLayer.isHidden = !OnScreenWidgetView.editMode
let smallWheelSize = CGSize(width: diameter*0.56766, height: diameter*0.56766)
self.stickWheelLayerSmall = GraphicUtils.makeCenteredSVGLayer(from: "StickWheelSmall.svg", in: self.layer, targetSize: smallWheelSize)
self.stickWheelLayerSmall.removeFromSuperlayer()
self.layer.insertSublayer(self.stickWheelLayerSmall, below: stickWheelLayer)
GraphicUtils.changeColor(layer: self.stickWheelLayerSmall, color: tintColor)
self.stickWheelLayerSmall.setAffineTransform(.identity)
self.stickWheelLayerSmall.isHidden = !OnScreenWidgetView.editMode
}
private func setHiddenForStickWheelLayer(hidden:Bool){
CATransaction.begin()
CATransaction.setDisableActions(true)
self.stickWheelLayer.isHidden = hidden;
self.stickWheelLayerSmall.isHidden = hidden;
CATransaction.commit()
}
private func handleStickWheelMove(touch:UITouch){
CATransaction.begin()
CATransaction.setDisableActions(true)
let isInWalkMode = hypot(stickOffsetVector.dx, stickOffsetVector.dy) < dWheelWalkModeThreshold
let angle = atan2(offSetY, offSetX) + .pi/2
let transform = CGAffineTransform(rotationAngle: angle)
if isInWalkMode {
self.stickWheelLayerSmall.setAffineTransform(transform)
}
else {
self.stickWheelLayer.setAffineTransform(transform)
}
if touch.phase == .began {
self.stickWheelLayer.isHidden = isInWalkMode
self.stickWheelLayerSmall.isHidden = !isInWalkMode
}
else if self.stickWheelLayer.isHidden != isInWalkMode {
self.stickWheelLayer.isHidden = isInWalkMode
self.stickWheelLayerSmall.isHidden = !isInWalkMode
}
CATransaction.commit()
switch self.touchPadString {
case "LSWHEEL":
DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
self.sendLeftStickTouchPadEvent(weightedTouchX: self.offSetX * self.sensitivityFactorX, weightedTouchY: self.offSetY * self.sensitivityFactorY, circulate: true)
}
case "RSWHEEL":
DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
self.sendRightStickTouchPadEvent(weightedTouchX: self.offSetX * self.sensitivityFactorX, weightedTouchY: self.offSetY * self.sensitivityFactorY, circulate: true)
}
default:
break
}
}
//=====LRUD(left right up & down buttons) touchPad touch =========================================
@@ -1260,7 +1450,7 @@ import UIKit
CATransaction.setDisableActions(true)
self.buttonDownVisualEffectStandardWidth = 8
if self.shape == "round" {
if deNormalizedWidthFactor < 1.3 {self.buttonDownVisualEffectStandardWidth = 15.3} // wider visual effect for osc buttons
if denormalizedWidthFactor < 1.3 {self.buttonDownVisualEffectStandardWidth = 15.3} // wider visual effect for osc buttons
else {self.buttonDownVisualEffectStandardWidth = 9}
}
@@ -1293,7 +1483,8 @@ import UIKit
//=========================================send on screen controller stick/trigger events
private func weightedTouchInputToStickOffset(input: CGFloat) -> CGFloat{
let target = stickMaxOffset * input / stickInputScale
return fmax(fmin(target, stickMaxOffset),-stickMaxOffset)
// return fmax(fmin(target, stickMaxOffset),-stickMaxOffset)
return target
}
private func stickOffsetToWeightedTouchInput(offset: CGFloat) -> CGFloat {
@@ -1310,7 +1501,7 @@ import UIKit
return input * (18/stickInputScale)
}
private func sendRightStickTouchPadEvent(weightedTouchX: CGFloat, weightedTouchY: CGFloat){
private func sendRightStickTouchPadEvent(weightedTouchX: CGFloat, weightedTouchY: CGFloat, circulate: Bool=false){
let targetX = self.weightedTouchInputToStickOffset(input: weightedTouchX)
let targetY = -self.weightedTouchInputToStickOffset(input: weightedTouchY)
@@ -1318,13 +1509,13 @@ import UIKit
&& oscProfile.yawPitchToRightStick)
if !mixRightStickInputToGyro || (self.motionHandler.gyroMixInputStarted() != true) {
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), withMinOffset: minStickOffset)
self.onScreenControls.sendRightStickTouchPadEvent(offsetVector.dx, offsetVector.dy)
stickOffsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), minOffset: minStickOffset, circulate: circulate)
self.onScreenControls.sendRightStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
}
self.motionHandler.mixOnScreenRightStickAndGyroInput(x: targetX, y: targetY)
}
private func sendLeftStickTouchPadEvent(weightedTouchX: CGFloat, weightedTouchY: CGFloat){
private func sendLeftStickTouchPadEvent(weightedTouchX:CGFloat, weightedTouchY:CGFloat, circulate:Bool=false){
let targetX = self.weightedTouchInputToStickOffset(input: weightedTouchX)
let targetY = -self.weightedTouchInputToStickOffset(input: weightedTouchY)
@@ -1332,8 +1523,8 @@ import UIKit
&& oscProfile.rollToLeftStick)
if !mixLeftStickInputToGyro || (self.motionHandler.gyroMixInputStarted() != true) {
let offsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), withMinOffset: minStickOffset)
self.onScreenControls.sendLeftStickTouchPadEvent(offsetVector.dx, offsetVector.dy)
stickOffsetVector = ControllerUtil.compensated(offsetVector: CGVector(dx: targetX, dy: targetY), minOffset: minStickOffset, circulate: circulate)
self.onScreenControls.sendLeftStickTouchPadEvent(stickOffsetVector.dx, stickOffsetVector.dy)
}
self.motionHandler.mixOnScreenLeftStickAndGyroInput(x: targetX, y: targetY)
}
@@ -1460,6 +1651,9 @@ import UIKit
if !OnScreenWidgetView.editMode {
if self.widgetType == WidgetTypeEnum.touchPad && touches.count == 1{ // don't use event?.allTouches?.count here, it will counts all touches including the ones captured by other UIViews
switch self.touchPadString {
case "LSWHEEL","RSWHEEL":
self.getVector(touch: touches.first!)
self.handleStickWheelMove(touch: touches.first!)
case "LSPAD","RSPAD":
self.showStickIndicator()
if quickDoubleTapDetected {
@@ -1728,8 +1922,9 @@ import UIKit
self.inertialScroller.vector = UITouchUtil.vector(of: touch, in: self)
}
self.offSetX = currentTouchLocation.x - self.touchBeganLocation.x
self.offSetY = currentTouchLocation.y - self.touchBeganLocation.y
let touchCentered = !self.isStickWheel
self.offSetX = touchCentered ? currentTouchLocation.x - self.touchBeganLocation.x : currentTouchLocation.x - self.bounds.midX
self.offSetY = touchCentered ? currentTouchLocation.y - self.touchBeganLocation.y : currentTouchLocation.y - self.bounds.midY
}
private func updateTouchLocation(touch: UITouch){
@@ -1782,6 +1977,8 @@ import UIKit
}
self.updateTouchLocation(touch: touches.first!)
break
case "LSWHEEL", "RSWHEEL":
self.handleStickWheelMove(touch: touches.first!)
case "LSPAD":
DispatchQueue.global(qos: .userInteractive).async {
self.weightedDeltaX = 1
@@ -2035,6 +2232,12 @@ import UIKit
// then other types of pads or buttons with touchPad function
if !OnScreenWidgetView.editMode && !self.touchPadString.isEmpty {
switch self.touchPadString{
case "LSWHEEL":
self.clearLeftStickTouchPadFlag()
self.setHiddenForStickWheelLayer(hidden: true)
case "RSWHEEL":
self.clearRightStickTouchPadFlag()
self.setHiddenForStickWheelLayer(hidden: true)
case "LSPAD":
self.clearLeftStickTouchPadFlag()
if widgetType == WidgetTypeEnum.touchPad {self.resetStickBallPositionAndHideIndicator()}