1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-24 22:33:52 +03:00

GH-426 Store active tools in user defaults

This commit is contained in:
Tae Won Ha 2017-05-01 17:15:21 +02:00
parent f428ca5adf
commit 40fd7e1eb5
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
10 changed files with 167 additions and 76 deletions

View File

@ -40,6 +40,7 @@
1929B67DA3EB21A631EF1DBB /* FileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BA8AC40B901B20F20B71 /* FileUtils.swift */; };
1929B6B886CFBCBF01D4B04A /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B5E3E722EFA5172E3455 /* Application.swift */; };
1929B6BE1610892E6C4C0CE6 /* GeneralPrefReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B0EB3F49C42A57D083AF /* GeneralPrefReducer.swift */; };
1929B6C0393DE40E34F4A49A /* ToolsPrefReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B694508FB5FDE607513A /* ToolsPrefReducer.swift */; };
1929B6D8F5FC723B7109031F /* OpenQuicklyReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B12CE56A9B36980288A4 /* OpenQuicklyReducer.swift */; };
1929B71381946860626E5224 /* FileBrowserReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929BDC8F5D48578A90236E9 /* FileBrowserReducer.swift */; };
1929B71610FF1DC6E459BA49 /* PreviewUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1929B8EF9A9F5ACC175452BD /* PreviewUtils.swift */; };
@ -354,6 +355,7 @@
1929B5E3E722EFA5172E3455 /* Application.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
1929B617C229B19DB3E987B8 /* PreviewService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewService.swift; sourceTree = "<group>"; };
1929B67A10E6BB2986B2416E /* OpenedFileListReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenedFileListReducer.swift; sourceTree = "<group>"; };
1929B694508FB5FDE607513A /* ToolsPrefReducer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToolsPrefReducer.swift; sourceTree = "<group>"; };
1929B69499B2569793350CEC /* FileItemIgnorePattern.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileItemIgnorePattern.swift; sourceTree = "<group>"; };
1929B6AD3396160AA2C46919 /* Debouncer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = "<group>"; };
1929B6C6C7792B05164B0216 /* PreviewTool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewTool.swift; sourceTree = "<group>"; };
@ -654,6 +656,7 @@
1929B0EB3F49C42A57D083AF /* GeneralPrefReducer.swift */,
1929BED01F5D94BFCA4CF80F /* AppearancePrefReducer.swift */,
1929B7039C5689CE45F53888 /* AdvancedPrefReducer.swift */,
1929B694508FB5FDE607513A /* ToolsPrefReducer.swift */,
);
name = Preferences;
sourceTree = "<group>";
@ -1487,6 +1490,7 @@
1929B4B00D7BB191A9A6532D /* HtmlPreviewToolReducer.swift in Sources */,
1929BCF7F7B9CC5499A3F506 /* AdvancedPrefReducer.swift in Sources */,
1929BF03FD6465F289AA80B2 /* ToolsPref.swift in Sources */,
1929B6C0393DE40E34F4A49A /* ToolsPrefReducer.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -82,6 +82,7 @@ class Context {
.of(
self.prefStateSource(by: PrefWindowReducer().reduce, prefService: prefService),
self.prefStateSource(by: GeneralPrefReducer().reduce, prefService: prefService),
self.prefStateSource(by: ToolsPrefReducer().reduce, prefService: prefService),
self.prefStateSource(by: AppearancePrefReducer().reduce, prefService: prefService),
self.prefStateSource(by: AdvancedPrefReducer().reduce, prefService: prefService)
)

View File

@ -85,10 +85,6 @@ class MainWindow: NSObject,
let workspace = Workspace(mainView: self.neoVimView)
self.workspace = workspace
self.preview = PreviewTool(source: source, emitter: emitter, state: state)
self.fileBrowser = FileBrowser(source: source, emitter: emitter, state: state)
self.openedFileList = OpenedFileList(source: source, emitter: emitter, state: state)
self.htmlPreview = HtmlPreviewTool(source: source, emitter: emitter, state: state)
if !state.isToolButtonsVisible {
self.workspace.toggleToolButtons()
@ -96,35 +92,45 @@ class MainWindow: NSObject,
self.windowController = NSWindowController(windowNibName: "MainWindow")
let previewConfig = WorkspaceTool.Config(title: "Markdown",
view: self.preview,
customMenuItems: self.preview.menuItems)
self.previewContainer = WorkspaceTool(previewConfig)
self.previewContainer.dimension = state.tools[.preview]?.dimension ?? 250
var tools: [Tools: WorkspaceTool] = [:]
if state.activeTools[.preview] == true {
self.preview = PreviewTool(source: source, emitter: emitter, state: state)
let previewConfig = WorkspaceTool.Config(title: "Markdown",
view: self.preview!,
customMenuItems: self.preview!.menuItems)
self.previewContainer = WorkspaceTool(previewConfig)
self.previewContainer!.dimension = state.tools[.preview]?.dimension ?? 250
tools[.preview] = self.previewContainer
}
let htmlPreviewConfig = WorkspaceTool.Config(title: "HTML",
view: self.htmlPreview,
customToolbar: self.htmlPreview.innerCustomToolbar)
self.htmlPreviewContainer = WorkspaceTool(htmlPreviewConfig)
self.htmlPreviewContainer.dimension = state.tools[.htmlPreview]?.dimension ?? 250
if state.activeTools[.htmlPreview] == true {
self.htmlPreview = HtmlPreviewTool(source: source, emitter: emitter, state: state)
let htmlPreviewConfig = WorkspaceTool.Config(title: "HTML",
view: self.htmlPreview!,
customToolbar: self.htmlPreview!.innerCustomToolbar)
self.htmlPreviewContainer = WorkspaceTool(htmlPreviewConfig)
self.htmlPreviewContainer!.dimension = state.tools[.htmlPreview]?.dimension ?? 250
tools[.htmlPreview] = self.htmlPreviewContainer
}
let fileBrowserConfig = WorkspaceTool.Config(title: "Files",
view: self.fileBrowser,
customToolbar: self.fileBrowser.innerCustomToolbar,
customMenuItems: self.fileBrowser.menuItems)
self.fileBrowserContainer = WorkspaceTool(fileBrowserConfig)
self.fileBrowserContainer.dimension = state.tools[.fileBrowser]?.dimension ?? 200
if state.activeTools[.fileBrowser] == true {
self.fileBrowser = FileBrowser(source: source, emitter: emitter, state: state)
let fileBrowserConfig = WorkspaceTool.Config(title: "Files",
view: self.fileBrowser!,
customToolbar: self.fileBrowser!.innerCustomToolbar,
customMenuItems: self.fileBrowser!.menuItems)
self.fileBrowserContainer = WorkspaceTool(fileBrowserConfig)
self.fileBrowserContainer!.dimension = state.tools[.fileBrowser]?.dimension ?? 200
tools[.fileBrowser] = self.fileBrowserContainer
}
let openedFileListConfig = WorkspaceTool.Config(title: "Buffers", view: self.openedFileList)
self.openedFileListContainer = WorkspaceTool(openedFileListConfig)
self.openedFileListContainer.dimension = state.tools[.openedFilesList]?.dimension ?? 200
let tools: [Tools: WorkspaceTool] = [
.fileBrowser: self.fileBrowserContainer,
.openedFilesList: self.openedFileListContainer,
.preview: self.previewContainer,
.htmlPreview: self.htmlPreviewContainer,
]
if state.activeTools[.openedFilesList] == true {
self.openedFileList = OpenedFileList(source: source, emitter: emitter, state: state)
let openedFileListConfig = WorkspaceTool.Config(title: "Buffers", view: self.openedFileList!)
self.openedFileListContainer = WorkspaceTool(openedFileListConfig)
self.openedFileListContainer!.dimension = state.tools[.openedFilesList]?.dimension ?? 200
tools[.openedFilesList] = self.openedFileListContainer
}
self.tools = tools
state.orderedTools.forEach { toolId in
@ -253,18 +259,18 @@ class MainWindow: NSObject,
fileprivate let workspace: Workspace
fileprivate let neoVimView: NeoVimView
fileprivate let previewContainer: WorkspaceTool
fileprivate let fileBrowserContainer: WorkspaceTool
fileprivate let openedFileListContainer: WorkspaceTool
fileprivate let htmlPreviewContainer: WorkspaceTool
fileprivate var previewContainer: WorkspaceTool?
fileprivate var fileBrowserContainer: WorkspaceTool?
fileprivate var openedFileListContainer: WorkspaceTool?
fileprivate var htmlPreviewContainer: WorkspaceTool?
fileprivate var editorPosition: Marked<Position>
fileprivate var previewPosition: Marked<Position>
fileprivate let preview: PreviewTool
fileprivate let htmlPreview: HtmlPreviewTool
fileprivate let fileBrowser: FileBrowser
fileprivate let openedFileList: OpenedFileList
fileprivate var preview: PreviewTool?
fileprivate var htmlPreview: HtmlPreviewTool?
fileprivate var fileBrowser: FileBrowser?
fileprivate var openedFileList: OpenedFileList?
fileprivate let tools: [Tools: WorkspaceTool]
@ -521,9 +527,9 @@ extension MainWindow {
@IBAction func toggleFileBrowser(_ sender: Any?) {
let fileBrowser = self.fileBrowserContainer
if fileBrowser.isSelected {
if fileBrowser.view.isFirstResponder {
fileBrowser.toggle()
if fileBrowser?.isSelected == true {
if fileBrowser?.view.isFirstResponder == true {
fileBrowser?.toggle()
self.focusNeoVimView(self)
} else {
self.emit(self.uuidAction(for: .focus(.fileBrowser)))
@ -532,7 +538,7 @@ extension MainWindow {
return
}
fileBrowser.toggle()
fileBrowser?.toggle()
self.emit(self.uuidAction(for: .focus(.fileBrowser)))
}
@ -577,24 +583,23 @@ extension MainWindow {
}
fileprivate func toolIdentifier(for tool: WorkspaceTool) -> Tools? {
switch tool {
case self.fileBrowserContainer:
if tool == self.fileBrowserContainer {
return .fileBrowser
case self.openedFileListContainer:
return .openedFilesList
case self.previewContainer:
return .preview
case self.htmlPreviewContainer:
return .htmlPreview
default:
return nil
}
if tool == self.openedFileListContainer {
return .openedFilesList
}
if tool == self.previewContainer {
return .preview
}
if tool == self.htmlPreviewContainer {
return .htmlPreview
}
return nil
}
}
@ -608,12 +613,21 @@ extension MainWindow {
let canOpen = canSave
let canOpenQuickly = canSave
let canFocusNeoVimView = self.window.firstResponder != self.neoVimView
let canToggleFileBrowser = self.tools.keys.contains(.fileBrowser)
let canToggleTools = !self.tools.isEmpty
guard let action = item.action else {
return true
}
switch action {
case #selector(toggleAllTools(_:)), #selector(toggleToolButtons(_:)):
return canToggleTools
case #selector(toggleFileBrowser(_:)):
return canToggleFileBrowser
case #selector(focusNeoVimView(_:)):
return canFocusNeoVimView
@ -631,6 +645,7 @@ extension MainWindow {
default:
return true
}
}
}

View File

@ -27,9 +27,9 @@ class PrefWindow: NSObject,
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),
ToolsPref(source: source, emitter: emitter, state: state),
]
super.init()

View File

@ -153,6 +153,7 @@ class Keys {
static let allToolsVisible = "is-all-tools-visible"
static let toolButtonsVisible = "is-tool-buttons-visible"
static let orderedTools = "ordered-tools"
static let activeTools = "active-tools"
static let isShowHidden = "is-show-hidden"
}

View File

@ -187,6 +187,12 @@ extension MainWindow {
var isAllToolsVisible = true
var isToolButtonsVisible = true
var activeTools = [
Tools.fileBrowser: true,
Tools.openedFilesList: true,
Tools.preview: true,
Tools.htmlPreview: true,
]
////// transient
@ -246,6 +252,18 @@ extension MainWindow {
let missingOrderedTools = MainWindow.Tools.all.subtracting(self.orderedTools)
self.orderedTools.append(contentsOf: missingOrderedTools)
// To stay compatible with 168 we do not guard against nil activeToolsAsString.
let activeToolsAsString = dict[Keys.MainWindow.activeTools] as? [String: Bool] ?? [:]
self.activeTools = activeToolsAsString.flatMapToDict { (key, value) in
guard let toolId = MainWindow.Tools(rawValue: key) else {
return nil
}
return (toolId, value)
}
let missingActiveTools = MainWindow.Tools.all.subtracting(self.activeTools.keys)
missingActiveTools.forEach { self.activeTools[$0] = true }
let workspaceToolsDict = dict[Keys.WorkspaceTool.key] as? [String: [String: Any]] ?? [:]
let toolKeys = workspaceToolsDict.keys.flatMap { MainWindow.Tools(rawValue: $0) }
let missingToolKeys = MainWindow.Tools.all.subtracting(toolKeys)
@ -271,10 +289,10 @@ extension MainWindow {
Keys.MainWindow.toolButtonsVisible: self.isToolButtonsVisible,
Keys.Appearance.key: self.appearance.dict(),
Keys.WorkspaceTool.key: Array(self.tools.keys.map { $0.rawValue })
.toDict { self.tools[MainWindow.Tools(rawValue: $0)!]!.dict() },
Keys.WorkspaceTool.key: self.tools.mapToDict { ($0.rawValue, $1.dict()) },
Keys.MainWindow.orderedTools: self.orderedTools.map { $0.rawValue },
Keys.MainWindow.activeTools: self.activeTools.mapToDict { ($0.rawValue, $1) },
Keys.PreviewTool.key: self.previewTool.dict(),

View File

@ -92,12 +92,12 @@ func toDict<K: Hashable, V, S: Sequence>(_ sequence: S) -> Dictionary<K, V> wher
extension Dictionary {
func mapToDict<T>(_ transform: ((key: Key, value: Value)) throws -> (Key, T)) rethrows -> Dictionary<Key, T> {
func mapToDict<K, T>(_ transform: ((key: Key, value: Value)) throws -> (K, T)) rethrows -> Dictionary<K, T> {
let array = try self.map(transform)
return toDict(array)
}
func flatMapToDict<T>(_ transform: ((key: Key, value: Value)) throws -> (Key, T)?) rethrows -> Dictionary<Key, T> {
func flatMapToDict<K, T>(_ transform: ((key: Key, value: Value)) throws -> (K, T)?) rethrows -> Dictionary<K, T> {
let array = try self.flatMap(transform)
return toDict(array)
}

View File

@ -13,6 +13,7 @@ class ToolsPref: PrefPane, UiComponent {
enum Action {
case setActiveTools([MainWindow.Tools: Bool])
}
override var displayName: String {
@ -26,6 +27,8 @@ class ToolsPref: PrefPane, UiComponent {
required init(source: Observable<StateType>, emitter: ActionEmitter, state: StateType) {
self.emit = emitter.typedEmit()
self.tools = state.mainWindowTemplate.activeTools
super.init(frame: .zero)
self.addViews()
@ -43,6 +46,8 @@ class ToolsPref: PrefPane, UiComponent {
fileprivate let emit: (Action) -> Void
fileprivate let disposeBag = DisposeBag()
fileprivate var tools: [MainWindow.Tools: Bool]
fileprivate let fileBrowserCheckbox = NSButton(forAutoLayout: ())
fileprivate let openedFilesListCheckbox = NSButton(forAutoLayout: ())
fileprivate let previewCheckbox = NSButton(forAutoLayout: ())
@ -53,27 +58,35 @@ class ToolsPref: PrefPane, UiComponent {
}
fileprivate func updateViews() {
self.fileBrowserCheckbox.boolState = self.tools[.fileBrowser] ?? true
self.openedFilesListCheckbox.boolState = self.tools[.openedFilesList] ?? true
self.previewCheckbox.boolState = self.tools[.preview] ?? true
self.htmlCheckbox.boolState = self.tools[.htmlPreview] ?? true
}
fileprivate func addViews() {
let paneTitle = self.paneTitleTextField(title: "Tools")
let fileBrowser = self.fileBrowserCheckbox
fileBrowser.target = self
self.configureCheckbox(button: fileBrowser,
title: "File Browser",
action: #selector(ToolsPref.fileBrowserAction(_:)))
let openedFilesList = self.openedFilesListCheckbox
openedFilesList.target = self
self.configureCheckbox(button: openedFilesList,
title: "Buffers",
action: #selector(ToolsPref.openedFilesListAction(_:)))
let preview = self.previewCheckbox
preview.target = self
self.configureCheckbox(button: preview,
title: "Markdown Preview",
action: #selector(ToolsPref.previewAction(_:)))
let html = self.htmlCheckbox
html.target = self
self.configureCheckbox(button: html,
title: "HTML Preview",
action: #selector(ToolsPref.htmlAction(_:)))
action: #selector(ToolsPref.htmlPreviewAction(_:)))
let info = self.infoTextField(
markdown: "You can turn off tools you don't need. The effect takes place when new windows are opened."
@ -113,18 +126,22 @@ class ToolsPref: PrefPane, UiComponent {
extension ToolsPref {
@IBAction func fileBrowserAction(_ sender: Any?) {
self.tools[.fileBrowser] = self.fileBrowserCheckbox.boolState
self.emit(.setActiveTools(self.tools))
}
@IBAction func openedFilesListAction(_ sender: Any?) {
self.tools[.openedFilesList] = self.openedFilesListCheckbox.boolState
self.emit(.setActiveTools(self.tools))
}
@IBAction func previewAction(_ sender: Any?) {
self.tools[.preview] = self.previewCheckbox.boolState
self.emit(.setActiveTools(self.tools))
}
@IBAction func htmlAction(_ sender: Any?) {
@IBAction func htmlPreviewAction(_ sender: Any?) {
self.tools[.htmlPreview] = self.htmlCheckbox.boolState
self.emit(.setActiveTools(self.tools))
}
}

View File

@ -0,0 +1,24 @@
/**
* Tae Won Ha - http://taewon.de - @hataewon
* See LICENSE
*/
import Foundation
class ToolsPrefReducer {
typealias Pair = StateActionPair<AppState, ToolsPref.Action>
func reduce(_ pair: Pair) -> Pair {
var state = pair.state
switch pair.action {
case let .setActiveTools(tools):
state.mainWindowTemplate.activeTools = tools
}
return StateActionPair(state: state, action: pair.action)
}
}

View File

@ -17,16 +17,14 @@ class UiRootReducer {
case .becomeKey:
appState.currentMainWindowUuid = uuid
appState.mainWindowTemplate = appState.mainWindows[uuid] ?? appState.mainWindowTemplate
appState.mainWindowTemplate = self.mainWindowTemplate(
from: appState.mainWindowTemplate, new: appState.mainWindows[uuid] ?? appState.mainWindowTemplate
)
case .close:
if appState.currentMainWindowUuid == uuid, let mainWindowToClose = appState.mainWindows[uuid] {
appState.mainWindowTemplate.isAllToolsVisible = mainWindowToClose.isAllToolsVisible
appState.mainWindowTemplate.isToolButtonsVisible = mainWindowToClose.isToolButtonsVisible
appState.mainWindowTemplate.tools = mainWindowToClose.tools
appState.mainWindowTemplate.previewTool = mainWindowToClose.previewTool
appState.mainWindowTemplate.fileBrowserShowHidden = mainWindowToClose.fileBrowserShowHidden
appState.mainWindowTemplate.htmlPreview = .default
appState.mainWindowTemplate = self.mainWindowTemplate(from: appState.mainWindowTemplate,
new: mainWindowToClose)
appState.currentMainWindowUuid = nil
}
@ -40,4 +38,17 @@ class UiRootReducer {
return StateActionPair(state: appState, action: pair.action)
}
fileprivate func mainWindowTemplate(from old: MainWindow.State, new: MainWindow.State) -> MainWindow.State {
var result = old
result.isAllToolsVisible = new.isAllToolsVisible
result.isToolButtonsVisible = new.isToolButtonsVisible
result.tools = new.tools
result.previewTool = new.previewTool
result.fileBrowserShowHidden = new.fileBrowserShowHidden
result.htmlPreview = .default
return result
}
}