Files

165 lines
5.1 KiB
Swift

//
// MainViewController.swift
// DetachablePopover
//
// Created by Lukas Kubanek on 25.10.2014.
// Copyright (c) 2014 Lukas Kubanek. All rights reserved.
//
import AppKit
class MainViewController: NSViewController, NSPopoverDelegate {
// MARK: - Outlets
@IBOutlet weak var appearanceSelection: NSMatrix!
@IBOutlet weak var positionSelection: NSMatrix!
@IBOutlet weak var windowTypeSelection: NSMatrix!
@IBOutlet weak var showButton: NSButton!
@IBOutlet weak var hideButton: NSButton!
@IBOutlet weak var detachButton: NSButton!
// MARK: - Popover and Detached Window Controller
lazy var popover: NSPopover = {
let popover = NSPopover()
popover.behavior = .semitransient
popover.contentViewController = ContentViewController()
popover.delegate = self
return popover
}()
private var detachedWindowControllerLoaded = false
lazy var detachedWindowController: DetachedWindowController = {
let detachedWindowController = DetachedWindowController(windowNibName: NSNib.Name(rawValue: "DetachedWindowController"))
detachedWindowController.contentViewController = ContentViewController()
self.detachedWindowControllerLoaded = true
NotificationCenter.default.addObserver(self, selector: #selector(detachedWindowWillClose(notification:)), name: NSWindow.willCloseNotification, object: detachedWindowController.window)
return detachedWindowController
}()
// MARK: - Actions
@IBAction func show(sender: NSButton) {
if (customDetachedWindowVisible) {
detachedWindowController.window?.makeKeyAndOrderFront(nil)
} else {
popover.appearance = appearanceForSelectedRadioButton(radioButton: appearanceSelection.selectedRow)
let positioningView = sender
let positioningRect = NSZeroRect
let preferredEdge = preferredEdgeForSelectedRadioButton(radioButton: positionSelection.selectedRow)
popover.show(relativeTo: positioningRect, of: positioningView, preferredEdge: preferredEdge)
}
}
@IBAction func hide(sender: NSButton) {
if (popoverVisible) {
popover.performClose(nil)
} else if (customDetachedWindowVisible) {
detachedWindowController.close()
}
}
@IBAction func detach(_ sender: NSButton) {
let window = detachableWindow(for: popover)
window?.windowController?.showWindow(self)
}
// MARK: - Popover Delegate
func popoverShouldDetach(_ popover: NSPopover) -> Bool {
return true
}
func detachableWindow(for popover: NSPopover) -> NSWindow? {
disableDetachButton()
return customWindowSelected ? detachedWindowController.window : nil
}
func popoverDidShow(_ notification: Notification) {
enableHideButton()
if customWindowSelected {
enableDetachButton()
}
}
func popoverDidClose(_ notification: Notification) {
let closeReason = notification.userInfo![NSPopover.closeReasonUserInfoKey] as! String
if (closeReason == NSPopover.CloseReason.standard.rawValue) {
disableHideButton()
disableDetachButton()
}
}
// MARK: - Notifications Handling
@objc func detachedWindowWillClose(notification: NSNotification) {
disableHideButton()
}
// MARK: - Helpers
private var popoverVisible: Bool {
get { return popover.isShown }
}
private var customDetachedWindowVisible : Bool {
get { return detachedWindowControllerLoaded && detachedWindowController.window!.isVisible }
}
private var customWindowSelected : Bool {
get { return (windowTypeSelection.selectedRow == 1) }
}
private func enableHideButton() {
hideButton.isEnabled = true
}
private func disableHideButton() {
hideButton.isEnabled = false
}
private func enableDetachButton() {
detachButton.isEnabled = true
}
private func disableDetachButton() {
detachButton.isEnabled = false
}
private func appearanceForSelectedRadioButton(radioButton: Int) -> NSAppearance {
switch radioButton {
case 0: return NSAppearance(named: NSAppearance.Name.aqua)!
case 1: return NSAppearance(named: NSAppearance.Name.vibrantDark)!
case 2: return NSAppearance(named: NSAppearance.Name.vibrantLight)!
default: fatalError("Unsupported appearence selected")
}
}
private func preferredEdgeForSelectedRadioButton(radioButton: Int) -> NSRectEdge {
switch radioButton {
case 0: return .maxX
case 1: return .maxY
case 2: return .minX
case 3: return .minY
default: fatalError("Unsupported preferred edge selected")
}
}
// MARK: - Deinitialization
deinit {
if (detachedWindowControllerLoaded) {
NotificationCenter.default.removeObserver(self)
}
}
}