mirror of
https://github.com/qvacua/vimr.git
synced 2024-12-01 10:02:36 +03:00
156 lines
4.4 KiB
Swift
156 lines
4.4 KiB
Swift
/**
|
|
* Tae Won Ha - http://taewon.de - @hataewon
|
|
* See LICENSE
|
|
*/
|
|
|
|
import Cocoa
|
|
import RxSwift
|
|
import PureLayout
|
|
|
|
class PrefWindow: NSObject,
|
|
UiComponent,
|
|
NSWindowDelegate,
|
|
NSTableViewDataSource, NSTableViewDelegate {
|
|
|
|
typealias StateType = AppState
|
|
|
|
enum Action {
|
|
|
|
case close
|
|
}
|
|
|
|
required init(source: Observable<StateType>, emitter: ActionEmitter, state: StateType) {
|
|
self.emit = emitter.typedEmit()
|
|
self.openStatusMark = state.preferencesOpen.mark
|
|
|
|
self.windowController = NSWindowController(windowNibName: NSNib.Name("PrefWindow"))
|
|
|
|
self.panes = [
|
|
GeneralPref(source: source, emitter: emitter, state: state),
|
|
ToolsPref(source: source, emitter: emitter, state: state),
|
|
AppearancePref(source: source, emitter: emitter, state: state),
|
|
AdvancedPref(source: source, emitter: emitter, state: state),
|
|
]
|
|
|
|
super.init()
|
|
|
|
self.window.delegate = self
|
|
|
|
self.addViews()
|
|
|
|
source
|
|
.observeOn(MainScheduler.instance)
|
|
.subscribe(onNext: { state in
|
|
if state.preferencesOpen.payload == false {
|
|
self.openStatusMark = state.preferencesOpen.mark
|
|
self.windowController.close()
|
|
return
|
|
}
|
|
|
|
if state.preferencesOpen.mark == self.openStatusMark {
|
|
return
|
|
}
|
|
|
|
self.openStatusMark = state.preferencesOpen.mark
|
|
self.windowController.showWindow(self)
|
|
})
|
|
.disposed(by: self.disposeBag)
|
|
}
|
|
|
|
fileprivate let emit: (Action) -> Void
|
|
fileprivate let disposeBag = DisposeBag()
|
|
|
|
fileprivate var openStatusMark: Token
|
|
|
|
fileprivate let windowController: NSWindowController
|
|
fileprivate var window: NSWindow { return self.windowController.window! }
|
|
|
|
fileprivate let categoryView = NSTableView.standardSourceListTableView()
|
|
fileprivate let categoryScrollView = NSScrollView.standardScrollView()
|
|
fileprivate let paneContainer = NSScrollView(forAutoLayout: ())
|
|
|
|
fileprivate let panes: [PrefPane]
|
|
fileprivate 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.
|
|
if newValue.pinToContainer {
|
|
newValue.autoPinEdgesToSuperviewEdges()
|
|
}
|
|
}
|
|
}
|
|
|
|
fileprivate func addViews() {
|
|
let categoryView = self.categoryView
|
|
categoryView.dataSource = self
|
|
categoryView.delegate = self
|
|
|
|
let categoryScrollView = self.categoryScrollView
|
|
categoryScrollView.documentView = categoryView
|
|
|
|
let paneContainer = self.paneContainer
|
|
paneContainer.hasVerticalScroller = true
|
|
paneContainer.hasHorizontalScroller = true
|
|
paneContainer.autohidesScrollers = true
|
|
paneContainer.borderType = .noBorder
|
|
paneContainer.autoresizesSubviews = false
|
|
paneContainer.backgroundColor = NSColor.windowBackgroundColor
|
|
|
|
self.window.contentView?.addSubview(categoryScrollView)
|
|
self.window.contentView?.addSubview(paneContainer)
|
|
|
|
categoryScrollView.autoSetDimension(.width, toSize: 150)
|
|
categoryScrollView.autoPinEdge(toSuperviewEdge: .top, withInset: -1)
|
|
categoryScrollView.autoPinEdge(toSuperviewEdge: .bottom, withInset: -1)
|
|
categoryScrollView.autoPinEdge(toSuperviewEdge: .left, withInset: -1)
|
|
|
|
paneContainer.autoSetDimension(.width, toSize: 200, relation: .greaterThanOrEqual)
|
|
paneContainer.autoPinEdge(toSuperviewEdge: .top)
|
|
paneContainer.autoPinEdge(toSuperviewEdge: .right)
|
|
paneContainer.autoPinEdge(toSuperviewEdge: .bottom)
|
|
paneContainer.autoPinEdge(.left, to: .right, of: categoryScrollView)
|
|
|
|
self.currentPane = self.panes[0]
|
|
}
|
|
}
|
|
|
|
// MARK: - NSWindowDelegate
|
|
extension PrefWindow {
|
|
|
|
func windowShouldClose(_: NSWindow) -> Bool {
|
|
self.emit(.close)
|
|
|
|
return false
|
|
}
|
|
|
|
func windowWillClose(_: Notification) {
|
|
self.panes.forEach { $0.windowWillClose() }
|
|
}
|
|
}
|
|
|
|
// MARK: - NSTableViewDataSource
|
|
extension PrefWindow {
|
|
|
|
@objc(numberOfRowsInTableView:) func numberOfRows(in _: NSTableView) -> Int {
|
|
return self.panes.count
|
|
}
|
|
|
|
@objc(tableView:objectValueForTableColumn:row:) func tableView(_: NSTableView, objectValueFor _: NSTableColumn?, row: Int) -> Any? {
|
|
return self.panes[row].displayName
|
|
}
|
|
}
|
|
|
|
// MARK: - NSTableViewDelegate
|
|
extension PrefWindow {
|
|
|
|
func tableViewSelectionDidChange(_: Notification) {
|
|
let idx = self.categoryView.selectedRow
|
|
self.currentPane = self.panes[idx]
|
|
}
|
|
}
|