diff --git a/PlayTools/Controls/MenuController.swift b/PlayTools/Controls/MenuController.swift index f2c04383..6d734d1e 100644 --- a/PlayTools/Controls/MenuController.swift +++ b/PlayTools/Controls/MenuController.swift @@ -12,8 +12,8 @@ class RotateViewController: UIViewController { .landscapeLeft, .portrait, .landscapeRight, .portraitUpsideDown] static var orientationTraverser = 0 - static func rotate() { - orientationTraverser += 1 + static func rotate(deviceOrientation: Int) { + orientationTraverser = deviceOrientation } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { @@ -58,7 +58,10 @@ extension UIApplication { guard let windowScene = scene as? UIWindowScene else { continue } for window in windowScene.windows { guard let rootViewController = window.rootViewController else { continue } - rootViewController.rotateView(sender) + if let dict = sender.propertyList as? [String: Any], + let index = dict["rotationIndex"] as? Int { + rootViewController.rotateView(sender, deviceOrientation: index) + } } } @@ -114,8 +117,9 @@ extension UIApplication { extension UIViewController { @objc - func rotateView(_ sender: AnyObject) { - RotateViewController.rotate() + func rotateView(_ sender: AnyObject, deviceOrientation: Int) { + RotateViewController.rotate(deviceOrientation: deviceOrientation) + RotateViewController.orientationTraverser %= RotateViewController.orientationList.count let viewController = RotateViewController(nibName: nil, bundle: nil) self.present(viewController, animated: true) DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, execute: { @@ -137,8 +141,6 @@ var keymapping = [ value: "Upsize selected element", comment: ""), NSLocalizedString("menu.keymapping.downsizeElement", tableName: "Playtools", value: "Downsize selected element", comment: ""), - NSLocalizedString("menu.keymapping.rotateDisplay", tableName: "Playtools", - value: "Rotate display area", comment: ""), NSLocalizedString("menu.keymapping.toggleDebug", tableName: "Playtools", value: "Toggle Debug Overlay", comment: ""), NSLocalizedString("menu.keymapping.hide.pointer", tableName: "Playtools", @@ -233,7 +235,6 @@ class MenuController { UIKeyCommand.inputDelete, // Remove keymap element UIKeyCommand.inputUpArrow, // Increase keymap element size UIKeyCommand.inputDownArrow, // Decrease keymap element size - "R", // Rotate display "D", // Toggle debug overlay ".", // Hide cursor until move "[", // Previous keymap @@ -241,8 +242,7 @@ class MenuController { ] let arrowKeyChildrenCommands = zip(zip(keyCommands, keymapping), iconsSelctor).map { (arg0, image) in let (command, btn) = arg0 - return UIKeyCommand(title: btn, - image: image, + return UIKeyCommand(title: btn, image: image, action: keymappingSelectors[keymapping.firstIndex(of: btn)!], input: command, modifierFlags: .command, @@ -250,15 +250,37 @@ class MenuController { ) } - let arrowKeysGroup = UIMenu(title: "", - image: nil, - identifier: .keymappingOptionsMenu, - options: .displayInline, - children: arrowKeyChildrenCommands) + // Every rotation item calls the *same selector*, passing its index in propertyList + let rotationMenuItems = [ + "Landscape Left (0°)", "Portrait (90°)", "Landscape Right (180°)", "Portrait Upside Down (270°)" + ].enumerated().map { (index, title) in + UIKeyCommand( + title: title, image: nil, + action: #selector(UIApplication.rotateView(_:)), + input: "\(index + 1)", + modifierFlags: [.command, .shift], // ⌘⇧1–4 + propertyList: ["rotationIndex": index] + ) + } + + let rotationMenu = UIMenu( + title: NSLocalizedString("menu.keymapping.rotateDisplay", tableName: "Playtools", + value: "Rotate display area", comment: ""), image: nil, + identifier: .rotationOptionsMenu, + options: [], + children: rotationMenuItems + ) + + // Combine all menus + let arrowKeysGroup = UIMenu( + title: "", image: nil, + identifier: .keymappingOptionsMenu, + options: .displayInline, + children: arrowKeyChildrenCommands + [rotationMenu] + ) return UIMenu(title: NSLocalizedString("menu.keymapping", tableName: "Playtools", - value: "Keymapping", comment: ""), - image: nil, + value: "Keymapping", comment: ""), image: nil, identifier: .keymappingMenu, options: [], children: [arrowKeysGroup]) @@ -270,4 +292,5 @@ extension UIMenu.Identifier { static var keymappingOptionsMenu: UIMenu.Identifier { UIMenu.Identifier("io.playcover.PlayTools.menus.keymapping") } static var debuggingMenu: UIMenu.Identifier { UIMenu.Identifier("io.playcover.PlayTools.menus.debug") } static var debuggingOptionsMenu: UIMenu.Identifier { UIMenu.Identifier("io.playcover.PlayTools.menus.debugging") } + static var rotationOptionsMenu: UIMenu.Identifier { UIMenu.Identifier("io.playcover.PlayTools.menus.rotation") } } diff --git a/PlayTools/PlayCover.swift b/PlayTools/PlayCover.swift index be768a0e..2040dab3 100644 --- a/PlayTools/PlayCover.swift +++ b/PlayTools/PlayCover.swift @@ -22,6 +22,25 @@ public class PlayCover: NSObject { // Change the working directory to / just like iOS FileManager.default.changeCurrentDirectoryPath("/") } + + if PlaySettings.shared.displayRotation != 0 { + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5, execute: { + let rotateCommand = UIKeyCommand( + title: "Keep Rotation Command", + image: nil, + action: #selector(UIApplication.rotateView(_:)), + input: "", + modifierFlags: [], + propertyList: ["rotationIndex": PlaySettings.shared.displayRotation] + ) + UIApplication.shared.sendAction( + #selector(UIApplication.rotateView(_:)), + to: UIApplication.shared, + from: rotateCommand, + for: nil + ) + }) + } } @objc static public func initMenu(menu: NSObject) { diff --git a/PlayTools/PlaySettings.swift b/PlayTools/PlaySettings.swift index c20d6d32..b034a1f4 100644 --- a/PlayTools/PlaySettings.swift +++ b/PlayTools/PlaySettings.swift @@ -88,6 +88,8 @@ let settings = PlaySettings.shared @objc lazy var floatingWindow = settingsData.floatingWindow + @objc lazy var displayRotation = settingsData.displayRotation + @objc lazy var checkMicPermissionSync = settingsData.checkMicPermissionSync @objc lazy var limitMotionUpdateFrequency = settingsData.limitMotionUpdateFrequency @@ -108,6 +110,7 @@ struct AppSettingsData: Codable { var customScaler = 2.0 var resolution = 2 var aspectRatio = 1 + var displayRotation = 0 var notch = false var bypass = false var discordActivity = DiscordActivity()