Skip to content

Commit e57e538

Browse files
Updated path picker design (#1502)
* Update the design of the pathbar and find navigator pickers for improved usability. * Fixed find navigator bindings and made text color the control accent color when something else is selected. * Fixed SwiftLint error. * WIP - Handling submenu items getting highlighted. * Removed logic to change the highlighted menu item to white. Will do in another PR. * Simplified button click implementation for EditorPathBarComponent * Swapped custom press modifier out for long press gesture with a minimum duration of zero.
1 parent 235ea68 commit e57e538

File tree

8 files changed

+304
-73
lines changed

8 files changed

+304
-73
lines changed

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@
387387
B61A606929F4481A009B43F9 /* MonospacedFontPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61A606829F4481A009B43F9 /* MonospacedFontPicker.swift */; };
388388
B61DA9DF29D929E100BF4A43 /* GeneralSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61DA9DE29D929E100BF4A43 /* GeneralSettingsView.swift */; };
389389
B628B7932B18369800F9775A /* GitClient+Validate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B628B7922B18369800F9775A /* GitClient+Validate.swift */; };
390+
B628B7B72B223BAD00F9775A /* FindModePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B628B7B62B223BAD00F9775A /* FindModePicker.swift */; };
390391
B62AEDAA2A1FCBE5009A9F52 /* AreaTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62AEDA92A1FCBE5009A9F52 /* AreaTabBar.swift */; };
391392
B62AEDB32A1FD95B009A9F52 /* UtilityAreaTerminalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62AEDB22A1FD95B009A9F52 /* UtilityAreaTerminalView.swift */; };
392393
B62AEDB52A1FE295009A9F52 /* UtilityAreaDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62AEDB42A1FE295009A9F52 /* UtilityAreaDebugView.swift */; };
@@ -896,6 +897,7 @@
896897
B61A606829F4481A009B43F9 /* MonospacedFontPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonospacedFontPicker.swift; sourceTree = "<group>"; };
897898
B61DA9DE29D929E100BF4A43 /* GeneralSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralSettingsView.swift; sourceTree = "<group>"; };
898899
B628B7922B18369800F9775A /* GitClient+Validate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GitClient+Validate.swift"; sourceTree = "<group>"; };
900+
B628B7B62B223BAD00F9775A /* FindModePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindModePicker.swift; sourceTree = "<group>"; };
899901
B62AEDA92A1FCBE5009A9F52 /* AreaTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AreaTabBar.swift; sourceTree = "<group>"; };
900902
B62AEDB22A1FD95B009A9F52 /* UtilityAreaTerminalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilityAreaTerminalView.swift; sourceTree = "<group>"; };
901903
B62AEDB42A1FE295009A9F52 /* UtilityAreaDebugView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UtilityAreaDebugView.swift; sourceTree = "<group>"; };
@@ -2805,6 +2807,7 @@
28052807
D7E201B127E8D50000CB86D0 /* FindNavigatorForm.swift */,
28062808
6C14CEB12877A5BE001468FE /* FindNavigatorResultList */,
28072809
B67DB0F52AFC2A7A002DC647 /* FindNavigatorToolbarBottom.swift */,
2810+
B628B7B62B223BAD00F9775A /* FindModePicker.swift */,
28082811
);
28092812
path = FindNavigator;
28102813
sourceTree = "<group>";
@@ -3184,6 +3187,7 @@
31843187
B640A99E29E2184700715F20 /* SettingsForm.swift in Sources */,
31853188
B62AEDD12A27B264009A9F52 /* View+paneToolbar.swift in Sources */,
31863189
5878DAB1291D627C00DD95A3 /* EditorPathBarComponent.swift in Sources */,
3190+
B628B7B72B223BAD00F9775A /* FindModePicker.swift in Sources */,
31873191
587B9E6E29301D8F00AC7927 /* GitLabProject.swift in Sources */,
31883192
58798234292E30B90085B254 /* FeedbackIssueArea.swift in Sources */,
31893193
852C7E332A587279006BA599 /* SearchableSettingsPage.swift in Sources */,

CodeEdit/Features/CodeEditUI/Views/PressActionsModifier.swift

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,22 @@
88
import SwiftUI
99

1010
struct PressActions: ViewModifier {
11-
var onPress: () -> Void
12-
var onRelease: () -> Void
11+
var onPress: () -> Void
12+
var onRelease: (() -> Void)?
1313

14-
init(onPress: @escaping () -> Void, onRelease: @escaping () -> Void) {
15-
self.onPress = onPress
16-
self.onRelease = onRelease
17-
}
14+
init(onPress: @escaping () -> Void, onRelease: (() -> Void)? = nil) {
15+
self.onPress = onPress
16+
self.onRelease = onRelease
17+
}
1818

19-
func body(content: Content) -> some View {
20-
content
21-
.simultaneousGesture(
22-
DragGesture(minimumDistance: 0)
23-
.onChanged({ _ in
24-
onPress()
25-
})
26-
.onEnded({ _ in
27-
onRelease()
28-
})
29-
)
30-
}
19+
func body(content: Content) -> some View {
20+
content
21+
.simultaneousGesture(
22+
DragGesture(minimumDistance: 0)
23+
.onChanged({ _ in onPress() })
24+
.onEnded({ _ in onRelease?() })
25+
)
26+
}
3127
}
3228

3329
extension View {
@@ -37,11 +33,7 @@ extension View {
3733
/// - onPress: Action to perform once the view is pressed.
3834
/// - onRelease: Action to perform once the view press is released.
3935
/// - Returns: some View
40-
func pressAction(onPress: @escaping (() -> Void), onRelease: @escaping (() -> Void)) -> some View {
41-
modifier(PressActions(onPress: {
42-
onPress()
43-
}, onRelease: {
44-
onRelease()
45-
}))
36+
func pressAction(onPress: @escaping (() -> Void), onRelease: (() -> Void)? = nil) -> some View {
37+
modifier(PressActions(onPress: onPress, onRelease: onRelease))
4638
}
4739
}

CodeEdit/Features/Editor/PathBar/Views/EditorPathBarComponent.swift

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77

88
import SwiftUI
99
import Combine
10+
import CodeEditSymbols
1011

1112
struct EditorPathBarComponent: View {
12-
1313
private let fileItem: CEWorkspaceFile
1414
private let tappedOpenFile: (CEWorkspaceFile) -> Void
15+
private let isLastItem: Bool
1516

1617
@Environment(\.colorScheme)
1718
var colorScheme
@@ -22,16 +23,19 @@ struct EditorPathBarComponent: View {
2223
@EnvironmentObject var workspace: WorkspaceDocument
2324

2425
@State var position: NSPoint?
25-
2626
@State var selection: CEWorkspaceFile
27+
@State var isHovering: Bool = false
28+
@State var button = NSPopUpButton()
2729

2830
init(
2931
fileItem: CEWorkspaceFile,
30-
tappedOpenFile: @escaping (CEWorkspaceFile) -> Void
32+
tappedOpenFile: @escaping (CEWorkspaceFile) -> Void,
33+
isLastItem: Bool
3134
) {
3235
self.fileItem = fileItem
3336
self._selection = .init(wrappedValue: fileItem)
3437
self.tappedOpenFile = tappedOpenFile
38+
self.isLastItem = isLastItem
3539
}
3640

3741
var siblings: [CEWorkspaceFile] {
@@ -49,7 +53,7 @@ struct EditorPathBarComponent: View {
4953
var body: some View {
5054
NSPopUpButtonView(selection: $selection) {
5155
guard let fileManager = workspace.workspaceFileManager else { return NSPopUpButton() }
52-
let button = NSPopUpButton()
56+
5357
button.menu = EditorPathBarMenu(
5458
fileItems: siblings,
5559
fileManager: fileManager,
@@ -58,11 +62,50 @@ struct EditorPathBarComponent: View {
5862
button.font = .systemFont(ofSize: NSFont.systemFontSize(for: .small))
5963
button.isBordered = false
6064
(button.cell as? NSPopUpButtonCell)?.arrowPosition = .noArrow
65+
6166
return button
6267
}
63-
.padding(.top, -0.5)
64-
.padding(.leading, -5)
65-
.padding(.trailing, -3)
68+
.padding(.trailing, 11)
69+
.background {
70+
Color(nsColor: colorScheme == .dark ? .white : .black)
71+
.opacity(isHovering ? 0.05 : 0)
72+
.clipShape(RoundedRectangle(cornerSize: CGSize(width: 4, height: 4)))
73+
HStack {
74+
Spacer()
75+
if isHovering {
76+
chevronUpDown
77+
.padding(.trailing, 4)
78+
} else if !isLastItem {
79+
chevron
80+
.padding(.trailing, 3)
81+
}
82+
}
83+
}
84+
.padding(.vertical, 3)
85+
.onHover { hover in
86+
isHovering = hover
87+
}
88+
.onLongPressGesture(minimumDuration: 0) {
89+
button.performClick(nil)
90+
}
91+
.opacity(activeState != .inactive ? 1 : 0.75)
92+
}
93+
94+
private var chevron: some View {
95+
Image(systemName: "chevron.compact.right")
96+
.font(.system(size: 9, weight: activeState != .inactive ? .medium : .bold, design: .default))
97+
.foregroundStyle(.secondary)
98+
.scaleEffect(x: 1.30, y: 1.0, anchor: .center)
99+
.imageScale(.large)
100+
}
101+
102+
private var chevronUpDown: some View {
103+
VStack(spacing: 1) {
104+
Image(systemName: "chevron.up")
105+
Image(systemName: "chevron.down")
106+
}
107+
.font(.system(size: 6, weight: .bold, design: .default))
108+
.padding(.top, 0.5)
66109
}
67110

68111
struct NSPopUpButtonView<ItemType>: NSViewRepresentable where ItemType: Equatable {

CodeEdit/Features/Editor/PathBar/Views/EditorPathBarMenu.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ final class EditorPathBarMenu: NSMenu, NSMenuDelegate {
2424
delegate = self
2525
fileItems.forEach { item in
2626
let menuItem = PathBarMenuItem(fileItem: item, tappedOpenFile: tappedOpenFile)
27+
menuItem.onStateImage = nil
2728
self.addItem(menuItem)
2829
}
2930
autoenablesItems = false
@@ -35,7 +36,7 @@ final class EditorPathBarMenu: NSMenu, NSMenuDelegate {
3536
}
3637

3738
/// Only when menu item is highlighted then generate its submenu
38-
func menu(_: NSMenu, willHighlight item: NSMenuItem?) {
39+
func menu(_ menu: NSMenu, willHighlight item: NSMenuItem?) {
3940
if let highlightedItem = item, let submenuItems = highlightedItem.submenu?.items, submenuItems.isEmpty {
4041
if let highlightedFileItem = highlightedItem.representedObject as? CEWorkspaceFile {
4142
highlightedItem.submenu = generateSubmenu(highlightedFileItem)

CodeEdit/Features/Editor/PathBar/Views/EditorPathBarView.swift

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct EditorPathBarView: View {
4444

4545
var body: some View {
4646
ScrollView(.horizontal, showsIndicators: false) {
47-
HStack(spacing: 1.5) {
47+
HStack(spacing: 0) {
4848
if file == nil {
4949
Text("No Selection")
5050
.font(.system(size: 11, weight: .regular))
@@ -55,11 +55,11 @@ struct EditorPathBarView: View {
5555
)
5656
} else {
5757
ForEach(fileItems, id: \.self) { fileItem in
58-
if fileItem.parent != nil {
59-
chevron
60-
}
61-
EditorPathBarComponent(fileItem: fileItem, tappedOpenFile: tappedOpenFile)
62-
.padding(.leading, 2.5)
58+
EditorPathBarComponent(
59+
fileItem: fileItem,
60+
tappedOpenFile: tappedOpenFile,
61+
isLastItem: fileItems.last == fileItem
62+
)
6363
}
6464
}
6565
}
@@ -69,13 +69,4 @@ struct EditorPathBarView: View {
6969
.opacity(activeState == .inactive ? 0.8 : 1.0)
7070
.grayscale(isActiveEditor ? 0.0 : 1.0)
7171
}
72-
73-
private var chevron: some View {
74-
Image(systemName: "chevron.compact.right")
75-
.font(.system(size: 14, weight: .thin, design: .default))
76-
.foregroundStyle(.primary)
77-
.scaleEffect(x: 1.30, y: 1.0, anchor: .center)
78-
.imageScale(.large)
79-
.opacity(activeState != .inactive ? 0.8 : 0.5)
80-
}
8172
}

0 commit comments

Comments
 (0)