mirror of
https://github.com/qvacua/vimr.git
synced 2024-11-28 11:35:35 +03:00
GH-293 Add inner tool bar to WorkspaceTool
This commit is contained in:
parent
e88c98428c
commit
b32656f600
@ -29,35 +29,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
contentView.addSubview(workspace)
|
||||
workspace.autoPinEdgesToSuperviewEdges()
|
||||
|
||||
workspace.append(tool: WorkspaceTool(title: "Top-1", view: DummyToolView(NSColor.yellow)), location: .top)
|
||||
workspace.append(tool: dummyTool(title: "Top-1", color: .yellow), location: .top)
|
||||
|
||||
workspace.append(tool: WorkspaceTool(title: "Right-1", view: DummyToolView(NSColor.magenta)), location: .right)
|
||||
workspace.append(tool: WorkspaceTool(title: "Right-2", view: DummyToolView(NSColor.black)), location: .right)
|
||||
workspace.append(tool: dummyTool(title: "Right-1", color: .magenta), location: .right)
|
||||
workspace.append(tool: dummyTool(title: "Right-2", color: .black), location: .right)
|
||||
|
||||
let dummyView = DummyToolView(NSColor.green)
|
||||
let tool = WorkspaceTool(title: "Left-1", view: dummyView, minimumDimension: 200)
|
||||
dummyView.innerToolbar.tool = tool
|
||||
workspace.append(tool: tool, location: .left)
|
||||
|
||||
workspace.append(tool: WorkspaceTool(title: "Left-2", view: DummyToolView(NSColor.red)), location: .left)
|
||||
workspace.append(tool: WorkspaceTool(title: "Left-3", view: DummyToolView(NSColor.gray)), location: .left)
|
||||
|
||||
workspace.append(tool: WorkspaceTool(title: "Bottom-1", view: DummyToolView(NSColor.cyan)), location: .bottom)
|
||||
workspace.append(tool: WorkspaceTool(title: "Bottom-2", view: DummyToolView(NSColor.blue)), location: .bottom)
|
||||
|
||||
tool.toggle()
|
||||
}
|
||||
}
|
||||
|
||||
class DummyToolView: NSView {
|
||||
|
||||
let innerToolbar: InnerToolBar
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
init(_ color: NSColor) {
|
||||
let menuItems = [
|
||||
NSMenuItem(title: "First", action: nil, keyEquivalent: ""),
|
||||
NSMenuItem(title: "Second", action: nil, keyEquivalent: ""),
|
||||
@ -66,25 +42,31 @@ class DummyToolView: NSView {
|
||||
NSMenuItem(title: "Fifth", action: nil, keyEquivalent: ""),
|
||||
]
|
||||
|
||||
self.innerToolbar = InnerToolBar(customToolbar: DummyView(.magenta), customMenuItems: menuItems)
|
||||
let tool = dummyTool(title: "Left-1", color: .blue, customToolbar: DummyView(.orange), customMenu: menuItems)
|
||||
|
||||
super.init(frame: .zero)
|
||||
self.configureForAutoLayout()
|
||||
self.wantsLayer = true
|
||||
workspace.append(tool: tool, location: .left)
|
||||
workspace.append(tool: dummyTool(title: "Left-2", color: .red), location: .left)
|
||||
workspace.append(tool: dummyTool(title: "Left-3", color: .gray), location: .left)
|
||||
|
||||
let dummyView = DummyView(color)
|
||||
workspace.append(tool: dummyTool(title: "Bottom-1", color: .cyan), location: .bottom)
|
||||
workspace.append(tool: dummyTool(title: "Bottom-2", color: .blue), location: .bottom)
|
||||
|
||||
self.addSubview(innerToolbar)
|
||||
self.addSubview(dummyView)
|
||||
tool.toggle()
|
||||
}
|
||||
|
||||
innerToolbar.autoPinEdge(toSuperviewEdge: .top)
|
||||
innerToolbar.autoPinEdge(toSuperviewEdge: .right)
|
||||
innerToolbar.autoPinEdge(toSuperviewEdge: .left)
|
||||
fileprivate func dummyTool(title: String,
|
||||
color: NSColor,
|
||||
customToolbar: NSView? = nil,
|
||||
customMenu: [NSMenuItem] = []) -> WorkspaceTool
|
||||
{
|
||||
let config = WorkspaceTool.Config(title: title,
|
||||
view: DummyView(color),
|
||||
minimumDimension: 150,
|
||||
withInnerToolbar: true,
|
||||
customToolbar: customToolbar,
|
||||
customMenuItems: customMenu)
|
||||
|
||||
dummyView.autoPinEdge(.top, to: .bottom, of: innerToolbar)
|
||||
dummyView.autoPinEdge(toSuperviewEdge: .right)
|
||||
dummyView.autoPinEdge(toSuperviewEdge: .left)
|
||||
dummyView.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
return WorkspaceTool(config)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,9 +90,7 @@
|
||||
4B81B3D91DE882D500ED1672 /* AppKitCommons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A70931D60E04200E12030 /* AppKitCommons.swift */; };
|
||||
4B854A1D1D31447C00E08DE1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B854A1C1D31447C00E08DE1 /* main.m */; };
|
||||
4B8AC0441DBCB3A2007CCC9B /* NeoVimObjectsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8AC0431DBCB3A1007CCC9B /* NeoVimObjectsExtensions.swift */; };
|
||||
4B91FFF31DEB772200447068 /* CocoaFontAwesome.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B337FBA1DEB76F20020ADD2 /* CocoaFontAwesome.framework */; };
|
||||
4B91FFF41DEB772200447068 /* CocoaFontAwesome.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B337FBA1DEB76F20020ADD2 /* CocoaFontAwesome.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
4B91FFF51DEB772B00447068 /* CocoaFontAwesome.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B337FBA1DEB76F20020ADD2 /* CocoaFontAwesome.framework */; };
|
||||
4B91FFF61DEB772B00447068 /* CocoaFontAwesome.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4B337FBA1DEB76F20020ADD2 /* CocoaFontAwesome.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
4B97E2CC1D33F53D00FC0660 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B97E2CE1D33F53D00FC0660 /* MainWindow.xib */; };
|
||||
4B9A15241D2993DA009F9F67 /* Nimble.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4B56F29B1D29926600C1F92E /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@ -422,7 +420,6 @@
|
||||
files = (
|
||||
4B6423AC1D8EFE9800FC78C8 /* PureLayout.framework in Frameworks */,
|
||||
4B337FBC1DEB76F20020ADD2 /* CocoaFontAwesome.framework in Frameworks */,
|
||||
4B91FFF31DEB772200447068 /* CocoaFontAwesome.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -456,7 +453,6 @@
|
||||
4B2A2BFE1D0351810074CE9A /* SwiftNeoVim.framework in Frameworks */,
|
||||
4BDD056A1DB0CAB700D1B405 /* Sparkle.framework in Frameworks */,
|
||||
4B337FBB1DEB76F20020ADD2 /* CocoaFontAwesome.framework in Frameworks */,
|
||||
4B91FFF51DEB772B00447068 /* CocoaFontAwesome.framework in Frameworks */,
|
||||
4B2A2BEE1D02261F0074CE9A /* RxSwift.framework in Frameworks */,
|
||||
4B401B141D0454DC00D99EDC /* PureLayout.framework in Frameworks */,
|
||||
4BDF50081D7607BF00D8FBC3 /* EonilFileSystemEvents.framework in Frameworks */,
|
||||
@ -965,7 +961,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0810;
|
||||
LastUpgradeCheck = 0800;
|
||||
LastUpgradeCheck = 0810;
|
||||
ORGANIZATIONNAME = "Tae Won Ha";
|
||||
TargetAttributes = {
|
||||
4B2A2BF61D0351810074CE9A = {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0810"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0810"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0810"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0810"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -163,16 +163,25 @@ class ViewComponent: NSView, Flow {
|
||||
|
||||
class WorkspaceToolComponent: WorkspaceTool, Flow {
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
let toolIdentifier: ToolIdentifier
|
||||
let viewComponent: ViewComponent
|
||||
var sink: Observable<Any> {
|
||||
return self.viewComponent.sink
|
||||
}
|
||||
|
||||
init(title: String, viewComponent: ViewComponent, toolIdentifier: ToolIdentifier, minimumDimension: CGFloat = 50) {
|
||||
init(toolIdentifier: ToolIdentifier, config: WorkspaceTool.Config) {
|
||||
guard let viewComponent = config.view as? ViewComponent else {
|
||||
preconditionFailure("ERROR view must be a ViewComponent!")
|
||||
}
|
||||
|
||||
self.toolIdentifier = toolIdentifier
|
||||
self.viewComponent = viewComponent
|
||||
super.init(title: title, view: viewComponent, minimumDimension: minimumDimension)
|
||||
|
||||
super.init(config)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,17 +170,23 @@ class MainWindowComponent: WindowComponent,
|
||||
// FIXME: We do not use [self.sink, source].toMergedObservables. If we do so, then self.sink seems to live as long
|
||||
// as source, i.e. forever. Thus, self (MainWindowComponent) does not get deallocated. Not nice...
|
||||
let fileBrowser = FileBrowserComponent(source: self.sink, fileItemService: self.fileItemService)
|
||||
let fileBrowserTool = WorkspaceToolComponent(title: "Files",
|
||||
viewComponent: fileBrowser,
|
||||
toolIdentifier: .fileBrowser,
|
||||
minimumDimension: 100)
|
||||
let fileBrowserConfig = WorkspaceTool.Config(title: "Files",
|
||||
view: fileBrowser,
|
||||
minimumDimension: 100,
|
||||
withInnerToolbar: true,
|
||||
customToolbar: nil,
|
||||
customMenuItems: [])
|
||||
let fileBrowserTool = WorkspaceToolComponent(toolIdentifier: .fileBrowser, config: fileBrowserConfig)
|
||||
self.tools[.fileBrowser] = fileBrowserTool
|
||||
|
||||
let bufferList = BufferListComponent(source: self.sink, fileItemService: self.fileItemService)
|
||||
let bufferListTool = WorkspaceToolComponent(title: "Buffers",
|
||||
viewComponent: bufferList,
|
||||
toolIdentifier: .bufferList,
|
||||
minimumDimension: 100)
|
||||
let bufferListConfig = WorkspaceTool.Config(title: "Buffers",
|
||||
view: bufferList,
|
||||
minimumDimension: 100,
|
||||
withInnerToolbar: true,
|
||||
customToolbar: nil,
|
||||
customMenuItems: [])
|
||||
let bufferListTool = WorkspaceToolComponent(toolIdentifier: .bufferList, config: bufferListConfig)
|
||||
self.tools[.bufferList] = bufferListTool
|
||||
|
||||
// By default the tool buttons are shown and no tools are shown.
|
||||
|
@ -596,7 +596,7 @@ extension WorkspaceBar {
|
||||
}
|
||||
|
||||
fileprivate func layoutWithoutButtons(_ tool: WorkspaceTool) {
|
||||
let view = tool.view
|
||||
let view = tool
|
||||
let thickness = WorkspaceBar.separatorThickness
|
||||
|
||||
self.addSubview(view)
|
||||
@ -641,7 +641,7 @@ extension WorkspaceBar {
|
||||
}
|
||||
|
||||
fileprivate func layout(_ tool: WorkspaceTool) {
|
||||
let view = tool.view
|
||||
let view = tool
|
||||
let button = tool.button
|
||||
let thickness = WorkspaceBar.separatorThickness
|
||||
|
||||
|
@ -4,20 +4,25 @@
|
||||
*/
|
||||
|
||||
import Cocoa
|
||||
import PureLayout
|
||||
|
||||
protocol WorkspaceToolDelegate: class {
|
||||
|
||||
func toggle(_ tool: WorkspaceTool)
|
||||
}
|
||||
|
||||
class WorkspaceTool: Hashable {
|
||||
class WorkspaceTool: NSView {
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
static func ==(left: WorkspaceTool, right: WorkspaceTool) -> Bool {
|
||||
return left.uuid == right.uuid
|
||||
}
|
||||
|
||||
// MARK: - API
|
||||
var hashValue: Int {
|
||||
override var hashValue: Int {
|
||||
return self.uuid.hashValue
|
||||
}
|
||||
/**
|
||||
@ -50,21 +55,84 @@ class WorkspaceTool: Hashable {
|
||||
return self.bar?.workspace
|
||||
}
|
||||
|
||||
var innerToolbar: InnerToolBar?
|
||||
|
||||
let minimumDimension: CGFloat
|
||||
var dimension: CGFloat
|
||||
|
||||
init(title: String, view: NSView, minimumDimension: CGFloat = 50) {
|
||||
struct Config {
|
||||
|
||||
let title: String
|
||||
let view: NSView
|
||||
let minimumDimension: CGFloat
|
||||
|
||||
let isWithInnerToolbar: Bool
|
||||
|
||||
let customToolbar: NSView?
|
||||
let customMenuItems: [NSMenuItem]
|
||||
|
||||
init(title: String,
|
||||
view: NSView,
|
||||
minimumDimension: CGFloat = 50,
|
||||
withInnerToolbar: Bool = true,
|
||||
customToolbar: NSView? = nil,
|
||||
customMenuItems: [NSMenuItem] = [])
|
||||
{
|
||||
self.title = title
|
||||
self.view = view
|
||||
self.minimumDimension = minimumDimension
|
||||
|
||||
self.isWithInnerToolbar = withInnerToolbar
|
||||
|
||||
self.customToolbar = customToolbar
|
||||
self.customMenuItems = customMenuItems
|
||||
}
|
||||
}
|
||||
|
||||
init(_ config: Config) {
|
||||
self.title = config.title
|
||||
self.view = config.view
|
||||
self.minimumDimension = config.minimumDimension
|
||||
self.dimension = minimumDimension
|
||||
|
||||
self.button = WorkspaceToolButton(title: title)
|
||||
|
||||
super.init(frame: .zero)
|
||||
self.configureForAutoLayout()
|
||||
|
||||
self.button.tool = self
|
||||
if config.isWithInnerToolbar {
|
||||
self.innerToolbar = InnerToolBar(customToolbar: config.customToolbar, customMenuItems: config.customMenuItems)
|
||||
self.innerToolbar?.tool = self
|
||||
}
|
||||
|
||||
self.addViews()
|
||||
}
|
||||
|
||||
func toggle() {
|
||||
self.delegate?.toggle(self)
|
||||
self.isSelected = !self.isSelected
|
||||
}
|
||||
|
||||
fileprivate func addViews() {
|
||||
let view = self.view
|
||||
self.addSubview(view)
|
||||
|
||||
if let innerToolbar = self.innerToolbar {
|
||||
self.addSubview(innerToolbar)
|
||||
|
||||
innerToolbar.autoPinEdge(toSuperviewEdge: .top)
|
||||
innerToolbar.autoPinEdge(toSuperviewEdge: .right)
|
||||
innerToolbar.autoPinEdge(toSuperviewEdge: .left)
|
||||
|
||||
view.autoPinEdge(.top, to: .bottom, of: innerToolbar)
|
||||
view.autoPinEdge(toSuperviewEdge: .right)
|
||||
view.autoPinEdge(toSuperviewEdge: .bottom)
|
||||
view.autoPinEdge(toSuperviewEdge: .left)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
view.autoPinEdgesToSuperviewEdges()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user