- update default widget template with profile name localized

- improve widget import
This commit is contained in:
True Zhuanjia
2026-06-06 20:07:01 +08:00
parent 384724ff27
commit 53209ce89e
9 changed files with 285 additions and 31 deletions
@@ -14,7 +14,7 @@ import UIKit
@objcMembers
class OSCProfilesManager: NSObject {
private static let profilesDefaultsKey = "OSCProfiles"
private static let widgetProfileUpdatedKey = "widgetProfileUpdated-20260605"
private static let widgetProfileUpdatedKey = "widgetProfileUpdated-20260606"
private static var sharedInstance: OSCProfilesManager?
private static var onScreenWidgetViews: NSMutableSet?
@@ -184,7 +184,8 @@ class OSCProfilesManager: NSObject {
for case let profile as OSCProfile in profilesDecoded {
if localProfileNames.contains(profile.name) {
profile.name = "\(profile.name)-\(LocalizationHelper.localizedString(forKey:"Restored"))"
// profile.name = "\(profile.name)-\(LocalizationHelper.localizedString(forKey:"Restored"))"
profile.name = "\(profile.name) - Restored"
}
}
@@ -201,8 +202,10 @@ class OSCProfilesManager: NSObject {
localProfiles.remove(profile)
}
var indexOffset = 0
for profile in localProfiles {
profilesDecoded.add(profile)
profilesDecoded.insert(profile, at: 1+indexOffset)
indexOffset += 1
}
persistEncodedProfiles(encodedProfiles(from: profilesDecoded))
@@ -228,6 +231,7 @@ class OSCProfilesManager: NSObject {
}
}
/*
func updateDefaultTemplates() {
guard let filePath = Bundle.main.path(forResource: isIPhone() ? "widgetTemplatesIPhone" : "widgetTemplates", ofType: "bin") else {
return
@@ -272,6 +276,7 @@ class OSCProfilesManager: NSObject {
return
}
}
*/
func getAllProfiles() -> NSMutableArray {
guard
@@ -304,11 +309,7 @@ class OSCProfilesManager: NSObject {
let needImportDefaultTemplates = defaults.object(forKey: Self.widgetProfileUpdatedKey) == nil
if profiles.count == 0 || needImportDefaultTemplates {
if profiles.count == 0 {
importDefaultTemplates()
} else {
updateDefaultTemplates()
}
importDefaultTemplates()
defaults.set(true, forKey: Self.widgetProfileUpdatedKey)
defaults.synchronize()
profiles = getAllProfiles()
@@ -526,6 +527,14 @@ class OSCProfilesManager: NSObject {
}
return nil
}
func getIndex(byName name: String) -> UInt32? {
let profiles = getAllProfiles()
for case let profile as OSCProfile in profiles where profile.name == name {
return UInt32(profiles.index(of: profile))
}
return nil
}
func unarchiveButtonStateEncoded(_ data: Data) -> OnScreenButtonState {
if let buttonState = try? NSKeyedUnarchiver.unarchivedObject(ofClasses: Self.buttonStateCodingClasses, from: data) as? OnScreenButtonState {
+16 -1
View File
@@ -3394,7 +3394,7 @@ import ObjectiveC.runtime
// MARK: - Auto Dock
private static let autoDockExposedEdgeLength: CGFloat = GenericUtils.isIPhone() ? 70 : 90
private static let autoDockExposedThickness: CGFloat = 22
private static let autoDockExposedThickness: CGFloat = 17
private static let autoDockVerticalInset: CGFloat = 12
@objc var autoDockIdleDuration: TimeInterval = 0
@objc var storedAutoDockIdleDuration: TimeInterval = 0
@@ -3901,6 +3901,21 @@ import ObjectiveC.runtime
}
}
@objc static func clearSubWidgets(for folder:OnScreenWidgetView, recursive:Bool = false){
for widget in OnScreenWidgetView.mapping.values where widget.parentSequence == folder.sequence && (!widget.isFolder || widget.sequenceSet.isEmpty) {
folder.sequenceSet.remove(widget.sequence)
OnScreenWidgetView.mapping.removeValue(forKey: widget.sequence)
widget.removeFromSuperview()
}
guard recursive else {return}
for subFolder in OnScreenWidgetView.mapping.values where subFolder.parentSequence == folder.sequence && subFolder.isFolder {
OnScreenWidgetView.clearSubWidgets(for: subFolder, recursive: true)
folder.sequenceSet.remove(subFolder.sequence)
OnScreenWidgetView.mapping.removeValue(forKey: subFolder.sequence)
subFolder.removeFromSuperview()
}
}
private static func getRootFolder(of widget:OnScreenWidgetView) -> OnScreenWidgetView?{
var widgetRef:OnScreenWidgetView? = widget
var parentFolder:OnScreenWidgetView? = OnScreenWidgetView.mapping[widgetRef?.parentSequence ?? -1]
+227 -1
View File
@@ -703,7 +703,7 @@
},
"zh-Hans" : {
"stringUnit" : {
"state" : "needs_review",
"state" : "translated",
"value" : "方向键"
}
},
@@ -779,6 +779,35 @@
}
}
},
"=buttonModeDemo" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Demo of 5 Button Combo and Slidable Buttons"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "理解技能组合键与可滑动按键"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "理解技能組合鍵與可滑動按鍵"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "理解技能組合鍵與可滑動按鍵"
}
}
}
},
"=closeTab" : {
"extractionState" : "manual",
"localizations" : {
@@ -1707,6 +1736,35 @@
}
}
},
"=kbmfps" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "= FPS Example (Keyboard & Mouse)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "键鼠FPS"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "键鼠FPS"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "键鼠FPS"
}
}
}
},
"=kbmTip" : {
"extractionState" : "manual",
"localizations" : {
@@ -1852,6 +1910,35 @@
}
}
},
"=legacyWidgets" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Legacy Widgets"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "旧版控件"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "舊版控制項"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "舊版控制項"
}
}
}
},
"=lock" : {
"extractionState" : "manual",
"localizations" : {
@@ -2258,6 +2345,35 @@
}
}
},
"=null" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Null"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "空白"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "空白"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "空白"
}
}
}
},
"=numpad" : {
"extractionState" : "manual",
"localizations" : {
@@ -3418,6 +3534,93 @@
}
}
},
"=vGamepad1" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gamepad Layout 1"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄布局1"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把配置1"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把配置1"
}
}
}
},
"=vGamepad2" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Gamepad Layout 2"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "手柄布局2"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把配置2"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "手把配置2"
}
}
}
},
"=vGamepad3" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Zenless Zone Zero (Genshin Style)"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "绝区零(原神风格)"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "絕區零(原神風格)"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "絕區零(原神風格)"
}
}
}
},
"=virtualGamepad" : {
"extractionState" : "manual",
"localizations" : {
@@ -5758,6 +5961,29 @@
}
}
},
"Default" : {
"extractionState" : "manual",
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "默认"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "預設"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "預設"
}
}
}
},
"Del" : {
"extractionState" : "manual",
"localizations" : {
Binary file not shown.
Binary file not shown.
+12
View File
@@ -700,6 +700,18 @@ extension CGPoint {
}
}
extension String {
var localized: String {
LocalizationHelper.localizedString(forKey: self)
}
var localizedProfileName: String {
let parts = self.components(separatedBy: " - Restored")
let isRestored = self.contains(" - Restored")
let localized = isRestored ? "\(parts.first?.localized ?? "") - \("Restored".localized)" : self.localized
return localized
}
}
private var previousSelectedSegmentIndexKey: UInt8 = 0
private var lastKnownSelectedSegmentIndexKey: UInt8 = 0
+4 -6
View File
@@ -251,13 +251,11 @@ import StoreKit
settings?.onscreenControls = 1
dataMan.saveData()
let profileMan = OSCProfilesManager.sharedManager(.zero)
profileMan.updateDefaultTemplates()
let profiles = profileMan.getAllProfiles()
guard profiles.count > 1 else { break }
guard let targetProfile = profiles[1] as? OSCProfile else { break }
if targetProfile.name == "Pencil Pro" {
profileMan.setProfileToSelected(1)
}
var toolkitProfileIndex = profileMan.getIndex(byName: "Pencil Pro")
if toolkitProfileIndex == nil {profileMan.importDefaultTemplates()}
toolkitProfileIndex = profileMan.getIndex(byName: "Pencil Pro")
profileMan.setProfileToSelected(toolkitProfileIndex ?? 1)
default:
break
}
@@ -395,7 +395,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
if folder != nil {
if buttonState.alias == "=widgets"
|| buttonState.alias == "=pickProfile"
|| buttonState.alias == "widgetTool" {
|| buttonState.alias == "=widgetTool" {
continue
}
}
@@ -587,15 +587,9 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
}
@IBAction func clearFolderButtonTapped(_ sender: Any?) {
for widget in OnScreenWidgetView.mapping.values {
if widget.parentSequence == selectedWidget?.sequence, widget.sequenceSet.isEmpty {
selectedWidget?.sequenceSet.remove(widget.sequence)
OnScreenWidgetView.mapping.removeValue(forKey: widget.sequence)
widget.removeFromSuperview()
}
if let selectedWidget = selectedWidget {
OnScreenWidgetView.clearSubWidgets(for: selectedWidget, recursive: true)
}
selectedWidget?.sequenceSet = Set()
}
private func setBulkEditStackHidden(_ hidden:Bool) {
@@ -839,7 +833,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
let key = decelerationRateSliderMode == .decelerationRateX ? "DecelerationRateX: %.3f " : "DecelerationRateY: %.3f "
decelerationRateLabel.text = LocalizationHelper.localizedString(forKey: key, decelerationRateSlider.value)
}
private func refreshPanelForSelectedWidget(_ widgetView: OnScreenWidgetView) {
// hideStickIndicators()
if OnScreenWidgetView.gamepadArrivalReported {clearSickInput()}
@@ -855,12 +849,12 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
autoFitLabel(currentProfileLabel)
currentProfileLabel.textAlignment = .left
currentProfileLabel.text = LocalizationHelper.localizedString(forKey: " Profile: %@ Alias: %@ Cmd: %@ Parent: %@", profilesManager.getSelectedProfile().name, widgetView.widgetLabel, widgetView.cmdString, LocalizationHelper.localizedString(forKey:OnScreenWidgetView.mapping[widgetView.parentSequence]?.widgetLabel ?? "null"))
currentProfileLabel.text = LocalizationHelper.localizedString(forKey: " Profile: %@ Alias: %@ Cmd: %@ Parent: %@", profilesManager.getSelectedProfile().name.localizedProfileName, widgetView.widgetLabel, widgetView.cmdString, (OnScreenWidgetView.mapping[widgetView.parentSequence]?.widgetLabel ?? "null").localized)
if selectedWidget?.hasWalkSprintKeys == true {
let cmdCounts = widgetView.comboButtonStrings.count
currentProfileLabel.text = LocalizationHelper.localizedString(forKey: " Cmd: %@ Sprint: %@ Walk: %@ Parent: %@",
widgetView.cmdString, cmdCounts>0 ? widgetView.comboButtonStrings[0] : LocalizationHelper.localizedString(forKey: "null"),
cmdCounts>1 ? widgetView.comboButtonStrings[1] : LocalizationHelper.localizedString(forKey: "null"), LocalizationHelper.localizedString(forKey:OnScreenWidgetView.mapping[widgetView.parentSequence]?.widgetLabel ?? "null"))
cmdCounts>1 ? widgetView.comboButtonStrings[1] : LocalizationHelper.localizedString(forKey: "null"), (OnScreenWidgetView.mapping[widgetView.parentSequence]?.widgetLabel ?? "null").localized)
}
undoButton.alpha = widgetView.layoutChanges.count > 1 ? 1.0 : 0.3
@@ -1120,7 +1114,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
autoFitLabel(currentProfileLabel)
currentProfileLabel.textAlignment = .left
currentProfileLabel.text = LocalizationHelper.localizedString(forKey: " Profile: %@ Widget: %@", profilesManager.getSelectedProfile().name, selectedControllerLayer?.name ?? "")
currentProfileLabel.text = LocalizationHelper.localizedString(forKey: " Profile: %@ Widget: %@", profilesManager.getSelectedProfile().name.localizedProfileName, selectedControllerLayer?.name ?? "")
let sizeFactor = OnScreenControls.getControllerLayerSizeFactor(controllerLayer)
widgetSizeSlider.value = Float(sizeFactor)
@@ -1757,7 +1751,7 @@ final class LayoutOnScreenControlsViewController: UIViewController, OnScreenWidg
widgetPanelStack.clipsToBounds = true
widgetPanelStack.backgroundColor = UIColor.black.withAlphaComponent(0.5)
currentProfileLabel.text = LocalizationHelper.localizedString(forKey: "Profile: %@", profilesManager.getSelectedProfile().name)
currentProfileLabel.text = LocalizationHelper.localizedString(forKey: "Profile: %@", profilesManager.getSelectedProfile().name.localizedProfileName)
currentProfileLabel.layer.cornerRadius = isIPhone() ? 9 : 12
currentProfileLabel.clipsToBounds = true
currentProfileLabel.textAlignment = .center
@@ -383,7 +383,7 @@ final class OSCProfilesTableViewController: UIViewController, UITableViewDelegat
return UITableViewCell()
}
nameLabel.text = profile.name
nameLabel.text = profile.name.localizedProfileName
nameLabel.backgroundColor = UIColor.clear
nameLabel.alpha = 1.0
nameLabel.textColor = UIColor.white.withAlphaComponent(0.9)