- 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:
1 parent
2912a3a5cb
commit
d8528fdc81
28 files changed
+977
-102
No files matched your search
@@ -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()}
|
||||
|
||||
Reference in new issue
Block a user