refactor toolboxView
This commit is contained in:
@@ -19,12 +19,14 @@ import UIKit
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
@objc public private(set) var identifier: String
|
||||
@objc var cmdString: String
|
||||
@objc var alias: String
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init(cmdString: String, alias: String) {
|
||||
self.identifier = UUID().uuidString
|
||||
self.cmdString = cmdString
|
||||
self.alias = alias
|
||||
}
|
||||
@@ -36,11 +38,13 @@ import UIKit
|
||||
let alias = coder.decodeObject(of: NSString.self, forKey: "alias") as String? else {
|
||||
return nil
|
||||
}
|
||||
self.identifier = coder.decodeObject(of: NSString.self, forKey: "identifier") as String? ?? UUID().uuidString
|
||||
self.cmdString = cmdString
|
||||
self.alias = alias
|
||||
}
|
||||
|
||||
public func encode(with coder: NSCoder) {
|
||||
coder.encode(identifier, forKey: "identifier")
|
||||
coder.encode(cmdString, forKey: "keyboardCmdString")
|
||||
coder.encode(alias, forKey: "alias")
|
||||
}
|
||||
@@ -50,6 +54,29 @@ import UIKit
|
||||
// Define the CommandManager class
|
||||
@objc public class CommandManager: NSObject {
|
||||
@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] = [
|
||||
"M_LEFT" : BUTTON_LEFT,
|
||||
@@ -463,17 +490,17 @@ import UIKit
|
||||
RemoteCommand(cmdString: "WIN", alias: "WIN"),
|
||||
RemoteCommand(cmdString: "F11", alias: "F11"),
|
||||
RemoteCommand(cmdString: "ESC", alias: "ESC"),
|
||||
RemoteCommand(cmdString: "CTRL+SHIFT+ESC", alias: "任务管理器(Task Manager)"),
|
||||
RemoteCommand(cmdString: "ALT+F1", alias: "N卡截图(Nvidia Screenshot)"),
|
||||
RemoteCommand(cmdString: "ALT+F9", alias: "N卡录屏(Nvidia Screen Recording)"),
|
||||
RemoteCommand(cmdString: "ALT+F4", alias: "关闭窗口(ALT+F4)"),
|
||||
RemoteCommand(cmdString: "CTRL+A", alias: "全选(Select All)"),
|
||||
RemoteCommand(cmdString: "CTRL+C", alias: "复制(Copy)"),
|
||||
RemoteCommand(cmdString: "CTRL+V", alias: "粘贴(Paste)"),
|
||||
RemoteCommand(cmdString: "WIN+D", alias: "切换桌面(Switch to Desktop)"),
|
||||
RemoteCommand(cmdString: "WIN+P", alias: "多显模式(Project)"),
|
||||
RemoteCommand(cmdString: "WIN+G", alias: "Xbox Game Bar"),
|
||||
RemoteCommand(cmdString: "SHIFT+TAB", alias: "Steam Overlay"),
|
||||
RemoteCommand(cmdString: "CTRL+SHIFT+ESC", alias: "=taskManager"),
|
||||
RemoteCommand(cmdString: "ALT+F1", alias: "=nvidiaShot"),
|
||||
RemoteCommand(cmdString: "ALT+F9", alias: "=nvidiaRec"),
|
||||
RemoteCommand(cmdString: "ALT+F4", alias: "=closeWindow"),
|
||||
RemoteCommand(cmdString: "CTRL+A", alias: "=selectAll"),
|
||||
RemoteCommand(cmdString: "CTRL+C", alias: "=copy"),
|
||||
RemoteCommand(cmdString: "CTRL+V", alias: "=paste"),
|
||||
RemoteCommand(cmdString: "WIN+D", alias: "=switchDesktop"),
|
||||
RemoteCommand(cmdString: "WIN+P", alias: "=projectDisplay"),
|
||||
RemoteCommand(cmdString: "WIN+G", alias: "=xboxGameBar"),
|
||||
RemoteCommand(cmdString: "SHIFT+TAB", alias: "=steamOverlay"),
|
||||
]
|
||||
|
||||
let data = try? NSKeyedArchiver.archivedData(withRootObject: defaultCommands, requiringSecureCoding: false)
|
||||
@@ -633,6 +660,29 @@ import UIKit
|
||||
@objc public func getAllCommands() -> [RemoteCommand] {
|
||||
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() {
|
||||
if let savedCommandsData = UserDefaults.standard.data(forKey: "savedCommands") {
|
||||
@@ -642,6 +692,7 @@ import UIKit
|
||||
// Assign the unarchived commands to your property
|
||||
print(" Assign the unarchived commands to your property ")
|
||||
commands = savedCommands
|
||||
migrateDefaultCommandAliasesIfNeeded()
|
||||
} else {
|
||||
// Handle the case where the data could not be unarchived into the expected type
|
||||
print("Data could not be unarchived into [RemoteCommand]")
|
||||
@@ -658,6 +709,21 @@ import UIKit
|
||||
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
|
||||
// 如果已处理完所有按键,则开始释放按键
|
||||
|
||||
@@ -23,6 +23,7 @@ final class ControllerNavigationElement: NSObject {
|
||||
|
||||
private var controllerNavigationSelectedIndexPathKey: UInt8 = 0
|
||||
private var controllerNavigationPersistTokenKey: UInt8 = 0
|
||||
private var controllerNavigationHighlightGenerationKey: UInt8 = 0
|
||||
private let settingsControllerNavigationHighlightedIdentifierKey = "SettingsControllerNavigationHighlightedIdentifier"
|
||||
private let hostControllerNavigationHighlightedUUIDKey = "HostControllerNavigationHighlightedUUID"
|
||||
|
||||
@@ -50,6 +51,27 @@ private final class ControllerMouseDisplayLinkTarget: NSObject {
|
||||
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, *)
|
||||
final class ControllerNavigator: NSObject {
|
||||
typealias Handler = (_ buttonDict: NSDictionary, _ gamepad: GCExtendedGamepad, _ element: GCControllerElement) -> Void
|
||||
@@ -416,7 +438,7 @@ final class ControllerNavigator: NSObject {
|
||||
mainFrameVC.hostCollectionVC?.clearCollectionControllerNavigationHighlightForControllerNavigator()
|
||||
} else {
|
||||
(uiNavigationDelegate as? SettingsViewController)?.clearControllerNavigationHighlightForControllerNavigator()
|
||||
(uiNavigationDelegate as? UICollectionViewController)?.clearCollectionControllerNavigationHighlightForControllerNavigator()
|
||||
(uiNavigationDelegate as? ControllerCollectionNavigationDelegate)?.clearCollectionControllerNavigationHighlightForControllerNavigator()
|
||||
}
|
||||
|
||||
controllerNavigationHighlightedView = nil
|
||||
@@ -486,6 +508,12 @@ final class ControllerNavigator: NSObject {
|
||||
}
|
||||
case .exit:
|
||||
exit(0)
|
||||
case .shortcuts:
|
||||
DispatchQueue.main.async {
|
||||
radialMenuView?.dismiss()
|
||||
radialMenuView = nil
|
||||
StreamFrameViewController.sharedInstance().bringUpToolboxMenu()
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -516,7 +544,7 @@ final class ControllerNavigator: NSObject {
|
||||
if radialMenuState == .moreOptions {
|
||||
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: "=shortcuts".localized, subtitle: "", symbol: "apple.terminal", item: .mouse))
|
||||
RadialMenuOverlayView.menuSectors.append(RadialMenuSector(title: "=shortcuts".localized, subtitle: "", symbol: "apple.terminal", item: .shortcuts))
|
||||
}
|
||||
else {
|
||||
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
|
||||
ControllerUtil.listenPrimaryControllerStickAxis(verticalNavigationAxis, threshold: 0.6) {state in
|
||||
GamepadNavigationIllustrationHud.updateActionState(for: verticalNavigationAxis, isInAction: state != .orderedSame)
|
||||
@@ -679,7 +707,7 @@ final class ControllerNavigator: NSObject {
|
||||
if uiNavigationDelegate is SettingsViewController {
|
||||
navigateContinuously(forward: true)
|
||||
}
|
||||
if uiNavigationDelegate is UICollectionViewController {
|
||||
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||
navigateContinuously(downward: true)
|
||||
}
|
||||
}
|
||||
@@ -688,7 +716,7 @@ final class ControllerNavigator: NSObject {
|
||||
if uiNavigationDelegate is SettingsViewController {
|
||||
navigateContinuously(forward: false)
|
||||
}
|
||||
if uiNavigationDelegate is UICollectionViewController {
|
||||
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||
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
|
||||
ControllerUtil.listenPrimaryControllerStickAxis(horizontalNavigationAxis, threshold: 0.6) {state in
|
||||
GamepadNavigationIllustrationHud.updateActionState(for: horizontalNavigationAxis, isInAction: state != .orderedSame)
|
||||
@@ -706,13 +734,13 @@ final class ControllerNavigator: NSObject {
|
||||
switch state {
|
||||
case .orderedAscending:
|
||||
if navigationTimer?.isRunning() != true {
|
||||
if uiNavigationDelegate is UICollectionViewController {
|
||||
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||
navigateContinuously(forward: false)
|
||||
}
|
||||
}
|
||||
case .orderedDescending:
|
||||
if navigationTimer?.isRunning() != true {
|
||||
if uiNavigationDelegate is UICollectionViewController {
|
||||
if uiNavigationDelegate is ControllerCollectionNavigationDelegate {
|
||||
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 buttonNavigations = navigations.filter({$0.control.type == .button})
|
||||
// let stickNavigations = navigations.filter({$0.control.type == .stick || $0.control.type == .stickAxis})
|
||||
@@ -764,7 +792,7 @@ final class ControllerNavigator: NSObject {
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
extension SettingsViewController: ControllerUINavigationDelegate {
|
||||
func persistControllerNavigationHighlight() {
|
||||
@objc func persistControllerNavigationHighlight() {
|
||||
guard let highlightedView = ControllerNavigator.controllerNavigationHighlightedView,
|
||||
let identifier = controllerNavigationPersistenceIdentifier(for: highlightedView) else {
|
||||
return
|
||||
@@ -773,20 +801,20 @@ extension SettingsViewController: ControllerUINavigationDelegate {
|
||||
UserDefaults.standard.set(identifier, forKey: settingsControllerNavigationHighlightedIdentifierKey)
|
||||
}
|
||||
|
||||
func restoreControllerNavigationHighlight() {
|
||||
@objc func restoreControllerNavigationHighlight() {
|
||||
guard ControllerNavigator.enabled, ControllerUtil.primaryGCController != nil else {return}
|
||||
PublicUtils.runOnMain { [weak self] in
|
||||
self?.restoreControllerNavigationHighlightOnMain()
|
||||
}
|
||||
}
|
||||
|
||||
func restoreControllerNavigationHighlightAfterSettingsModeSwitch() {
|
||||
@objc func restoreControllerNavigationHighlightAfterSettingsModeSwitch() {
|
||||
PublicUtils.runOnMain { [weak self] in
|
||||
self?.restoreControllerNavigationHighlightAfterSettingsModeSwitchOnMain()
|
||||
}
|
||||
}
|
||||
|
||||
func uiButtonActionForControllerNavigator(pressed: Bool, from navigation: ControllerNavigationElement) {
|
||||
@objc func uiButtonActionForControllerNavigator(pressed: Bool, from navigation: ControllerNavigationElement) {
|
||||
let isHighlightingUIStack = ControllerNavigator.controllerNavigationHighlightedView is UIStackView
|
||||
|
||||
if navigation.action == "holdToReorder", isHighlightingUIStack {
|
||||
@@ -1427,7 +1455,8 @@ extension SettingsViewController: ControllerUINavigationDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
extension UICollectionViewController {
|
||||
@available(iOS 13.0, *)
|
||||
extension ControllerCollectionNavigationDelegate {
|
||||
var controllerNavigationSelectedIndexPath: IndexPath? {
|
||||
get {
|
||||
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) {
|
||||
clearControllerNavigationHighlightBorder(in: cell)
|
||||
guard highlighted else { return }
|
||||
let highlightedView = controllerNavigationHighlightTargetView(for: cell)
|
||||
highlightedView.layer.borderWidth = (self is HostCollectionViewController) ? 3 : 5
|
||||
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) {
|
||||
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 {
|
||||
view.layer.borderWidth = 0
|
||||
view.layer.borderColor = nil
|
||||
@@ -1463,6 +1525,10 @@ extension UICollectionViewController {
|
||||
}
|
||||
|
||||
private func controllerNavigationHighlightTargetView(for cell: UICollectionViewCell) -> UIView {
|
||||
if let highlightProvider = cell as? ControllerNavigationHighlightTargetProviding {
|
||||
return highlightProvider.controllerNavigationHighlightTargetView
|
||||
}
|
||||
|
||||
if let contentView = controllerNavigationContentView(in: cell) {
|
||||
return contentView
|
||||
}
|
||||
@@ -1486,8 +1552,41 @@ extension UICollectionViewController {
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
func persistControllerNavigationHighlight() {
|
||||
extension UICollectionViewController: ControllerCollectionNavigationDelegate {
|
||||
@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 {
|
||||
persistHostControllerNavigationHighlight(in: hostCollectionVC)
|
||||
return
|
||||
@@ -1498,7 +1597,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func restoreControllerNavigationHighlight() {
|
||||
func controllerNavigationRestoreCollectionHighlight() {
|
||||
guard ControllerNavigator.enabled, ControllerUtil.primaryGCController != nil else {return}
|
||||
|
||||
PublicUtils.runOnMain { [weak self] in
|
||||
@@ -1515,18 +1614,15 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func restoreControllerNavigationHighlightAfterSettingsModeSwitch() {
|
||||
}
|
||||
|
||||
private func currentControllerNavigationCell() -> UICollectionViewCell? {
|
||||
guard let selectedIndexPath = controllerNavigationSelectedIndexPath,
|
||||
selectedIndexPath.section < collectionView.numberOfSections,
|
||||
selectedIndexPath.section < controllerNavigationCollectionView.numberOfSections,
|
||||
selectedIndexPath.item >= 0,
|
||||
selectedIndexPath.item < collectionView.numberOfItems(inSection: selectedIndexPath.section) else {
|
||||
selectedIndexPath.item < controllerNavigationCollectionView.numberOfItems(inSection: selectedIndexPath.section) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return collectionView.cellForItem(at: selectedIndexPath)
|
||||
return controllerNavigationCollectionView.cellForItem(at: selectedIndexPath)
|
||||
}
|
||||
|
||||
private func currentControllerNavigationContentView() -> UIView? {
|
||||
@@ -1534,7 +1630,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
return controllerNavigationContentView(in: cell)
|
||||
}
|
||||
|
||||
func uiButtonActionForControllerNavigator(pressed: Bool, from navigation: ControllerNavigationElement) {
|
||||
func controllerNavigationPerformDefaultButtonAction(pressed: Bool, from navigation: ControllerNavigationElement) {
|
||||
PublicUtils.runOnMain { [weak self] in
|
||||
guard let self else { return }
|
||||
|
||||
@@ -1570,10 +1666,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func uiWidgetActionForControllerNavigator(forward: Bool, from navigation: ControllerNavigationElement) {
|
||||
}
|
||||
|
||||
func getNavigationElements() -> [ControllerNavigationElement] {
|
||||
func controllerNavigationDefaultNavigationElements() -> [ControllerNavigationElement] {
|
||||
var elements: [ControllerNavigationElement] = []
|
||||
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButton, action: "radialMenu"))
|
||||
elements.append(ControllerNavigationElement(control:ControllerNavigator.radialMenuButtonPosition == .left ? .rightStick : .leftStick, action: "focusNavigation"))
|
||||
@@ -1584,13 +1677,13 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
return elements
|
||||
}
|
||||
|
||||
func navigateByController(forward: Bool) {
|
||||
func controllerNavigationNavigateCollection(forward: Bool) {
|
||||
guard hasNoPresentedVC else { return }
|
||||
performControllerNavigationSelectionMove(horizontalOffset: forward ? 1 : -1)
|
||||
scheduleControllerNavigationHighlightPersistenceWhenStickSettles()
|
||||
}
|
||||
|
||||
func navigateByController(downward: Bool) {
|
||||
func controllerNavigationNavigateCollection(downward: Bool) {
|
||||
guard hasNoPresentedVC else { return }
|
||||
performControllerNavigationSelectionMove(verticalOffset: downward ? 1 : -1)
|
||||
scheduleControllerNavigationHighlightPersistenceWhenStickSettles()
|
||||
@@ -1648,7 +1741,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
continue
|
||||
}
|
||||
|
||||
highlightControllerNavigationItem(at: IndexPath(item: index, section: 0))
|
||||
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: index, section: 0))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1674,7 +1767,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1682,13 +1775,13 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
}
|
||||
|
||||
private func restoreFirstControllerNavigationItemIfNeeded() {
|
||||
guard collectionView.numberOfSections > 0,
|
||||
collectionView.numberOfItems(inSection: 0) > 0 else {
|
||||
guard controllerNavigationCollectionView.numberOfSections > 0,
|
||||
controllerNavigationCollectionView.numberOfItems(inSection: 0) > 0 else {
|
||||
clearCollectionControllerNavigationHighlight()
|
||||
return
|
||||
}
|
||||
|
||||
highlightControllerNavigationItem(at: IndexPath(item: 0, section: 0))
|
||||
controllerNavigationHighlightItemForControllerNavigator(at: IndexPath(item: 0, section: 0))
|
||||
}
|
||||
|
||||
private func performControllerNavigationSelectionMove(horizontalOffset: Int) {
|
||||
@@ -1704,23 +1797,23 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
}
|
||||
|
||||
private func moveControllerNavigationSelection(horizontalOffset: Int) {
|
||||
let itemCount = collectionView.numberOfItems(inSection: 0)
|
||||
let itemCount = controllerNavigationCollectionView.numberOfItems(inSection: 0)
|
||||
guard itemCount > 0 else {
|
||||
clearCollectionControllerNavigationHighlight()
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
let itemCount = collectionView.numberOfItems(inSection: 0)
|
||||
let itemCount = controllerNavigationCollectionView.numberOfItems(inSection: 0)
|
||||
guard itemCount > 0 else {
|
||||
clearCollectionControllerNavigationHighlight()
|
||||
return
|
||||
@@ -1728,7 +1821,7 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
|
||||
guard let currentIndexPath = currentControllerNavigationIndexPath(),
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1767,65 +1860,77 @@ extension UICollectionViewController: ControllerUINavigationDelegate {
|
||||
}?.indexPath
|
||||
|
||||
if let nextIndexPath {
|
||||
highlightControllerNavigationItem(at: nextIndexPath)
|
||||
controllerNavigationHighlightItemForControllerNavigator(at: nextIndexPath)
|
||||
}
|
||||
}
|
||||
|
||||
private func currentControllerNavigationIndexPath() -> IndexPath? {
|
||||
if let selectedIndexPath = controllerNavigationSelectedIndexPath,
|
||||
selectedIndexPath.section < collectionView.numberOfSections,
|
||||
selectedIndexPath.item < collectionView.numberOfItems(inSection: selectedIndexPath.section) {
|
||||
selectedIndexPath.section < controllerNavigationCollectionView.numberOfSections,
|
||||
selectedIndexPath.item < controllerNavigationCollectionView.numberOfItems(inSection: selectedIndexPath.section) {
|
||||
return selectedIndexPath
|
||||
}
|
||||
|
||||
if let highlightedView = ControllerNavigator.controllerNavigationHighlightedView,
|
||||
let highlightedCell = collectionViewCell(containing: highlightedView),
|
||||
let indexPath = collectionView.indexPath(for: highlightedCell) {
|
||||
let indexPath = controllerNavigationCollectionView.indexPath(for: highlightedCell) {
|
||||
return indexPath
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
private func highlightControllerNavigationItem(at indexPath: IndexPath) {
|
||||
func controllerNavigationCurrentIndexPathForControllerNavigator() -> IndexPath? {
|
||||
currentControllerNavigationIndexPath()
|
||||
}
|
||||
|
||||
func controllerNavigationHighlightItemForControllerNavigator(at indexPath: IndexPath) {
|
||||
PublicUtils.runOnMain { [weak self] in
|
||||
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 < self.collectionView.numberOfItems(inSection: indexPath.section) else {
|
||||
indexPath.item < collectionView.numberOfItems(inSection: indexPath.section) else {
|
||||
self.clearCollectionControllerNavigationHighlight()
|
||||
return
|
||||
}
|
||||
|
||||
self.collectionView.layoutIfNeeded()
|
||||
collectionView.layoutIfNeeded()
|
||||
|
||||
let previousIndexPath = self.controllerNavigationSelectedIndexPath
|
||||
self.controllerNavigationHighlightGeneration += 1
|
||||
let highlightGeneration = self.controllerNavigationHighlightGeneration
|
||||
self.controllerNavigationSelectedIndexPath = indexPath
|
||||
|
||||
if let previousIndexPath,
|
||||
previousIndexPath != indexPath,
|
||||
let previousCell = self.collectionView.cellForItem(at: previousIndexPath) {
|
||||
let previousCell = collectionView.cellForItem(at: previousIndexPath) {
|
||||
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) {
|
||||
self.applyControllerNavigationHighlight(to: cell, highlighted: true)
|
||||
ControllerNavigator.controllerNavigationHighlightedView = self.controllerNavigationHighlightTargetView(for: cell)
|
||||
}
|
||||
private func applyControllerNavigationHighlightWhenCellIsReady(at indexPath: IndexPath, generation: Int, remainingAttempts: Int) {
|
||||
guard controllerNavigationSelectedIndexPath == indexPath,
|
||||
controllerNavigationHighlightGeneration == generation else { return }
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self,
|
||||
self.controllerNavigationSelectedIndexPath == indexPath,
|
||||
let cell = self.collectionView.cellForItem(at: indexPath) else {
|
||||
return
|
||||
}
|
||||
let collectionView = controllerNavigationCollectionView
|
||||
collectionView.layoutIfNeeded()
|
||||
|
||||
self.applyControllerNavigationHighlight(to: cell, highlighted: true)
|
||||
ControllerNavigator.controllerNavigationHighlightedView = self.controllerNavigationHighlightTargetView(for: cell)
|
||||
}
|
||||
if let cell = collectionView.cellForItem(at: indexPath) {
|
||||
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 }
|
||||
|
||||
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.controllerNavigationHighlightGeneration += 1
|
||||
self.controllerNavigationSelectedIndexPath = nil
|
||||
ControllerNavigator.controllerNavigationHighlightedView = nil
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func clearCollectionControllerNavigationHighlightForControllerNavigator() {
|
||||
func clearCollectionControllerNavigationHighlightForControllerNavigator() {
|
||||
clearCollectionControllerNavigationHighlight()
|
||||
}
|
||||
|
||||
func invalidateCollectionControllerNavigationHighlightForControllerNavigator() {
|
||||
controllerNavigationHighlightGeneration += 1
|
||||
controllerNavigationSelectedIndexPath = nil
|
||||
ControllerNavigator.controllerNavigationHighlightedView = nil
|
||||
}
|
||||
|
||||
private func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
collectionView.collectionViewLayout.layoutAttributesForItem(at: indexPath)
|
||||
controllerNavigationCollectionView.collectionViewLayout.layoutAttributesForItem(at: indexPath)
|
||||
}
|
||||
|
||||
private func collectionViewCell(containing view: UIView) -> UICollectionViewCell? {
|
||||
|
||||
@@ -866,7 +866,7 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Close"
|
||||
"value" : "Close Window"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
@@ -2519,25 +2519,25 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Nvidia Rec"
|
||||
"value" : "NVIDIA Recording"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "N卡录屏"
|
||||
"value" : "NVIDIA 录屏"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "N卡錄影"
|
||||
"value" : "NVIDIA 螢幕錄影"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "N卡錄影"
|
||||
"value" : "NVIDIA 螢幕錄影"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2548,25 +2548,25 @@
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Nvidia Shot"
|
||||
"value" : "NVIDIA Screenshot"
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "N卡截图"
|
||||
"value" : "NVIDIA 截图"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "N卡截圖"
|
||||
"value" : "NVIDIA 螢幕截圖"
|
||||
}
|
||||
},
|
||||
"zh-HK" : {
|
||||
"stringUnit" : {
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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." : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
"localizations" : {
|
||||
@@ -17730,6 +18049,35 @@
|
||||
},
|
||||
"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" : {
|
||||
"extractionState" : "manual",
|
||||
@@ -18514,4 +18862,4 @@
|
||||
}
|
||||
},
|
||||
"version" : "1.1"
|
||||
}
|
||||
}
|
||||
@@ -208,7 +208,9 @@ class HostCollectionViewController: UICollectionViewController, UICollectionView
|
||||
if let host = items[indexPath.item] as? TemporaryHost {
|
||||
cell.configure(with: host)
|
||||
}
|
||||
applyControllerNavigationHighlight(to: cell, highlighted: indexPath == controllerNavigationSelectedIndexPath)
|
||||
if #available(iOS 13.0, *) {
|
||||
applyControllerNavigationHighlight(to: cell, highlighted: indexPath == controllerNavigationSelectedIndexPath)
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
|
||||
@@ -62,5 +62,6 @@
|
||||
- (void)setMagnifierViewportInteractionEnabled:(BOOL)enabled;
|
||||
- (void)resetMagnifierStreamViewWithAnimated:(BOOL)animated;
|
||||
- (void)returnToMainFrame;
|
||||
- (void)bringUpToolboxMenu;
|
||||
|
||||
@end
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ import UIKit
|
||||
case more
|
||||
case navigationSettings
|
||||
case exit
|
||||
case shortcuts
|
||||
}
|
||||
|
||||
@objc public enum RadialMenuState:Int {
|
||||
|
||||
@@ -221,4 +221,16 @@ public final class WidgetPickerViewController: UIViewController {
|
||||
hostViewController.setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
|
||||
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