Skip to content

Commit aecf112

Browse files
Splitview (#1080)
* Semi working version of splitview Signed-off-by: Wouter01 <[email protected]> * added custom splitview + some debug views Signed-off-by: Wouter01 <[email protected]> * Add even splitting on new tabs * removed unused variable in SplitViewController Signed-off-by: Wouter01 <[email protected]> * Added tab selection logic Signed-off-by: Wouter01 <[email protected]> * partially fixed edgeinsets Signed-off-by: Wouter01 <[email protected]> * Fixed top toolbar edgeinsets Signed-off-by: Wouter01 <[email protected]> * Moved isBelowToolbar to environment Signed-off-by: Wouter01 <[email protected]> * Partial support for statusbarview (expanded wip) Signed-off-by: Wouter01 <[email protected]> * Fixed terminal view Signed-off-by: Wouter01 <[email protected]> * fixed some things regarding splitview Signed-off-by: Wouter01 <[email protected]> * added filter bar to terminal view Signed-off-by: Wouter01 <[email protected]> * Fixed small issues Signed-off-by: Wouter01 <[email protected]> * statusbarview height fixes Signed-off-by: Wouter01 <[email protected]> * Removed excess background Signed-off-by: Wouter01 <[email protected]> * Focus fixes Signed-off-by: Wouter01 <[email protected]> * size fixes for statusbar Signed-off-by: Wouter01 <[email protected]> * small fix Signed-off-by: Wouter01 <[email protected]> * Added ability to close splitview Signed-off-by: Wouter01 <[email protected]> * Fixed some logic regarding closing splitviews Signed-off-by: Wouter01 <[email protected]> * Refactored tabs management Signed-off-by: Wouter01 <[email protected]> * removed unused function Signed-off-by: Wouter01 <[email protected]> * Cleaned up code Signed-off-by: Wouter01 <[email protected]> * Moved over code from workspacedocument Signed-off-by: Wouter01 <[email protected]> * Further cleaned up code Signed-off-by: Wouter01 <[email protected]> * Fixed references to selectionState Signed-off-by: Wouter01 <[email protected]> * Removed references to selectionstate Signed-off-by: Wouter01 <[email protected]> * Removed commented out functions Signed-off-by: Wouter01 <[email protected]> * Bugfixes Signed-off-by: Wouter01 <[email protected]> * small fixes Signed-off-by: Wouter01 <[email protected]> * renamed variables Signed-off-by: Wouter01 <[email protected]> * Removed unneeded Task Signed-off-by: Wouter01 <[email protected]> * Fixed issue with NSSplitView Signed-off-by: Wouter01 <[email protected]> * Added functionality to split button Signed-off-by: Wouter01 <[email protected]> * Fixed issue with breadcrumbsview Signed-off-by: Wouter01 <[email protected]> * breadcrumbs are grayed out when out of focus Signed-off-by: Wouter01 <[email protected]> * Added forward/backward functionality Signed-off-by: Wouter01 <[email protected]> * small cleanup Signed-off-by: Wouter01 <[email protected]> * Added custom move buttonstyle Signed-off-by: Wouter01 <[email protected]> * Fixed some logic, removed animations Signed-off-by: Wouter01 <[email protected]> * renamed split buttons Signed-off-by: Wouter01 <[email protected]> * Fixed abug where the app would freeze if file contents are empty Signed-off-by: Wouter01 <[email protected]> * Fixed temporary tabs Signed-off-by: Wouter01 <[email protected]> * Fixed force unwrap crash Signed-off-by: Wouter01 <[email protected]> * removed prints Signed-off-by: Wouter01 <[email protected]> * Removed TODOs Signed-off-by: Wouter01 <[email protected]> * fixed warnings Signed-off-by: Wouter01 <[email protected]> * Added docs Signed-off-by: Wouter01 <[email protected]> * Reorganised some files Signed-off-by: Wouter01 <[email protected]> * Fixed scrolling to active tab Signed-off-by: Wouter01 <[email protected]> * Fixed warning Signed-off-by: Wouter01 <[email protected]> * Fixed tabbar scroll glitch Signed-off-by: Wouter01 <[email protected]> * fixed tabbarview active state Signed-off-by: Wouter01 <[email protected]> * renamed WorkspaceSplitViewData to SplitViewData Signed-off-by: Wouter01 <[email protected]> * adds splitview flattening Signed-off-by: Wouter01 <[email protected]> * Fixed warning Signed-off-by: Wouter01 <[email protected]> * Removed unused dependency Signed-off-by: Wouter01 <[email protected]> * Changed representation of temporary tab Signed-off-by: Wouter01 <[email protected]> * Fixed some issues regarding tabbarview Signed-off-by: Wouter01 <[email protected]> * Fixed animation Signed-off-by: Wouter01 <[email protected]> * Removed splitview button animation Signed-off-by: Wouter01 <[email protected]> * fixed text coloring in light mode Signed-off-by: Wouter01 <[email protected]> * improvements to tabbar and breadcrumbs in light mode Signed-off-by: Wouter01 <[email protected]> * New splitted editor now has focus by default Signed-off-by: Wouter01 <[email protected]> * Empty tabgroup can get focus Signed-off-by: Wouter01 <[email protected]> * Fixed memory leak Signed-off-by: Wouter01 <[email protected]> * test for improved focus Signed-off-by: Wouter01 <[email protected]> * other fix for focus Signed-off-by: Wouter01 <[email protected]> * new try for focus Signed-off-by: Wouter01 <[email protected]> * reverted changes Signed-off-by: Wouter01 <[email protected]> * code style fixes Signed-off-by: Wouter01 <[email protected]> * Code style fixes Signed-off-by: Wouter01 <[email protected]> * code style fix Signed-off-by: Wouter01 <[email protected]> * Code style fixes Signed-off-by: Wouter01 <[email protected]> * Added docs Signed-off-by: Wouter01 <[email protected]> * Fixed scroll to active tab on editor width change Signed-off-by: Wouter01 <[email protected]> * Fixed warnings Signed-off-by: Wouter01 <[email protected]> * Fix for focus Signed-off-by: Wouter01 <[email protected]> * Fixed issues regarding tabbarview Signed-off-by: Wouter01 <[email protected]> * Fixed minor issues Signed-off-by: Wouter01 <[email protected]> * Fixed focus issue for history buttons Signed-off-by: Wouter01 <[email protected]> * removed transparent titlebar for native tab style Signed-off-by: Wouter01 <[email protected]> --------- Signed-off-by: Wouter01 <[email protected]> Co-authored-by: Khan Winter <[email protected]>
1 parent a2b225f commit aecf112

File tree

55 files changed

+1758
-886
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1758
-886
lines changed

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 108 additions & 11 deletions
Large diffs are not rendered by default.

CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 11 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CodeEdit/Features/AppPreferences/Model/AppPreferencesModel.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ final class AppPreferencesModel: ObservableObject {
3232
var preferences: AppPreferences {
3333
didSet {
3434
try? savePreferences()
35-
objectWillChange.send()
3635
}
3736
}
3837

CodeEdit/Features/Breadcrumbs/Views/BreadcrumbsComponent.swift

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
import SwiftUI
9+
import Combine
910

1011
struct BreadcrumbsComponent: View {
1112

@@ -59,14 +60,19 @@ struct BreadcrumbsComponent: View {
5960
}
6061

6162
struct NSPopUpButtonView<ItemType>: NSViewRepresentable where ItemType: Equatable {
62-
@Binding var selection: ItemType
63+
@Binding
64+
var selection: ItemType
65+
6366
var popupCreator: () -> NSPopUpButton
6467

6568
typealias NSViewType = NSPopUpButton
6669

6770
func makeNSView(context: NSViewRepresentableContext<NSPopUpButtonView>) -> NSPopUpButton {
6871
let newPopupButton = popupCreator()
6972
setPopUpFromSelection(newPopupButton, selection: selection)
73+
if let menu = newPopupButton.menu {
74+
context.coordinator.registerForChanges(in: menu)
75+
}
7076
return newPopupButton
7177
}
7278

@@ -89,24 +95,24 @@ struct BreadcrumbsComponent: View {
8995
}
9096

9197
class Coordinator: NSObject {
92-
var parent: NSPopUpButtonView!
98+
var parent: NSPopUpButtonView
99+
100+
var cancellable: AnyCancellable?
93101

94102
init(_ parent: NSPopUpButtonView) {
95-
super.init()
96103
self.parent = parent
97-
NotificationCenter.default.addObserver(
98-
self,
99-
selector: #selector(dropdownItemSelected),
100-
name: NSMenu.didSendActionNotification,
101-
object: nil
102-
)
104+
super.init()
103105
}
104106

105-
@objc func dropdownItemSelected(_ notification: NSNotification) {
106-
let menuItem = (notification.userInfo?["MenuItem"])! as? NSMenuItem
107-
if let selection = menuItem?.representedObject as? ItemType {
108-
parent.selection = selection
109-
}
107+
func registerForChanges(in menu: NSMenu) {
108+
cancellable = NotificationCenter.default
109+
.publisher(for: NSMenu.didSendActionNotification, object: menu)
110+
.sink { notification in
111+
if let menuItem = notification.userInfo?["MenuItem"] as? NSMenuItem,
112+
let selection = menuItem as? ItemType {
113+
self.parent.selection = selection
114+
}
115+
}
110116
}
111117
}
112118
}

CodeEdit/Features/Breadcrumbs/Views/BreadcrumbsView.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,14 @@ struct BreadcrumbsView: View {
1515
@Environment(\.colorScheme)
1616
private var colorScheme
1717

18+
@Environment(\.isActiveTabGroup)
19+
private var isActiveTabGroup
20+
1821
@Environment(\.controlActiveState)
1922
private var activeState
2023

24+
static let height = 27.0
25+
2126
init(
2227
file: WorkspaceClient.FileItem,
2328
tappedOpenFile: @escaping (WorkspaceClient.FileItem) -> Void
@@ -51,8 +56,10 @@ struct BreadcrumbsView: View {
5156
}
5257
.padding(.horizontal, 10)
5358
}
54-
.frame(height: 27, alignment: .center)
55-
.background(EffectView(.headerView).frame(height: 27))
59+
.frame(height: Self.height, alignment: .center)
60+
.opacity(activeState == .inactive ? 0.8 : 1.0)
61+
.grayscale(isActiveTabGroup ? 0.0 : 1.0)
62+
.background(EffectView(.headerView).frame(height: Self.height))
5663
}
5764

5865
private var chevron: some View {

CodeEdit/Features/CodeFile/CodeFileView.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ struct CodeFileView: View {
6060
return AppPreferencesModel.shared.preferences.textEditing.font.current()
6161
}()
6262

63+
@Environment(\.edgeInsets)
64+
private var edgeInsets
65+
66+
@EnvironmentObject
67+
private var tabgroup: TabGroupData
68+
6369
var body: some View {
6470
CodeEditTextView(
6571
$codeFile.content,
@@ -70,7 +76,8 @@ struct CodeFileView: View {
7076
lineHeight: $prefs.preferences.textEditing.lineHeightMultiple,
7177
wrapLines: $prefs.preferences.textEditing.wrapLinesToEditorWidth,
7278
cursorPosition: codeFile.$cursorPosition,
73-
useThemeBackground: prefs.preferences.theme.useThemeBackground
79+
useThemeBackground: prefs.preferences.theme.useThemeBackground,
80+
contentInsets: edgeInsets.nsEdgeInsets
7481
)
7582
.id(codeFile.fileURL)
7683
.background {
@@ -90,7 +97,8 @@ struct CodeFileView: View {
9097
}
9198
}
9299
.disabled(!editable)
93-
.frame(maxHeight: .infinity)
100+
// minHeight zero fixes a bug where the app would freeze if the contents of the file are empty.
101+
.frame(minHeight: .zero, maxHeight: .infinity)
94102
.onChange(of: ThemeModel.shared.selectedTheme) { newValue in
95103
guard let theme = newValue else { return }
96104
self.selectedTheme = theme

CodeEdit/Features/Documents/Controllers/CodeEditWindowController.swift

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate {
7171
let splitVC = CodeEditSplitViewController(workspace: workspace, feedbackPerformer: feedbackPerformer)
7272

7373
let navigatorView = NavigatorSidebarView(workspace: workspace)
74+
.environmentObject(workspace)
75+
.environmentObject(workspace.tabManager)
76+
7477
let navigator = NSSplitViewItem(
7578
sidebarWithViewController: NSHostingController(rootView: navigatorView)
7679
)
@@ -80,7 +83,9 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate {
8083
splitVC.addSplitViewItem(navigator)
8184

8285
let workspaceView = WindowObserver(window: window!) {
83-
WorkspaceView(workspace: workspace)
86+
WorkspaceView()
87+
.environmentObject(workspace)
88+
.environmentObject(workspace.tabManager)
8489
}
8590

8691
let mainContent = NSSplitViewItem(
@@ -90,6 +95,9 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate {
9095
splitVC.addSplitViewItem(mainContent)
9196

9297
let inspectorView = InspectorSidebarView(workspace: workspace)
98+
.environmentObject(workspace)
99+
.environmentObject(workspace.tabManager)
100+
93101
let inspector = NSSplitViewItem(
94102
viewController: NSHostingController(rootView: inspectorView)
95103
)
@@ -113,12 +121,10 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate {
113121
if prefs.preferences.general.tabBarStyle == .native {
114122
// Set titlebar background as transparent by default in order to
115123
// style the toolbar background in native tab bar style.
116-
self.window?.titlebarAppearsTransparent = true
117124
self.window?.titlebarSeparatorStyle = .none
118125
} else {
119126
// In xcode tab bar style, we use default toolbar background with
120127
// line separator.
121-
self.window?.titlebarAppearsTransparent = false
122128
self.window?.titlebarSeparatorStyle = .automatic
123129
}
124130
self.window?.toolbar = toolbar
@@ -234,17 +240,12 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate {
234240
}
235241

236242
private func getSelectedCodeFile() -> CodeFileDocument? {
237-
guard let id = workspace?.selectionState.selectedId else { return nil }
238-
guard let item = workspace?.selectionState.openFileItems.first(where: { item in
239-
item.tabID == id
240-
}) else { return nil }
241-
guard let file = workspace?.selectionState.openedCodeFiles[item] else { return nil }
242-
return file
243+
workspace?.tabManager.activeTabGroup.selected?.fileDocument
243244
}
244245

245246
@IBAction func saveDocument(_ sender: Any) {
246247
getSelectedCodeFile()?.save(sender)
247-
workspace?.convertTemporaryTab()
248+
workspace?.tabManager.activeTabGroup.temporaryTab = nil
248249
}
249250

250251
@IBAction func openCommandPalette(_ sender: Any) {
@@ -283,11 +284,13 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate {
283284
} else {
284285
let panel = OverlayPanel()
285286
self.quickOpenPanel = panel
286-
let contentView = QuickOpenView(
287-
state: state,
288-
onClose: { panel.close() },
289-
openFile: workspace.openTab(item:)
290-
)
287+
288+
let contentView = QuickOpenView(state: state) {
289+
panel.close()
290+
} openFile: { file in
291+
workspace.tabManager.openTab(item: file)
292+
}
293+
291294
panel.contentView = NSHostingView(rootView: contentView)
292295
window?.addChildWindow(panel, ordered: .above)
293296
panel.makeKeyAndOrderFront(self)

CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,37 @@ import SwiftUI
99
import UniformTypeIdentifiers
1010

1111
struct WorkspaceCodeFileView: View {
12+
13+
@EnvironmentObject
14+
private var tabManager: TabManager
15+
1216
@EnvironmentObject
13-
private var workspace: WorkspaceDocument
17+
private var tabgroup: TabGroupData
18+
19+
var file: WorkspaceClient.FileItem
1420

1521
@StateObject
1622
private var prefs: AppPreferencesModel = .shared
1723

1824
@ViewBuilder
1925
var codeView: some View {
20-
ZStack {
21-
if let item = workspace.selectionState.openFileItems.first(where: { file in
22-
if file.tabID == workspace.selectionState.selectedId {
23-
print("Item loaded is: ", file.url)
26+
if let document = file.fileDocument {
27+
Group {
28+
switch document.typeOfFile {
29+
case .some(.text), .some(.data):
30+
CodeFileView(codeFile: document)
31+
default:
32+
otherFileView(document, for: file)
2433
}
25-
return file.tabID == workspace.selectionState.selectedId
26-
}) {
27-
if let fileItem = workspace.selectionState.openedCodeFiles[item] {
28-
if fileItem.typeOfFile == .text || fileItem.typeOfFile == .data {
29-
codeFileView(fileItem, for: item)
30-
} else {
31-
otherFileView(fileItem, for: item)
32-
}
33-
}
34-
} else {
35-
Text("No Editor")
36-
.font(.system(size: 17))
37-
.foregroundColor(.secondary)
38-
.frame(minHeight: 0)
39-
.clipped()
4034
}
41-
}
42-
.frame(maxWidth: .infinity, maxHeight: .infinity)
43-
}
44-
45-
@ViewBuilder
46-
private func codeFileView(
47-
_ codeFile: CodeFileDocument,
48-
for item: WorkspaceClient.FileItem
49-
) -> some View {
50-
VStack(spacing: 0) {
51-
BreadcrumbsView(file: item, tappedOpenFile: workspace.openTab(item:))
52-
Divider()
53-
CodeFileView(codeFile: codeFile)
35+
.frame(maxWidth: .infinity, maxHeight: .infinity)
36+
} else {
37+
Spacer()
38+
VStack(spacing: 10) {
39+
ProgressView()
40+
Text("Opening \(file.fileName)...")
41+
}
42+
Spacer()
5443
}
5544
}
5645

@@ -60,8 +49,6 @@ struct WorkspaceCodeFileView: View {
6049
for item: WorkspaceClient.FileItem
6150
) -> some View {
6251
VStack(spacing: 0) {
63-
BreadcrumbsView(file: item, tappedOpenFile: workspace.openTab(item:))
64-
Divider()
6552

6653
if let url = otherFile.previewItemURL,
6754
let image = NSImage(contentsOf: url),

CodeEdit/Features/Documents/WorkspaceDocument+Selection.swift

Lines changed: 0 additions & 65 deletions
This file was deleted.

0 commit comments

Comments
 (0)