diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard
index 3281df73..03befc7c 100644
--- a/VoidLink/Base.lproj/iPad.storyboard
+++ b/VoidLink/Base.lproj/iPad.storyboard
@@ -2748,8 +2748,26 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -3718,6 +3736,7 @@
+
@@ -3939,22 +3958,22 @@
-
+
-
+
-
+
-
+
-
+
diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard
index baff8836..01aed6c7 100644
--- a/VoidLink/Base.lproj/iPhone.storyboard
+++ b/VoidLink/Base.lproj/iPhone.storyboard
@@ -155,10 +155,10 @@
-
+
-
+
@@ -351,7 +351,25 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -1377,6 +1395,7 @@
+
diff --git a/VoidLink/Input/CustomOSC/OSCProfilesManager.m b/VoidLink/Input/CustomOSC/OSCProfilesManager.m
index f8b42427..25a1a691 100644
--- a/VoidLink/Input/CustomOSC/OSCProfilesManager.m
+++ b/VoidLink/Input/CustomOSC/OSCProfilesManager.m
@@ -470,6 +470,7 @@ static CGRect layoutViewBounds;
buttonState.borderWidth = widgetView.borderWidth;
buttonState.highlightSizeFactor = widgetView.highlightSizeFactor;
buttonState.autoTapInterval = widgetView.autoTapInterval;
+ buttonState.autoTapRepeats = widgetView.autoTapRepeats;
buttonState.vibrationStyle = widgetView.vibrationStyle;
buttonState.mouseButtonAction = widgetView.mouseButtonAction;
buttonState.animatesTransition = widgetView.animatesTransition;
diff --git a/VoidLink/Input/CustomOSC/OnScreenButtonState.h b/VoidLink/Input/CustomOSC/OnScreenButtonState.h
index 42ad2ace..3c66ac9c 100644
--- a/VoidLink/Input/CustomOSC/OnScreenButtonState.h
+++ b/VoidLink/Input/CustomOSC/OnScreenButtonState.h
@@ -66,6 +66,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) uint8_t mouseButtonAction;
@property (nonatomic, assign) bool animatesTransition;
@property (nonatomic, assign) uint16_t autoTapInterval;
+@property (nonatomic, assign) uint32_t autoTapRepeats;
@property (nonatomic, assign) uint8_t walkKeyActionType;
@property (nonatomic, assign) CGFloat walkKeyThreshold;
diff --git a/VoidLink/Input/CustomOSC/OnScreenButtonState.m b/VoidLink/Input/CustomOSC/OnScreenButtonState.m
index 3e94821b..5365b457 100644
--- a/VoidLink/Input/CustomOSC/OnScreenButtonState.m
+++ b/VoidLink/Input/CustomOSC/OnScreenButtonState.m
@@ -49,6 +49,7 @@
[encoder encodeBool:self.animatesTransition forKey:@"animatesTransition"];
[encoder encodeInt:self.buttonMode forKey:@"slideMode"]; // buttonMode: previously slideMode, keep it for consistency
[encoder encodeInt:self.autoTapInterval forKey:@"autoTapInterval"];
+ [encoder encodeInt:self.autoTapRepeats forKey:@"autoTapRepeats"];
[encoder encodeCGPoint:self.position forKey:@"position"];
[encoder encodeBool:self.isHidden forKey:@"isHidden"];
[encoder encodeFloat:self.widthFactor forKey:@"widthFactor"];
@@ -100,6 +101,7 @@
self.animatesTransition = [decoder containsValueForKey:@"animatesTransition"] ? [decoder decodeBoolForKey:@"animatesTransition"] : true;
self.buttonMode = [decoder containsValueForKey:@"slideMode"] ? [decoder decodeIntForKey:@"slideMode"] : 0;
self.autoTapInterval = [decoder containsValueForKey:@"autoTapInterval"] ? [decoder decodeIntForKey:@"autoTapInterval"] : 45;
+ self.autoTapRepeats = [decoder containsValueForKey:@"autoTapRepeats"] ? [decoder decodeIntForKey:@"autoTapRepeats"] : 0;
self.position = [decoder decodeCGPointForKey:@"position"];
self.isHidden = [decoder decodeBoolForKey:@"isHidden"];
self.widthFactor = [decoder decodeFloatForKey:@"widthFactor"];
diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift
index a8170960..27c3905f 100644
--- a/VoidLink/Input/OnScreenWidgetView.swift
+++ b/VoidLink/Input/OnScreenWidgetView.swift
@@ -194,6 +194,8 @@ import ObjectiveC.runtime
//autoTapTimer
@objc public var autoTapInterval: Int = 49;
+ @objc public var autoTapRepeats: UInt32 = 0;
+ private var autoTapCount: UInt32 = 0;
private var autoTapTimer: SafeTimer?
private let appWindow: UIView
@@ -676,6 +678,15 @@ import ObjectiveC.runtime
if self.widgetType == WidgetTypeEnum.button, autoTapInterval >= OnScreenWidgetView.MinAutotapInterval {
self.autoTapTimer = SafeTimer(interval:0.001 * Double(autoTapInterval)) {
// print("timer instance \(Unmanaged.passUnretained(self.autoTapTimer!).toOpaque()), \(CACurrentMediaTime())")
+ if self.autoTapRepeats > 0 {
+ self.autoTapCount += 1
+ if self.autoTapCount >= self.autoTapRepeats {
+ self.autoTapTimer?.pause()
+ if self.buttonMode == .tapToToggle {
+ self.tapToToggleFlag = !self.tapToToggleFlag
+ }
+ }
+ }
self.handleButtonDown()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.025) {
self.handleButtonUp()
@@ -1580,6 +1591,7 @@ import ObjectiveC.runtime
handleButtonDown()
}
else{
+ self.autoTapCount = 0
self.autoTapTimer?.restart()
}
}
diff --git a/VoidLink/Input/StreamView.m b/VoidLink/Input/StreamView.m
index 0d0654f1..69acf6d9 100644
--- a/VoidLink/Input/StreamView.m
+++ b/VoidLink/Input/StreamView.m
@@ -744,6 +744,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
widgetView.borderWidth = buttonState.borderWidth;
widgetView.highlightSizeFactor = buttonState.highlightSizeFactor;
widgetView.autoTapInterval = buttonState.autoTapInterval;
+ widgetView.autoTapRepeats = buttonState.autoTapRepeats;
[widgetView setVibrationWithStyle:buttonState.vibrationStyle];
widgetView.mouseButtonAction = buttonState.mouseButtonAction;
widgetView.animatesTransition = buttonState.animatesTransition;
diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings
index ccc43398..c9daeeed 100644
--- a/VoidLink/Localization/Localizable.xcstrings
+++ b/VoidLink/Localization/Localizable.xcstrings
@@ -1985,6 +1985,29 @@
}
}
},
+ "0 - infinite" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "0 - 无限"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "0 - 無限"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "0 - 無限"
+ }
+ }
+ }
+ },
"A button with touchpad functionality will be created" : {
"extractionState" : "manual",
"localizations" : {
@@ -2549,6 +2572,35 @@
}
}
},
+ "autoTapTimerTip" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Min: 50ms. 0 - disable. ms(milliSec),s(sec),m(min). ⏎ save"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "最低: 50ms, 输入0关闭. 单位: ms毫秒, s秒, m分钟. ⏎ 保存."
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "最低: 50 ms, 輸入 0 關閉. 單位:ms 秒, s秒, m分鐘. ⏎ 儲存."
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "最低: 50 ms, 輸入 0 關閉. 單位:ms 秒, s秒, m分鐘. ⏎ 儲存."
+ }
+ }
+ }
+ },
"Back" : {
"extractionState" : "manual",
"localizations" : {
@@ -7136,6 +7188,29 @@
}
}
},
+ "Insert trigger interval" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "插入触发间隔"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "插入觸發間隔"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "插入觸發間隔"
+ }
+ }
+ }
+ },
"Interval of Multi-Touch Move Events: %d μs" : {
"extractionState" : "manual",
"localizations" : {
@@ -8087,6 +8162,52 @@
}
}
},
+ "Manually enter press duration in milliseconds" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "手动输入按压时长, 单位毫秒"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "手動輸入按壓時長, 單位毫秒"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "手動輸入按壓時長, 單位毫秒"
+ }
+ }
+ }
+ },
+ "Manually enter trigger interval in milliseconds" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "手动输入间隔,单位毫秒"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "手動輸入間隔,單位毫秒"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "手動輸入間隔,單位毫秒"
+ }
+ }
+ }
+ },
"Map controller to mouse" : {
"extractionState" : "manual",
"localizations" : {
@@ -8289,29 +8410,6 @@
}
}
},
- "Minimum: 50ms. 0 to disable. ms(milliSec),s(sec),m(min). ⏎ to save" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "最低: 50ms, 输入0关闭. 单位: ms毫秒, s秒, m分钟. 按 ⏎ 保存设定值."
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "最低: 50 ms, 輸入 0 關閉. 單位:ms 秒, s秒, m分鐘. 按 ⏎ 儲存設定值."
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "最低: 50 ms, 輸入 0 關閉. 單位:ms 秒, s秒, m分鐘. 按 ⏎ 儲存設定值."
- }
- }
- }
- },
"ML_TEST_RESULT_INCONCLUSIVE" : {
"extractionState" : "manual",
"localizations" : {
@@ -8825,6 +8923,29 @@
}
}
},
+ "Not enough room to insert trigger interval slots" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "没有足够空间插入触发间隔格"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "沒有足夠空間插入觸發間隔格"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "沒有足夠空間插入觸發間隔格"
+ }
+ }
+ }
+ },
"Nothing to Undo" : {
"extractionState" : "manual",
"localizations" : {
@@ -10321,52 +10442,6 @@
}
}
},
- "Manually enter press duration in milliseconds" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "手动输入按压时长, 单位毫秒"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "手動輸入按壓時長, 單位毫秒"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "手動輸入按壓時長, 單位毫秒"
- }
- }
- }
- },
- "Manually enter trigger interval in milliseconds" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "手动输入间隔,单位毫秒"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "手動輸入間隔,單位毫秒"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "手動輸入間隔,單位毫秒"
- }
- }
- }
- },
"Press the button for mouse left button" : {
"extractionState" : "manual",
"localizations" : {
@@ -11879,6 +11954,29 @@
}
}
},
+ "Select at least two button controls before inserting trigger intervals" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "请至少先选择两个按钮型控件,再插入触发间隔"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "請至少先選擇兩個按鈕型控制項,再插入觸發間隔"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "請至少先選擇兩個按鈕型控制項,再插入觸發間隔"
+ }
+ }
+ }
+ },
"Select brush shortcut keys" : {
"extractionState" : "manual",
"localizations" : {
@@ -12138,6 +12236,29 @@
}
}
},
+ "Set all" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "统一设置间隔"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "統一設定間隔"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "統一設定間隔"
+ }
+ }
+ }
+ },
"Set PC/Game resolution:" : {
"extractionState" : "manual",
"localizations" : {
@@ -12161,6 +12282,29 @@
}
}
},
+ "Set this" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "单独设置间隔"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "單獨設定間隔"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "單獨設定間隔"
+ }
+ }
+ }
+ },
"Settings" : {
"extractionState" : "manual",
"localizations" : {
@@ -13867,6 +14011,52 @@
}
}
},
+ "Trigger interval cannot be inserted when WASDPAD or ARROWPAD is in the pool" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "池中存在 WASDPAD 或 ARROWPAD 时,不能插入触发间隔"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "池中存在 WASDPAD 或 ARROWPAD 時,不能插入觸發間隔"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "池中存在 WASDPAD 或 ARROWPAD 時,不能插入觸發間隔"
+ }
+ }
+ }
+ },
+ "Trigger interval slots are already inserted" : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "触发间隔格已经插入"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "觸發間隔格已經插入"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "觸發間隔格已經插入"
+ }
+ }
+ }
+ },
"Tutorial" : {
"extractionState" : "manual",
"localizations" : {
@@ -14763,167 +14953,6 @@
}
}
},
- "Insert trigger interval" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "插入触发间隔"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "插入觸發間隔"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "插入觸發間隔"
- }
- }
- }
- },
- "Not enough room to insert trigger interval slots" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "没有足够空间插入触发间隔格"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "沒有足夠空間插入觸發間隔格"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "沒有足夠空間插入觸發間隔格"
- }
- }
- }
- },
- "Select at least two button controls before inserting trigger intervals" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "请至少先选择两个按钮型控件,再插入触发间隔"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "請至少先選擇兩個按鈕型控制項,再插入觸發間隔"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "請至少先選擇兩個按鈕型控制項,再插入觸發間隔"
- }
- }
- }
- },
- "Set all" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "统一设置间隔"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "統一設定間隔"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "統一設定間隔"
- }
- }
- }
- },
- "Set this" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "单独设置间隔"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "單獨設定間隔"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "單獨設定間隔"
- }
- }
- }
- },
- "Trigger interval cannot be inserted when WASDPAD or ARROWPAD is in the pool" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "池中存在 WASDPAD 或 ARROWPAD 时,不能插入触发间隔"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "池中存在 WASDPAD 或 ARROWPAD 時,不能插入觸發間隔"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "池中存在 WASDPAD 或 ARROWPAD 時,不能插入觸發間隔"
- }
- }
- }
- },
- "Trigger interval slots are already inserted" : {
- "extractionState" : "manual",
- "localizations" : {
- "zh-Hans" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "触发间隔格已经插入"
- }
- },
- "zh-Hant" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "觸發間隔格已經插入"
- }
- },
- "zh-HK" : {
- "stringUnit" : {
- "state" : "translated",
- "value" : "觸發間隔格已經插入"
- }
- }
- }
- },
"Your network connection isn't performing well. Reduce your video bitrate setting or try a faster connection." : {
"extractionState" : "manual",
"localizations" : {
@@ -15010,4 +15039,4 @@
}
},
"version" : "1.1"
-}
+}
\ No newline at end of file
diff --git a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift
index 3dfac8be..5504d97a 100644
--- a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift
+++ b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.swift
@@ -97,9 +97,12 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
@IBOutlet weak var mouseButtonDownSelector: UISegmentedControl!
@IBOutlet weak var buttonModeStack: UIStackView!
@IBOutlet weak var buttonModeSelector: UISegmentedControl!
+
@IBOutlet weak var autoTapStack: UIStackView!
@IBOutlet weak var autoTapLabel: UILabel!
@IBOutlet weak var autoTapField: UITextField!
+ @IBOutlet weak var autoTapRepeatsField: UITextField!
+
@IBOutlet weak var slideThresholdStack: UIStackView!
@IBOutlet weak var slideThresholdLabel: UILabel!
@IBOutlet weak var slideThresholdSlider: UISlider!
@@ -407,6 +410,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widgetView.borderWidth = buttonState.borderWidth
widgetView.highlightSizeFactor = buttonState.highlightSizeFactor
widgetView.autoTapInterval = Int(buttonState.autoTapInterval)
+ widgetView.autoTapRepeats = UInt32(buttonState.autoTapRepeats)
widgetView.setVibration(style: Int(buttonState.vibrationStyle))
widgetView.mouseButtonAction = MouseButtonAction(rawValue: Int(buttonState.mouseButtonAction)) ?? .hovering
widgetView.animatesTransition = buttonState.animatesTransition
@@ -966,9 +970,18 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
autoTapField.textColor = .white
autoTapField.keyboardType = .numbersAndPunctuation
autoTapField.attributedPlaceholder = NSAttributedString(
- string: LocalizationHelper.localizedString(forKey: "Minimum: 50ms. 0 to disable. ms(milliSec),s(sec),m(min). ⏎ to save"),
- attributes: [.foregroundColor: UIColor.white.withAlphaComponent(0.77)]
+ string: LocalizationHelper.localizedString(forKey: "autoTapTimerTip"),
+ attributes: [.foregroundColor: UIColor.white.withAlphaComponent(0.77), .font: UIFont.systemFont(ofSize: 10)]
)
+
+ autoTapRepeatsField.text = widgetView.autoTapRepeats == 0 ? "∞" : "\(widgetView.autoTapRepeats)"
+ autoTapRepeatsField.textColor = .white
+ autoTapRepeatsField.keyboardType = .numbersAndPunctuation
+ autoTapRepeatsField.attributedPlaceholder = NSAttributedString(
+ string: LocalizationHelper.localizedString(forKey: "0 - infinite"),
+ attributes: [.foregroundColor: UIColor.white.withAlphaComponent(0.77), .font: UIFont.systemFont(ofSize: 10)]
+ )
+
autoFitLabel(autoTapLabel)
decelerationRateStack.isHidden = !widgetView.hasInertia
@@ -1220,6 +1233,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
newWidget.borderWidth = widget.borderWidth
newWidget.highlightSizeFactor = widget.highlightSizeFactor
newWidget.autoTapInterval = widget.autoTapInterval
+ newWidget.autoTapRepeats = widget.autoTapRepeats
newWidget.sensitivityFactorY = widget.sensitivityFactorY
newWidget.slideThreshold = widget.slideThreshold
newWidget.yawFactor = widget.yawFactor
@@ -1743,9 +1757,12 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widgetBorderWidthLabel.isUserInteractionEnabled = true
widgetBorderWidthLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(switchBorderWidthSlider(_:))))
borderWidthAlphaStack.isHidden = true
+
autoTapLabel.text = LocalizationHelper.localizedString(forKey: "Autotap timer ")
autoTapField.delegate = self
+ autoTapRepeatsField.delegate = self
autoTapStack.isHidden = true
+
sensitivityXSlider.addTarget(self, action: #selector(sensitivityXSliderMoved(_:)), for: .valueChanged)
sensitivityXLabel.text = LocalizationHelper.localizedString(forKey: "SensitivityX")
sensitivityXStack.isHidden = true
@@ -1915,6 +1932,13 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
textField.resignFirstResponder()
selectedWidget?.setAutoTapIntervalByText(str: textField.text ?? "")
}
+ if textField == autoTapRepeatsField {
+ textField.resignFirstResponder()
+ if let repeats = UInt32(textField.text ?? "") {
+ selectedWidget?.autoTapRepeats = repeats
+ }
+ else {selectedWidget?.autoTapRepeats = 0}
+ }
return true
}
diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings
index bc36acb3..b357ff04 100644
--- a/VoidLink/mul.lproj/iPad.xcstrings
+++ b/VoidLink/mul.lproj/iPad.xcstrings
@@ -3620,6 +3620,36 @@
}
}
},
+ "iiK-9g-N5s.text" : {
+ "comment" : "Class = \"UILabel\"; text = \"Repeats\"; ObjectID = \"iiK-9g-N5s\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Repeats"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "循环次数"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "循環次數"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "循環次數"
+ }
+ }
+ }
+ },
"iPd-Ra-Lbl.text" : {
"comment" : "Class = \"UILabel\"; text = \"Full Color Range\"; ObjectID = \"iPd-Ra-Lbl\";",
"extractionState" : "extracted_with_value",
diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings
index df78af9d..a3be7278 100644
--- a/VoidLink/mul.lproj/iPhone.xcstrings
+++ b/VoidLink/mul.lproj/iPhone.xcstrings
@@ -2677,6 +2677,36 @@
}
}
},
+ "gSL-YJ-0ME.text" : {
+ "comment" : "Class = \"UILabel\"; text = \"Repeats\"; ObjectID = \"gSL-YJ-0ME\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Repeats"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "循环次数"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "循環次數"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "循環次數"
+ }
+ }
+ }
+ },
"GX4-zV-pQ8.text" : {
"comment" : "Class = \"UILabel\"; text = \"Map Gyro to\"; ObjectID = \"GX4-zV-pQ8\";",
"extractionState" : "extracted_with_value",