Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Tab State, Add Window Restoration #1368

Merged
merged 4 commits into from
Jul 7, 2023
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
44 changes: 34 additions & 10 deletions CodeEdit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@
6C049A372A49E2DB00D42923 /* DirectoryEventStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C049A362A49E2DB00D42923 /* DirectoryEventStream.swift */; };
6C05A8AF284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C05A8AE284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift */; };
6C092EC62A4E803300489202 /* CodeEditTextView in Frameworks */ = {isa = PBXBuildFile; productRef = 6C092EC52A4E803300489202 /* CodeEditTextView */; };
6C092EDA2A53A58600489202 /* TabGroup+StateRestoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C092ED92A53A58600489202 /* TabGroup+StateRestoration.swift */; };
6C092EE02A53BFCF00489202 /* WorkspaceStateKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C092EDF2A53BFCF00489202 /* WorkspaceStateKey.swift */; };
6C0D0C6829E861B000AE4D3F /* SettingsSidebarFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C0D0C6729E861B000AE4D3F /* SettingsSidebarFix.swift */; };
6C0F3A3C2A1D0D5000223D19 /* CodeEditKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6C0F3A3B2A1D0D5000223D19 /* CodeEditKit */; };
6C147C4029A328BC0089B630 /* SplitViewData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C147C3F29A328560089B630 /* SplitViewData.swift */; };
Expand Down Expand Up @@ -703,6 +705,8 @@
5C4BB1E028212B1E00A92FB2 /* World.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = World.swift; sourceTree = "<group>"; };
6C049A362A49E2DB00D42923 /* DirectoryEventStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectoryEventStream.swift; sourceTree = "<group>"; };
6C05A8AE284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WorkspaceDocument+Listeners.swift"; sourceTree = "<group>"; };
6C092ED92A53A58600489202 /* TabGroup+StateRestoration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TabGroup+StateRestoration.swift"; sourceTree = "<group>"; };
6C092EDF2A53BFCF00489202 /* WorkspaceStateKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkspaceStateKey.swift; sourceTree = "<group>"; };
6C0D0C6729E861B000AE4D3F /* SettingsSidebarFix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSidebarFix.swift; sourceTree = "<group>"; };
6C147C3D29A3281D0089B630 /* TabGroupData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabGroupData.swift; sourceTree = "<group>"; };
6C147C3E29A3281D0089B630 /* TabGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabGroup.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -903,6 +907,7 @@
043C321527E3201F006AE443 /* WorkspaceDocument.swift */,
043BCF02281DA18A000AC47C /* WorkspaceDocument+Search.swift */,
6C05A8AE284D0CA3007F4EAA /* WorkspaceDocument+Listeners.swift */,
6C092EDF2A53BFCF00489202 /* WorkspaceStateKey.swift */,
);
path = Documents;
sourceTree = "<group>";
Expand Down Expand Up @@ -2025,30 +2030,47 @@
name = Frameworks;
sourceTree = "<group>";
};
6C092EDC2A53A63E00489202 /* Views */ = {
isa = PBXGroup;
children = (
6C147C4829A32A080089B630 /* EditorView.swift */,
6C53AAD729A6C4FD00EE9ED6 /* SplitView.swift */,
6C2C156029B4F52F00EA60A5 /* SplitViewModifiers.swift */,
6C2C155C29B4F4E500EA60A5 /* SplitViewReader.swift */,
6C2C155929B4F4CC00EA60A5 /* Variadic.swift */,
6C7256D629A3D7D000C2D3E0 /* SplitViewControllerView.swift */,
);
path = Views;
sourceTree = "<group>";
};
6C092EDD2A53A64900489202 /* Model */ = {
isa = PBXGroup;
children = (
6C147C4A29A32A7B0089B630 /* Environment+SplitEditor.swift */,
6C5228B429A868BD00AC48F6 /* Environment+ContentInsets.swift */,
6C2C155729B4F49100EA60A5 /* SplitViewItem.swift */,
6C147C3F29A328560089B630 /* SplitViewData.swift */,
);
path = Model;
sourceTree = "<group>";
};
6C147C3C29A328020089B630 /* TabGroup */ = {
isa = PBXGroup;
children = (
6C147C4C29A32AA30089B630 /* WorkspaceTabGroupView.swift */,
6CC9E4B129B5669900C97388 /* Environment+ActiveTabGroup.swift */,
6C147C3E29A3281D0089B630 /* TabGroup.swift */,
6C147C3D29A3281D0089B630 /* TabGroupData.swift */,
6C092ED92A53A58600489202 /* TabGroup+StateRestoration.swift */,
);
path = TabGroup;
sourceTree = "<group>";
};
6C147C4729A329E50089B630 /* SplitView */ = {
isa = PBXGroup;
children = (
6C147C4A29A32A7B0089B630 /* Environment+SplitEditor.swift */,
6C5228B429A868BD00AC48F6 /* Environment+ContentInsets.swift */,
6C147C4829A32A080089B630 /* EditorView.swift */,
6C53AAD729A6C4FD00EE9ED6 /* SplitView.swift */,
6C2C156029B4F52F00EA60A5 /* SplitViewModifiers.swift */,
6C2C155C29B4F4E500EA60A5 /* SplitViewReader.swift */,
6C2C155929B4F4CC00EA60A5 /* Variadic.swift */,
6C7256D629A3D7D000C2D3E0 /* SplitViewControllerView.swift */,
6C2C155729B4F49100EA60A5 /* SplitViewItem.swift */,
6C147C3F29A328560089B630 /* SplitViewData.swift */,
6C092EDD2A53A64900489202 /* Model */,
6C092EDC2A53A63E00489202 /* Views */,
);
path = SplitView;
sourceTree = "<group>";
Expand Down Expand Up @@ -2911,6 +2933,8 @@
B6F0517729D9E3AD00D72287 /* SourceControlGeneralView.swift in Sources */,
587B9E8929301D8F00AC7927 /* GitHubGist.swift in Sources */,
0485EB1F27E7458B00138301 /* WorkspaceCodeFileView.swift in Sources */,
6C092EDA2A53A58600489202 /* TabGroup+StateRestoration.swift in Sources */,
6C092EE02A53BFCF00489202 /* WorkspaceStateKey.swift in Sources */,
58D01C94293167DC00C5B6B4 /* Color+HEX.swift in Sources */,
6C578D8729CD345900DC73B2 /* ExtensionSceneView.swift in Sources */,
B640A9A129E2188F00715F20 /* View+NavigationBarBackButtonVisible.swift in Sources */,
Expand Down
11 changes: 9 additions & 2 deletions CodeEdit/Features/CodeFile/CodeFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,26 @@ final class CodeFileDocument: NSDocument, ObservableObject, QLPreviewItem {

override func makeWindowControllers() {
let window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 1400, height: 600),
contentRect: NSRect(x: 0, y: 0, width: 750, height: 800),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false
)
let windowController = NSWindowController(window: window)
if let fileURL {
windowController.shouldCascadeWindows = false
windowController.windowFrameAutosaveName = fileURL.path
}
addWindowController(windowController)

window.contentView = NSHostingView(rootView: SettingsInjector {
WindowCodeFileView(codeFile: self)
})

window.makeKeyAndOrderFront(nil)
window.center()

if let fileURL, UserDefaults.standard.object(forKey: "NSWindow Frame \(fileURL.path)") == nil {
window.center()
}
}

override func data(ofType _: String) throws -> Data {
Expand Down
27 changes: 10 additions & 17 deletions CodeEdit/Features/DebugArea/ViewModels/DebugAreaViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ import SwiftUI
/// A model class to host and manage data for the ``StatusBarView``
///
class DebugAreaViewModel: ObservableObject {
private let isDebugAreaViewCollapsedStateName: String
= "\(String(describing: DebugAreaViewModel.self))-IsDebugAreaViewCollapsed"
private let statusBarDrawerHeightStateName: String
= "\(String(describing: DebugAreaViewModel.self))-DebugAreaViewHeight"

/// Returns the current location of the cursor in an editing view
@Published var cursorLocation: CursorLocation = .init(line: 1, column: 1) // Implementation needed!!

Expand Down Expand Up @@ -45,16 +40,6 @@ class DebugAreaViewModel: ObservableObject {
/// Returns the font for status bar items to use
private(set) var toolbarFont: Font = .system(size: 11, weight: .medium)

/// The maximum height of the drawer
/// when isMaximized is true the height gets set to maxHeight
private(set) var maxHeight: Double = 5000

/// The default height of the drawer
private(set) var standardHeight: Double = 300

/// The minimum height of the drawer
private(set) var minHeight: Double = 100

func removeTerminals(_ ids: Set<UUID>) {
terminals.removeAll(where: { terminal in
ids.contains(terminal.id)
Expand All @@ -63,7 +48,15 @@ class DebugAreaViewModel: ObservableObject {
selectedTerminals = [terminals.last?.id ?? UUID()]
}

init() {
// !!!: Lots of things in this class can be removed, such as maxHeight, as they are defined in the UI.
func restoreFromState(_ workspace: WorkspaceDocument) {
isCollapsed = workspace.getFromWorkspaceState(.debugAreaCollapsed) as? Bool ?? false
currentHeight = workspace.getFromWorkspaceState(.debugAreaHeight) as? Double ?? 300.0
isMaximized = workspace.getFromWorkspaceState(.debugAreaMaximized) as? Bool ?? false
}

func saveRestorationState(_ workspace: WorkspaceDocument) {
workspace.addToWorkspaceState(key: .debugAreaCollapsed, value: isCollapsed)
workspace.addToWorkspaceState(key: .debugAreaHeight, value: currentHeight)
workspace.addToWorkspaceState(key: .debugAreaMaximized, value: isMaximized)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ private extension CGFloat {

final class CodeEditSplitViewController: NSSplitViewController {
private var workspace: WorkspaceDocument
private let widthStateName: String = "\(String(describing: CodeEditSplitViewController.self))-Width"
private let isNavigatorCollapsedStateName: String
= "\(String(describing: CodeEditSplitViewController.self))-IsNavigatorCollapsed"
private let isInspectorCollapsedStateName: String
= "\(String(describing: CodeEditSplitViewController.self))-IsInspectorCollapsed"
private var setWidthFromState = false
private var viewIsReady = false

Expand Down Expand Up @@ -64,19 +59,19 @@ final class CodeEditSplitViewController: NSSplitViewController {
super.viewWillAppear()

viewIsReady = false
let width = workspace.getFromWorkspaceState(key: self.widthStateName) as? CGFloat
let width = workspace.getFromWorkspaceState(.splitViewWidth) as? CGFloat
splitView.setPosition(width ?? .snapWidth, ofDividerAt: .zero)
setWidthFromState = true

if let firstSplitView = splitViewItems.first {
firstSplitView.isCollapsed = workspace.getFromWorkspaceState(
key: isNavigatorCollapsedStateName
.navigatorCollapsed
) as? Bool ?? false
}

if let lastSplitView = splitViewItems.last {
lastSplitView.isCollapsed = workspace.getFromWorkspaceState(
key: isInspectorCollapsedStateName
.inspectorCollapsed
) as? Bool ?? true
}

Expand Down Expand Up @@ -131,17 +126,17 @@ final class CodeEditSplitViewController: NSSplitViewController {
let panel = splitView.subviews[0]
let width = panel.frame.size.width
if width > 0 && setWidthFromState {
workspace.addToWorkspaceState(key: self.widthStateName, value: width)
workspace.addToWorkspaceState(key: .splitViewWidth, value: width)
}
}
}

func saveNavigatorCollapsedState(isCollapsed: Bool) {
workspace.addToWorkspaceState(key: isNavigatorCollapsedStateName, value: isCollapsed)
workspace.addToWorkspaceState(key: .navigatorCollapsed, value: isCollapsed)
}

func saveInspectorCollapsedState(isCollapsed: Bool) {
workspace.addToWorkspaceState(key: isInspectorCollapsedStateName, value: isCollapsed)
workspace.addToWorkspaceState(key: .inspectorCollapsed, value: isCollapsed)
}

/// Quick fix for list tracking separator needing to be added again after closing,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
init(window: NSWindow, workspace: WorkspaceDocument) {
super.init(window: window)
self.workspace = workspace

setupSplitView(with: workspace)

let view = CodeEditSplitView(controller: splitViewController).ignoresSafeArea()
Expand Down Expand Up @@ -189,15 +188,15 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
) -> NSToolbarItem? {
switch itemIdentifier {
case .itemListTrackingSeparator:
guard let splitViewController else {
return nil
}
guard let splitViewController else {
return nil
}

return NSTrackingSeparatorToolbarItem(
identifier: .itemListTrackingSeparator,
splitView: splitViewController.splitView,
dividerIndex: 1
)
return NSTrackingSeparatorToolbarItem(
identifier: .itemListTrackingSeparator,
splitView: splitViewController.splitView,
dividerIndex: 1
)
case .toggleFirstSidebarItem:
let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier.toggleFirstSidebarItem)
toolbarItem.label = "Navigator Sidebar"
Expand Down Expand Up @@ -242,10 +241,6 @@ final class CodeEditWindowController: NSWindowController, NSToolbarDelegate, Obs
}
}

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

private func getSelectedCodeFile() -> CodeFileDocument? {
workspace?.tabManager.activeTabGroup.selected?.fileDocument
}
Expand Down
20 changes: 20 additions & 0 deletions CodeEdit/Features/Documents/Views/WorkspaceCodeFileView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ struct WorkspaceCodeFileView: View {

var file: CEWorkspaceFile

@State private var update: Bool = false

@ViewBuilder var codeView: some View {
if let document = file.fileDocument {
Group {
Expand All @@ -28,12 +30,30 @@ struct WorkspaceCodeFileView: View {
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
if update {
Spacer()
}
Spacer()
VStack(spacing: 10) {
ProgressView()
Text("Opening \(file.name)...")
}
Spacer()
.onAppear {
Task.detached {
let contentType = try await file.url.resourceValues(forKeys: [.contentTypeKey]).contentType
let codeFile = try await CodeFileDocument(
for: file.url,
withContentsOf: file.url,
ofType: contentType?.identifier ?? ""
)
await MainActor.run {
file.fileDocument = codeFile
CodeEditDocumentController.shared.addDocument(codeFile)
update.toggle()
}
}
}
}
}

Expand Down
Loading