From 0993639c6937349e6c45407a134b40ac831cc2fb Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 16:54:11 -0500 Subject: [PATCH 01/25] Improved overall tab style to feel more native to macOS --- CodeEdit.xcodeproj/project.pbxproj | 22 +++++++ .../xcshareddata/swiftpm/Package.resolved | 9 +++ CodeEdit/Rows/FileTabRow.swift | 58 +++++++++++-------- CodeEdit/SideBar/SideBarItem.swift | 1 + CodeEdit/TabBar/TabBar.swift | 26 ++++++--- CodeEdit/TabBar/TabBarItem.swift | 19 +++++- CodeEdit/Welcome/RecentProjectsView.swift | 16 ++++- 7 files changed, 114 insertions(+), 37 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 15858e2ffd..3137e43ff6 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 5CF38A5E27E48E6C0096A0F7 /* CodeFile in Frameworks */ = {isa = PBXBuildFile; productRef = 5CF38A5D27E48E6C0096A0F7 /* CodeFile */; }; B658FB3427DA9E1000EA4DBD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3327DA9E1000EA4DBD /* Assets.xcassets */; }; B658FB3727DA9E1000EA4DBD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3627DA9E1000EA4DBD /* Preview Assets.xcassets */; }; + B65E614627E6765D00255275 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = B65E614527E6765D00255275 /* Introspect */; }; D70F5E2C27E4E8CF004EE4B9 /* WelcomeModule in Frameworks */ = {isa = PBXBuildFile; productRef = D70F5E2B27E4E8CF004EE4B9 /* WelcomeModule */; }; D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7211D4227E066CE008F2ED7 /* Localized+Ex.swift */; }; D7211D4727E06BFE008F2ED7 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D7211D4927E06BFE008F2ED7 /* Localizable.strings */; }; @@ -103,6 +104,7 @@ buildActionMask = 2147483647; files = ( 5C403B8F27E20F8000788241 /* WorkspaceClient in Frameworks */, + B65E614627E6765D00255275 /* Introspect in Frameworks */, D70F5E2C27E4E8CF004EE4B9 /* WelcomeModule in Frameworks */, 5CF38A5E27E48E6C0096A0F7 /* CodeFile in Frameworks */, ); @@ -298,6 +300,7 @@ 5C403B8E27E20F8000788241 /* WorkspaceClient */, 5CF38A5D27E48E6C0096A0F7 /* CodeFile */, D70F5E2B27E4E8CF004EE4B9 /* WelcomeModule */, + B65E614527E6765D00255275 /* Introspect */, ); productName = CodeEdit; productReference = B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */; @@ -375,6 +378,9 @@ de, ); mainGroup = B658FB2327DA9E0F00EA4DBD; + packageReferences = ( + B65E614427E6765D00255275 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, + ); productRefGroup = B658FB2D27DA9E0F00EA4DBD /* Products */; projectDirPath = ""; projectRoot = ""; @@ -846,6 +852,17 @@ }; /* End XCConfigurationList section */ +/* Begin XCRemoteSwiftPackageReference section */ + B65E614427E6765D00255275 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/siteline/SwiftUI-Introspect"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.1.4; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + /* Begin XCSwiftPackageProductDependency section */ 5C403B8E27E20F8000788241 /* WorkspaceClient */ = { isa = XCSwiftPackageProductDependency; @@ -855,6 +872,11 @@ isa = XCSwiftPackageProductDependency; productName = CodeFile; }; + B65E614527E6765D00255275 /* Introspect */ = { + isa = XCSwiftPackageProductDependency; + package = B65E614427E6765D00255275 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */; + productName = Introspect; + }; D70F5E2B27E4E8CF004EE4B9 /* WelcomeModule */ = { isa = XCSwiftPackageProductDependency; productName = WelcomeModule; diff --git a/CodeEdit.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CodeEdit.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8450bfb4c9..7d8fafa3f9 100644 --- a/CodeEdit.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CodeEdit.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -27,6 +27,15 @@ "revision": "f8a9c997c3c1dab4e216a8ec9014e23144cbab37", "version": "1.9.0" } + }, + { + "package": "Introspect", + "repositoryURL": "https://github.com/siteline/SwiftUI-Introspect", + "state": { + "branch": null, + "revision": "f2616860a41f9d9932da412a8978fec79c06fe24", + "version": "0.1.4" + } } ] }, diff --git a/CodeEdit/Rows/FileTabRow.swift b/CodeEdit/Rows/FileTabRow.swift index 610be85fde..c2c49d7069 100644 --- a/CodeEdit/Rows/FileTabRow.swift +++ b/CodeEdit/Rows/FileTabRow.swift @@ -9,16 +9,18 @@ import SwiftUI import WorkspaceClient struct FileTabRow: View { - @State var mouseHovering = false - + @State var isHoveringClose: Bool = false + var fileItem: WorkspaceClient.FileItem var isSelected: Bool - var closeAction: () -> Void + var isHovering: Bool + var closeAction: () -> Void + var body: some View { - let showingCloseButton = mouseHovering || isSelected + let showingCloseButton = isHovering - HStack { + HStack(alignment: .center, spacing: 5) { ZStack { if isSelected { // Create a hidden button, if the tab is selected @@ -31,32 +33,37 @@ struct FileTabRow: View { .opacity(0) .keyboardShortcut("w", modifiers: [.command]) } - - Button(action: closeAction) { - Image(systemName: showingCloseButton ? "xmark.square.fill" : fileItem.systemImage) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 12, height: 12) + + Button(action: closeAction, label: { + Rectangle() + .fill(isHoveringClose ? Color(nsColor: .secondaryLabelColor).opacity(0.28) : Color(.clear)) + .frame(width: 16, height: 16) + .cornerRadius(2) + .overlay( + Image(systemName: "xmark") + .font(.system(size: 9.5, weight: .medium, design: .rounded)) + .foregroundColor(.secondary) + ) + }) + .buttonStyle(PlainButtonStyle()) + .accessibilityLabel(Text("Close")) + .opacity(showingCloseButton ? 1 : 0) + .onHover { hover in + isHoveringClose = hover } - .buttonStyle(.plain) - } + } + Image(systemName: fileItem.systemImage) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 12, height: 12) Text(fileItem.url.lastPathComponent) .font(.system(size: 11.0)) .lineLimit(1) - .padding(.leading, 3) - } - .padding(.horizontal) - .onHover { hover in - mouseHovering = hover - DispatchQueue.main.async { - if hover { - NSCursor.arrow.push() - } else { - NSCursor.pop() - } - } } + .padding(.leading, 4) + .padding(.trailing, 28) + } } @@ -67,6 +74,7 @@ struct FileTabRow_Previews: PreviewProvider { url: URL(string: "Code.swift")! ), isSelected: false, + isHovering: false, closeAction: {} ) .frame(width: 160.0, height: 28.0) diff --git a/CodeEdit/SideBar/SideBarItem.swift b/CodeEdit/SideBar/SideBarItem.swift index a18c871774..7a43f82603 100644 --- a/CodeEdit/SideBar/SideBarItem.swift +++ b/CodeEdit/SideBar/SideBarItem.swift @@ -36,6 +36,7 @@ struct SideBarItem: View { .safeAreaInset(edge: .top, spacing: 0) { VStack(spacing: 0) { TabBar(windowController: windowController, workspace: workspace) + CustomDivider() BreadcrumbsView(item, workspace: workspace) } } diff --git a/CodeEdit/TabBar/TabBar.swift b/CodeEdit/TabBar/TabBar.swift index 8e0337cd57..5ca451bb03 100644 --- a/CodeEdit/TabBar/TabBar.swift +++ b/CodeEdit/TabBar/TabBar.swift @@ -8,10 +8,23 @@ import SwiftUI import WorkspaceClient +struct CustomDivider: View { + @Environment(\.colorScheme) var colorScheme + let height: CGFloat = 1 + + var body: some View { + Group { + Rectangle() + } + .frame(height: height) + .foregroundColor(colorScheme == .dark ? Color(nsColor: .black) : Color(nsColor: .separatorColor)) + } +} + struct TabBar: View { var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument - + var tabBarHeight = 28.0 var body: some View { @@ -27,7 +40,8 @@ struct TabBar: View { label: { if isActive { TabBarItem(item: item, windowController: windowController, workspace: workspace) - .background(Material.bar) + .background(BlurView(material: NSVisualEffectView.Material.titlebar, + blendingMode: NSVisualEffectView.BlendingMode.withinWindow)) } else { TabBarItem(item: item, windowController: windowController, workspace: workspace) } @@ -47,12 +61,10 @@ struct TabBar: View { } } } - - Divider() - .foregroundColor(.gray) - .frame(height: 1.0) } - .background(Material.regular) + .background(BlurView(material: NSVisualEffectView.Material.windowBackground, + blendingMode: NSVisualEffectView.BlendingMode.withinWindow)) + } func getTabId(fileName: String) -> KeyEquivalent { diff --git a/CodeEdit/TabBar/TabBarItem.swift b/CodeEdit/TabBar/TabBarItem.swift index 91cc93426f..96ac474419 100644 --- a/CodeEdit/TabBar/TabBarItem.swift +++ b/CodeEdit/TabBar/TabBarItem.swift @@ -9,6 +9,8 @@ import SwiftUI import WorkspaceClient struct TabBarItem: View { + @State var isHovering: Bool = false + var item: WorkspaceClient.FileItem var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument @@ -19,15 +21,26 @@ struct TabBarItem: View { let isActive = item.id == workspace.selectedId HStack(spacing: 0.0) { - FileTabRow(fileItem: item, isSelected: isActive) { + FileTabRow(fileItem: item, isSelected: isActive, isHovering: isHovering) { withAnimation { workspace.closeFileTab(item: item) } } - Divider() } + .background(Color(nsColor: .secondaryLabelColor).opacity(!isActive && isHovering ? 0.11 : 0).animation(.easeInOut(duration: 0.15))) + .frame(height: tabBarHeight) - .foregroundColor(isActive ? .primary : .gray) + .foregroundColor(isActive ? .primary : .secondary) + .onHover { hover in + isHovering = hover + DispatchQueue.main.async { + if hover { + NSCursor.arrow.push() + } else { + NSCursor.pop() + } + } + } } } diff --git a/CodeEdit/Welcome/RecentProjectsView.swift b/CodeEdit/Welcome/RecentProjectsView.swift index 2afcd619ae..ff14d42e1d 100644 --- a/CodeEdit/Welcome/RecentProjectsView.swift +++ b/CodeEdit/Welcome/RecentProjectsView.swift @@ -4,11 +4,23 @@ // // Created by Ziyuan Zhao on 2022/3/18. // - +import Introspect import SwiftUI import WelcomeModule import WorkspaceClient +extension List { + /// List on macOS uses an opaque background with no option for + /// removing/changing it. listRowBackground() doesn't work either. + /// This workaround works because List is backed by NSTableView. + func removeBackground() -> some View { + return introspectTableView { tableView in + tableView.backgroundColor = .clear + tableView.enclosingScrollView!.drawsBackground = false + } + } +} + struct RecentProjectsView: View { @State var recentProjectPaths: [String] = UserDefaults.standard.array(forKey: "recentProjectPaths") as? [String] ?? [] @@ -68,7 +80,7 @@ struct RecentProjectsView: View { .buttonStyle(.borderless) .keyboardShortcut(.defaultAction) } - } + }.removeBackground() } else { emptyView } From 85f29ee92e6ccb48c255237f7cfa0c8d07a3f960 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 16:59:37 -0500 Subject: [PATCH 02/25] Fixed lint error --- CodeEdit/Rows/FileTabRow.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CodeEdit/Rows/FileTabRow.swift b/CodeEdit/Rows/FileTabRow.swift index c2c49d7069..ca22762489 100644 --- a/CodeEdit/Rows/FileTabRow.swift +++ b/CodeEdit/Rows/FileTabRow.swift @@ -33,10 +33,11 @@ struct FileTabRow: View { .opacity(0) .keyboardShortcut("w", modifiers: [.command]) } - Button(action: closeAction, label: { Rectangle() - .fill(isHoveringClose ? Color(nsColor: .secondaryLabelColor).opacity(0.28) : Color(.clear)) + .fill(isHoveringClose + ? Color(nsColor: .secondaryLabelColor).opacity(0.28) + : Color(.clear)) .frame(width: 16, height: 16) .cornerRadius(2) .overlay( @@ -51,7 +52,6 @@ struct FileTabRow: View { .onHover { hover in isHoveringClose = hover } - } Image(systemName: fileItem.systemImage) .resizable() From 21639764bdb9f145beb7c1dd67feb7cda951dc97 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 17:04:45 -0500 Subject: [PATCH 03/25] More lint error fixes --- CodeEdit/Rows/FileTabRow.swift | 5 ----- CodeEdit/TabBar/TabBar.swift | 3 --- CodeEdit/TabBar/TabBarItem.swift | 5 ----- 3 files changed, 13 deletions(-) diff --git a/CodeEdit/Rows/FileTabRow.swift b/CodeEdit/Rows/FileTabRow.swift index ca22762489..b94dd09e4a 100644 --- a/CodeEdit/Rows/FileTabRow.swift +++ b/CodeEdit/Rows/FileTabRow.swift @@ -10,16 +10,12 @@ import WorkspaceClient struct FileTabRow: View { @State var isHoveringClose: Bool = false - var fileItem: WorkspaceClient.FileItem var isSelected: Bool var isHovering: Bool - var closeAction: () -> Void - var body: some View { let showingCloseButton = isHovering - HStack(alignment: .center, spacing: 5) { ZStack { if isSelected { @@ -63,7 +59,6 @@ struct FileTabRow: View { } .padding(.leading, 4) .padding(.trailing, 28) - } } diff --git a/CodeEdit/TabBar/TabBar.swift b/CodeEdit/TabBar/TabBar.swift index 5ca451bb03..a0782bb767 100644 --- a/CodeEdit/TabBar/TabBar.swift +++ b/CodeEdit/TabBar/TabBar.swift @@ -24,9 +24,7 @@ struct CustomDivider: View { struct TabBar: View { var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument - var tabBarHeight = 28.0 - var body: some View { VStack(spacing: 0.0) { ScrollView(.horizontal, showsIndicators: false) { @@ -64,7 +62,6 @@ struct TabBar: View { } .background(BlurView(material: NSVisualEffectView.Material.windowBackground, blendingMode: NSVisualEffectView.BlendingMode.withinWindow)) - } func getTabId(fileName: String) -> KeyEquivalent { diff --git a/CodeEdit/TabBar/TabBarItem.swift b/CodeEdit/TabBar/TabBarItem.swift index 96ac474419..68a4540817 100644 --- a/CodeEdit/TabBar/TabBarItem.swift +++ b/CodeEdit/TabBar/TabBarItem.swift @@ -10,16 +10,12 @@ import WorkspaceClient struct TabBarItem: View { @State var isHovering: Bool = false - var item: WorkspaceClient.FileItem var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument - var tabBarHeight: Double = 28.0 - var body: some View { let isActive = item.id == workspace.selectedId - HStack(spacing: 0.0) { FileTabRow(fileItem: item, isSelected: isActive, isHovering: isHovering) { withAnimation { @@ -29,7 +25,6 @@ struct TabBarItem: View { Divider() } .background(Color(nsColor: .secondaryLabelColor).opacity(!isActive && isHovering ? 0.11 : 0).animation(.easeInOut(duration: 0.15))) - .frame(height: tabBarHeight) .foregroundColor(isActive ? .primary : .secondary) .onHover { hover in From 5effe0f8ad1024e6b58ab10235442c150780bfee Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 17:07:44 -0500 Subject: [PATCH 04/25] More lint error fixes --- CodeEdit/TabBar/TabBarItem.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CodeEdit/TabBar/TabBarItem.swift b/CodeEdit/TabBar/TabBarItem.swift index 68a4540817..647f3949fa 100644 --- a/CodeEdit/TabBar/TabBarItem.swift +++ b/CodeEdit/TabBar/TabBarItem.swift @@ -24,7 +24,11 @@ struct TabBarItem: View { } Divider() } - .background(Color(nsColor: .secondaryLabelColor).opacity(!isActive && isHovering ? 0.11 : 0).animation(.easeInOut(duration: 0.15))) + .background( + Color(nsColor: .secondaryLabelColor) + .opacity(!isActive && isHovering ? 0.11 : 0) + .animation(.easeInOut(duration: 0.15)) + ) .frame(height: tabBarHeight) .foregroundColor(isActive ? .primary : .secondary) .onHover { hover in From 0240e504d4ce82880acc1ed74094c0ffbe1202ad Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 17:11:11 -0500 Subject: [PATCH 05/25] More liner error fixes --- CodeEdit/TabBar/TabBar.swift | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/CodeEdit/TabBar/TabBar.swift b/CodeEdit/TabBar/TabBar.swift index a0782bb767..9a7aad6a96 100644 --- a/CodeEdit/TabBar/TabBar.swift +++ b/CodeEdit/TabBar/TabBar.swift @@ -37,11 +37,23 @@ struct TabBar: View { action: { workspace.selectedId = item.id }, label: { if isActive { - TabBarItem(item: item, windowController: windowController, workspace: workspace) - .background(BlurView(material: NSVisualEffectView.Material.titlebar, - blendingMode: NSVisualEffectView.BlendingMode.withinWindow)) + TabBarItem( + item: item, + windowController: windowController, + workspace: workspace + ) + .background( + BlurView( + material: NSVisualEffectView.Material.titlebar, + blendingMode: NSVisualEffectView.BlendingMode.withinWindow + ) + ) } else { - TabBarItem(item: item, windowController: windowController, workspace: workspace) + TabBarItem( + item: item, + windowController: windowController, + workspace: workspace + ) } } ) From 72797ecb628bfd8f53a84f9f3ea54f2bb011a6ed Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 19 Mar 2022 14:35:26 +0100 Subject: [PATCH 06/25] Create CONTRIBUTING.md --- CONTRIBUTING.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..03d56025b0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,41 @@ +# Contribute to CodeEdit + +Feel free to join and collaborate on our [Discord Server](https://discord.gg/vChUXVf9Em). + +## Fork & Clone CodeEdit + +Tap the **"Fork"** button on the top of the site. After forking clone the forked repository to your Mac. + +## Open the Workspace + +Inside the CodeEdit folder you just cloned to your Mac, make sure you open the `CodeEdit.xcworkspace` file with Xcode. + +Open CodeEdit.xcworkspace in Xcode + +> Note: Opening the `CodeEdit.xcodeproj` file will not include the local packages which are required to build & run. + +## SwiftLint + +In order to keep a unified style in our codebase we use `SwiftLint` to warn about inconsistencies. Make sure you have `SwiftLint` installed. + +```bash +brew install swiftlint +``` + +> If this command does not work, make sure to install [Homebrew](https://brew.sh). + +## Pull Request + +Once you are happy with your changes, submit a `Pull Request`. + +The `PR` should include follwing information: +* A descriptive **title** on what changed +* A detailed **description** of changes +* If you made changes to the UI please add a **screenshot** as well +* If there is a related issue please add a **reference to the issue** +* If your PR is still in progress mark it as **Draft**. + +Once you submitted the `PR` GitHub will run a couple of actions which run tests and `SwiftLint` (this can take a couple of minutes). Should a test fail it will not be merged until tests succeed. + +Make sure to resolve all conflicts otherwise the `PR` cannot be merged. + From 9ef2fdaca67163db6a82cd5900924fb458aa9893 Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 19 Mar 2022 15:47:56 +0100 Subject: [PATCH 07/25] Update CONTRIBUTING.md --- CONTRIBUTING.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 03d56025b0..866901b494 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,7 +35,9 @@ The `PR` should include follwing information: * If there is a related issue please add a **reference to the issue** * If your PR is still in progress mark it as **Draft**. -Once you submitted the `PR` GitHub will run a couple of actions which run tests and `SwiftLint` (this can take a couple of minutes). Should a test fail it will not be merged until tests succeed. +> Please resolve all `Violation` warnings in Xcode (except: _TODO:_ warnings). Otherwise the swiftlint check on GitHub will fail. -Make sure to resolve all conflicts otherwise the `PR` cannot be merged. +Once you submitted the `PR` GitHub will run a couple of actions which run tests and `SwiftLint` (this can take a couple of minutes). Should a test fail it cannot be merged until tests succeed. + +Make sure to resolve all merge-conflicts otherwise the `PR` cannot be merged. From 5b8f0635e843b116d1f91248e3a540a8aee79a25 Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 19 Mar 2022 16:26:22 +0100 Subject: [PATCH 08/25] Update CONTRIBUTING.md --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 866901b494..63e4d35994 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,10 @@ Feel free to join and collaborate on our [Discord Server](https://discord.gg/vCh Tap the **"Fork"** button on the top of the site. After forking clone the forked repository to your Mac. +## Explore Issues + +Find issues from the Issues tab or from the To Do column in our project. If you find an issue you want to work on, please indicate it in the issue and/or attach a draft PR once available. A moderator will then assign the Issue and/or PR to you. + ## Open the Workspace Inside the CodeEdit folder you just cloned to your Mac, make sure you open the `CodeEdit.xcworkspace` file with Xcode. From 6f5347da7e6c90429916078e9e040cf0a93d7079 Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 19 Mar 2022 16:27:29 +0100 Subject: [PATCH 09/25] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 63e4d35994..3343a65697 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ Tap the **"Fork"** button on the top of the site. After forking clone the forked ## Explore Issues -Find issues from the Issues tab or from the To Do column in our project. If you find an issue you want to work on, please indicate it in the issue and/or attach a draft PR once available. A moderator will then assign the Issue and/or PR to you. +Find issues from the [Issues tab](https://github.com/CodeEditApp/CodeEdit/issues) or from the To Do column in our project. If you find an issue you want to work on, please indicate it in the issue and/or attach a draft PR once available. A moderator will then assign the Issue and/or PR to you. ## Open the Workspace From b340d99e6ca4a2f014c61ffd3a8ce3926806f52f Mon Sep 17 00:00:00 2001 From: Pavel Kasila Date: Sun, 20 Mar 2022 01:16:05 +0300 Subject: [PATCH 10/25] Fix "Welcome to CodeEdit" Main Menu item (#106) --- CodeEdit/MainMenu.xib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeEdit/MainMenu.xib b/CodeEdit/MainMenu.xib index 84e1e02ee3..7460f6d538 100644 --- a/CodeEdit/MainMenu.xib +++ b/CodeEdit/MainMenu.xib @@ -643,7 +643,7 @@ - + From c5a2cb5d325ae5c75eba34124e5407937966ddd0 Mon Sep 17 00:00:00 2001 From: Pavel Kasila Date: Sun, 20 Mar 2022 01:16:40 +0300 Subject: [PATCH 11/25] Fix data format (#105) * Allow opening of `public.item` instead of `public.source-code` * Handle errors --- CodeEdit/Documents/CodeEditDocumentController.swift | 8 +++++--- CodeEdit/Info.plist | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CodeEdit/Documents/CodeEditDocumentController.swift b/CodeEdit/Documents/CodeEditDocumentController.swift index 345be63bcf..09a0f9a952 100644 --- a/CodeEdit/Documents/CodeEditDocumentController.swift +++ b/CodeEdit/Documents/CodeEditDocumentController.swift @@ -35,14 +35,16 @@ extension NSDocumentController { dialog.begin { result in if result == NSApplication.ModalResponse.OK, let url = dialog.url { self.openDocument(withContentsOf: url, display: true) { document, documentWasAlreadyOpen, error in - // TODO: handle errors if let error = error { - print("Error: \(error.localizedDescription)") + NSAlert(error: error).runModal() return } guard let document = document else { - print("Error: Failed to get document") + let alert = NSAlert() + alert.messageText = NSLocalizedString("Failed to get document", + comment: "Failed to get document") + alert.runModal() return } var recentProjectPaths: [String] = UserDefaults.standard.array( diff --git a/CodeEdit/Info.plist b/CodeEdit/Info.plist index 8bd6939483..94e974e6f4 100644 --- a/CodeEdit/Info.plist +++ b/CodeEdit/Info.plist @@ -27,7 +27,7 @@ Default LSItemContentTypes - public.source-code + public.item NSDocumentClass CodeFileDocument From 0b22e113f2d802e7f6362e79dcd9d76ed17ebb74 Mon Sep 17 00:00:00 2001 From: Nanashi Li Date: Sun, 20 Mar 2022 00:17:02 +0200 Subject: [PATCH 12/25] Message Preview when opening the non coding file (#102) * Cleaned up the typography for Welcome Screen * Added support for more code editor themes * Revert "Added support for more code editor themes" This reverts commit 8139217589c342e92c0acd96d6a088f127747cdf. * Revert "Cleaned up the typography for Welcome Screen" This reverts commit 78b748bd56cd4f09e942222ff13a1c59c9a26d7a. * Update the error message to be more informative when trying to open files that are not code related * Added language translations for editor error and support for the Afrikaans Language * Fixed localization changes in Russian and Belarusian * Updated the editor error string to be short and sweet * Update to editor error for file types. --- CodeEdit.xcodeproj/project.pbxproj | 3 ++ .../Localization/af.lproj/Localizable.strings | 44 +++++++++++++++++++ .../Localization/be.lproj/Localizable.strings | 3 ++ .../Localization/de.lproj/Localizable.strings | 3 ++ .../Localization/en.lproj/Localizable.strings | 3 ++ .../Localization/ru.lproj/Localizable.strings | 3 ++ CodeEdit/SideBar/SideBarItem.swift | 2 +- 7 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 CodeEdit/Localization/af.lproj/Localizable.strings diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 3137e43ff6..723038b1c7 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 04ADA0CA27E5D41F00BF00B2 /* be */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = be; path = be.lproj/Localizable.strings; sourceTree = ""; }; 04F2BF0E27DBB28E0024EAB1 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 04F2BF1127DBB3C10024EAB1 /* GeneralSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingsView.swift; sourceTree = ""; }; + 20F8067027E65A5200EB7827 /* af */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = af; path = af.lproj/Localizable.strings; sourceTree = ""; }; 2805D9E827E5ED180032BC56 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 286620A427E4AB6900E18C2B /* BreadcrumbsComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbsComponent.swift; sourceTree = ""; }; 2875A46C27E3BE5B007805F8 /* BreadcrumbsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbsView.swift; sourceTree = ""; }; @@ -376,6 +377,7 @@ ru, be, de, + af, ); mainGroup = B658FB2327DA9E0F00EA4DBD; packageReferences = ( @@ -529,6 +531,7 @@ 04ADA0C827E5D29000BF00B2 /* ru */, 04ADA0CA27E5D41F00BF00B2 /* be */, 2805D9E827E5ED180032BC56 /* de */, + 20F8067027E65A5200EB7827 /* af */, ); name = Localizable.strings; sourceTree = ""; diff --git a/CodeEdit/Localization/af.lproj/Localizable.strings b/CodeEdit/Localization/af.lproj/Localizable.strings new file mode 100644 index 0000000000..3ad2e85801 --- /dev/null +++ b/CodeEdit/Localization/af.lproj/Localizable.strings @@ -0,0 +1,44 @@ +"Hello, world!"="Hi, wereld!"; + +// Settings - General Tab +"General"="Algemeen"; + +// Settings - File Icon Style +"File Icon Style"="Lêer-ikoonstyl"; +"Color"="Kleur"; +"Monochrome"="Monochroom"; + +// Settings - Appearance +"Appearance"="Voorkoms"; +"System"="Stelsel"; +"Light"="Lig"; +"Dark"="Donker"; + +// Settings - Reopen Behavior +"Reopen Behavior"="Heropen Gedrag"; +"Welcome Screen"="Welkom Skerm"; +"Open Panel"="Maak Paneel Oop"; +"New Document"="Nuwe Dokument"; + +// Settings - Editor Theme +"Editor Theme"="Redakteur Tema"; + +// Welcome Screen +"Welcome to CodeEdit"="Welkom tot CodeEdit"; +"Version %@ (%@)"="Weergawe %@ (%@)"; +"No Recent Projects"="Geen Onlangse Projekte Nie"; + +// Welcome Screen - New File +"Create a new file"="Skep 'n nuwe lêer"; +"Clone an exisiting project"="Kloon 'n bestaande projek"; + +// Welcome Screen - SCM +"Start working on something from a Git repository"="Begin werk aan iets vanaf 'n Git-bewaarplek"; +"Open a project or file"="Maak 'n projek of lêer oop"; + +// Welcome Screen - Workspaces +"Open an existing project or file on your Mac"="Maak 'n bestaande projek of lêer op jou Mac oop"; +"Show this window when CodeEdit launches"="Wys hierdie venster wanneer CodeEdit begin"; + +//Editor Screen +"CodeEdit cannot open this file because its file type is not supported." = "CodeEdit kan nie hierdie lêer oopmaak nie omdat die lêertipe nie ondersteun word nie."; diff --git a/CodeEdit/Localization/be.lproj/Localizable.strings b/CodeEdit/Localization/be.lproj/Localizable.strings index ac05ab747a..893e16f5f6 100644 --- a/CodeEdit/Localization/be.lproj/Localizable.strings +++ b/CodeEdit/Localization/be.lproj/Localizable.strings @@ -39,3 +39,6 @@ // Welcome Screen - Workspaces "Open a project or file"="Адкрыйце праект або файл"; "Open an existing project or file on your Mac"="Адкрыйце існуючы праект або файл на вашым Mac"; + +//Editor Screen +"CodeEdit cannot open this file because its file type is not supported." = "CodeEdit не можа адчыніць гэты файл, таму што яго тып не падтрымліваецца "; diff --git a/CodeEdit/Localization/de.lproj/Localizable.strings b/CodeEdit/Localization/de.lproj/Localizable.strings index 4506897bdf..92fa2378a2 100644 --- a/CodeEdit/Localization/de.lproj/Localizable.strings +++ b/CodeEdit/Localization/de.lproj/Localizable.strings @@ -39,3 +39,6 @@ // Welcome Screen - Workspaces "Open an existing project or file on your Mac"="Vorhandenes Projekt oder Datei auf Mac öffnen"; "Show this window when CodeEdit launches"="Zeigen wenn CodeEdit geöffnet wird"; + +//Editor Screen +"CodeEdit cannot open this file because its file type is not supported." = "CodeEdit kann diese Datei nicht öffnen, da ihr Dateityp nicht unterstützt wird."; diff --git a/CodeEdit/Localization/en.lproj/Localizable.strings b/CodeEdit/Localization/en.lproj/Localizable.strings index 68abbc783d..c9ff23bb27 100644 --- a/CodeEdit/Localization/en.lproj/Localizable.strings +++ b/CodeEdit/Localization/en.lproj/Localizable.strings @@ -39,3 +39,6 @@ // Welcome Screen - Workspaces "Open an existing project or file on your Mac"="Open an existing project or file on your Mac"; "Show this window when CodeEdit launches"="Show this window when CodeEdit launches"; + +//Editor Screen +"CodeEdit cannot open this file because its file type is not supported." = "CodeEdit cannot open this file because its file type is not supported."; diff --git a/CodeEdit/Localization/ru.lproj/Localizable.strings b/CodeEdit/Localization/ru.lproj/Localizable.strings index 242faf018e..aafb59142c 100644 --- a/CodeEdit/Localization/ru.lproj/Localizable.strings +++ b/CodeEdit/Localization/ru.lproj/Localizable.strings @@ -39,3 +39,6 @@ // Welcome Screen - Workspaces "Open a project or file"="Откройте проект или файл"; "Open an existing project or file on your Mac"="Откройте существующий проект или файл на вашем Mac"; + +//Editor Screen +"CodeEdit cannot open this file because its file type is not supported." = "CodeEdit не может открыть этот файл, потому что его тип не поддерживается"; diff --git a/CodeEdit/SideBar/SideBarItem.swift b/CodeEdit/SideBar/SideBarItem.swift index 7a43f82603..6708529213 100644 --- a/CodeEdit/SideBar/SideBarItem.swift +++ b/CodeEdit/SideBar/SideBarItem.swift @@ -41,7 +41,7 @@ struct SideBarItem: View { } } } else { - Text("File cannot be opened") + Text("CodeEdit cannot open this file because its file type is not supported.") } } .onAppear { workspace.openFile(item: item) } From 90507d9c411eb3e027aedee2a0493af7d2be630a Mon Sep 17 00:00:00 2001 From: Pavel Kasila Date: Sun, 20 Mar 2022 09:04:43 +0300 Subject: [PATCH 13/25] Change document types priority, prioritize workspace over source code file to fix #110 --- CodeEdit/Info.plist | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CodeEdit/Info.plist b/CodeEdit/Info.plist index 94e974e6f4..16de6697dc 100644 --- a/CodeEdit/Info.plist +++ b/CodeEdit/Info.plist @@ -6,31 +6,31 @@ CFBundleTypeName - Workspace Folder + Source Code CFBundleTypeRole - Viewer + Editor LSHandlerRank Default LSItemContentTypes - public.folder + public.item NSDocumentClass - WorkspaceDocument + CodeFileDocument CFBundleTypeName - Source Code + Workspace Folder CFBundleTypeRole - Editor + Viewer LSHandlerRank Default LSItemContentTypes - public.item + public.folder NSDocumentClass - CodeFileDocument + WorkspaceDocument CFBundleURLTypes From 1cdfff60cf6f1c75c630a74650aa66a5c5844c69 Mon Sep 17 00:00:00 2001 From: Ziyuan Zhao Date: Sun, 20 Mar 2022 14:58:50 +0800 Subject: [PATCH 14/25] Fix multiple welcome window --- CodeEdit/AppDelegate.swift | 9 ++++++++- CodeEdit/Welcome/WelcomeWindowView.swift | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CodeEdit/AppDelegate.swift b/CodeEdit/AppDelegate.swift index a731d9d391..2521b4b005 100644 --- a/CodeEdit/AppDelegate.swift +++ b/CodeEdit/AppDelegate.swift @@ -69,11 +69,18 @@ class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject { } @IBAction func openWelcome(_ sender: Any) { + if let window = NSApp.windows.filter({ window in + return (window.contentView as? NSHostingView) != nil + }).first { + window.makeKeyAndOrderFront(self) + return + } + let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 800, height: 460), styleMask: [.titled, .fullSizeContentView], backing: .buffered, defer: false) let windowController = NSWindowController(window: window) window.center() - let contentView = WelcomeWindowView(windowController: windowController).edgesIgnoringSafeArea(.top) + let contentView = WelcomeWindowView(windowController: windowController) window.titlebarAppearsTransparent = true window.isMovableByWindowBackground = true window.contentView = NSHostingView(rootView: contentView) diff --git a/CodeEdit/Welcome/WelcomeWindowView.swift b/CodeEdit/Welcome/WelcomeWindowView.swift index 0072c18360..c0f722ea3d 100644 --- a/CodeEdit/Welcome/WelcomeWindowView.swift +++ b/CodeEdit/Welcome/WelcomeWindowView.swift @@ -18,5 +18,6 @@ struct WelcomeWindowView: View { windowController.window?.close() } } + .edgesIgnoringSafeArea(.top) } } From 978aae2195066bf15c80fe645d7e436b3bca3bd1 Mon Sep 17 00:00:00 2001 From: Pavel Kasila Date: Sun, 20 Mar 2022 12:12:50 +0300 Subject: [PATCH 15/25] Fix version localization key (#120) --- CodeEdit/Welcome/WelcomeView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeEdit/Welcome/WelcomeView.swift b/CodeEdit/Welcome/WelcomeView.swift index 1bc5093a06..6b961f3ca8 100644 --- a/CodeEdit/Welcome/WelcomeView.swift +++ b/CodeEdit/Welcome/WelcomeView.swift @@ -53,7 +53,7 @@ struct WelcomeView: View { .frame(width: 128, height: 128) Text("Welcome to CodeEdit") .font(.system(size: 38)) - Text("Version \(appVersion)(\(appBuild))") + Text("Version \(appVersion) (\(appBuild))") .foregroundColor(.secondary) .font(.system(size: 13)) Spacer().frame(height: 20) From f2f2db63179893cc952701fabf33284ef26d7625 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 16:54:11 -0500 Subject: [PATCH 16/25] Improved overall tab style to feel more native to macOS --- CodeEdit/Rows/FileTabRow.swift | 7 +++++++ CodeEdit/TabBar/TabBar.swift | 2 ++ CodeEdit/TabBar/TabBarItem.swift | 1 + 3 files changed, 10 insertions(+) diff --git a/CodeEdit/Rows/FileTabRow.swift b/CodeEdit/Rows/FileTabRow.swift index b94dd09e4a..d0ac8c59b7 100644 --- a/CodeEdit/Rows/FileTabRow.swift +++ b/CodeEdit/Rows/FileTabRow.swift @@ -10,12 +10,16 @@ import WorkspaceClient struct FileTabRow: View { @State var isHoveringClose: Bool = false + var fileItem: WorkspaceClient.FileItem var isSelected: Bool var isHovering: Bool + var closeAction: () -> Void + var body: some View { let showingCloseButton = isHovering + HStack(alignment: .center, spacing: 5) { ZStack { if isSelected { @@ -29,6 +33,7 @@ struct FileTabRow: View { .opacity(0) .keyboardShortcut("w", modifiers: [.command]) } + Button(action: closeAction, label: { Rectangle() .fill(isHoveringClose @@ -48,6 +53,7 @@ struct FileTabRow: View { .onHover { hover in isHoveringClose = hover } + } Image(systemName: fileItem.systemImage) .resizable() @@ -59,6 +65,7 @@ struct FileTabRow: View { } .padding(.leading, 4) .padding(.trailing, 28) + } } diff --git a/CodeEdit/TabBar/TabBar.swift b/CodeEdit/TabBar/TabBar.swift index 9a7aad6a96..e7d5fe26e0 100644 --- a/CodeEdit/TabBar/TabBar.swift +++ b/CodeEdit/TabBar/TabBar.swift @@ -24,6 +24,7 @@ struct CustomDivider: View { struct TabBar: View { var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument + var tabBarHeight = 28.0 var body: some View { VStack(spacing: 0.0) { @@ -74,6 +75,7 @@ struct TabBar: View { } .background(BlurView(material: NSVisualEffectView.Material.windowBackground, blendingMode: NSVisualEffectView.BlendingMode.withinWindow)) + } func getTabId(fileName: String) -> KeyEquivalent { diff --git a/CodeEdit/TabBar/TabBarItem.swift b/CodeEdit/TabBar/TabBarItem.swift index 647f3949fa..b59a2a2778 100644 --- a/CodeEdit/TabBar/TabBarItem.swift +++ b/CodeEdit/TabBar/TabBarItem.swift @@ -10,6 +10,7 @@ import WorkspaceClient struct TabBarItem: View { @State var isHovering: Bool = false + var item: WorkspaceClient.FileItem var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument From ce4fd995aaec449caea67cd64c4c9dc73643707b Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 16:59:37 -0500 Subject: [PATCH 17/25] Fixed lint error --- CodeEdit/Rows/FileTabRow.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/CodeEdit/Rows/FileTabRow.swift b/CodeEdit/Rows/FileTabRow.swift index d0ac8c59b7..ca22762489 100644 --- a/CodeEdit/Rows/FileTabRow.swift +++ b/CodeEdit/Rows/FileTabRow.swift @@ -33,7 +33,6 @@ struct FileTabRow: View { .opacity(0) .keyboardShortcut("w", modifiers: [.command]) } - Button(action: closeAction, label: { Rectangle() .fill(isHoveringClose @@ -53,7 +52,6 @@ struct FileTabRow: View { .onHover { hover in isHoveringClose = hover } - } Image(systemName: fileItem.systemImage) .resizable() From 5fa1de771e39eea1442cde888f0951d3cdfe0ff8 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sat, 19 Mar 2022 17:04:45 -0500 Subject: [PATCH 18/25] More lint error fixes --- CodeEdit/Rows/FileTabRow.swift | 5 ----- CodeEdit/TabBar/TabBar.swift | 2 -- CodeEdit/TabBar/TabBarItem.swift | 1 - 3 files changed, 8 deletions(-) diff --git a/CodeEdit/Rows/FileTabRow.swift b/CodeEdit/Rows/FileTabRow.swift index ca22762489..b94dd09e4a 100644 --- a/CodeEdit/Rows/FileTabRow.swift +++ b/CodeEdit/Rows/FileTabRow.swift @@ -10,16 +10,12 @@ import WorkspaceClient struct FileTabRow: View { @State var isHoveringClose: Bool = false - var fileItem: WorkspaceClient.FileItem var isSelected: Bool var isHovering: Bool - var closeAction: () -> Void - var body: some View { let showingCloseButton = isHovering - HStack(alignment: .center, spacing: 5) { ZStack { if isSelected { @@ -63,7 +59,6 @@ struct FileTabRow: View { } .padding(.leading, 4) .padding(.trailing, 28) - } } diff --git a/CodeEdit/TabBar/TabBar.swift b/CodeEdit/TabBar/TabBar.swift index e7d5fe26e0..9a7aad6a96 100644 --- a/CodeEdit/TabBar/TabBar.swift +++ b/CodeEdit/TabBar/TabBar.swift @@ -24,7 +24,6 @@ struct CustomDivider: View { struct TabBar: View { var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument - var tabBarHeight = 28.0 var body: some View { VStack(spacing: 0.0) { @@ -75,7 +74,6 @@ struct TabBar: View { } .background(BlurView(material: NSVisualEffectView.Material.windowBackground, blendingMode: NSVisualEffectView.BlendingMode.withinWindow)) - } func getTabId(fileName: String) -> KeyEquivalent { diff --git a/CodeEdit/TabBar/TabBarItem.swift b/CodeEdit/TabBar/TabBarItem.swift index b59a2a2778..647f3949fa 100644 --- a/CodeEdit/TabBar/TabBarItem.swift +++ b/CodeEdit/TabBar/TabBarItem.swift @@ -10,7 +10,6 @@ import WorkspaceClient struct TabBarItem: View { @State var isHovering: Bool = false - var item: WorkspaceClient.FileItem var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument From ee5fd1833b98de05bcea55cfd5b14fe830c98b0a Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 20 Mar 2022 17:54:26 -0500 Subject: [PATCH 19/25] Replicating aesthetic and behavior of standard tabs. Removed wrapper component so that code is more straightforward. --- CodeEdit.xcodeproj/project.pbxproj | 16 +-- CodeEdit/CustomViews/BlurView.swift | 3 +- CodeEdit/Documents/WorkspaceDocument.swift | 26 ++++ CodeEdit/Rows/FileTabRow.swift | 77 ---------- CodeEdit/SideBar/SideBarItem.swift | 16 ++- CodeEdit/TabBar/TabBar.swift | 85 +++-------- CodeEdit/TabBar/TabBarItem.swift | 159 +++++++++++++++++++-- CodeEdit/Welcome/WelcomeView.swift | 4 +- 8 files changed, 217 insertions(+), 169 deletions(-) delete mode 100644 CodeEdit/Rows/FileTabRow.swift diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 723038b1c7..d6e4f2dd65 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -26,10 +26,10 @@ 28B0A19827E385C300B73177 /* SideBarToolbarTop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28B0A19727E385C300B73177 /* SideBarToolbarTop.swift */; }; 28FFE1BF27E3A441001939DB /* SideBarToolbarBottom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FFE1BE27E3A441001939DB /* SideBarToolbarBottom.swift */; }; 2B7A583527E4BA0100D25D4E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0468438427DC76E200F8E88E /* AppDelegate.swift */; }; - 345F667527DF6C180069BD69 /* FileTabRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 345F667427DF6C180069BD69 /* FileTabRow.swift */; }; 34EE19BE27E0469C00F152CE /* BlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34EE19BD27E0469C00F152CE /* BlurView.swift */; }; 5C403B8F27E20F8000788241 /* WorkspaceClient in Frameworks */ = {isa = PBXBuildFile; productRef = 5C403B8E27E20F8000788241 /* WorkspaceClient */; }; 5CF38A5E27E48E6C0096A0F7 /* CodeFile in Frameworks */ = {isa = PBXBuildFile; productRef = 5CF38A5D27E48E6C0096A0F7 /* CodeFile */; }; + B658C07827E71F910063DB7A /* PressActionsModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B658C07727E71F910063DB7A /* PressActionsModifier.swift */; }; B658FB3427DA9E1000EA4DBD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3327DA9E1000EA4DBD /* Assets.xcassets */; }; B658FB3727DA9E1000EA4DBD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3627DA9E1000EA4DBD /* Preview Assets.xcassets */; }; B65E614627E6765D00255275 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = B65E614527E6765D00255275 /* Introspect */; }; @@ -82,8 +82,8 @@ 289978EC27E4E97E00BB0357 /* FileIconStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileIconStyle.swift; sourceTree = ""; }; 28B0A19727E385C300B73177 /* SideBarToolbarTop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarToolbarTop.swift; sourceTree = ""; }; 28FFE1BE27E3A441001939DB /* SideBarToolbarBottom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarToolbarBottom.swift; sourceTree = ""; }; - 345F667427DF6C180069BD69 /* FileTabRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileTabRow.swift; sourceTree = ""; }; 34EE19BD27E0469C00F152CE /* BlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurView.swift; sourceTree = ""; }; + B658C07727E71F910063DB7A /* PressActionsModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PressActionsModifier.swift; path = ../../../../Downloads/HandlePressReleaseEventsDemo/HandlePressReleaseEventsDemo/PressActionsModifier.swift; sourceTree = ""; }; B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeEdit.app; sourceTree = BUILT_PRODUCTS_DIR; }; B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkspaceView.swift; sourceTree = ""; }; B658FB3327DA9E1000EA4DBD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -187,14 +187,6 @@ path = TabBar; sourceTree = ""; }; - 345F667327DF6BCC0069BD69 /* Rows */ = { - isa = PBXGroup; - children = ( - 345F667427DF6C180069BD69 /* FileTabRow.swift */, - ); - path = Rows; - sourceTree = ""; - }; 34EE19BC27E0467F00F152CE /* CustomViews */ = { isa = PBXGroup; children = ( @@ -237,10 +229,10 @@ 043C321227E31FE8006AE443 /* Documents */, 0468438427DC76E200F8E88E /* AppDelegate.swift */, B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */, + B658C07727E71F910063DB7A /* PressActionsModifier.swift */, 2875A46E27E3BE63007805F8 /* Breadcrumbs */, 287776EA27E350A100D46668 /* SideBar */, 287776EB27E350BA00D46668 /* TabBar */, - 345F667327DF6BCC0069BD69 /* Rows */, 04F2BF1027DBB3AF0024EAB1 /* Settings */, 34EE19BC27E0467F00F152CE /* CustomViews */, D7211D4427E066D4008F2ED7 /* Localization */, @@ -477,6 +469,7 @@ 34EE19BE27E0469C00F152CE /* BlurView.swift in Sources */, D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */, 287776E927E34BC700D46668 /* TabBar.swift in Sources */, + B658C07827E71F910063DB7A /* PressActionsModifier.swift in Sources */, 286620A527E4AB6900E18C2B /* BreadcrumbsComponent.swift in Sources */, 287776EF27E3515300D46668 /* TabBarItem.swift in Sources */, D72E1A8727E4242900EB11B9 /* RecentProjectsView.swift in Sources */, @@ -488,7 +481,6 @@ D72E1A8327E3B0D400EB11B9 /* WelcomeView.swift in Sources */, 043C321627E3201F006AE443 /* WorkspaceDocument.swift in Sources */, 28B0A19827E385C300B73177 /* SideBarToolbarTop.swift in Sources */, - 345F667527DF6C180069BD69 /* FileTabRow.swift in Sources */, 28FFE1BF27E3A441001939DB /* SideBarToolbarBottom.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/CodeEdit/CustomViews/BlurView.swift b/CodeEdit/CustomViews/BlurView.swift index b4acf57f4f..f19ea16b6f 100644 --- a/CodeEdit/CustomViews/BlurView.swift +++ b/CodeEdit/CustomViews/BlurView.swift @@ -16,7 +16,8 @@ struct BlurView: NSViewRepresentable { let visualEffectView = NSVisualEffectView() visualEffectView.material = material visualEffectView.blendingMode = blendingMode - visualEffectView.state = NSVisualEffectView.State.active + visualEffectView.state = NSVisualEffectView.State.followsWindowActiveState + return visualEffectView } diff --git a/CodeEdit/Documents/WorkspaceDocument.swift b/CodeEdit/Documents/WorkspaceDocument.swift index 755973fc1b..fdc8bc02b7 100644 --- a/CodeEdit/Documents/WorkspaceDocument.swift +++ b/CodeEdit/Documents/WorkspaceDocument.swift @@ -20,6 +20,11 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { @Published var sortFoldersOnTop: Bool = true @Published var fileItems: [WorkspaceClient.FileItem] = [] + var selected: WorkspaceClient.FileItem? { + guard let selectedId = selectedId else { return nil } + return fileItems.first(where: { $0.id == selectedId }) + } + var openedCodeFiles: [WorkspaceClient.FileItem: CodeFileDocument] = [:] var folderURL: URL? private var cancellables = Set() @@ -47,6 +52,27 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { selectedId = openFileItems[idx - 1].id } } + + func closeFileTabs(items: Items) where Items: Collection, Items.Element == WorkspaceClient.FileItem { + // TODO: Could potentially be optimized + for item in items { + closeFileTab(item: item) + } + } + + func closeFileTab(where predicate: (WorkspaceClient.FileItem) -> Bool) { + closeFileTabs(items: openFileItems.filter(predicate)) + } + + func closeFileTabs(after item: WorkspaceClient.FileItem) { + guard let startIdx = openFileItems.firstIndex(where: { $0.id == item.id }) else { + assert(false, "Expected file item to be present in openFileItems") + return + } + + let range = openFileItems[(startIdx+1)...] + closeFileTabs(items: range) + } func openFile(item: WorkspaceClient.FileItem) { do { diff --git a/CodeEdit/Rows/FileTabRow.swift b/CodeEdit/Rows/FileTabRow.swift deleted file mode 100644 index b94dd09e4a..0000000000 --- a/CodeEdit/Rows/FileTabRow.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// FileTabRow.swift -// CodeEdit -// -// Created by Rehatbir Singh on 14/03/2022. -// - -import SwiftUI -import WorkspaceClient - -struct FileTabRow: View { - @State var isHoveringClose: Bool = false - var fileItem: WorkspaceClient.FileItem - var isSelected: Bool - var isHovering: Bool - var closeAction: () -> Void - var body: some View { - let showingCloseButton = isHovering - HStack(alignment: .center, spacing: 5) { - ZStack { - if isSelected { - // Create a hidden button, if the tab is selected - // and hide the button in the ZStack. - Button(action: closeAction) { - Text("").hidden() - } - .frame(width: 0, height: 0) - .padding(0) - .opacity(0) - .keyboardShortcut("w", modifiers: [.command]) - } - Button(action: closeAction, label: { - Rectangle() - .fill(isHoveringClose - ? Color(nsColor: .secondaryLabelColor).opacity(0.28) - : Color(.clear)) - .frame(width: 16, height: 16) - .cornerRadius(2) - .overlay( - Image(systemName: "xmark") - .font(.system(size: 9.5, weight: .medium, design: .rounded)) - .foregroundColor(.secondary) - ) - }) - .buttonStyle(PlainButtonStyle()) - .accessibilityLabel(Text("Close")) - .opacity(showingCloseButton ? 1 : 0) - .onHover { hover in - isHoveringClose = hover - } - } - Image(systemName: fileItem.systemImage) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 12, height: 12) - Text(fileItem.url.lastPathComponent) - .font(.system(size: 11.0)) - .lineLimit(1) - } - .padding(.leading, 4) - .padding(.trailing, 28) - } -} - -struct FileTabRow_Previews: PreviewProvider { - static var previews: some View { - FileTabRow( - fileItem: WorkspaceClient.FileItem( - url: URL(string: "Code.swift")! - ), - isSelected: false, - isHovering: false, - closeAction: {} - ) - .frame(width: 160.0, height: 28.0) - } -} diff --git a/CodeEdit/SideBar/SideBarItem.swift b/CodeEdit/SideBar/SideBarItem.swift index 6708529213..58b7c046bd 100644 --- a/CodeEdit/SideBar/SideBarItem.swift +++ b/CodeEdit/SideBar/SideBarItem.swift @@ -9,6 +9,20 @@ import SwiftUI import WorkspaceClient import CodeFile +struct TabBarDivider: View { + @Environment(\.colorScheme) var colorScheme + let height: CGFloat = 1 + + var body: some View { + Group { + Rectangle() + } + .frame(height: height) + .foregroundColor(colorScheme == .dark ? Color(nsColor: .black) : Color(nsColor: .separatorColor)) + } +} + + struct SideBarItem: View { @AppStorage(FileIconStyle.storageKey) var iconStyle: FileIconStyle = .default @@ -36,7 +50,7 @@ struct SideBarItem: View { .safeAreaInset(edge: .top, spacing: 0) { VStack(spacing: 0) { TabBar(windowController: windowController, workspace: workspace) - CustomDivider() + TabBarDivider() BreadcrumbsView(item, workspace: workspace) } } diff --git a/CodeEdit/TabBar/TabBar.swift b/CodeEdit/TabBar/TabBar.swift index 9a7aad6a96..9724609f1a 100644 --- a/CodeEdit/TabBar/TabBar.swift +++ b/CodeEdit/TabBar/TabBar.swift @@ -8,82 +8,37 @@ import SwiftUI import WorkspaceClient -struct CustomDivider: View { - @Environment(\.colorScheme) var colorScheme - let height: CGFloat = 1 - - var body: some View { - Group { - Rectangle() - } - .frame(height: height) - .foregroundColor(colorScheme == .dark ? Color(nsColor: .black) : Color(nsColor: .separatorColor)) - } -} - struct TabBar: View { + @Environment(\.colorScheme) var colorScheme var windowController: NSWindowController @ObservedObject var workspace: WorkspaceDocument var tabBarHeight = 28.0 var body: some View { VStack(spacing: 0.0) { - ScrollView(.horizontal, showsIndicators: false) { - ScrollViewReader { value in - HStack(alignment: .center, spacing: 0.0) { - ForEach(workspace.openFileItems, id: \.id) { item in - let isActive = workspace.selectedId == item.id - - Button( - action: { workspace.selectedId = item.id }, - label: { - if isActive { - TabBarItem( - item: item, - windowController: windowController, - workspace: workspace - ) - .background( - BlurView( - material: NSVisualEffectView.Material.titlebar, - blendingMode: NSVisualEffectView.BlendingMode.withinWindow - ) - ) - } else { - TabBarItem( - item: item, - windowController: windowController, - workspace: workspace - ) - } - } - ) - .animation(.easeOut(duration: 0.2), value: workspace.openFileItems) - .buttonStyle(.plain) - .id(item.id) - .keyboardShortcut( - self.getTabId(fileName: item.fileName), - modifiers: [.command] - ) + ZStack(alignment: .top) { + Rectangle() + .fill(Color(nsColor: .black).opacity(colorScheme == .dark ? 0.45 : 0.05)) + .frame(height: 28) + ScrollView(.horizontal, showsIndicators: false) { + ScrollViewReader { value in + HStack(alignment: .center, spacing: -1) { + ForEach(workspace.openFileItems, id: \.id) { item in + TabBarItem( + item: item, + windowController: windowController, + workspace: workspace + ) + } + } + .onAppear { + value.scrollTo(self.workspace.selectedId) } - } - .onAppear { - value.scrollTo(self.workspace.selectedId) } } + .padding(.leading, -1) } } - .background(BlurView(material: NSVisualEffectView.Material.windowBackground, + .background(BlurView(material: NSVisualEffectView.Material.titlebar, blendingMode: NSVisualEffectView.BlendingMode.withinWindow)) } - - func getTabId(fileName: String) -> KeyEquivalent { - for counter in 0..<9 where workspace.openFileItems.count > counter && - workspace.openFileItems[counter].fileName == fileName { - return KeyEquivalent.init( - Character.init("\(counter + 1)") - ) - } - - return "0" - } } diff --git a/CodeEdit/TabBar/TabBarItem.swift b/CodeEdit/TabBar/TabBarItem.swift index 647f3949fa..b2619c8750 100644 --- a/CodeEdit/TabBar/TabBarItem.swift +++ b/CodeEdit/TabBar/TabBarItem.swift @@ -8,27 +8,114 @@ import SwiftUI import WorkspaceClient +struct TabDivider: View { + @Environment(\.colorScheme) var colorScheme + let width: CGFloat = 1 + + var body: some View { + Group { + Rectangle() + } + .frame(width: width) + .foregroundColor( + Color(nsColor: colorScheme == .dark ? .white : .black) + .opacity(colorScheme == .dark ? 0.08 : 0.12) + ) + } +} + struct TabBarItem: View { + @Environment(\.colorScheme) var colorScheme @State var isHovering: Bool = false - var item: WorkspaceClient.FileItem + @State var isHoveringClose: Bool = false + @State var isPressingClose: Bool = false + + var item: WorkspaceClient.FileItem var windowController: NSWindowController + + func closeAction () { + withAnimation() { + workspace.closeFileTab(item: item) + } + } + @ObservedObject var workspace: WorkspaceDocument var tabBarHeight: Double = 28.0 - var body: some View { - let isActive = item.id == workspace.selectedId + var isActive: Bool { + item.id == workspace.selectedId + } + + @ViewBuilder + var content: some View { HStack(spacing: 0.0) { - FileTabRow(fileItem: item, isSelected: isActive, isHovering: isHovering) { - withAnimation { - workspace.closeFileTab(item: item) + TabDivider() + HStack(alignment: .center, spacing: 5) { + ZStack { + if isActive { + // Create a hidden button, if the tab is selected + // and hide the button in the ZStack. + Button(action: closeAction) { + Text("").hidden() + } + .frame(width: 0, height: 0) + .padding(0) + .opacity(0) + .keyboardShortcut("w", modifiers: [.command]) + } + Button(action: closeAction) { + Image(systemName: "xmark") + .font(.system(size: 9.5, weight: .medium, design: .rounded)) + .frame(width: 16, height: 16) + .contentShape(Rectangle()) + } + .buttonStyle(PlainButtonStyle()) + .foregroundColor(isPressingClose ? .primary : .secondary) + .background(colorScheme == .dark + ? isPressingClose + ? Color(nsColor: .white).opacity(0.32) + : isHoveringClose + ? Color(nsColor: .white).opacity(0.18) + : Color(.clear) + : isPressingClose + ? Color(nsColor: .black).opacity(0.29) + : isHoveringClose + ? Color(nsColor: .black).opacity(0.11) + : Color(.clear) + ) + .cornerRadius(2) + .accessibilityLabel(Text("Close")) + .onHover { hover in + isHoveringClose = hover + } + .pressAction { + isPressingClose = true + } onRelease: { + isPressingClose = false + } + .opacity(isHovering ? 1 : 0) } + Image(systemName: item.systemImage) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 12, height: 12) + Text(item.url.lastPathComponent) + .font(.system(size: 11.0)) + .lineLimit(1) } - Divider() + .frame(height: 28) + .padding(.leading, 4) + .padding(.trailing, 28) + .background( + Color(nsColor: isActive ? .clear : .black) + .opacity( + colorScheme == .dark + ? isHovering ? 0.15 : isActive ? 0 : 0.45 + : isHovering ? 0.15 : isActive ? 0 : 0.05 + ) + .animation(.easeInOut(duration: 0.15)) + ) + TabDivider() } - .background( - Color(nsColor: .secondaryLabelColor) - .opacity(!isActive && isHovering ? 0.11 : 0) - .animation(.easeInOut(duration: 0.15)) - ) .frame(height: tabBarHeight) .foregroundColor(isActive ? .primary : .secondary) .onHover { hover in @@ -42,4 +129,52 @@ struct TabBarItem: View { } } } + + var body: some View { + Button( + action: { workspace.selectedId = item.id }, + label: { content } + ) + .background(BlurView( + material: NSVisualEffectView.Material.titlebar, + blendingMode: NSVisualEffectView.BlendingMode.withinWindow + )) + .animation(.easeOut(duration: 0.2), value: workspace.openFileItems) + .buttonStyle(.plain) + .id(item.id) + .keyboardShortcut( + workspace.getTabKeyEquivalent(item: item), + modifiers: [.command] + ) + .contextMenu { + Button("Close Tab") { + withAnimation { + workspace.closeFileTab(item: item) + } + } + Button("Close Other Tabs") { + withAnimation { + workspace.closeFileTab(where: { $0.id != item.id }) + } + } + Button("Close Tabs to the Right") { + withAnimation { + workspace.closeFileTabs(after: item) + } + } + } + } +} + +fileprivate extension WorkspaceDocument { + func getTabKeyEquivalent(item: WorkspaceClient.FileItem) -> KeyEquivalent { + for counter in 0..<9 where self.openFileItems.count > counter && + self.openFileItems[counter].fileName == item.fileName { + return KeyEquivalent.init( + Character.init("\(counter + 1)") + ) + } + + return "0" + } } diff --git a/CodeEdit/Welcome/WelcomeView.swift b/CodeEdit/Welcome/WelcomeView.swift index 6b961f3ca8..3303be7988 100644 --- a/CodeEdit/Welcome/WelcomeView.swift +++ b/CodeEdit/Welcome/WelcomeView.swift @@ -11,6 +11,8 @@ import Foundation import WelcomeModule struct WelcomeView: View { + @Environment(\.colorScheme) var colorScheme + @State var isHovering: Bool = false @State var isHoveringClose: Bool = false @@ -94,7 +96,7 @@ struct WelcomeView: View { .padding(.top, 20) .padding(.horizontal, 56) .padding(.bottom, 16) - .background(Color(nsColor: .windowBackgroundColor)) + .background(Color(nsColor: colorScheme == .dark ? .windowBackgroundColor : .white)) .onHover { isHovering in self.isHovering = isHovering } From cf3420b35ebc576b4c7bc2ec9f1f81e4af674da5 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 20 Mar 2022 18:42:43 -0500 Subject: [PATCH 20/25] Update WorkspaceCodeFileView.swift Resolved conflicts --- CodeEdit/Documents/WorkspaceCodeFileView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeEdit/Documents/WorkspaceCodeFileView.swift b/CodeEdit/Documents/WorkspaceCodeFileView.swift index 2a6db0fdc0..a5deea8514 100644 --- a/CodeEdit/Documents/WorkspaceCodeFileView.swift +++ b/CodeEdit/Documents/WorkspaceCodeFileView.swift @@ -23,7 +23,7 @@ struct WorkspaceCodeFileView: View { .safeAreaInset(edge: .top, spacing: 0) { VStack(spacing: 0) { TabBar(windowController: windowController, workspace: workspace) - CustomDivider() + TabBarDivider() BreadcrumbsView(item, workspace: workspace) } } From e9c3c8f28b0a23d4f825883b30905eec7200f51d Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 20 Mar 2022 22:09:41 -0500 Subject: [PATCH 21/25] Fixed lint errors and animations --- CodeEdit/CustomViews/BlurView.swift | 1 - CodeEdit/Documents/WorkspaceDocument.swift | 2 -- CodeEdit/SideBar/SideBarItem.swift | 15 ------------ CodeEdit/TabBar/TabBar.swift | 2 +- CodeEdit/TabBar/TabBarItem.swift | 27 ++++++---------------- CodeEdit/Welcome/WelcomeView.swift | 3 --- 6 files changed, 8 insertions(+), 42 deletions(-) diff --git a/CodeEdit/CustomViews/BlurView.swift b/CodeEdit/CustomViews/BlurView.swift index f19ea16b6f..9ad6502fc4 100644 --- a/CodeEdit/CustomViews/BlurView.swift +++ b/CodeEdit/CustomViews/BlurView.swift @@ -17,7 +17,6 @@ struct BlurView: NSViewRepresentable { visualEffectView.material = material visualEffectView.blendingMode = blendingMode visualEffectView.state = NSVisualEffectView.State.followsWindowActiveState - return visualEffectView } diff --git a/CodeEdit/Documents/WorkspaceDocument.swift b/CodeEdit/Documents/WorkspaceDocument.swift index 5c522cb641..40eddfc6a4 100644 --- a/CodeEdit/Documents/WorkspaceDocument.swift +++ b/CodeEdit/Documents/WorkspaceDocument.swift @@ -25,7 +25,6 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { guard let selectedId = selectedId else { return nil } return fileItems.first(where: { $0.id == selectedId }) } - var quickOpenState: QuickOpenState? var openedCodeFiles: [WorkspaceClient.FileItem: CodeFileDocument] = [:] private var cancellables = Set() @@ -52,7 +51,6 @@ class WorkspaceDocument: NSDocument, ObservableObject, NSToolbarDelegate { selectedId = openFileItems[idx - 1].id } } - func closeFileTabs(items: Items) where Items: Collection, Items.Element == WorkspaceClient.FileItem { // TODO: Could potentially be optimized for item in items { diff --git a/CodeEdit/SideBar/SideBarItem.swift b/CodeEdit/SideBar/SideBarItem.swift index 9039dbe452..389e526bfa 100644 --- a/CodeEdit/SideBar/SideBarItem.swift +++ b/CodeEdit/SideBar/SideBarItem.swift @@ -9,22 +9,7 @@ import SwiftUI import WorkspaceClient import CodeFile -struct TabBarDivider: View { - @Environment(\.colorScheme) var colorScheme - let height: CGFloat = 1 - - var body: some View { - Group { - Rectangle() - } - .frame(height: height) - .foregroundColor(colorScheme == .dark ? Color(nsColor: .black) : Color(nsColor: .separatorColor)) - } -} - - struct SideBarItem: View { - @AppStorage(FileIconStyle.storageKey) var iconStyle: FileIconStyle = .default var item: WorkspaceClient.FileItem diff --git a/CodeEdit/TabBar/TabBar.swift b/CodeEdit/TabBar/TabBar.swift index aa143f5f18..9d8d983ddd 100644 --- a/CodeEdit/TabBar/TabBar.swift +++ b/CodeEdit/TabBar/TabBar.swift @@ -8,7 +8,7 @@ import SwiftUI import WorkspaceClient -struct CustomDivider: View { +struct TabBarDivider: View { @Environment(\.colorScheme) var colorScheme let height: CGFloat = 1 diff --git a/CodeEdit/TabBar/TabBarItem.swift b/CodeEdit/TabBar/TabBarItem.swift index b2619c8750..30b04f7b38 100644 --- a/CodeEdit/TabBar/TabBarItem.swift +++ b/CodeEdit/TabBar/TabBarItem.swift @@ -29,22 +29,18 @@ struct TabBarItem: View { @State var isHovering: Bool = false @State var isHoveringClose: Bool = false @State var isPressingClose: Bool = false - var item: WorkspaceClient.FileItem var windowController: NSWindowController - func closeAction () { - withAnimation() { + withAnimation { workspace.closeFileTab(item: item) } } - @ObservedObject var workspace: WorkspaceDocument var tabBarHeight: Double = 28.0 var isActive: Bool { item.id == workspace.selectedId } - @ViewBuilder var content: some View { HStack(spacing: 0.0) { @@ -71,16 +67,8 @@ struct TabBarItem: View { .buttonStyle(PlainButtonStyle()) .foregroundColor(isPressingClose ? .primary : .secondary) .background(colorScheme == .dark - ? isPressingClose - ? Color(nsColor: .white).opacity(0.32) - : isHoveringClose - ? Color(nsColor: .white).opacity(0.18) - : Color(.clear) - : isPressingClose - ? Color(nsColor: .black).opacity(0.29) - : isHoveringClose - ? Color(nsColor: .black).opacity(0.11) - : Color(.clear) + ? Color(nsColor: .white).opacity(isPressingClose ? 0.32 : isHoveringClose ? 0.18 : 0) + : Color(nsColor: .black).opacity(isPressingClose ? 0.29 : isHoveringClose ? 0.11 : 0) ) .cornerRadius(2) .accessibilityLabel(Text("Close")) @@ -93,6 +81,7 @@ struct TabBarItem: View { isPressingClose = false } .opacity(isHovering ? 1 : 0) + .animation(.easeInOut(duration: 0.15), value: isHovering) } Image(systemName: item.systemImage) .resizable() @@ -109,10 +98,10 @@ struct TabBarItem: View { Color(nsColor: isActive ? .clear : .black) .opacity( colorScheme == .dark - ? isHovering ? 0.15 : isActive ? 0 : 0.45 - : isHovering ? 0.15 : isActive ? 0 : 0.05 + ? isHovering ? 0.15 : 0.45 + : isHovering ? 0.15 : 0.05 ) - .animation(.easeInOut(duration: 0.15)) + .animation(.easeInOut(duration: 0.15), value: isHovering) ) TabDivider() } @@ -129,7 +118,6 @@ struct TabBarItem: View { } } } - var body: some View { Button( action: { workspace.selectedId = item.id }, @@ -139,7 +127,6 @@ struct TabBarItem: View { material: NSVisualEffectView.Material.titlebar, blendingMode: NSVisualEffectView.BlendingMode.withinWindow )) - .animation(.easeOut(duration: 0.2), value: workspace.openFileItems) .buttonStyle(.plain) .id(item.id) .keyboardShortcut( diff --git a/CodeEdit/Welcome/WelcomeView.swift b/CodeEdit/Welcome/WelcomeView.swift index 3303be7988..354b4c3a47 100644 --- a/CodeEdit/Welcome/WelcomeView.swift +++ b/CodeEdit/Welcome/WelcomeView.swift @@ -12,12 +12,9 @@ import WelcomeModule struct WelcomeView: View { @Environment(\.colorScheme) var colorScheme - @State var isHovering: Bool = false @State var isHoveringClose: Bool = false - @AppStorage(ReopenBehavior.storageKey) var behavior: ReopenBehavior = .welcome - var dismissWindow: () -> Void private var dismissButton: some View { From e307354a74d33e4e5eb128e06a0493a371770cdb Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 20 Mar 2022 22:40:48 -0500 Subject: [PATCH 22/25] Added PressActionsModifier file to project --- CodeEdit.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CodeEdit.xcodeproj/project.pbxproj b/CodeEdit.xcodeproj/project.pbxproj index 0b88e65cfd..8a2824db43 100644 --- a/CodeEdit.xcodeproj/project.pbxproj +++ b/CodeEdit.xcodeproj/project.pbxproj @@ -35,10 +35,10 @@ 34EE19BE27E0469C00F152CE /* BlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34EE19BD27E0469C00F152CE /* BlurView.swift */; }; 5C403B8F27E20F8000788241 /* WorkspaceClient in Frameworks */ = {isa = PBXBuildFile; productRef = 5C403B8E27E20F8000788241 /* WorkspaceClient */; }; 5CF38A5E27E48E6C0096A0F7 /* CodeFile in Frameworks */ = {isa = PBXBuildFile; productRef = 5CF38A5D27E48E6C0096A0F7 /* CodeFile */; }; - B658C07827E71F910063DB7A /* PressActionsModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B658C07727E71F910063DB7A /* PressActionsModifier.swift */; }; B658FB3427DA9E1000EA4DBD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3327DA9E1000EA4DBD /* Assets.xcassets */; }; B658FB3727DA9E1000EA4DBD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3627DA9E1000EA4DBD /* Preview Assets.xcassets */; }; B65E614627E6765D00255275 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = B65E614527E6765D00255275 /* Introspect */; }; + B673FDAD27E8296A00795864 /* PressActionsModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B673FDAC27E8296A00795864 /* PressActionsModifier.swift */; }; D70F5E2C27E4E8CF004EE4B9 /* WelcomeModule in Frameworks */ = {isa = PBXBuildFile; productRef = D70F5E2B27E4E8CF004EE4B9 /* WelcomeModule */; }; D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7211D4227E066CE008F2ED7 /* Localized+Ex.swift */; }; D7211D4727E06BFE008F2ED7 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D7211D4927E06BFE008F2ED7 /* Localizable.strings */; }; @@ -93,7 +93,6 @@ 28B0A19727E385C300B73177 /* SideBarToolbarTop.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarToolbarTop.swift; sourceTree = ""; }; 28FFE1BE27E3A441001939DB /* SideBarToolbarBottom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideBarToolbarBottom.swift; sourceTree = ""; }; 34EE19BD27E0469C00F152CE /* BlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurView.swift; sourceTree = ""; }; - B658C07727E71F910063DB7A /* PressActionsModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PressActionsModifier.swift; path = ../../../../Downloads/HandlePressReleaseEventsDemo/HandlePressReleaseEventsDemo/PressActionsModifier.swift; sourceTree = ""; }; 5E3C6A3427E72AE000A7CA0D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeEdit.app; sourceTree = BUILT_PRODUCTS_DIR; }; B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkspaceView.swift; sourceTree = ""; }; @@ -102,6 +101,7 @@ B658FB3827DA9E1000EA4DBD /* CodeEdit.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CodeEdit.entitlements; sourceTree = ""; }; B658FB3D27DA9E1000EA4DBD /* CodeEditTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B658FB4727DA9E1000EA4DBD /* CodeEditUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + B673FDAC27E8296A00795864 /* PressActionsModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PressActionsModifier.swift; sourceTree = ""; }; D7211D4227E066CE008F2ED7 /* Localized+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Localized+Ex.swift"; sourceTree = ""; }; D7211D4827E06BFE008F2ED7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; D7211D4A27E06C01008F2ED7 /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sr; path = sr.lproj/Localizable.strings; sourceTree = ""; }; @@ -253,8 +253,8 @@ D72E1A8127E3B0A300EB11B9 /* Welcome */, 043C321227E31FE8006AE443 /* Documents */, 0468438427DC76E200F8E88E /* AppDelegate.swift */, + B673FDAC27E8296A00795864 /* PressActionsModifier.swift */, B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */, - B658C07727E71F910063DB7A /* PressActionsModifier.swift */, 2875A46E27E3BE63007805F8 /* Breadcrumbs */, 287776EA27E350A100D46668 /* SideBar */, 287776EB27E350BA00D46668 /* TabBar */, @@ -492,13 +492,13 @@ 04540D5B27DD08C300E91B77 /* SettingsView.swift in Sources */, D72E1A8927E44D7C00EB11B9 /* WelcomeWindowView.swift in Sources */, 04540D5C27DD08C300E91B77 /* GeneralSettingsView.swift in Sources */, + B673FDAD27E8296A00795864 /* PressActionsModifier.swift in Sources */, 043C321427E31FF6006AE443 /* CodeEditDocumentController.swift in Sources */, 04660F6427E3ACAF00477777 /* Appearances.swift in Sources */, 04540D5E27DD08C300E91B77 /* WorkspaceView.swift in Sources */, 34EE19BE27E0469C00F152CE /* BlurView.swift in Sources */, D7211D4327E066CE008F2ED7 /* Localized+Ex.swift in Sources */, 287776E927E34BC700D46668 /* TabBar.swift in Sources */, - B658C07827E71F910063DB7A /* PressActionsModifier.swift in Sources */, 0485EB1F27E7458B00138301 /* WorkspaceCodeFileView.swift in Sources */, 0485EB1927E70F4900138301 /* QuickOpenView.swift in Sources */, 286620A527E4AB6900E18C2B /* BreadcrumbsComponent.swift in Sources */, From b37110d90f132d8baf14d78cb454522006986051 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 20 Mar 2022 23:01:06 -0500 Subject: [PATCH 23/25] Added PressActionsModifier.swift --- CodeEdit/PressActionsModifier.swift | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 CodeEdit/PressActionsModifier.swift diff --git a/CodeEdit/PressActionsModifier.swift b/CodeEdit/PressActionsModifier.swift new file mode 100644 index 0000000000..f3185f59c9 --- /dev/null +++ b/CodeEdit/PressActionsModifier.swift @@ -0,0 +1,34 @@ +// +// Created by Gabriel Theodoropoulos on 1/11/20. +// + +import SwiftUI + +struct PressActions: ViewModifier { + var onPress: () -> Void + var onRelease: () -> Void + + func body(content: Content) -> some View { + content + .simultaneousGesture( + DragGesture(minimumDistance: 0) + .onChanged({ _ in + onPress() + }) + .onEnded({ _ in + onRelease() + }) + ) + } +} + + +extension View { + func pressAction(onPress: @escaping (() -> Void), onRelease: @escaping (() -> Void)) -> some View { + modifier(PressActions(onPress: { + onPress() + }, onRelease: { + onRelease() + })) + } +} From 556553d8212b1bfaf850f15ac143464e401bd268 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 20 Mar 2022 23:04:22 -0500 Subject: [PATCH 24/25] Fixed lint error --- CodeEdit/PressActionsModifier.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/CodeEdit/PressActionsModifier.swift b/CodeEdit/PressActionsModifier.swift index f3185f59c9..2a49a9dfa2 100644 --- a/CodeEdit/PressActionsModifier.swift +++ b/CodeEdit/PressActionsModifier.swift @@ -22,7 +22,6 @@ struct PressActions: ViewModifier { } } - extension View { func pressAction(onPress: @escaping (() -> Void), onRelease: @escaping (() -> Void)) -> some View { modifier(PressActions(onPress: { From 2c5e533f559a8960a208b803a7d86b07dfe2fa19 Mon Sep 17 00:00:00 2001 From: Austin Condiff Date: Sun, 20 Mar 2022 23:11:03 -0500 Subject: [PATCH 25/25] Fixed lint error --- CodeEdit/PressActionsModifier.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/CodeEdit/PressActionsModifier.swift b/CodeEdit/PressActionsModifier.swift index 2a49a9dfa2..22a57ac210 100644 --- a/CodeEdit/PressActionsModifier.swift +++ b/CodeEdit/PressActionsModifier.swift @@ -7,7 +7,6 @@ import SwiftUI struct PressActions: ViewModifier { var onPress: () -> Void var onRelease: () -> Void - func body(content: Content) -> some View { content .simultaneousGesture(