1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-22 13:11:55 +03:00
vimr/VimR/PrefWindowComponent.swift

180 lines
5.2 KiB
Swift
Raw Normal View History

/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Cocoa
import RxSwift
import PureLayout
2016-07-21 20:28:58 +03:00
struct PrefData {
2016-08-14 15:29:50 +03:00
var general: GeneralPrefData
2016-07-21 20:28:58 +03:00
var appearance: AppearancePrefData
}
2016-07-24 21:32:07 +03:00
class PrefWindowComponent: NSObject, NSTableViewDataSource, NSTableViewDelegate, Component {
private let source: Observable<Any>
private let disposeBag = DisposeBag()
2016-07-21 20:28:58 +03:00
private let subject = PublishSubject<Any>()
var sink: Observable<Any> {
return self.subject.asObservable()
}
2016-07-27 00:40:20 +03:00
private var data: PrefData
2016-07-21 20:28:58 +03:00
private let windowController = NSWindowController(windowNibName: "PrefWindow")
2016-07-24 21:32:07 +03:00
private let window: NSWindow
private let categoryView = NSTableView(frame: CGRect.zero)
private let categoryScrollView = NSScrollView(forAutoLayout: ())
2016-08-14 15:29:50 +03:00
private let paneContainer = NSScrollView(forAutoLayout: ())
2016-08-14 15:29:50 +03:00
private let paneNames = [ "General", "Appearance" ]
private let panes: [PrefPane]
private var currentPane: PrefPane {
get {
return self.paneContainer.documentView as! PrefPane
}
set {
self.paneContainer.documentView = newValue
// Auto-layout seems to be smart enough not to add redundant constraints.
2016-08-15 22:35:21 +03:00
newValue.autoPinEdgesToSuperviewEdges()
2016-08-14 15:29:50 +03:00
}
}
2016-07-27 00:40:20 +03:00
init(source: Observable<Any>, initialData: PrefData) {
self.source = source
2016-07-27 00:40:20 +03:00
self.data = initialData
2016-07-21 20:28:58 +03:00
self.panes = [
2016-08-14 15:29:50 +03:00
GeneralPrefPane(source: source, initialData: self.data.general),
2016-07-27 00:40:20 +03:00
AppearancePrefPane(source: source, initialData: self.data.appearance)
2016-07-21 20:28:58 +03:00
]
self.window = self.windowController.window!
2016-07-24 21:32:07 +03:00
super.init()
self.addViews()
2016-07-21 20:28:58 +03:00
self.addReactions()
}
2016-07-21 20:28:58 +03:00
deinit {
self.subject.onCompleted()
}
2016-07-24 21:32:07 +03:00
func show() {
self.windowController.showWindow(self)
2016-07-24 21:32:07 +03:00
}
2016-07-21 20:28:58 +03:00
private func addReactions() {
2016-07-27 00:40:20 +03:00
self.source
.filter { $0 is PrefData }
.map { $0 as! PrefData }
.subscribeNext { [unowned self] prefData in
if prefData.appearance.editorFont == self.data.appearance.editorFont
&& prefData.appearance.editorUsesLigatures == self.data.appearance.editorUsesLigatures {
2016-07-27 00:40:20 +03:00
return
}
self.data = prefData
}
.addDisposableTo(self.disposeBag)
2016-07-21 20:28:58 +03:00
self.panes
.map { $0.sink }
.toMergedObservables()
2016-07-24 21:32:07 +03:00
.map { [unowned self] action in
2016-07-21 20:28:58 +03:00
switch action {
case let data as AppearancePrefData:
self.data.appearance = data
2016-08-14 16:38:41 +03:00
case let data as GeneralPrefData:
self.data.general = data
2016-07-21 20:28:58 +03:00
default:
NSLog("nothing to see here")
}
return self.data
}
2016-07-24 21:32:07 +03:00
.subscribeNext { [unowned self] action in self.subject.onNext(action) }
2016-07-21 20:28:58 +03:00
.addDisposableTo(self.disposeBag)
}
private func addViews() {
let tableColumn = NSTableColumn(identifier: "name")
let textFieldCell = NSTextFieldCell()
textFieldCell.allowsEditingTextAttributes = false
textFieldCell.lineBreakMode = .ByTruncatingTail
tableColumn.dataCell = textFieldCell
let categoryView = self.categoryView
categoryView.addTableColumn(tableColumn)
categoryView.rowSizeStyle = .Default
categoryView.sizeLastColumnToFit()
categoryView.allowsEmptySelection = false
categoryView.allowsMultipleSelection = false
categoryView.headerView = nil
categoryView.focusRingType = .None
categoryView.selectionHighlightStyle = .SourceList
categoryView.setDataSource(self)
categoryView.setDelegate(self)
let categoryScrollView = self.categoryScrollView
categoryScrollView.hasVerticalScroller = true
categoryScrollView.hasHorizontalScroller = true
categoryScrollView.autohidesScrollers = true
categoryScrollView.borderType = .BezelBorder
categoryScrollView.documentView = categoryView
2016-08-14 15:29:50 +03:00
let paneContainer = self.paneContainer
paneContainer.hasVerticalScroller = true;
paneContainer.hasHorizontalScroller = true;
paneContainer.autohidesScrollers = true;
paneContainer.borderType = .NoBorder;
paneContainer.autoresizesSubviews = false;
paneContainer.backgroundColor = NSColor.windowBackgroundColor();
2016-07-24 21:32:07 +03:00
self.window.contentView?.addSubview(categoryScrollView)
2016-08-14 15:29:50 +03:00
self.window.contentView?.addSubview(paneContainer)
categoryScrollView.autoSetDimension(.Width, toSize: 150)
categoryScrollView.autoPinEdgeToSuperviewEdge(.Top, withInset: -1)
categoryScrollView.autoPinEdgeToSuperviewEdge(.Bottom, withInset: -1)
categoryScrollView.autoPinEdgeToSuperviewEdge(.Left, withInset: -1)
2016-08-14 15:29:50 +03:00
paneContainer.autoSetDimension(.Width, toSize: 200, relation: .GreaterThanOrEqual)
paneContainer.autoPinEdgeToSuperviewEdge(.Top)
paneContainer.autoPinEdgeToSuperviewEdge(.Right)
paneContainer.autoPinEdgeToSuperviewEdge(.Bottom)
paneContainer.autoPinEdge(.Left, toEdge: .Right, ofView: categoryScrollView)
self.currentPane = self.panes[0]
}
}
// MARK: - NSTableViewDataSource
2016-07-24 21:32:07 +03:00
extension PrefWindowComponent {
2016-07-21 20:28:58 +03:00
2016-08-14 15:29:50 +03:00
func numberOfRowsInTableView(_: NSTableView) -> Int {
return self.paneNames.count
}
2016-07-21 20:28:58 +03:00
func tableView(_: NSTableView, objectValueForTableColumn _: NSTableColumn?, row: Int) -> AnyObject? {
return self.paneNames[row]
}
}
// MARK: - NSTableViewDelegate
2016-07-24 21:32:07 +03:00
extension PrefWindowComponent {
2016-07-21 20:28:58 +03:00
2016-08-14 15:29:50 +03:00
func tableViewSelectionDidChange(_: NSNotification) {
let idx = self.categoryView.selectedRow
self.currentPane = self.panes[idx]
}
}