From 1711cb4c9061861fccb7c2c7d7e1a4ed2afdc6f0 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Thu, 6 Oct 2022 20:42:34 +0800 Subject: [PATCH] Removes the need for AboutView and Notifications - Subclassed NSHostingController manages the tab bar to keep things tidy. --- Mac/AppDelegate.swift | 8 +- .../About/AboutNetNewsWireView.swift | 1 + Mac/MainWindow/About/AboutView.swift | 46 --------- .../About/AboutWindowController.swift | 95 ++++++++++++------- NetNewsWire.xcodeproj/project.pbxproj | 6 +- 5 files changed, 67 insertions(+), 89 deletions(-) delete mode 100644 Mac/MainWindow/About/AboutView.swift diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 0c4c8d413..111585f6d 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -729,16 +729,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, return } } - AboutWindowController.default.window?.makeKeyAndOrderFront(nil) + let controller = AboutWindowController() + controller.window?.makeKeyAndOrderFront(nil) } else { NSApplication.shared.orderFrontStandardAboutPanel(self) } } - - @objc - func segmentedControlSelectionChanged(_ sender: NSSegmentedControl) { - NotificationCenter.default.post(name: .AboutSelectionDidChange, object: sender.selectedSegment) - } } diff --git a/Mac/MainWindow/About/AboutNetNewsWireView.swift b/Mac/MainWindow/About/AboutNetNewsWireView.swift index ee10463a0..94937cc85 100644 --- a/Mac/MainWindow/About/AboutNetNewsWireView.swift +++ b/Mac/MainWindow/About/AboutNetNewsWireView.swift @@ -43,6 +43,7 @@ struct AboutNetNewsWireView: View { Spacer() } .multilineTextAlignment(.center) + .frame(width: 400, height: 400) } } diff --git a/Mac/MainWindow/About/AboutView.swift b/Mac/MainWindow/About/AboutView.swift deleted file mode 100644 index 1ec8808ae..000000000 --- a/Mac/MainWindow/About/AboutView.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// AboutView.swift -// NetNewsWire -// -// Created by Stuart Breckenridge on 03/10/2022. -// Copyright © 2022 Ranchero Software. All rights reserved. -// - -import SwiftUI - -public extension Notification.Name { - static let AboutSelectionDidChange = Notification.Name(rawValue: "AboutSelectionDidChange") -} - -@available(macOS 12, *) -struct AboutView: View { - - enum AboutSelection: Int { - case about = 0 - case credits = 1 - } - - @State private var selection: AboutSelection = .about - - var body: some View { - VStack { - if selection == .about { - AboutNetNewsWireView() - } else { - CreditsNetNewsWireView() - } - } - .onReceive(NotificationCenter.default.publisher(for: .AboutSelectionDidChange)) { newSelection in - selection = AboutSelection(rawValue: newSelection.object as! Int)! - } - .frame(width: 400, height: 400) - } -} - - -@available(macOS 12, *) -struct AboutView_Previews: PreviewProvider { - static var previews: some View { - AboutView() - } -} diff --git a/Mac/MainWindow/About/AboutWindowController.swift b/Mac/MainWindow/About/AboutWindowController.swift index 6a32fe98d..233e1743a 100644 --- a/Mac/MainWindow/About/AboutWindowController.swift +++ b/Mac/MainWindow/About/AboutWindowController.swift @@ -18,63 +18,81 @@ extension NSUserInterfaceItemIdentifier { static let aboutNetNewsWire = NSUserInterfaceItemIdentifier("about.netnewswire") } +// MARK: - AboutWindowController + @available(macOS 12, *) class AboutWindowController: NSWindowController, NSToolbarDelegate { - static var `default`: AboutWindowController { - let hostingController = NSHostingController(rootView: AboutView()) + var hostingController: AboutHostingController + + override init(window: NSWindow?) { + self.hostingController = AboutHostingController(rootView: AnyView(AboutNetNewsWireView())) + super.init(window: window) let window = NSWindow(contentViewController: hostingController) window.identifier = .aboutNetNewsWire - let controller = AboutWindowController(window: window) - controller.configure() - return controller + window.standardWindowButton(.zoomButton)?.isEnabled = false + window.titleVisibility = .hidden + self.window = window + self.hostingController.configureToolbar() } - func configure() { - window?.title = NSLocalizedString("About", comment: "About") - window?.titleVisibility = .hidden - let toolbar = NSToolbar(identifier: NSToolbar.Identifier("netnewswire.about.toolbar")) - toolbar.delegate = self - window?.toolbar = toolbar - window?.toolbarStyle = .unified - toolbar.insertItem(withItemIdentifier: .flexibleSpace, at: 0) - toolbar.insertItem(withItemIdentifier: .flexibleSpace, at: 2) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") } override func windowDidLoad() { super.windowDidLoad() } - @objc - func segmentedControlSelectionChanged(_ sender: NSSegmentedControl) { - print(sender) +} + +// MARK: - AboutHostingController + +@available(macOS 12, *) +class AboutHostingController: NSHostingController, NSToolbarDelegate { + + private lazy var segmentedControl: NSSegmentedControl = { + let control = NSSegmentedControl(labels: ["About", "Credits"], + trackingMode: .selectOne, + target: self, + action: #selector(segmentedControlSelectionChanged(_:))) + control.segmentCount = 2 + control.setSelected(true, forSegment: 0) + return control + }() + + override init(rootView: AnyView) { + super.init(rootView: rootView) } + @MainActor required dynamic init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public func configureToolbar() { + let toolbar = NSToolbar(identifier: NSToolbar.Identifier("netnewswire.about.toolbar")) + toolbar.delegate = self + toolbar.autosavesConfiguration = false + toolbar.allowsUserCustomization = false + view.window?.toolbar = toolbar + view.window?.toolbarStyle = .unified + toolbar.insertItem(withItemIdentifier: .flexibleSpace, at: 0) + toolbar.insertItem(withItemIdentifier: .flexibleSpace, at: 2) + } // MARK: NSToolbarDelegate func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? { - switch itemIdentifier { case .aboutGroup: - let toolbarItem: NSToolbarItem - let group = NSToolbarItemGroup(itemIdentifier: itemIdentifier) - - let segmented = NSSegmentedControl(labels: ["About", "Credits"], - trackingMode: .selectOne, - target: NSApplication.shared.delegate as? AppDelegate, - action: #selector(AppDelegate.segmentedControlSelectionChanged(_:))) - segmented.segmentStyle = .texturedRounded - segmented.segmentCount = 2 - segmented.setSelected(true, forSegment: 0) - group.view = segmented - toolbarItem = group + var toolbarItem = NSToolbarItem(itemIdentifier: .aboutGroup) + toolbarItem.view = segmentedControl + toolbarItem.autovalidates = true return toolbarItem default: return nil } - } func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { @@ -94,8 +112,21 @@ class AboutWindowController: NSWindowController, NSToolbarDelegate { } func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { - return [.aboutGroup] + return [] } + // MARK: - Target/Action + @objc + func segmentedControlSelectionChanged(_ sender: NSSegmentedControl) { + print(#function) + if sender.selectedSegment == 0 { + rootView = AnyView(AboutNetNewsWireView()) + } else { + rootView = AnyView(CreditsNetNewsWireView()) + } + } } + + + diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 211e9fa26..925f0464a 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -851,7 +851,6 @@ DF5AD10128D6922200CA3BF7 /* SmartFeedSummaryWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1768144D2564BCE000D98635 /* SmartFeedSummaryWidget.swift */; }; DF790D6028E9769300455FC7 /* Thanks.md in Resources */ = {isa = PBXBuildFile; fileRef = DF790D5F28E9769300455FC7 /* Thanks.md */; }; DF790D6228E990A900455FC7 /* AboutData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF790D6128E990A900455FC7 /* AboutData.swift */; }; - DFC14F0D28EA520E00F6EE86 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC14F0C28EA520E00F6EE86 /* AboutView.swift */; }; DFC14F0F28EA55BD00F6EE86 /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */; }; DFC14F1028EA5D7C00F6EE86 /* Thanks.md in Resources */ = {isa = PBXBuildFile; fileRef = DF790D5F28E9769300455FC7 /* Thanks.md */; }; DFC14F1128EA5D7C00F6EE86 /* About.plist in Resources */ = {isa = PBXBuildFile; fileRef = DFFC4E7528E95F78006B82AF /* About.plist */; }; @@ -1599,7 +1598,6 @@ DD82AB09231003F6002269DF /* SharingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharingTests.swift; sourceTree = ""; }; DF790D5F28E9769300455FC7 /* Thanks.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Thanks.md; sourceTree = ""; }; DF790D6128E990A900455FC7 /* AboutData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutData.swift; sourceTree = ""; }; - DFC14F0C28EA520E00F6EE86 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = ""; }; DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = ""; }; DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutNetNewsWireView.swift; sourceTree = ""; }; DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditsNetNewsWireView.swift; sourceTree = ""; }; @@ -2889,10 +2887,9 @@ DFC14F0928EA51AB00F6EE86 /* About */ = { isa = PBXGroup; children = ( - DFC14F0C28EA520E00F6EE86 /* AboutView.swift */, + DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */, DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */, DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */, - DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */, ); path = About; sourceTree = ""; @@ -4343,7 +4340,6 @@ 84DEE56522C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */, 845213231FCA5B11003B6E93 /* ImageDownloader.swift in Sources */, 51FA73B72332D5F70090D516 /* LegacyArticleExtractorButton.swift in Sources */, - DFC14F0D28EA520E00F6EE86 /* AboutView.swift in Sources */, 849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */, 8405DDA522168C62008CE1BF /* TimelineContainerViewController.swift in Sources */, 844B5B671FEA18E300C7C76A /* MainWIndowKeyboardHandler.swift in Sources */,