diff --git a/PlayTools/Controls/MenuController.swift b/PlayTools/Controls/MenuController.swift index cd1d37f5..dfbf00ce 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", @@ -222,7 +224,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 @@ -238,11 +239,43 @@ class MenuController { ) } - let arrowKeysGroup = UIMenu(title: "", - image: nil, - identifier: .keymappingOptionsMenu, - options: .displayInline, - children: arrowKeyChildrenCommands) + let rotationTitles = [ + "Landscape Left (0°)", + "Portrait (90°)", + "Landscape Right (180°)", + "Portrait Upside Down (270°)" + ] + let rotationInputs = ["1", "2", "3", "4"] + + // Every rotation item calls the *same selector*, passing its index in propertyList + let rotationMenuItems = rotationTitles.enumerated().map { (index, title) in + UIKeyCommand( + title: title, + image: nil, + action: #selector(UIApplication.rotateView(_:)), + input: rotationInputs[index], + 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: ""), @@ -258,4 +291,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 a45a24ab..df974a19 100644 --- a/PlayTools/PlayCover.swift +++ b/PlayTools/PlayCover.swift @@ -21,6 +21,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 d4d80ba4..fcc17b2d 100644 --- a/PlayTools/PlaySettings.swift +++ b/PlayTools/PlaySettings.swift @@ -86,6 +86,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 @@ -104,6 +106,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()