Skip to content

Instantly share code, notes, and snippets.

@Dev1an
Created January 25, 2019 14:16
Show Gist options
  • Select an option

  • Save Dev1an/30f480e086fcb1e14126b687fb352e4b to your computer and use it in GitHub Desktop.

Select an option

Save Dev1an/30f480e086fcb1e14126b687fb352e4b to your computer and use it in GitHub Desktop.
//
// Created by Damiaan on 25/01/2019.
// Copyright © 2019 Devian. All rights reserved.
//
import AppKit
class PopUpButton<Element>: NSPopUpButton {
var items: SmartCollection<Element> { didSet {bindSmartCollection()} }
var titleSpecifier: (Element) -> String
required init?(coder: NSCoder) {
items = SmartCollection()
titleSpecifier = {return String(describing: $0)}
super.init(coder: coder)
bindSmartCollection()
}
func bindSmartCollection() {
func addItem(for element: Element) {
super.addItem(withTitle: self.titleSpecifier(element))
}
super.removeAllItems()
items.forEach(addItem)
items.postReplaceSubscriptions.append { range, elements in
for index in range.reversed() {
super.removeItem(at: index)
}
elements.forEach(addItem)
}
items.postFieldChangeSubscriptions.append { index, _ in
self.item(at: index)?.title = self.titleSpecifier(self.items[index])
}
}
override func addItem(withTitle title: String) {
fatalError("use items to add or remove items")
}
override func addItems(withTitles itemTitles: [String]) {
addItem(withTitle: "")
}
override func insertItem(withTitle title: String, at index: Int) {
addItem(withTitle: "")
}
override func removeItem(at index: Int) {
items.remove(at: index)
}
override func removeAllItems() {
items.removeAll()
}
override func removeItem(withTitle title: String) {
let indicesToRemove = items.indices.filter {titleSpecifier(items[$0]) == title}
for index in indicesToRemove { items.remove(at: index) }
}
var selectedElement: Element? {
return indexOfSelectedItem == -1 ? nil : items[indexOfSelectedItem]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment