Skip to content

Commit

Permalink
macOS: rework window menu
Browse files Browse the repository at this point in the history
  • Loading branch information
BLeeEZ committed Nov 27, 2024
1 parent 084f127 commit 44dd052
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 30 deletions.
82 changes: 58 additions & 24 deletions Amperfy/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return nil
}

#if targetEnvironment(macCatalyst)
var isMainOrMiniPlayerPlayerOpen: Bool {
return isMainWindowOpen || isShowingMiniPlayer
}

var isMainWindowOpen: Bool {
return !UIApplication.shared.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.filter { ($0.rootViewController as? SplitVC) != nil }
.isEmpty
}

func closeMainWindow() {
// Close all main sessions (this might be more than one with multiple tabs open)
UIApplication.shared.connectedScenes
Expand All @@ -395,25 +407,60 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
let defaultActivity = NSUserActivity(activityType: defaultWindowActivityType)
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: defaultActivity, options: nil, errorHandler: nil)
}

#if targetEnvironment(macCatalyst)

public func rebuildMainMenu() {
UIMenuSystem.main.setNeedsRebuild()
}

override func buildMenu(with builder: any UIMenuBuilder) {
super.buildMenu(with: builder)

guard builder.system == .main else { return }

// Add a settings menu
let settingsMenu = UIMenu(options: .displayInline, children: [
UIKeyCommand(title: "Settings…", action: #selector(showSettings), input: ",", modifierFlags: .command)
// Add File menu
let fileMenu = UIMenu(title: "File", children: [
UIMenu(options: .displayInline, children: [
UIAction(title: "Open Player Window", attributes: self.isMainOrMiniPlayerPlayerOpen ? .disabled : []) { _ in
self.openMainWindow()
},
UIAction(title: "Close Player Window", attributes: !self.isMainOrMiniPlayerPlayerOpen ? .disabled : []) { _ in
if self.isMainWindowOpen {
self.closeMainWindow()
} else if self.isShowingMiniPlayer {
self.closeMiniPlayer()
}
}
]),
UIMenu(options: .displayInline, children: [
UIAction(title: "Switch Library/Mini Player") { _ in
if self.isShowingMiniPlayer {
self.closeMiniPlayer()
self.openMainWindow()
} else {
self.closeMainWindow()
self.showMiniPlayer()
}
}
]),
// Add a settings menu
UIMenu(options: .displayInline, children: [
UIKeyCommand(title: "Open Settings", action: #selector(showSettings), input: ",", modifierFlags: .command)
])
])
builder.insertSibling(settingsMenu, afterMenu: .about)
builder.insertSibling(fileMenu, beforeMenu: .view)

// Add media controls
builder.insertSibling(buildControlsMenu(), afterMenu: .view)

// Remove "new window" and toolbar options
// Remove not needed default menu items
builder.remove(menu: .toolbar)
builder.remove(menu: .newScene)
builder.remove(menu: .file)
builder.remove(menu: .edit)
builder.remove(menu: .format)
builder.remove(menu: .font)
builder.remove(menu: .text)
builder.remove(menu: .services)
builder.remove(menu: .help)

if (self.focusedWindowTitle == windowSettingsTitle) || (self.focusedWindowTitle == windowMiniPlayerTitle) {
// Do any settings specific menu setup here
Expand Down Expand Up @@ -499,25 +546,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
}

let section3 = [
UIAction(title: self.player.playerMode.nextMode.description) { _ in
UIAction(title: "Switch Music/Podcast mode") { _ in
self.player.setPlayerMode(self.player.playerMode.nextMode)
}
]

let section4 = [
UIAction(title: self.isShowingMiniPlayer ? "Main Window" : "Mini Player") { _ in
if self.isShowingMiniPlayer {
self.closeMiniPlayer()
// Is automatically opened
//self.openMainWindow()
} else {
self.closeMainWindow()
self.showMiniPlayer()
}
}
]

let sections: [[UIMenuElement]] = [section1, section2, section3, section4]
let sections: [[UIMenuElement]] = [section1, section2, section3]

return UIMenu(title: "Controls", children: sections.reduce([], { (result, section) in
result + [UIMenu(options: .displayInline)] + section
Expand Down Expand Up @@ -547,7 +581,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
UIApplication.shared.requestSceneSessionDestruction($0.session, options: options, errorHandler: nil)
}
}
#endif
#endif
}

#if targetEnvironment(macCatalyst)
Expand Down
16 changes: 10 additions & 6 deletions Amperfy/MiniPlayerSceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ class MiniPlayerSceneDelegate: UIResponder, UIWindowSceneDelegate {
self.window = UIWindow(windowScene: windowScene)
self.window?.backgroundColor = .secondarySystemBackground

#if targetEnvironment(macCatalyst)

#if targetEnvironment(macCatalyst)
windowScene.title = windowMiniPlayerTitle

if let titleBar = windowScene.titlebar {
Expand All @@ -73,13 +72,14 @@ class MiniPlayerSceneDelegate: UIResponder, UIWindowSceneDelegate {
windowScene.sizeRestrictions?.allowsFullScreen = false
}
windowScene.sizeRestrictions?.minimumSize = minSize

#endif
#endif

self.window?.rootViewController = PopupPlayerVC()
self.window?.makeKeyAndVisible()

#if targetEnvironment(macCatalyst)
self.appDelegate.closeMainWindow()
#endif
}

/** Called when the user activates your application by selecting a shortcut on the Home Screen,
Expand All @@ -98,14 +98,18 @@ class MiniPlayerSceneDelegate: UIResponder, UIWindowSceneDelegate {
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
os_log("MiniPlayer: sceneDidDisconnect", log: self.log, type: .info)

self.appDelegate.openMainWindow()
#if targetEnvironment(macCatalyst)
appDelegate.rebuildMainMenu()
#endif
}

func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
os_log("MiniPlayer: sceneDidBecomeActive", log: self.log, type: .info)
#if targetEnvironment(macCatalyst)
appDelegate.rebuildMainMenu()
#endif
}

func sceneWillResignActive(_ scene: UIScene) {
Expand Down
6 changes: 6 additions & 0 deletions Amperfy/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,19 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead).
os_log("sceneDidDisconnect", log: self.log, type: .info)
#if targetEnvironment(macCatalyst)
appDelegate.rebuildMainMenu()
#endif
}

func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
os_log("sceneDidBecomeActive", log: self.log, type: .info)
appDelegate.quickActionsManager.handleSavedShortCutItemIfSaved()
#if targetEnvironment(macCatalyst)
appDelegate.rebuildMainMenu()
#endif
}

func sceneWillResignActive(_ scene: UIScene) {
Expand Down

0 comments on commit 44dd052

Please sign in to comment.