Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 149 additions & 3 deletions CodeEdit/Documents/CodeEditWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,155 @@ import SwiftUI
import CodeFile
import Overlays

class CodeEditWindowController: NSWindowController {
class CodeEditWindowController: NSWindowController, NSToolbarDelegate {

var workspace: WorkspaceDocument?
var quickOpenPanel: OverlayPanel?

private var splitViewController: NSSplitViewController! {
get { return contentViewController as? NSSplitViewController }
set { contentViewController = newValue }
}

init(window: NSWindow, workspace: WorkspaceDocument) {
super.init(window: window)
self.workspace = workspace

setupSplitView(with: workspace)
setupToolbar()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func setupSplitView(with workspace: WorkspaceDocument) {
let splitVC = NSSplitViewController()

let navigatorView = NavigatorSidebar(workspace: workspace, windowController: self)
let navigator = NSSplitViewItem(
sidebarWithViewController: NSHostingController(rootView: navigatorView)
)
navigator.minimumThickness = 260
splitVC.addSplitViewItem(navigator)

let workspaceView = WorkspaceView(windowController: self, workspace: workspace)
let mainContent = NSSplitViewItem(
viewController: NSHostingController(rootView: workspaceView)
)
splitVC.addSplitViewItem(mainContent)

let inspectorView = InspectorSidebar(workspace: workspace, windowController: self)
let inspector = NSSplitViewItem(
viewController: NSHostingController(rootView: inspectorView)
)
inspector.minimumThickness = 260
inspector.maximumThickness = 260
inspector.isCollapsed = true
inspector.collapseBehavior = .preferResizingSiblingsWithFixedSplitView
splitVC.addSplitViewItem(inspector)

self.splitViewController = splitVC
}

private func setupToolbar() {
let toolbar = NSToolbar(identifier: UUID().uuidString)
toolbar.delegate = self
toolbar.displayMode = .labelOnly
self.window?.toolbarStyle = .unifiedCompact
self.window?.titlebarSeparatorStyle = .none
self.window?.toolbar = toolbar
}

// MARK: - Toolbar

func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [
.toggleFirstSidebarItem,
.sidebarTrackingSeparator,
.flexibleSpace,
.flexibleSpace,
.toggleLastSidebarItem
]
}

func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [
.toggleFirstSidebarItem,
.sidebarTrackingSeparator,
.flexibleSpace,
.itemListTrackingSeparator,
.toggleLastSidebarItem
]
}

// swiftlint:disable all
func toolbar(
_ toolbar: NSToolbar,
itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier,
willBeInsertedIntoToolbar flag: Bool
) -> NSToolbarItem? {
switch itemIdentifier {
case .itemListTrackingSeparator:
if ((splitViewController) != nil) {
return NSTrackingSeparatorToolbarItem(
identifier: .itemListTrackingSeparator,
splitView: splitViewController.splitView,
dividerIndex: 1
)
} else {
return nil
}
case .toggleFirstSidebarItem:
let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier.toggleFirstSidebarItem)
toolbarItem.label = "Navigator Sidebar"
toolbarItem.paletteLabel = " Navigator Sidebar"
toolbarItem.toolTip = "Hide or show the Navigator"
toolbarItem.isBordered = true
toolbarItem.target = self
toolbarItem.action = #selector(self.toggleFirstPanel)
toolbarItem.image = NSImage(
systemSymbolName: "sidebar.leading",
accessibilityDescription: nil
)?.withSymbolConfiguration(.init(scale: .large))

return toolbarItem
case .toggleLastSidebarItem:
let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier.toggleFirstSidebarItem)
toolbarItem.label = "Inspector Sidebar"
toolbarItem.paletteLabel = "Inspector Sidebar"
toolbarItem.toolTip = "Hide or show the Inspectors"
toolbarItem.isBordered = true
toolbarItem.target = self
toolbarItem.action = #selector(self.toggleLastPanel)
toolbarItem.image = NSImage(
systemSymbolName: "sidebar.trailing",
accessibilityDescription: nil
)?.withSymbolConfiguration(.init(scale: .large))

return toolbarItem
default:
return NSToolbarItem(itemIdentifier: itemIdentifier)
}
}

override func windowDidLoad() {
super.windowDidLoad()
}

@objc func toggleFirstPanel() {
guard let firstSplitView = splitViewController.splitViewItems.first else { return }
firstSplitView.animator().isCollapsed.toggle()
}

// Implement this method to handle any initialization after your window controller's
// window has been loaded from its nib file.
@objc func toggleLastPanel() {
guard let lastSplitView = splitViewController.splitViewItems.last else { return }
lastSplitView.animator().isCollapsed.toggle()
if lastSplitView.animator().isCollapsed {
window?.toolbar?.removeItem(at: 3)
} else {
window?.toolbar?.insertItem(withItemIdentifier: .itemListTrackingSeparator, at: 3)
}
}

private func getSelectedCodeFile() -> CodeFileDocument? {
Expand Down Expand Up @@ -57,3 +197,9 @@ class CodeEditWindowController: NSWindowController {
}
}
}

private extension NSToolbarItem.Identifier {
static let toggleFirstSidebarItem: NSToolbarItem.Identifier = NSToolbarItem.Identifier("ToggleFirstSidebarItem")
static let toggleLastSidebarItem: NSToolbarItem.Identifier = NSToolbarItem.Identifier("ToggleLastSidebarItem")
static let itemListTrackingSeparator = NSToolbarItem.Identifier("ItemListTrackingSeparator")
}
14 changes: 5 additions & 9 deletions CodeEdit/Documents/WorkspaceDocument.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,11 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate {
backing: .buffered, defer: false
)
window.center()
window.toolbar = NSToolbar(identifier: UUID().uuidString)
window.toolbarStyle = .unifiedCompact
window.titlebarSeparatorStyle = .line
window.toolbar?.displayMode = .iconOnly
window.toolbar?.insertItem(withItemIdentifier: .toggleSidebar, at: 0)
let windowController = CodeEditWindowController(window: window)
windowController.workspace = self
let contentView = WorkspaceView(windowController: windowController, workspace: self)
window.contentView = NSHostingView(rootView: contentView)
window.minSize = .init(width: 1000, height: 600)
let windowController = CodeEditWindowController(
window: window,
workspace: self
)
self.addWindowController(windowController)
}

Expand Down
1 change: 1 addition & 0 deletions CodeEdit/InspectorSidebar/InspectorSidebar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct InspectorSidebar: View {
}
.frame(
minWidth: 250,
idealWidth: 260,
minHeight: 0,
maxHeight: .infinity,
alignment: .center
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ struct FindNavigatorResultList: View {
state.workspace.openFile(item: foundFile.file)
}
}
}.onChange(of: selectedResult) { newValue in
}
.listStyle(.sidebar)
.onChange(of: selectedResult) { newValue in
if let file = newValue?.file {
state.workspace.openFile(item: file)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct ProjectNavigator: View {
.padding(.vertical, 8)
}
}
.listStyle(.sidebar)
.listRowInsets(.init())
.onChange(of: selection) { newValue in
guard let id = newValue,
Expand Down
34 changes: 10 additions & 24 deletions CodeEdit/WorkspaceView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,21 @@ struct WorkspaceView: View {
var showInspector = true

var body: some View {
NavigationView {
ZStack {
if workspace.workspaceClient != nil {
content
WorkspaceCodeFileView(windowController: windowController, workspace: workspace)
.safeAreaInset(edge: .bottom) {
if let url = workspace.fileURL {
StatusBarView(workspaceURL: url)
}
}
.overlay(alignment: .top) {
Divider()
}
} else {
EmptyView()
}
}
.frame(minWidth: 1000, minHeight: 600)
.alert(alertTitle, isPresented: $showingAlert, actions: {
Button(
action: { showingAlert = false },
Expand All @@ -55,27 +62,6 @@ struct WorkspaceView: View {
}
}
}

@ViewBuilder
private var content: some View {
NavigatorSidebar(workspace: workspace, windowController: windowController)
.frame(minWidth: 250)

HSplitView {
ZStack {
WorkspaceCodeFileView(windowController: windowController, workspace: workspace)
.frame(minWidth: 500, maxHeight: .infinity)
}
.safeAreaInset(edge: .bottom) {
if let url = workspace.fileURL {
StatusBarView(workspaceURL: url)
}
}
.layoutPriority(1)
InspectorSidebar(workspace: workspace, windowController: windowController)
.frame(minWidth: 260, idealWidth: 300, maxHeight: .infinity)
}
}
}

struct WorkspaceView_Previews: PreviewProvider {
Expand Down