2017-01-22 16:22:05 +03:00
|
|
|
/**
|
|
|
|
* Tae Won Ha - http://taewon.de - @hataewon
|
|
|
|
* See LICENSE
|
|
|
|
*/
|
2017-01-17 21:47:59 +03:00
|
|
|
|
|
|
|
import Cocoa
|
|
|
|
import RxSwift
|
|
|
|
|
|
|
|
class UiRoot: UiComponent {
|
|
|
|
|
2017-01-22 16:22:05 +03:00
|
|
|
typealias StateType = AppState
|
2017-01-17 21:47:59 +03:00
|
|
|
|
2017-01-25 00:39:19 +03:00
|
|
|
required init(source: Observable<StateType>, emitter: ActionEmitter, state: StateType) {
|
2017-01-17 21:47:59 +03:00
|
|
|
self.source = source
|
|
|
|
self.emitter = emitter
|
|
|
|
|
2017-02-19 20:00:41 +03:00
|
|
|
self.fileMonitor = FileMonitor(source: source, emitter: emitter, state: state)
|
2017-02-20 21:33:22 +03:00
|
|
|
self.openQuicklyWindow = OpenQuicklyWindow(source: source, emitter: emitter, state: state)
|
2017-05-01 15:48:23 +03:00
|
|
|
self.prefWindow = PrefWindow(source: source, emitter: emitter, state: state)
|
2017-05-01 01:39:34 +03:00
|
|
|
|
2017-01-17 21:47:59 +03:00
|
|
|
source
|
|
|
|
.observeOn(MainScheduler.instance)
|
|
|
|
.subscribe(onNext: { [unowned self] state in
|
2017-04-15 11:38:07 +03:00
|
|
|
let uuidsInState = Set(state.mainWindows.keys)
|
2017-01-17 21:47:59 +03:00
|
|
|
|
2017-01-25 00:39:19 +03:00
|
|
|
uuidsInState
|
2017-01-17 21:47:59 +03:00
|
|
|
.subtracting(self.mainWindows.keys)
|
2017-01-22 16:22:05 +03:00
|
|
|
.flatMap { state.mainWindows[$0] }
|
2017-01-17 21:47:59 +03:00
|
|
|
.forEach(self.createNewMainWindow)
|
|
|
|
|
2017-06-24 16:42:07 +03:00
|
|
|
if self.mainWindows.isEmpty {
|
|
|
|
// We exit here if there are no main windows open. Otherwise, when hide/quit after last main window is active,
|
|
|
|
// you have to be really quick to open a new window when re-activating VimR w/o automatic new main window.
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-04-15 11:38:07 +03:00
|
|
|
self.mainWindows.keys
|
|
|
|
.filter { !uuidsInState.contains($0) }
|
2017-04-01 22:02:31 +03:00
|
|
|
.forEach(self.removeMainWindow)
|
2017-06-13 23:36:43 +03:00
|
|
|
|
|
|
|
guard self.mainWindows.isEmpty else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
switch state.afterLastWindowAction {
|
|
|
|
|
|
|
|
case .doNothing: return
|
|
|
|
case .hide: NSApp.hide(self)
|
|
|
|
case .quit: NSApp.terminate(self)
|
|
|
|
|
|
|
|
}
|
2017-01-17 21:47:59 +03:00
|
|
|
})
|
2017-04-22 17:30:40 +03:00
|
|
|
.disposed(by: self.disposeBag)
|
2017-01-17 21:47:59 +03:00
|
|
|
}
|
|
|
|
|
2017-06-11 17:28:25 +03:00
|
|
|
// The following should only be used when Cmd-Q'ing
|
|
|
|
func prepareQuit() {
|
|
|
|
self.mainWindows.values.forEach { $0.quitNeoVimWithoutSaving() }
|
|
|
|
}
|
|
|
|
|
2017-02-28 00:45:26 +03:00
|
|
|
fileprivate let source: Observable<AppState>
|
|
|
|
fileprivate let emitter: ActionEmitter
|
|
|
|
fileprivate let disposeBag = DisposeBag()
|
|
|
|
|
|
|
|
fileprivate let fileMonitor: FileMonitor
|
|
|
|
fileprivate let openQuicklyWindow: OpenQuicklyWindow
|
2017-05-01 15:48:23 +03:00
|
|
|
fileprivate let prefWindow: PrefWindow
|
2017-02-28 00:45:26 +03:00
|
|
|
|
|
|
|
fileprivate var mainWindows = [String: MainWindow]()
|
|
|
|
fileprivate var subjectForMainWindows = [String: PublishSubject<MainWindow.State>]()
|
|
|
|
fileprivate var disposables = [String: Disposable]()
|
|
|
|
|
2017-01-17 21:47:59 +03:00
|
|
|
fileprivate func createNewMainWindow(with state: MainWindow.State) {
|
2017-02-12 12:53:24 +03:00
|
|
|
let subject = PublishSubject<MainWindow.State>()
|
|
|
|
let source = self.source.mapOmittingNil { $0.mainWindows[state.uuid] }
|
|
|
|
|
|
|
|
self.subjectForMainWindows[state.uuid] = subject
|
|
|
|
self.disposables[state.uuid] = source.subscribe(subject)
|
2017-01-17 21:47:59 +03:00
|
|
|
|
2017-02-12 12:53:24 +03:00
|
|
|
let mainWindow = MainWindow(source: subject.asObservable(), emitter: self.emitter, state: state)
|
|
|
|
self.mainWindows[state.uuid] = mainWindow
|
2017-01-17 21:47:59 +03:00
|
|
|
mainWindow.show()
|
|
|
|
}
|
|
|
|
|
2017-02-12 12:53:24 +03:00
|
|
|
fileprivate func removeMainWindow(with uuid: String) {
|
|
|
|
self.subjectForMainWindows[uuid]?.onCompleted()
|
|
|
|
self.disposables[uuid]?.dispose()
|
|
|
|
|
|
|
|
self.subjectForMainWindows.removeValue(forKey: uuid)
|
|
|
|
self.disposables.removeValue(forKey: uuid)
|
|
|
|
self.mainWindows.removeValue(forKey: uuid)
|
|
|
|
}
|
2017-01-17 21:47:59 +03:00
|
|
|
}
|