125 lines
4.9 KiB
Swift
Executable File
125 lines
4.9 KiB
Swift
Executable File
//
|
|
// ContentViewController.swift
|
|
// TagTunes
|
|
//
|
|
// Created by Kim Wittenburg on 21.01.16.
|
|
// Copyright © 2016 Kim Wittenburg. All rights reserved.
|
|
//
|
|
|
|
import Cocoa
|
|
import SearchAPI
|
|
|
|
/// A `ContentViewController` displays a set of `TagTunesItem`s. It is
|
|
/// responsible for allowing the user to associate `TagTunesTrack`s with
|
|
/// `TagTunesEntityItem`s.
|
|
///
|
|
/// The expected structure of the content view controller is a tree structure in
|
|
/// the following form:
|
|
///
|
|
/// 1. At the root level there are `TagTunesGroupItem`s (groups) and
|
|
/// `TagTunesEntityItem`s (entities).
|
|
/// 2. Groups can contain other entities (children).
|
|
/// 3. Entities can have tracks associated with them. A track should not be
|
|
/// associated with multiple entities.
|
|
public class ContentViewController: NSViewController {
|
|
|
|
override public func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ContentViewController.itemDidChangeState(_:)), name: TagTunesGroupItem.StateChangedNotificationName, object: nil)
|
|
}
|
|
|
|
/// Called when the `TagTunesGroupItem.StateChangedNotification` is posted.
|
|
private dynamic func itemDidChangeState(notification: NSNotification) {
|
|
if let item = notification.object as? TagTunesItem {
|
|
updateItem(item)
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
NSNotificationCenter.defaultCenter().removeObserver(self)
|
|
}
|
|
|
|
/// Returns all selected items. This property should remove duplicate items
|
|
/// from the selection following these three rules:
|
|
///
|
|
/// 1. If an entity is selected (and thus contained in the returned array)
|
|
/// none of its `associatedTracks` should be contained in the returned
|
|
/// array.
|
|
/// 2. If a group is selected none of its children should be contained in the
|
|
/// returned array.
|
|
/// 3. If a track is selected and (1) and (2) do not appy it should be
|
|
/// contained in the returned array.
|
|
///
|
|
/// This value is not cached. If you need to access this multiple times in a
|
|
/// row, you should consider caching it yourself in a local variable. The
|
|
/// order in which the selected objects occur in the returned array may be
|
|
/// different from the order in which they are displayed.
|
|
///
|
|
/// This method must be implemented by subclasses.
|
|
public var selectedItems: [AnyObject] {
|
|
fatalError("Must override property selectedItems")
|
|
}
|
|
|
|
/// Returns the item the user clicked on. This property should be used
|
|
/// instead of the `selectedItems` for any context menu related actions. This
|
|
/// property should behave the same way that `selectedItems` does.
|
|
///
|
|
/// This method must be implemented by subclasses.
|
|
public var clickedItems: [AnyObject] {
|
|
fatalError("Must override property clickedItem")
|
|
}
|
|
|
|
/// Returns the item that represents the specified `entity`. If no such item
|
|
/// exists in the content view controller `nil` is returned.
|
|
///
|
|
/// This method must be implemented by subclasses.
|
|
public func itemForEntity(entity: SearchAPIEntity) -> TagTunesItem? {
|
|
fatalError("Must override itemForEntity(_:)")
|
|
}
|
|
|
|
/// Adds the specified `item` to the view controller. This should insert the
|
|
/// `item` at the root level of the controller. If the controller already
|
|
/// contains an item that represents the same entity as the specified `item`
|
|
/// this method should do nothing.
|
|
///
|
|
/// This method must be implemented by subclasses.
|
|
public func addItem(item: TagTunesItem) {
|
|
fatalError("Must override addItem(_:)")
|
|
}
|
|
|
|
/// Updates the specified `item`. This method should be called if the
|
|
/// properties of the `item` changed in any way and the view should be
|
|
/// notified about it. If the `item` has not previously been added to the
|
|
/// view controller this method should do nothing.
|
|
///
|
|
/// This method must be implemented by subclasses.
|
|
public func updateItem(item: TagTunesItem) {
|
|
fatalError("Must override updateItem(_:)")
|
|
}
|
|
|
|
/// Updates all items. If many items in the view controller changed it may be
|
|
/// more efficient to use this method instead of `updateItem(_:)`.
|
|
///
|
|
/// This method must be implemented by subclasses.
|
|
public func updateAllItems() {
|
|
fatalError("Must override updateAllItems()")
|
|
}
|
|
|
|
/// Removes the selected items from the view controller. By default the
|
|
/// implementation just calls `removeItems(selectedItems` but subclasses may
|
|
/// override this method to optimize the behavior.
|
|
public func removeSelectedItems() {
|
|
removeItems(selectedItems)
|
|
}
|
|
|
|
/// Removes the specified items from the view controller and updates the view
|
|
/// accordingly.
|
|
///
|
|
/// This method must be implemented by subclasses.
|
|
public func removeItems(items: [AnyObject]) {
|
|
fatalError("Must override removeItems(_:)")
|
|
}
|
|
|
|
}
|