Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename "preference" to "settings" #90

Merged
merged 6 commits into from Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions Example/AdvancedPreferenceViewController.swift
Expand Up @@ -2,8 +2,8 @@ import Cocoa
import Preferences

final class AdvancedSettingsViewController: NSViewController, SettingsPane {
let preferencePaneIdentifier = Settings.PaneIdentifier.advanced
let preferencePaneTitle = "Advanced"
let paneIdentifier = Settings.PaneIdentifier.advanced
let paneTitle = "Advanced"
let toolbarItemIcon = NSImage(systemSymbolName: "gearshape.2", accessibilityDescription: "Advanced settings")!

@IBOutlet private var fontLabel: NSTextField!
Expand Down
6 changes: 3 additions & 3 deletions Example/AppDelegate.swift
Expand Up @@ -18,14 +18,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}
}

private lazy var settings: [SettingsPane] = [
private lazy var panes: [SettingsPane] = [
GeneralSettingsViewController(),
AccountsSettingsViewController(),
AdvancedSettingsViewController()
]

private lazy var settingsWindowController = SettingsWindowController(
preferencePanes: settings,
panes: panes,
style: settingsStyle,
animated: true,
hidesToolbarForSingleItem: true
Expand All @@ -36,7 +36,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
}

func applicationDidFinishLaunching(_ notification: Notification) {
settingsWindowController.show(preferencePane: .accounts)
settingsWindowController.show(pane: .accounts)
}

@IBAction private func settingsMenuItemActionHandler(_ sender: NSMenuItem) {
Expand Down
4 changes: 2 additions & 2 deletions Example/GeneralSettingsViewController.swift
Expand Up @@ -2,8 +2,8 @@ import Cocoa
import Preferences

final class GeneralSettingsViewController: NSViewController, SettingsPane {
let preferencePaneIdentifier = Settings.PaneIdentifier.general
let preferencePaneTitle = "General"
let paneIdentifier = Settings.PaneIdentifier.general
let paneTitle = "General"
let toolbarItemIcon = NSImage(systemSymbolName: "gearshape", accessibilityDescription: "General settings")!

override var nibName: NSNib.Name? { "GeneralSettingsViewController" }
Expand Down
12 changes: 6 additions & 6 deletions Sources/Preferences/Pane.swift
Expand Up @@ -9,7 +9,7 @@ public protocol SettingsPaneConvertible {
/**
Convert `self` to equivalent `SettingsPane`.
*/
func asPreferencePane() -> SettingsPane
func asSettingsPane() -> SettingsPane
}

@available(macOS 10.15, *)
Expand Down Expand Up @@ -39,7 +39,7 @@ extension Settings {

public var body: some View { content }

public func asPreferencePane() -> SettingsPane {
public func asSettingsPane() -> SettingsPane {
PaneHostingController(pane: self)
}
}
Expand All @@ -48,8 +48,8 @@ extension Settings {
Hosting controller enabling `Settings.Pane` to be used alongside AppKit `NSViewController`'s.
*/
public final class PaneHostingController<Content: View>: NSHostingController<Content>, SettingsPane {
public let preferencePaneIdentifier: PaneIdentifier
public let preferencePaneTitle: String
public let paneIdentifier: PaneIdentifier
public let paneTitle: String
public let toolbarItemIcon: NSImage

init(
Expand All @@ -58,8 +58,8 @@ extension Settings {
toolbarIcon: NSImage,
content: Content
) {
self.preferencePaneIdentifier = identifier
self.preferencePaneTitle = title
self.paneIdentifier = identifier
self.paneTitle = title
self.toolbarItemIcon = toolbarIcon
super.init(rootView: content)
}
Expand Down
12 changes: 6 additions & 6 deletions Sources/Preferences/SegmentedControlStyleViewController.swift
Expand Up @@ -54,7 +54,7 @@ final class SegmentedControlStyleViewController: NSViewController, SettingsStyle
var maxSize = CGSize.zero

for pane in panes {
let title = pane.preferencePaneTitle
let title = pane.paneTitle
let titleSize = title.size(
withAttributes: [
.font: NSFont.systemFont(ofSize: NSFont.systemFontSize(for: .regular))
Expand All @@ -79,7 +79,7 @@ final class SegmentedControlStyleViewController: NSViewController, SettingsStyle
segmentedControl.frame = CGRect(x: 0, y: 0, width: segmentWidth, height: segmentHeight)

for (index, pane) in panes.enumerated() {
segmentedControl.setLabel(pane.preferencePaneTitle, forSegment: index)
segmentedControl.setLabel(pane.paneTitle, forSegment: index)
segmentedControl.setWidth(segmentSize.width, forSegment: index)
if let cell = segmentedControl.cell as? NSSegmentedCell {
cell.setTag(index, forSegment: index)
Expand Down Expand Up @@ -114,12 +114,12 @@ final class SegmentedControlStyleViewController: NSViewController, SettingsStyle
// context menu that pops up at the right edge of the window.
let toolbarItemGroup = NSToolbarItemGroup(itemIdentifier: toolbarItemIdentifier)
toolbarItemGroup.view = segmentedControl
toolbarItemGroup.subitems = panes.enumerated().map { index, settingsPane in
let item = NSToolbarItem(itemIdentifier: .init("segment-\(settingsPane.preferencePaneTitle)"))
item.label = settingsPane.preferencePaneTitle
toolbarItemGroup.subitems = panes.enumerated().map { index, settingsPane -> NSToolbarItem in
let item = NSToolbarItem(itemIdentifier: .init("segment-\(settingsPane.paneTitle)"))
item.label = settingsPane.paneTitle

let menuItem = NSMenuItem(
title: settingsPane.preferencePaneTitle,
title: settingsPane.paneTitle,
action: #selector(segmentedControlMenuAction),
keyEquivalent: ""
)
Expand Down
28 changes: 28 additions & 0 deletions Sources/Preferences/Settings.swift
Expand Up @@ -5,7 +5,35 @@ public enum Settings {}

// TODO: Remove in the next major version.
// Preserve backwards compatibility.
@available(*, deprecated, renamed: "Settings")
DivineDominion marked this conversation as resolved.
Show resolved Hide resolved
public typealias Preferences = Settings
@available(*, deprecated, renamed: "SettingsPane")
public typealias PreferencePane = SettingsPane
@available(*, deprecated, renamed: "SettingsPaneConvertible")
public typealias PreferencePaneConvertible = SettingsPaneConvertible
@available(*, deprecated, renamed: "SettingsWindowController")
public typealias PreferencesWindowController = SettingsWindowController

@available(macOS 10.15, *)
extension Settings.Pane {
@available(*, deprecated, renamed: "asSettingsPane()")
public func asPreferencePane() -> PreferencePane {
asSettingsPane()
}
}

extension SettingsWindowController {
@available(*, deprecated, renamed: "init(panes:style:animated:hidesToolbarForSingleItem:)")
public convenience init(
preferencePanes: [PreferencePane],
style: Settings.Style = .toolbarItems,
animated: Bool = true,
hidesToolbarForSingleItem: Bool = true
) {
self.init(
panes: preferencePanes,
style: style,
animated: animated,
hidesToolbarForSingleItem: hidesToolbarForSingleItem)
}
}
6 changes: 3 additions & 3 deletions Sources/Preferences/SettingsPane.swift
Expand Up @@ -11,14 +11,14 @@ extension Settings {
}

public protocol SettingsPane: NSViewController {
var preferencePaneIdentifier: Settings.PaneIdentifier { get }
var preferencePaneTitle: String { get }
var paneIdentifier: Settings.PaneIdentifier { get }
var paneTitle: String { get }
var toolbarItemIcon: NSImage { get }
}

extension SettingsPane {
public var toolbarItemIdentifier: NSToolbarItem.Identifier {
preferencePaneIdentifier.toolbarItemIdentifier
paneIdentifier.toolbarItemIdentifier
}

public var toolbarItemIcon: NSImage { .empty }
Expand Down
4 changes: 2 additions & 2 deletions Sources/Preferences/SettingsTabViewController.swift
Expand Up @@ -57,7 +57,7 @@ final class SettingsTabViewController: NSViewController, SettingsStyleController
}

func activateTab(paneIdentifier: Settings.PaneIdentifier, animated: Bool) {
guard let index = (panes.firstIndex { $0.preferencePaneIdentifier == paneIdentifier }) else {
guard let index = (panes.firstIndex { $0.paneIdentifier == paneIdentifier }) else {
return activateTab(index: 0, animated: animated)
}

Expand Down Expand Up @@ -91,7 +91,7 @@ final class SettingsTabViewController: NSViewController, SettingsStyleController
private func updateWindowTitle(tabIndex: Int) {
window.title = {
if panes.count > 1 {
return panes[tabIndex].preferencePaneTitle
return panes[tabIndex].paneTitle
} else {
let settings: String
if #available(macOS 13, *) {
Expand Down
20 changes: 10 additions & 10 deletions Sources/Preferences/SettingsWindowController.swift
Expand Up @@ -26,15 +26,15 @@ public final class SettingsWindowController: NSWindowController {
}

public init(
preferencePanes: [SettingsPane],
panes: [SettingsPane],
style: Settings.Style = .toolbarItems,
animated: Bool = true,
hidesToolbarForSingleItem: Bool = true
) {
precondition(!preferencePanes.isEmpty, "You need to set at least one view controller")
precondition(!panes.isEmpty, "You need to set at least one pane")

let window = UserInteractionPausableWindow(
contentRect: preferencePanes[0].view.bounds,
contentRect: panes[0].view.bounds,
styleMask: [
.titled,
.closable
Expand All @@ -52,7 +52,7 @@ public final class SettingsWindowController: NSWindowController {
case .toolbarItems:
return .visible
case .segmentedControl:
return preferencePanes.count <= 1 ? .visible : .hidden
return panes.count <= 1 ? .visible : .hidden
}
}()

Expand All @@ -61,18 +61,18 @@ public final class SettingsWindowController: NSWindowController {
}

tabViewController.isAnimated = animated
tabViewController.configure(panes: preferencePanes, style: style)
tabViewController.configure(panes: panes, style: style)
updateToolbarVisibility()
}

@available(*, unavailable)
override public init(window: NSWindow?) {
fatalError("init(window:) is not supported, use init(preferences:style:animated:)")
fatalError("init(window:) is not supported, use init(panes:style:animated:hidesToolbarForSingleItem:)")
}

@available(*, unavailable)
public required init?(coder: NSCoder) {
fatalError("init(coder:) is not supported, use init(preferences:style:animated:)")
fatalError("init(coder:) is not supported, use init(panes:style:animated:hidesToolbarForSingleItem:hidesToolbarForSingleItem:)")
}


Expand All @@ -81,14 +81,14 @@ public final class SettingsWindowController: NSWindowController {

If you pass a `Settings.PaneIdentifier`, the window will activate the corresponding tab.

- Parameter preferencePane: Identifier of the settings pane to display, or `nil` to show the tab that was open when the user last closed the window.
- Parameter paneIdentifier: Identifier of the settings pane to display, or `nil` to show the tab that was open when the user last closed the window.

- Note: Unless you need to open a specific pane, prefer not to pass a parameter at all or `nil`.

- See `close()` to close the window again.
- See `showWindow(_:)` to show the window without the convenience of activating the app.
*/
public func show(preferencePane paneIdentifier: Settings.PaneIdentifier? = nil) {
public func show(pane paneIdentifier: Settings.PaneIdentifier? = nil) {
if let paneIdentifier {
tabViewController.activateTab(paneIdentifier: paneIdentifier, animated: false)
} else {
Expand Down Expand Up @@ -154,7 +154,7 @@ extension SettingsWindowController {
hidesToolbarForSingleItem: Bool = true
) {
self.init(
preferencePanes: panes.map { $0.asPreferencePane() },
panes: panes.map { $0.asSettingsPane() },
style: style,
animated: animated,
hidesToolbarForSingleItem: hidesToolbarForSingleItem
Expand Down
4 changes: 2 additions & 2 deletions Sources/Preferences/ToolbarItemStyleViewController.swift
Expand Up @@ -32,12 +32,12 @@ final class ToolbarItemStyleViewController: NSObject, SettingsStyleController {
}

func toolbarItem(paneIdentifier: Settings.PaneIdentifier) -> NSToolbarItem? {
guard let pane = (panes.first { $0.preferencePaneIdentifier == paneIdentifier }) else {
guard let pane = (panes.first { $0.paneIdentifier == paneIdentifier }) else {
preconditionFailure()
}

let toolbarItem = NSToolbarItem(itemIdentifier: paneIdentifier.toolbarItemIdentifier)
toolbarItem.label = pane.preferencePaneTitle
toolbarItem.label = pane.paneTitle
toolbarItem.image = pane.toolbarItemIcon
toolbarItem.target = self
toolbarItem.action = #selector(toolbarItemSelected)
Expand Down
26 changes: 13 additions & 13 deletions readme.md
Expand Up @@ -31,7 +31,7 @@ extension Settings.PaneIdentifier {
}
```

Second, create a couple of view controllers for the settings panes you want. The only difference from implementing a normal view controller is that you have to add the `SettingsPane` protocol and implement the `preferencePaneIdentifier`, `toolbarItemTitle`, and `toolbarItemIcon` properties, as shown below. You can leave out `toolbarItemIcon` if you're using the `.segmentedControl` style.
Second, create a couple of view controllers for the settings panes you want. The only difference from implementing a normal view controller is that you have to add the `SettingsPane` protocol and implement the `paneIdentifier`, `toolbarItemTitle`, and `toolbarItemIcon` properties, as shown below. You can leave out `toolbarItemIcon` if you're using the `.segmentedControl` style.

`GeneralSettingsViewController.swift`

Expand All @@ -40,8 +40,8 @@ import Cocoa
import Preferences

final class GeneralSettingsViewController: NSViewController, SettingsPane {
let preferencePaneIdentifier = Settings.PaneIdentifier.general
let preferencePaneTitle = "General"
let paneIdentifier = Settings.PaneIdentifier.general
let paneTitle = "General"
let toolbarItemIcon = NSImage(systemSymbolName: "gearshape", accessibilityDescription: "General settings")!

override var nibName: NSNib.Name? { "GeneralSettingsViewController" }
Expand All @@ -63,8 +63,8 @@ import Cocoa
import Preferences

final class AdvancedSettingsViewController: NSViewController, SettingsPane {
let preferencePaneIdentifier = Settings.PaneIdentifier.advanced
let preferencePaneTitle = "Advanced"
let paneIdentifier = Settings.PaneIdentifier.advanced
let paneTitle = "Advanced"
let toolbarItemIcon = NSImage(systemSymbolName: "gearshape.2", accessibilityDescription: "Advanced settings")!

override var nibName: NSNib.Name? { "AdvancedSettingsViewController" }
Expand Down Expand Up @@ -103,7 +103,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet private var window: NSWindow!

private lazy var settingsWindowController = SettingsWindowController(
preferencePanes: [
panes: [
GeneralSettingsViewController(),
AdvancedSettingsViewController()
]
Expand All @@ -125,7 +125,7 @@ When you create the `SettingsWindowController`, you can choose between the `NSTo
```swift
// …
private lazy var settingsWindowController = SettingsWindowController(
preferencePanes: [
panes: [
GeneralSettingsViewController(),
AdvancedSettingsViewController()
],
Expand Down Expand Up @@ -155,14 +155,14 @@ extension Settings {
}

public protocol SettingsPane: NSViewController {
var preferencePaneIdentifier: Settings.PaneIdentifier { get }
var preferencePaneTitle: String { get }
var paneIdentifier: Settings.PaneIdentifier { get }
var paneTitle: String { get }
var toolbarItemIcon: NSImage { get } // Not required when using the .`segmentedControl` style
}

public final class SettingsWindowController: NSWindowController {
init(
preferencePanes: [SettingsPane],
panes: [SettingsPane],
style: Settings.Style = .toolbarItems,
animated: Bool = true,
hidesToolbarForSingleItem: Bool = true
Expand All @@ -175,7 +175,7 @@ public final class SettingsWindowController: NSWindowController {
hidesToolbarForSingleItem: Bool = true
)

func show(preferencePane: Settings.PaneIdentifier? = nil)
func show(pane: Settings.PaneIdentifier? = nil)
}
```

Expand Down Expand Up @@ -260,7 +260,7 @@ let CustomViewSettingsPaneViewController: () -> SettingsPane = {
// …

private lazy var settingsWindowController = SettingsWindowController(
preferencePanes: [
panes: [
GeneralSettingsViewController(),
AdvancedSettingsViewController(),
CustomViewSettingsPaneViewController()
Expand Down Expand Up @@ -293,7 +293,7 @@ The `animated` parameter of `SettingsWindowController.init` has no effect on mac

The `SettingsWindowController` adheres to the [macOS Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/macos/app-architecture/preferences/) and uses this set of rules to determine the window title:

- **Multiple settings panes:** Uses the currently selected `preferencePaneTitle` as the window title. Localize your `preferencePaneTitle`s to get localized window titles.
- **Multiple settings panes:** Uses the currently selected `paneTitle` as the window title. Localize your `paneTitle`s to get localized window titles.
- **Single settings pane:** Sets the window title to `APPNAME Settings`. The app name is obtained from your app's bundle. You can localize its `Info.plist` to customize the title. The `Settings` part is taken from the "Settings…" menu item, see #12. The order of lookup for the app name from your bundle:
1. `CFBundleDisplayName`
2. `CFBundleName`
Expand Down