refactor toolboxView
This commit is contained in:
@@ -19,12 +19,14 @@ import UIKit
|
|||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
|
|
||||||
|
@objc public private(set) var identifier: String
|
||||||
@objc var cmdString: String
|
@objc var cmdString: String
|
||||||
@objc var alias: String
|
@objc var alias: String
|
||||||
|
|
||||||
// MARK: - Initialization
|
// MARK: - Initialization
|
||||||
|
|
||||||
init(cmdString: String, alias: String) {
|
init(cmdString: String, alias: String) {
|
||||||
|
self.identifier = UUID().uuidString
|
||||||
self.cmdString = cmdString
|
self.cmdString = cmdString
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
}
|
}
|
||||||
@@ -36,11 +38,13 @@ import UIKit
|
|||||||
let alias = coder.decodeObject(of: NSString.self, forKey: "alias") as String? else {
|
let alias = coder.decodeObject(of: NSString.self, forKey: "alias") as String? else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
self.identifier = coder.decodeObject(of: NSString.self, forKey: "identifier") as String? ?? UUID().uuidString
|
||||||
self.cmdString = cmdString
|
self.cmdString = cmdString
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(with coder: NSCoder) {
|
public func encode(with coder: NSCoder) {
|
||||||
|
coder.encode(identifier, forKey: "identifier")
|
||||||
coder.encode(cmdString, forKey: "keyboardCmdString")
|
coder.encode(cmdString, forKey: "keyboardCmdString")
|
||||||
coder.encode(alias, forKey: "alias")
|
coder.encode(alias, forKey: "alias")
|
||||||
}
|
}
|
||||||
@@ -50,6 +54,29 @@ import UIKit
|
|||||||
// Define the CommandManager class
|
// Define the CommandManager class
|
||||||
@objc public class CommandManager: NSObject {
|
@objc public class CommandManager: NSObject {
|
||||||
@objc public static let shared = CommandManager()
|
@objc public static let shared = CommandManager()
|
||||||
|
|
||||||
|
private static let defaultCommandAliasMigrationMap: [String: String] = [
|
||||||
|
"任务管理器(Task Manager)": "=taskManager",
|
||||||
|
"Task Manager": "=taskManager",
|
||||||
|
"N卡截图(Nvidia Screenshot)": "=nvidiaShot",
|
||||||
|
"Nvidia Screenshot": "=nvidiaShot",
|
||||||
|
"N卡录屏(Nvidia Screen Recording)": "=nvidiaRec",
|
||||||
|
"Nvidia Screen Recording": "=nvidiaRec",
|
||||||
|
"关闭窗口(ALT+F4)": "=closeWindow",
|
||||||
|
"Close Window": "=closeWindow",
|
||||||
|
"全选(Select All)": "=selectAll",
|
||||||
|
"Select All": "=selectAll",
|
||||||
|
"复制(Copy)": "=copy",
|
||||||
|
"Copy": "=copy",
|
||||||
|
"粘贴(Paste)": "=paste",
|
||||||
|
"Paste": "=paste",
|
||||||
|
"切换桌面(Switch to Desktop)": "=switchDesktop",
|
||||||
|
"Switch to Desktop": "=switchDesktop",
|
||||||
|
"多显模式(Project)": "=projectDisplay",
|
||||||
|
"Project": "=projectDisplay",
|
||||||
|
"Xbox Game Bar": "=xboxGameBar",
|
||||||
|
"Steam Overlay": "=steamOverlay",
|
||||||
|
]
|
||||||
|
|
||||||
@objc public static let mouseButtonMappings: [String: Int32] = [
|
@objc public static let mouseButtonMappings: [String: Int32] = [
|
||||||
"M_LEFT" : BUTTON_LEFT,
|
"M_LEFT" : BUTTON_LEFT,
|
||||||
@@ -463,17 +490,17 @@ import UIKit
|
|||||||
RemoteCommand(cmdString: "WIN", alias: "WIN"),
|
RemoteCommand(cmdString: "WIN", alias: "WIN"),
|
||||||
RemoteCommand(cmdString: "F11", alias: "F11"),
|
RemoteCommand(cmdString: "F11", alias: "F11"),
|
||||||
RemoteCommand(cmdString: "ESC", alias: "ESC"),
|
RemoteCommand(cmdString: "ESC", alias: "ESC"),
|
||||||
RemoteCommand(cmdString: "CTRL+SHIFT+ESC", alias: "任务管理器(Task Manager)"),
|
RemoteCommand(cmdString: "CTRL+SHIFT+ESC", alias: "=taskManager"),
|
||||||
RemoteCommand(cmdString: "ALT+F1", alias: "N卡截图(Nvidia Screenshot)"),
|
RemoteCommand(cmdString: "ALT+F1", alias: "=nvidiaShot"),
|
||||||
RemoteCommand(cmdString: "ALT+F9", alias: "N卡录屏(Nvidia Screen Recording)"),
|
RemoteCommand(cmdString: "ALT+F9", alias: "=nvidiaRec"),
|
||||||
RemoteCommand(cmdString: "ALT+F4", alias: "关闭窗口(ALT+F4)"),
|
RemoteCommand(cmdString: "ALT+F4", alias: "=closeWindow"),
|
||||||
RemoteCommand(cmdString: "CTRL+A", alias: "全选(Select All)"),
|
RemoteCommand(cmdString: "CTRL+A", alias: "=selectAll"),
|
||||||
RemoteCommand(cmdString: "CTRL+C", alias: "复制(Copy)"),
|
RemoteCommand(cmdString: "CTRL+C", alias: "=copy"),
|
||||||
RemoteCommand(cmdString: "CTRL+V", alias: "粘贴(Paste)"),
|
RemoteCommand(cmdString: "CTRL+V", alias: "=paste"),
|
||||||
RemoteCommand(cmdString: "WIN+D", alias: "切换桌面(Switch to Desktop)"),
|
RemoteCommand(cmdString: "WIN+D", alias: "=switchDesktop"),
|
||||||
RemoteCommand(cmdString: "WIN+P", alias: "多显模式(Project)"),
|
RemoteCommand(cmdString: "WIN+P", alias: "=projectDisplay"),
|
||||||
RemoteCommand(cmdString: "WIN+G", alias: "Xbox Game Bar"),
|
RemoteCommand(cmdString: "WIN+G", alias: "=xboxGameBar"),
|
||||||
RemoteCommand(cmdString: "SHIFT+TAB", alias: "Steam Overlay"),
|
RemoteCommand(cmdString: "SHIFT+TAB", alias: "=steamOverlay"),
|
||||||
]
|
]
|
||||||
|
|
||||||
let data = try? NSKeyedArchiver.archivedData(withRootObject: defaultCommands, requiringSecureCoding: false)
|
let data = try? NSKeyedArchiver.archivedData(withRootObject: defaultCommands, requiringSecureCoding: false)
|
||||||
@@ -633,6 +660,29 @@ import UIKit
|
|||||||
@objc public func getAllCommands() -> [RemoteCommand] {
|
@objc public func getAllCommands() -> [RemoteCommand] {
|
||||||
return commands
|
return commands
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func reorderCommands(withIdentifiers identifiers: [String]) {
|
||||||
|
guard !identifiers.isEmpty else { return }
|
||||||
|
|
||||||
|
var remainingCommandsByID = Dictionary(grouping: commands, by: { $0.identifier })
|
||||||
|
var reorderedCommands: [RemoteCommand] = []
|
||||||
|
|
||||||
|
for identifier in identifiers {
|
||||||
|
guard var commandGroup = remainingCommandsByID[identifier],
|
||||||
|
!commandGroup.isEmpty else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
reorderedCommands.append(commandGroup.removeFirst())
|
||||||
|
remainingCommandsByID[identifier] = commandGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
for command in commands where !reorderedCommands.contains(where: { $0 === command }) {
|
||||||
|
reorderedCommands.append(command)
|
||||||
|
}
|
||||||
|
|
||||||
|
commands = reorderedCommands
|
||||||
|
saveCommands()
|
||||||
|
}
|
||||||
|
|
||||||
private func loadCommands() {
|
private func loadCommands() {
|
||||||
if let savedCommandsData = UserDefaults.standard.data(forKey: "savedCommands") {
|
if let savedCommandsData = UserDefaults.standard.data(forKey: "savedCommands") {
|
||||||
@@ -642,6 +692,7 @@ import UIKit
|
|||||||
// Assign the unarchived commands to your property
|
// Assign the unarchived commands to your property
|
||||||
print(" Assign the unarchived commands to your property ")
|
print(" Assign the unarchived commands to your property ")
|
||||||
commands = savedCommands
|
commands = savedCommands
|
||||||
|
migrateDefaultCommandAliasesIfNeeded()
|
||||||
} else {
|
} else {
|
||||||
// Handle the case where the data could not be unarchived into the expected type
|
// Handle the case where the data could not be unarchived into the expected type
|
||||||
print("Data could not be unarchived into [RemoteCommand]")
|
print("Data could not be unarchived into [RemoteCommand]")
|
||||||
@@ -658,6 +709,21 @@ import UIKit
|
|||||||
UserDefaults.standard.set(data, forKey: "savedCommands")
|
UserDefaults.standard.set(data, forKey: "savedCommands")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func migrateDefaultCommandAliasesIfNeeded() {
|
||||||
|
var didMigrate = false
|
||||||
|
for command in commands {
|
||||||
|
guard let migratedAlias = Self.defaultCommandAliasMigrationMap[command.alias] else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
command.alias = migratedAlias
|
||||||
|
didMigrate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if didMigrate {
|
||||||
|
saveCommands()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@objc public func sendAutoReleaseComboCommand(cmdStrings: [String]?, delay: TimeInterval = 0.2, index: Int = 0, pressOnly: Bool = false, releaseOnly:Bool = false) { // we need a large delay for WAN streaming
|
@objc public func sendAutoReleaseComboCommand(cmdStrings: [String]?, delay: TimeInterval = 0.2, index: Int = 0, pressOnly: Bool = false, releaseOnly:Bool = false) { // we need a large delay for WAN streaming
|
||||||
// 如果已处理完所有按键,则开始释放按键
|
// 如果已处理完所有按键,则开始释放按键
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ final class ControllerNavigationElement: NSObject {
|
|||||||
|
|
||||||
private var controllerNavigationSelectedIndexPathKey: UInt8 = 0
|
private var controllerNavigationSelectedIndexPathKey: UInt8 = 0
|
||||||
private var controllerNavigationPersistTokenKey: UInt8 = 0
|
private var controllerNavigationPersistTokenKey: UInt8 = 0
|
||||||
|
private var controllerNavigationHighlightGenerationKey: UInt8 = 0
|
||||||
private let settingsControllerNavigationHighlightedIdentifierKey = "SettingsControllerNavigationHighlightedIdentifier"
|
private let settingsControllerNavigationHighlightedIdentifierKey = "SettingsControllerNavigationHighlightedIdentifier"
|
||||||
private let hostControllerNavigationHighlightedUUIDKey = "HostControllerNavigationHighlightedUUID"
|
private let hostControllerNavigationHighlightedUUIDKey = "HostControllerNavigationHighlightedUUID"
|
||||||
|
|
||||||
@@ -50,6 +51,27 @@ private final class ControllerMouseDisplayLinkTarget: NSObject {
|
|||||||
func restoreControllerNavigationHighlightAfterSettingsModeSwitch()
|
func restoreControllerNavigationHighlightAfterSettingsModeSwitch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protocol ControllerNavigationHighlightTargetProviding: AnyObject {
|
||||||
|
var controllerNavigationHighlightTargetView: UIView { get }
|
||||||
|
func controllerNavigationHighlightDidApply()
|
||||||
|
func controllerNavigationHighlightDidClear()
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ControllerNavigationHighlightTargetProviding {
|
||||||
|
func controllerNavigationHighlightDidApply() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func controllerNavigationHighlightDidClear() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, *)
|
||||||
|
protocol ControllerCollectionNavigationDelegate: ControllerUINavigationDelegate where Self: UIViewController {
|
||||||
|
var controllerNavigationCollectionView: UICollectionView { get }
|
||||||
|
func controllerNavigationCurrentIndexPathForControllerNavigator() -> IndexPath?
|
||||||
|
func clearCollectionControllerNavigationHighlightForControllerNavigator()
|
||||||
|
}
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
@available(iOS 13.0, *)
|
||||||
final class ControllerNavigator: NSObject {
|
final class ControllerNavigator: NSObject {
|
||||||
typealias Handler = (_ buttonDict: NSDictionary, _ gamepad: GCExtendedGamepad, _ element: GCControllerElement) -> Void
|
typealias Handler = (_ buttonDict: NSDictionary, _ gamepad: GCExtendedGamepad, _ element: GCControllerElement) -> Void
|
||||||
@@ -416,7 +438,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
mainFrameVC.hostCollectionVC?.clearCollectionControllerNavigationHighlightForControllerNavigator()
|
mainFrameVC.hostCollectionVC?.clearCollectionControllerNavigationHighlightForControllerNavigator()
|
||||||
} else {
|
} else {
|
||||||
(uiNavigationDelegate as? SettingsViewController)?.clearControllerNavigationHighlightForControllerNavigator()
|
(uiNavigationDelegate as? SettingsViewController)?.clearControllerNavigationHighlightForControllerNavigator()
|
||||||
(uiNavigationDelegate as? UICollectionViewController)?.clearCollectionControllerNavigationHighlightForControllerNavigator()
|
(uiNavigationDelegate as? ControllerCollectionNavigationDelegate)?.clearCollectionControllerNavigationHighlightForControllerNavigator()
|
||||||
}
|
}
|
||||||
|
|
||||||
controllerNavigationHighlightedView = nil
|
controllerNavigationHighlightedView = nil
|
||||||
@@ -486,6 +508,12 @@ final class ControllerNavigator: NSObject {
|
|||||||
}
|
}
|
||||||
case .exit:
|
case .exit:
|
||||||
exit(0)
|
exit(0)
|
||||||
|
case .shortcuts:
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
radialMenuView?.dismiss()
|
||||||
|
radialMenuView = nil
|
||||||
|
StreamFrameViewController.sharedInstance().bringUpToolboxMenu()
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -516,7 +544,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
if radialMenuState == .moreOptions {
|
if radialMenuState == .moreOptions {
|
||||||
if mainFrameVC.isStreaming() {
|
if mainFrameVC.isStreaming() {
|
||||||
RadialMenuOverlayView.menuSectors.append(RadialMenuSector(title: "Game Profiles".localized, subtitle: "", symbol:PublicUtils.iOS18Available ? "gamecontroller.circle" : "gamecontroller.fill", item: .gameProfiles))
|
RadialMenuOverlayView.menuSectors.append(RadialMenuSector(title: "Game Profiles".localized, subtitle: "", symbol:PublicUtils.iOS18Available ? "gamecontroller.circle" : "gamecontroller.fill", item: .gameProfiles))
|
||||||
RadialMenuOverlayView.menuSectors.append(RadialMenuSector(title: "=shortcuts".localized, subtitle: "", symbol: "apple.terminal", item: .mouse))
|
RadialMenuOverlayView.menuSectors.append(RadialMenuSector(title: "=shortcuts".localized, subtitle: "", symbol: "apple.terminal", item: .shortcuts))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if !mainFrameVC.isInAppView(), !mainFrameVC.settingsViewExpanded {RadialMenuOverlayView.menuSectors.append(RadialMenuSector(title: "About".localized, subtitle: "", symbol: "questionmark.circle", item: .aboutView))}
|
if !mainFrameVC.isInAppView(), !mainFrameVC.settingsViewExpanded {RadialMenuOverlayView.menuSectors.append(RadialMenuSector(title: "About".localized, subtitle: "", symbol: "questionmark.circle", item: .aboutView))}
|
||||||
@@ -668,7 +696,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if let uiNavigationDelegate = uiNavigationDelegate, !mainFrameVC.isStreaming() || mainFrameVC.settingsExpandedInStreamView {
|
if let uiNavigationDelegate = uiNavigationDelegate, !mainFrameVC.isStreaming() || mainFrameVC.settingsExpandedInStreamView || uiNavigationDelegate is ToolboxViewController {
|
||||||
let verticalNavigationAxis: ControllerElement = ControllerNavigator.radialMenuButtonPosition == .right ? .leftStickY : .rightStickY
|
let verticalNavigationAxis: ControllerElement = ControllerNavigator.radialMenuButtonPosition == .right ? .leftStickY : .rightStickY
|
||||||
ControllerUtil.listenPrimaryControllerStickAxis(verticalNavigationAxis, threshold: 0.6) {state in
|
ControllerUtil.listenPrimaryControllerStickAxis(verticalNavigationAxis, threshold: 0.6) {state in
|
||||||
GamepadNavigationIllustrationHud.updateActionState(for: verticalNavigationAxis, isInAction: state != .orderedSame)
|
GamepadNavigationIllustrationHud.updateActionState(for: verticalNavigationAxis, isInAction: state != .orderedSame)
|
||||||
@@ -679,7 +707,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
if uiNavigationDelegate is SettingsViewController {
|
if uiNavigationDelegate is SettingsViewController {
|
||||||
navigateContinuously(forward: true)
|
navigateContinuously(forward: true)
|
||||||
}
|
}
|
||||||
if uiNavigationDelegate is UICollectionViewController {
|
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||||
navigateContinuously(downward: true)
|
navigateContinuously(downward: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -688,7 +716,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
if uiNavigationDelegate is SettingsViewController {
|
if uiNavigationDelegate is SettingsViewController {
|
||||||
navigateContinuously(forward: false)
|
navigateContinuously(forward: false)
|
||||||
}
|
}
|
||||||
if uiNavigationDelegate is UICollectionViewController {
|
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||||
navigateContinuously(downward: false)
|
navigateContinuously(downward: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -698,7 +726,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let uiNavigationDelegate = uiNavigationDelegate, !mainFrameVC.isStreaming() {
|
if let uiNavigationDelegate = uiNavigationDelegate, !mainFrameVC.isStreaming() || uiNavigationDelegate is ToolboxViewController{
|
||||||
let horizontalNavigationAxis: ControllerElement = ControllerNavigator.radialMenuButtonPosition == .right ? .leftStickX : .rightStickX
|
let horizontalNavigationAxis: ControllerElement = ControllerNavigator.radialMenuButtonPosition == .right ? .leftStickX : .rightStickX
|
||||||
ControllerUtil.listenPrimaryControllerStickAxis(horizontalNavigationAxis, threshold: 0.6) {state in
|
ControllerUtil.listenPrimaryControllerStickAxis(horizontalNavigationAxis, threshold: 0.6) {state in
|
||||||
GamepadNavigationIllustrationHud.updateActionState(for: horizontalNavigationAxis, isInAction: state != .orderedSame)
|
GamepadNavigationIllustrationHud.updateActionState(for: horizontalNavigationAxis, isInAction: state != .orderedSame)
|
||||||
@@ -706,13 +734,13 @@ final class ControllerNavigator: NSObject {
|
|||||||
switch state {
|
switch state {
|
||||||
case .orderedAscending:
|
case .orderedAscending:
|
||||||
if navigationTimer?.isRunning() != true {
|
if navigationTimer?.isRunning() != true {
|
||||||
if uiNavigationDelegate is UICollectionViewController {
|
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||||
navigateContinuously(forward: false)
|
navigateContinuously(forward: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .orderedDescending:
|
case .orderedDescending:
|
||||||
if navigationTimer?.isRunning() != true {
|
if navigationTimer?.isRunning() != true {
|
||||||
if uiNavigationDelegate is UICollectionViewController {
|
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||||
navigateContinuously(forward: true)
|
navigateContinuously(forward: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -722,7 +750,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let uiNavigationDelegate = uiNavigationDelegate, !mainFrameVC.isStreaming() || mainFrameVC.settingsExpandedInStreamView || uiNavigationDelegate is UIAlertController || uiNavigationDelegate is OSCProfilesTableViewController {
|
if let uiNavigationDelegate = uiNavigationDelegate, !mainFrameVC.isStreaming() || mainFrameVC.settingsExpandedInStreamView || uiNavigationDelegate is UIAlertController || uiNavigationDelegate is OSCProfilesTableViewController || uiNavigationDelegate is ToolboxViewController {
|
||||||
let navigations = uiNavigationDelegate.getNavigationElements()
|
let navigations = uiNavigationDelegate.getNavigationElements()
|
||||||
let buttonNavigations = navigations.filter({$0.control.type == .button})
|
let buttonNavigations = navigations.filter({$0.control.type == .button})
|
||||||
// let stickNavigations = navigations.filter({$0.control.type == .stick || $0.control.type == .stickAxis})
|
// let stickNavigations = navigations.filter({$0.control.type == .stick || $0.control.type == .stickAxis})
|
||||||
@@ -764,7 +792,7 @@ final class ControllerNavigator: NSObject {
|
|||||||
|
|
||||||
@available(iOS 13.0, *)
|
@available(iOS 13.0, *)
|
||||||
extension SettingsViewController: ControllerUINavigationDelegate {
|
extension SettingsViewController: ControllerUINavigationDelegate {
|
||||||
func persistControllerNavigationHighlight() {
|
@objc func persistControllerNavigationHighlight() {
|
||||||
guard let highlightedView = ControllerNavigator.controllerNavigationHighlightedView,
|
guard let highlightedView = ControllerNavigator.controllerNavigationHighlightedView,
|
||||||
let identifier = controllerNavigationPersistenceIdentifier(for: highlightedView) else {
|
let identifier = controllerNavigationPersistenceIdentifier(for: highlightedView) else {
|
||||||
return
|
return
|
||||||
@@ -773,20 +801,20 @@ extension SettingsViewController: ControllerUINavigationDelegate {
|
|||||||
UserDefaults.standard.set(identifier, forKey: settingsControllerNavigationHighlightedIdentifierKey)
|
UserDefaults.standard.set(identifier, forKey: settingsControllerNavigationHighlightedIdentifierKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreControllerNavigationHighlight() {
|
@objc func restoreControllerNavigationHighlight() {
|
||||||
guard ControllerNavigator.enabled, ControllerUtil.primaryGCController != nil else {return}
|
guard ControllerNavigator.enabled, ControllerUtil.primaryGCController != nil else {return}
|
||||||
PublicUtils.runOnMain { [weak self] in
|
PublicUtils.runOnMain { [weak self] in
|
||||||
self?.restoreControllerNavigationHighlightOnMain()
|
self?.restoreControllerNavigationHighlightOnMain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreControllerNavigationHighlightAfterSettingsModeSwitch() {
|
@objc func restoreControllerNavigationHighlightAfterSettingsModeSwitch() {
|
||||||
PublicUtils.runOnMain { [weak self] in
|
PublicUtils.runOnMain { [weak self] in
|
||||||
self?.restoreControllerNavigationHighlightAfterSettingsModeSwitchOnMain()
|
self?.restoreControllerNavigationHighlightAfterSettingsModeSwitchOnMain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func uiButtonActionForControllerNavigator(pressed: Bool, from navigation: ControllerNavigationElement) {
|
@objc func uiButtonActionForControllerNavigator(pressed: Bool, from navigation: ControllerNavigationElement) {
|
||||||
let isHighlightingUIStack = ControllerNavigator.controllerNavigationHighlightedView is UIStackView
|
let isHighlightingUIStack = ControllerNavigator.controllerNavigationHighlightedView is UIStackView
|
||||||
|
|
||||||
if navigation.action == "holdToReorder", isHighlightingUIStack {
|
if navigation.action == "holdToReorder", isHighlightingUIStack {
|
||||||
@@ -1427,7 +1455,8 @@ extension SettingsViewController: ControllerUINavigationDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UICollectionViewController {
|
@available(iOS 13.0, *)
|
||||||
|
extension ControllerCollectionNavigationDelegate {
|
||||||
var controllerNavigationSelectedIndexPath: IndexPath? {
|
var controllerNavigationSelectedIndexPath: IndexPath? {
|
||||||
get {
|
get {
|
||||||
objc_getAssociatedObject(self, &controllerNavigationSelectedIndexPathKey) as? IndexPath
|
objc_getAssociatedObject(self, &controllerNavigationSelectedIndexPathKey) as? IndexPath
|
||||||
@@ -1446,16 +1475,49 @@ extension UICollectionViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var controllerNavigationHighlightGeneration: Int {
|
||||||
|
get {
|
||||||
|
objc_getAssociatedObject(self, &controllerNavigationHighlightGenerationKey) as? Int ?? 0
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
objc_setAssociatedObject(self, &controllerNavigationHighlightGenerationKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var controllerNavigationCollectionView: UICollectionView {
|
||||||
|
guard let collectionViewController = self as? UICollectionViewController else {
|
||||||
|
assertionFailure("ControllerCollectionNavigationDelegate adopters must provide controllerNavigationCollectionView")
|
||||||
|
return UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
|
||||||
|
}
|
||||||
|
|
||||||
|
return collectionViewController.collectionView
|
||||||
|
}
|
||||||
|
|
||||||
func applyControllerNavigationHighlight(to cell: UICollectionViewCell, highlighted: Bool) {
|
func applyControllerNavigationHighlight(to cell: UICollectionViewCell, highlighted: Bool) {
|
||||||
clearControllerNavigationHighlightBorder(in: cell)
|
clearControllerNavigationHighlightBorder(in: cell)
|
||||||
guard highlighted else { return }
|
guard highlighted else { return }
|
||||||
let highlightedView = controllerNavigationHighlightTargetView(for: cell)
|
let highlightedView = controllerNavigationHighlightTargetView(for: cell)
|
||||||
highlightedView.layer.borderWidth = (self is HostCollectionViewController) ? 3 : 5
|
|
||||||
let isDarkTheme = ThemeManager.userInterfaceStyle() == .dark
|
let isDarkTheme = ThemeManager.userInterfaceStyle() == .dark
|
||||||
highlightedView.layer.borderColor = ThemeManager.appPrimaryColor.withAlphaComponent(isDarkTheme ? 0.85 : 0.93).cgColor
|
if self is ToolboxViewController {
|
||||||
|
highlightedView.layer.borderColor = UIColor.systemOrange.withAlphaComponent(isDarkTheme ? 0.8 : 0.97).cgColor
|
||||||
|
highlightedView.layer.borderWidth = 3
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
highlightedView.layer.borderColor = ThemeManager.appPrimaryColor.withAlphaComponent(isDarkTheme ? 0.85 : 0.93).cgColor
|
||||||
|
highlightedView.layer.borderWidth = (self is HostCollectionViewController) ? 3 : 5
|
||||||
|
}
|
||||||
|
(cell as? ControllerNavigationHighlightTargetProviding)?.controllerNavigationHighlightDidApply()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func clearControllerNavigationHighlightBorder(in cell: UICollectionViewCell) {
|
private func clearControllerNavigationHighlightBorder(in cell: UICollectionViewCell) {
|
||||||
|
if let highlightProvider = cell as? ControllerNavigationHighlightTargetProviding {
|
||||||
|
let targetView = highlightProvider.controllerNavigationHighlightTargetView
|
||||||
|
targetView.layer.borderWidth = 0
|
||||||
|
targetView.layer.borderColor = nil
|
||||||
|
highlightProvider.controllerNavigationHighlightDidClear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for view in [cell, cell.contentView] + cell.contentView.subviews + cell.subviews {
|
for view in [cell, cell.contentView] + cell.contentView.subviews + cell.subviews {
|
||||||
view.layer.borderWidth = 0
|
view.layer.borderWidth = 0
|
||||||
view.layer.borderColor = nil
|
view.layer.borderColor = nil
|
||||||
@@ -1463,6 +1525,10 @@ extension UICollectionViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func controllerNavigationHighlightTargetView(for cell: UICollectionViewCell) -> UIView {
|
private func controllerNavigationHighlightTargetView(for cell: UICollectionViewCell) -> UIView {
|
||||||
|
if let highlightProvider = cell as? ControllerNavigationHighlightTargetProviding {
|
||||||
|
return highlightProvider.controllerNavigationHighlightTargetView
|
||||||
|
}
|
||||||
|
|
||||||
if let contentView = controllerNavigationContentView(in: cell) {
|
if let contentView = controllerNavigationContentView(in: cell) {
|
||||||
return contentView
|
return contentView
|
||||||
}
|
}
|
||||||
@@ -1486,8 +1552,41 @@ extension UICollectionViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@available(iOS 13.0, *)
|
@available(iOS 13.0, *)
|
||||||
extension UICollectionViewController: ControllerUINavigationDelegate {
|
extension UICollectionViewController: ControllerCollectionNavigationDelegate {
|
||||||
func persistControllerNavigationHighlight() {
|
@objc func persistControllerNavigationHighlight() {
|
||||||
|
controllerNavigationPersistCollectionHighlight()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func restoreControllerNavigationHighlight() {
|
||||||
|
controllerNavigationRestoreCollectionHighlight()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func restoreControllerNavigationHighlightAfterSettingsModeSwitch() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func uiWidgetActionForControllerNavigator(forward: Bool, from navigation: ControllerNavigationElement) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func uiButtonActionForControllerNavigator(pressed: Bool, from navigation: ControllerNavigationElement) {
|
||||||
|
controllerNavigationPerformDefaultButtonAction(pressed: pressed, from: navigation)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func getNavigationElements() -> [ControllerNavigationElement] {
|
||||||
|
controllerNavigationDefaultNavigationElements()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func navigateByController(forward: Bool) {
|
||||||
|
controllerNavigationNavigateCollection(forward: forward)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func navigateByController(downward: Bool) {
|
||||||
|
controllerNavigationNavigateCollection(downward: downward)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 13.0, *)
|
||||||
|
extension ControllerCollectionNavigationDelegate {
|
||||||
|
func controllerNavigationPersistCollectionHighlight() {
|
||||||
if let hostCollectionVC = self as? HostCollectionViewController {
|
if let hostCollectionVC = self as? HostCollectionViewController {
|
||||||
persistHostControllerNavigationHighlight(in: hostCollectionVC)
|
persistHostControllerNavigationHighlight(in: hostCollectionVC)
|
||||||
return
|
return
|
||||||
@@ -1498,7 +1597,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreControllerNavigationHighlight() {
|
func controllerNavigationRestoreCollectionHighlight() {
|
||||||
guard ControllerNavigator.enabled, ControllerUtil.primaryGCController != nil else {return}
|
guard ControllerNavigator.enabled, ControllerUtil.primaryGCController != nil else {return}
|
||||||
|
|
||||||
PublicUtils.runOnMain { [weak self] in
|
PublicUtils.runOnMain { [weak self] in
|
||||||
@@ -1515,18 +1614,15 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreControllerNavigationHighlightAfterSettingsModeSwitch() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private func currentControllerNavigationCell() -> UICollectionViewCell? {
|
private func currentControllerNavigationCell() -> UICollectionViewCell? {
|
||||||
guard let selectedIndexPath = controllerNavigationSelectedIndexPath,
|
guard let selectedIndexPath = controllerNavigationSelectedIndexPath,
|
||||||
selectedIndexPath.section < collectionView.numberOfSections,
|
selectedIndexPath.section < controllerNavigationCollectionView.numberOfSections,
|
||||||
selectedIndexPath.item >= 0,
|
selectedIndexPath.item >= 0,
|
||||||
selectedIndexPath.item < collectionView.numberOfItems(inSection: selectedIndexPath.section) else {
|
selectedIndexPath.item < controllerNavigationCollectionView.numberOfItems(inSection: selectedIndexPath.section) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return collectionView.cellForItem(at: selectedIndexPath)
|
return controllerNavigationCollectionView.cellForItem(at: selectedIndexPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func currentControllerNavigationContentView() -> UIView? {
|
private func currentControllerNavigationContentView() -> UIView? {
|
||||||
@@ -1534,7 +1630,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
return controllerNavigationContentView(in: cell)
|
return controllerNavigationContentView(in: cell)
|
||||||
}
|
}
|
||||||
|
|
||||||
func uiButtonActionForControllerNavigator(pressed: Bool, from navigation: ControllerNavigationElement) {
|
func controllerNavigationPerformDefaultButtonAction(pressed: Bool, from navigation: ControllerNavigationElement) {
|
||||||
PublicUtils.runOnMain { [weak self] in
|
PublicUtils.runOnMain { [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
@@ -1570,10 +1666,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func uiWidgetActionForControllerNavigator(forward: Bool, from navigation: ControllerNavigationElement) {
|
func controllerNavigationDefaultNavigationElements() -> [ControllerNavigationElement] {
|
||||||
}
|
|
||||||
|
|
||||||
func getNavigationElements() -> [ControllerNavigationElement] {
|
|
||||||
var elements: [ControllerNavigationElement] = []
|
var elements: [ControllerNavigationElement] = []
|
||||||
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButton, action: "radialMenu"))
|
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButton, action: "radialMenu"))
|
||||||
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButtonPosition == .left ? .rightStick : .leftStick, action: "focusNavigation"))
|
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButtonPosition == .left ? .rightStick : .leftStick, action: "focusNavigation"))
|
||||||
@@ -1584,13 +1677,13 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
return elements
|
return elements
|
||||||
}
|
}
|
||||||
|
|
||||||
func navigateByController(forward: Bool) {
|
func controllerNavigationNavigateCollection(forward: Bool) {
|
||||||
guard hasNoPresentedVC else { return }
|
guard hasNoPresentedVC else { return }
|
||||||
performControllerNavigationSelectionMove(horizontalOffset: forward ? 1 : -1)
|
performControllerNavigationSelectionMove(horizontalOffset: forward ? 1 : -1)
|
||||||
scheduleControllerNavigationHighlightPersistenceWhenStickSettles()
|
scheduleControllerNavigationHighlightPersistenceWhenStickSettles()
|
||||||
}
|
}
|
||||||
|
|
||||||
func navigateByController(downward: Bool) {
|
func controllerNavigationNavigateCollection(downward: Bool) {
|
||||||
guard hasNoPresentedVC else { return }
|
guard hasNoPresentedVC else { return }
|
||||||
performControllerNavigationSelectionMove(verticalOffset: downward ? 1 : -1)
|
performControllerNavigationSelectionMove(verticalOffset: downward ? 1 : -1)
|
||||||
scheduleControllerNavigationHighlightPersistenceWhenStickSettles()
|
scheduleControllerNavigationHighlightPersistenceWhenStickSettles()
|
||||||
@@ -1648,7 +1741,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
highlightControllerNavigationItem(at: IndexPath(item: index, section: 0))
|
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: index, section: 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1674,7 +1767,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (index, app) in mainFrameVC.sortedAppList.enumerated() where app.id == appID {
|
for (index, app) in mainFrameVC.sortedAppList.enumerated() where app.id == appID {
|
||||||
highlightControllerNavigationItem(at: IndexPath(item: index, section: 0))
|
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: index, section: 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1682,13 +1775,13 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func restoreFirstControllerNavigationItemIfNeeded() {
|
private func restoreFirstControllerNavigationItemIfNeeded() {
|
||||||
guard collectionView.numberOfSections > 0,
|
guard controllerNavigationCollectionView.numberOfSections > 0,
|
||||||
collectionView.numberOfItems(inSection: 0) > 0 else {
|
controllerNavigationCollectionView.numberOfItems(inSection: 0) > 0 else {
|
||||||
clearCollectionControllerNavigationHighlight()
|
clearCollectionControllerNavigationHighlight()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
highlightControllerNavigationItem(at: IndexPath(item: 0, section: 0))
|
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: 0, section: 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func performControllerNavigationSelectionMove(horizontalOffset: Int) {
|
private func performControllerNavigationSelectionMove(horizontalOffset: Int) {
|
||||||
@@ -1704,23 +1797,23 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func moveControllerNavigationSelection(horizontalOffset: Int) {
|
private func moveControllerNavigationSelection(horizontalOffset: Int) {
|
||||||
let itemCount = collectionView.numberOfItems(inSection: 0)
|
let itemCount = controllerNavigationCollectionView.numberOfItems(inSection: 0)
|
||||||
guard itemCount > 0 else {
|
guard itemCount > 0 else {
|
||||||
clearCollectionControllerNavigationHighlight()
|
clearCollectionControllerNavigationHighlight()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let currentIndexPath = currentControllerNavigationIndexPath() else {
|
guard let currentIndexPath = currentControllerNavigationIndexPath() else {
|
||||||
highlightControllerNavigationItem(at: IndexPath(item: horizontalOffset >= 0 ? 0 : itemCount - 1, section: 0))
|
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: horizontalOffset >= 0 ? 0 : itemCount - 1, section: 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let nextItem = (currentIndexPath.item + horizontalOffset + itemCount) % itemCount
|
let nextItem = (currentIndexPath.item + horizontalOffset + itemCount) % itemCount
|
||||||
highlightControllerNavigationItem(at: IndexPath(item: nextItem, section: currentIndexPath.section))
|
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: nextItem, section: currentIndexPath.section))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func moveControllerNavigationSelection(verticalOffset: Int) {
|
private func moveControllerNavigationSelection(verticalOffset: Int) {
|
||||||
let itemCount = collectionView.numberOfItems(inSection: 0)
|
let itemCount = controllerNavigationCollectionView.numberOfItems(inSection: 0)
|
||||||
guard itemCount > 0 else {
|
guard itemCount > 0 else {
|
||||||
clearCollectionControllerNavigationHighlight()
|
clearCollectionControllerNavigationHighlight()
|
||||||
return
|
return
|
||||||
@@ -1728,7 +1821,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
|
|
||||||
guard let currentIndexPath = currentControllerNavigationIndexPath(),
|
guard let currentIndexPath = currentControllerNavigationIndexPath(),
|
||||||
let currentAttributes = layoutAttributesForItem(at: currentIndexPath) else {
|
let currentAttributes = layoutAttributesForItem(at: currentIndexPath) else {
|
||||||
highlightControllerNavigationItem(at: IndexPath(item: verticalOffset >= 0 ? 0 : itemCount - 1, section: 0))
|
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: verticalOffset >= 0 ? 0 : itemCount - 1, section: 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1767,65 +1860,77 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
}?.indexPath
|
}?.indexPath
|
||||||
|
|
||||||
if let nextIndexPath {
|
if let nextIndexPath {
|
||||||
highlightControllerNavigationItem(at: nextIndexPath)
|
controllerNavigationHighlightItemForControllerNavigator(at: nextIndexPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func currentControllerNavigationIndexPath() -> IndexPath? {
|
private func currentControllerNavigationIndexPath() -> IndexPath? {
|
||||||
if let selectedIndexPath = controllerNavigationSelectedIndexPath,
|
if let selectedIndexPath = controllerNavigationSelectedIndexPath,
|
||||||
selectedIndexPath.section < collectionView.numberOfSections,
|
selectedIndexPath.section < controllerNavigationCollectionView.numberOfSections,
|
||||||
selectedIndexPath.item < collectionView.numberOfItems(inSection: selectedIndexPath.section) {
|
selectedIndexPath.item < controllerNavigationCollectionView.numberOfItems(inSection: selectedIndexPath.section) {
|
||||||
return selectedIndexPath
|
return selectedIndexPath
|
||||||
}
|
}
|
||||||
|
|
||||||
if let highlightedView = ControllerNavigator.controllerNavigationHighlightedView,
|
if let highlightedView = ControllerNavigator.controllerNavigationHighlightedView,
|
||||||
let highlightedCell = collectionViewCell(containing: highlightedView),
|
let highlightedCell = collectionViewCell(containing: highlightedView),
|
||||||
let indexPath = collectionView.indexPath(for: highlightedCell) {
|
let indexPath = controllerNavigationCollectionView.indexPath(for: highlightedCell) {
|
||||||
return indexPath
|
return indexPath
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func highlightControllerNavigationItem(at indexPath: IndexPath) {
|
func controllerNavigationCurrentIndexPathForControllerNavigator() -> IndexPath? {
|
||||||
|
currentControllerNavigationIndexPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
func controllerNavigationHighlightItemForControllerNavigator(at indexPath: IndexPath) {
|
||||||
PublicUtils.runOnMain { [weak self] in
|
PublicUtils.runOnMain { [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
guard indexPath.section < self.collectionView.numberOfSections,
|
let collectionView = self.controllerNavigationCollectionView
|
||||||
|
guard indexPath.section < collectionView.numberOfSections,
|
||||||
indexPath.item >= 0,
|
indexPath.item >= 0,
|
||||||
indexPath.item < self.collectionView.numberOfItems(inSection: indexPath.section) else {
|
indexPath.item < collectionView.numberOfItems(inSection: indexPath.section) else {
|
||||||
self.clearCollectionControllerNavigationHighlight()
|
self.clearCollectionControllerNavigationHighlight()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.collectionView.layoutIfNeeded()
|
collectionView.layoutIfNeeded()
|
||||||
|
|
||||||
let previousIndexPath = self.controllerNavigationSelectedIndexPath
|
let previousIndexPath = self.controllerNavigationSelectedIndexPath
|
||||||
|
self.controllerNavigationHighlightGeneration += 1
|
||||||
|
let highlightGeneration = self.controllerNavigationHighlightGeneration
|
||||||
self.controllerNavigationSelectedIndexPath = indexPath
|
self.controllerNavigationSelectedIndexPath = indexPath
|
||||||
|
|
||||||
if let previousIndexPath,
|
if let previousIndexPath,
|
||||||
previousIndexPath != indexPath,
|
previousIndexPath != indexPath,
|
||||||
let previousCell = self.collectionView.cellForItem(at: previousIndexPath) {
|
let previousCell = collectionView.cellForItem(at: previousIndexPath) {
|
||||||
self.applyControllerNavigationHighlight(to: previousCell, highlighted: false)
|
self.applyControllerNavigationHighlight(to: previousCell, highlighted: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.collectionView.scrollToItem(at: indexPath, at: [.centeredHorizontally, .centeredVertically], animated: true)
|
collectionView.scrollToItem(at: indexPath, at: [.centeredHorizontally, .centeredVertically], animated: true)
|
||||||
|
self.applyControllerNavigationHighlightWhenCellIsReady(at: indexPath, generation: highlightGeneration, remainingAttempts: 8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let cell = self.collectionView.cellForItem(at: indexPath) {
|
private func applyControllerNavigationHighlightWhenCellIsReady(at indexPath: IndexPath, generation: Int, remainingAttempts: Int) {
|
||||||
self.applyControllerNavigationHighlight(to: cell, highlighted: true)
|
guard controllerNavigationSelectedIndexPath == indexPath,
|
||||||
ControllerNavigator.controllerNavigationHighlightedView = self.controllerNavigationHighlightTargetView(for: cell)
|
controllerNavigationHighlightGeneration == generation else { return }
|
||||||
}
|
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
let collectionView = controllerNavigationCollectionView
|
||||||
guard let self,
|
collectionView.layoutIfNeeded()
|
||||||
self.controllerNavigationSelectedIndexPath == indexPath,
|
|
||||||
let cell = self.collectionView.cellForItem(at: indexPath) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.applyControllerNavigationHighlight(to: cell, highlighted: true)
|
if let cell = collectionView.cellForItem(at: indexPath) {
|
||||||
ControllerNavigator.controllerNavigationHighlightedView = self.controllerNavigationHighlightTargetView(for: cell)
|
applyControllerNavigationHighlight(to: cell, highlighted: true)
|
||||||
}
|
ControllerNavigator.controllerNavigationHighlightedView = controllerNavigationHighlightTargetView(for: cell)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard remainingAttempts > 0 else { return }
|
||||||
|
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { [weak self] in
|
||||||
|
self?.applyControllerNavigationHighlightWhenCellIsReady(at: indexPath, generation: generation, remainingAttempts: remainingAttempts - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1834,21 +1939,28 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
|||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
|
|
||||||
if let selectedIndexPath = self.controllerNavigationSelectedIndexPath,
|
if let selectedIndexPath = self.controllerNavigationSelectedIndexPath,
|
||||||
let cell = self.collectionView.cellForItem(at: selectedIndexPath) {
|
let cell = self.controllerNavigationCollectionView.cellForItem(at: selectedIndexPath) {
|
||||||
self.applyControllerNavigationHighlight(to: cell, highlighted: false)
|
self.applyControllerNavigationHighlight(to: cell, highlighted: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.controllerNavigationHighlightGeneration += 1
|
||||||
self.controllerNavigationSelectedIndexPath = nil
|
self.controllerNavigationSelectedIndexPath = nil
|
||||||
ControllerNavigator.controllerNavigationHighlightedView = nil
|
ControllerNavigator.controllerNavigationHighlightedView = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func clearCollectionControllerNavigationHighlightForControllerNavigator() {
|
func clearCollectionControllerNavigationHighlightForControllerNavigator() {
|
||||||
clearCollectionControllerNavigationHighlight()
|
clearCollectionControllerNavigationHighlight()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func invalidateCollectionControllerNavigationHighlightForControllerNavigator() {
|
||||||
|
controllerNavigationHighlightGeneration += 1
|
||||||
|
controllerNavigationSelectedIndexPath = nil
|
||||||
|
ControllerNavigator.controllerNavigationHighlightedView = nil
|
||||||
|
}
|
||||||
|
|
||||||
private func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
private func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
||||||
collectionView.collectionViewLayout.layoutAttributesForItem(at: indexPath)
|
controllerNavigationCollectionView.collectionViewLayout.layoutAttributesForItem(at: indexPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func collectionViewCell(containing view: UIView) -> UICollectionViewCell? {
|
private func collectionViewCell(containing view: UIView) -> UICollectionViewCell? {
|
||||||
|
|||||||
@@ -866,7 +866,7 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "Close"
|
"value" : "Close Window"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
@@ -2519,25 +2519,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "Nvidia Rec"
|
"value" : "NVIDIA Recording"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "N卡录屏"
|
"value" : "NVIDIA 录屏"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "N卡錄影"
|
"value" : "NVIDIA 螢幕錄影"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "N卡錄影"
|
"value" : "NVIDIA 螢幕錄影"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2548,25 +2548,25 @@
|
|||||||
"en" : {
|
"en" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "Nvidia Shot"
|
"value" : "NVIDIA Screenshot"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hans" : {
|
"zh-Hans" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "N卡截图"
|
"value" : "NVIDIA 截图"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-Hant" : {
|
"zh-Hant" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "N卡截圖"
|
"value" : "NVIDIA 螢幕截圖"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"zh-HK" : {
|
"zh-HK" : {
|
||||||
"stringUnit" : {
|
"stringUnit" : {
|
||||||
"state" : "translated",
|
"state" : "translated",
|
||||||
"value" : "N卡截圖"
|
"value" : "NVIDIA 螢幕截圖"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2832,6 +2832,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"=projectDisplay" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Project Display"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "投影显示"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "投影顯示"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "投影顯示"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"=prone" : {
|
"=prone" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -3470,6 +3499,64 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"=steamOverlay" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Steam Overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Steam 覆盖层"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Steam 覆蓋介面"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Steam 覆蓋介面"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"=switchDesktop" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Switch to Desktop"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "切换到桌面"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "切換到桌面"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "切換到桌面"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"=switchWindow" : {
|
"=switchWindow" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -3586,6 +3673,151 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"=toolboxDisconnectQuit" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Disconnect & Quit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "断开并退出"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "斷線並退出"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "斷線並退出"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"=toolboxSoftKeyboard" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Soft Keyboard"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "软键盘"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "軟體鍵盤"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "軟體鍵盤"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"=toolboxStatsOverlay" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Stats Overlay"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "统计覆盖层"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "統計覆蓋層"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "統計覆蓋層"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"=toolboxSwitchProfile" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Switch Profile"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "切换配置"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "切換配置"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "切換配置"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"=toolboxWidgetLayout" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Edit Layout"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "编辑布局"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "編輯佈局"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "編輯佈局"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"=ult" : {
|
"=ult" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -3876,6 +4108,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"=xboxGameBar" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Xbox Game Bar"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Xbox 游戏栏"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Xbox 遊戲列"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Xbox 遊戲列"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"=zoomIn" : {
|
"=zoomIn" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -4256,6 +4517,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"addEntry" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Add Entry"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "新增条目"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "新增條目"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "新增條目"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Adjust the pressure curve by adding or dragging the purple squares." : {
|
"Adjust the pressure curve by adding or dragging the purple squares." : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -6716,6 +7006,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"doublePressPinExecute" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Double Press Pin Execute"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "双击执行不退出"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "雙擊執行不退出"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "雙擊執行不退出"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"doublePressToAddFavorite" : {
|
"doublePressToAddFavorite" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -7742,6 +8061,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"execute" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Execute"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "执行"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "執行"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "執行"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"exit" : {
|
"exit" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -10193,35 +10541,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"leftButton" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Left Button"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "鼠标左键"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "滑鼠左鍵"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "滑鼠左鍵"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Layout of the Default profile can not be changed" : {
|
"Layout of the Default profile can not be changed" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -10504,6 +10823,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"leftButton" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Left Button"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "鼠标左键"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "滑鼠左鍵"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "滑鼠左鍵"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"legacyFramePacingTip" : {
|
"legacyFramePacingTip" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -11410,6 +11758,29 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Move the stick you want to use for mouse control. The other stick will be used for vertical and horizontal scrolling" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "移动用于控制鼠标指针的摇杆。另一侧的摇杆将用于控制垂直、水平滚动。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "移動用於控制滑鼠指標的搖桿。另一側的搖桿將用於控制垂直、水平滾動。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "移動用於控制滑鼠指標的搖桿。另一側的搖桿將用於控制垂直、水平滾動。"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"moveCursor" : {
|
"moveCursor" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -11439,29 +11810,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Move the stick you want to use for mouse control. The other stick will be used for vertical and horizontal scrolling" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "移动用于控制鼠标指针的摇杆。另一侧的摇杆将用于控制垂直、水平滚动。"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "移動用於控制滑鼠指標的搖桿。另一側的搖桿將用於控制垂直、水平滾動。"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "移動用於控制滑鼠指標的搖桿。另一側的搖桿將用於控制垂直、水平滾動。"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"name" : {
|
"name" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -14679,35 +15027,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rightButton" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Right Button"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "鼠标右键"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "滑鼠右鍵"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "滑鼠右鍵"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Right Button" : {
|
"Right Button" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -14777,6 +15096,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rightButton" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Right Button"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "鼠标右键"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "滑鼠右鍵"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "滑鼠右鍵"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Roll factor: %.2f" : {
|
"Roll factor: %.2f" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -17618,35 +17966,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"verticalHorizontalScroll" : {
|
|
||||||
"extractionState" : "manual",
|
|
||||||
"localizations" : {
|
|
||||||
"en" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "Scroll"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hans" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "横纵滚动"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-Hant" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "橫縱捲動"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"zh-HK" : {
|
|
||||||
"stringUnit" : {
|
|
||||||
"state" : "translated",
|
|
||||||
"value" : "橫縱捲動"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Velocity-based right stick pad" : {
|
"Velocity-based right stick pad" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
"localizations" : {
|
"localizations" : {
|
||||||
@@ -17730,6 +18049,35 @@
|
|||||||
},
|
},
|
||||||
"Version %@" : {
|
"Version %@" : {
|
||||||
|
|
||||||
|
},
|
||||||
|
"verticalHorizontalScroll" : {
|
||||||
|
"extractionState" : "manual",
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Scroll"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hans" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "横纵滚动"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-Hant" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "橫縱捲動"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zh-HK" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "橫縱捲動"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Video" : {
|
"Video" : {
|
||||||
"extractionState" : "manual",
|
"extractionState" : "manual",
|
||||||
@@ -18514,4 +18862,4 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version" : "1.1"
|
"version" : "1.1"
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,9 @@ class HostCollectionViewController: UICollectionViewController, UICollectionView
|
|||||||
if let host = items[indexPath.item] as? TemporaryHost {
|
if let host = items[indexPath.item] as? TemporaryHost {
|
||||||
cell.configure(with: host)
|
cell.configure(with: host)
|
||||||
}
|
}
|
||||||
applyControllerNavigationHighlight(to: cell, highlighted: indexPath == controllerNavigationSelectedIndexPath)
|
if #available(iOS 13.0, *) {
|
||||||
|
applyControllerNavigationHighlight(to: cell, highlighted: indexPath == controllerNavigationSelectedIndexPath)
|
||||||
|
}
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,5 +62,6 @@
|
|||||||
- (void)setMagnifierViewportInteractionEnabled:(BOOL)enabled;
|
- (void)setMagnifierViewportInteractionEnabled:(BOOL)enabled;
|
||||||
- (void)resetMagnifierStreamViewWithAnimated:(BOOL)animated;
|
- (void)resetMagnifierStreamViewWithAnimated:(BOOL)animated;
|
||||||
- (void)returnToMainFrame;
|
- (void)returnToMainFrame;
|
||||||
|
- (void)bringUpToolboxMenu;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ import UIKit
|
|||||||
case more
|
case more
|
||||||
case navigationSettings
|
case navigationSettings
|
||||||
case exit
|
case exit
|
||||||
|
case shortcuts
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc public enum RadialMenuState:Int {
|
@objc public enum RadialMenuState:Int {
|
||||||
|
|||||||
@@ -221,4 +221,16 @@ public final class WidgetPickerViewController: UIViewController {
|
|||||||
hostViewController.setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
|
hostViewController.setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
|
||||||
hostViewController.setNeedsUpdateOfHomeIndicatorAutoHidden()
|
hostViewController.setNeedsUpdateOfHomeIndicatorAutoHidden()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func getNavigationElements() -> [ControllerNavigationElement] {
|
||||||
|
var elements: [ControllerNavigationElement] = []
|
||||||
|
elements.append(ControllerNavigationElement(control: ControllerNavigator.radialMenuButtonPosition == .left ? .rightStick : .leftStick, action: "focusNavigation"))
|
||||||
|
elements.append(ControllerNavigationElement(control: ControllerNavigator.radialMenuButtonPosition == .left ? .dpadRight : .a, action: "execute"))
|
||||||
|
elements.append(ControllerNavigationElement(control: ControllerNavigator.radialMenuButtonPosition == .left ? .dpadRight : .a, action: "doublePressPinExecute"))
|
||||||
|
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButtonPosition == .left ? .dpadUp : .y, action: "holdToReorder"))
|
||||||
|
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButtonPosition == .left ? .dpadUp : .y, action: "doublePressToDelete"))
|
||||||
|
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButtonPosition == .left ? .dpadLeft : .x, action: "addEntry"))
|
||||||
|
elements.append(ControllerNavigationElement(control: ControllerNavigator.radialMenuButtonPosition == .left ? .dpadDown : .b, action: "exit"))
|
||||||
|
return elements
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user