Skip to content

Commit 40a325c

Browse files
committed
Fixed most gesture issues and refactored background colors. Separated into different views for better organization.
1 parent 9b54737 commit 40a325c

File tree

5 files changed

+200
-94
lines changed

5 files changed

+200
-94
lines changed

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,13 @@
312312
6C48D8F22972DAFC00D6D205 /* Env+IsFullscreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F12972DAFC00D6D205 /* Env+IsFullscreen.swift */; };
313313
6C48D8F42972DB1A00D6D205 /* Env+Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F32972DB1A00D6D205 /* Env+Window.swift */; };
314314
6C48D8F72972E5F300D6D205 /* WindowObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48D8F62972E5F300D6D205 /* WindowObserver.swift */; };
315-
6CDA84AB284C0E4A00C1CC3A /* TabBarItemButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CDA84AA284C0E4A00C1CC3A /* TabBarItemButtonStyle.swift */; };
316315
6CDA84AD284C1BA000C1CC3A /* TabBarContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CDA84AC284C1BA000C1CC3A /* TabBarContextMenu.swift */; };
317316
B62617282964924E00E866AB /* CodeEditKit in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 2801BB89290D5A8E00EBF552 /* CodeEditKit */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
318317
B658FB3427DA9E1000EA4DBD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3327DA9E1000EA4DBD /* Assets.xcassets */; };
319318
B658FB3727DA9E1000EA4DBD /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B658FB3627DA9E1000EA4DBD /* Preview Assets.xcassets */; };
319+
B6C6A42A297716A500A3D28F /* TabBarItemCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C6A429297716A500A3D28F /* TabBarItemCloseButton.swift */; };
320+
B6C6A42E29771A8D00A3D28F /* TabBarItemButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C6A42D29771A8D00A3D28F /* TabBarItemButtonStyle.swift */; };
321+
B6C6A43029771F7100A3D28F /* TabBarItemBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C6A42F29771F7100A3D28F /* TabBarItemBackground.swift */; };
320322
B6D7EA592971078500301FAC /* InspectorSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D7EA582971078500301FAC /* InspectorSection.swift */; };
321323
B6D7EA5C297107DD00301FAC /* InspectorField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D7EA5B297107DD00301FAC /* InspectorField.swift */; };
322324
B6EE989027E8879A00CDD8AB /* InspectorSidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6EE988F27E8879A00CDD8AB /* InspectorSidebarView.swift */; };
@@ -687,7 +689,6 @@
687689
6C48D8F12972DAFC00D6D205 /* Env+IsFullscreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Env+IsFullscreen.swift"; sourceTree = "<group>"; };
688690
6C48D8F32972DB1A00D6D205 /* Env+Window.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Env+Window.swift"; sourceTree = "<group>"; };
689691
6C48D8F62972E5F300D6D205 /* WindowObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowObserver.swift; sourceTree = "<group>"; };
690-
6CDA84AA284C0E4A00C1CC3A /* TabBarItemButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItemButtonStyle.swift; sourceTree = "<group>"; };
691692
6CDA84AC284C1BA000C1CC3A /* TabBarContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarContextMenu.swift; sourceTree = "<group>"; };
692693
B658FB2C27DA9E0F00EA4DBD /* CodeEdit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeEdit.app; sourceTree = BUILT_PRODUCTS_DIR; };
693694
B658FB3127DA9E0F00EA4DBD /* WorkspaceView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = WorkspaceView.swift; sourceTree = "<group>"; tabWidth = 4; };
@@ -696,6 +697,9 @@
696697
B658FB3827DA9E1000EA4DBD /* CodeEdit.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CodeEdit.entitlements; sourceTree = "<group>"; };
697698
B658FB3D27DA9E1000EA4DBD /* CodeEditTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
698699
B658FB4727DA9E1000EA4DBD /* CodeEditUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeEditUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
700+
B6C6A429297716A500A3D28F /* TabBarItemCloseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItemCloseButton.swift; sourceTree = "<group>"; };
701+
B6C6A42D29771A8D00A3D28F /* TabBarItemButtonStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarItemButtonStyle.swift; sourceTree = "<group>"; };
702+
B6C6A42F29771F7100A3D28F /* TabBarItemBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarItemBackground.swift; sourceTree = "<group>"; };
699703
B6D7EA582971078500301FAC /* InspectorSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorSection.swift; sourceTree = "<group>"; };
700704
B6D7EA5B297107DD00301FAC /* InspectorField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorField.swift; sourceTree = "<group>"; };
701705
B6EE988F27E8879A00CDD8AB /* InspectorSidebarView.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = InspectorSidebarView.swift; sourceTree = "<group>"; tabWidth = 4; };
@@ -1795,12 +1799,14 @@
17951799
children = (
17961800
287776E827E34BC700D46668 /* TabBarView.swift */,
17971801
287776EE27E3515300D46668 /* TabBarItemView.swift */,
1802+
B6C6A429297716A500A3D28F /* TabBarItemCloseButton.swift */,
17981803
6CDA84AC284C1BA000C1CC3A /* TabBarContextMenu.swift */,
1799-
6CDA84AA284C0E4A00C1CC3A /* TabBarItemButtonStyle.swift */,
1804+
B6C6A42D29771A8D00A3D28F /* TabBarItemButtonStyle.swift */,
18001805
DE6F77862813625500D00A76 /* TabBarDivider.swift */,
18011806
DE6405A52817734700881FDF /* TabBarNative.swift */,
18021807
DE513F51281B672D002260B9 /* TabBarAccessory.swift */,
18031808
DE513F53281DE5D0002260B9 /* TabBarXcode.swift */,
1809+
B6C6A42F29771F7100A3D28F /* TabBarItemBackground.swift */,
18041810
);
18051811
path = Views;
18061812
sourceTree = "<group>";
@@ -2605,6 +2611,7 @@
26052611
201169E72837B5CA00F92B46 /* SourceControlModel.swift in Sources */,
26062612
58798265292EC4080085B254 /* ExtensionsStoreAPI.swift in Sources */,
26072613
58822528292C280D00E83CDE /* StatusBarEncodingSelector.swift in Sources */,
2614+
B6C6A43029771F7100A3D28F /* TabBarItemBackground.swift in Sources */,
26082615
58F2EB0F292FB2B0004A9BDE /* PreferencesSection.swift in Sources */,
26092616
587B9E8C29301D8F00AC7927 /* GitHubOpenness.swift in Sources */,
26102617
587B9E8229301D8F00AC7927 /* GitHubPreviewHeader.swift in Sources */,
@@ -2675,6 +2682,7 @@
26752682
58F2EAEE292FB2B0004A9BDE /* TextEditingPreferencesView.swift in Sources */,
26762683
58D01C95293167DC00C5B6B4 /* Bundle+Info.swift in Sources */,
26772684
587D9B762933BF5700BF7490 /* Mocks.swift in Sources */,
2685+
B6C6A42A297716A500A3D28F /* TabBarItemCloseButton.swift in Sources */,
26782686
58A5DF7D2931787A00D1BD5D /* ShellClient.swift in Sources */,
26792687
5879821A292D92370085B254 /* SearchResultModel.swift in Sources */,
26802688
587B9E8929301D8F00AC7927 /* GitHubGist.swift in Sources */,
@@ -2771,6 +2779,7 @@
27712779
587B9E8629301D8F00AC7927 /* GitHubComment.swift in Sources */,
27722780
58F2EAE9292FB2B0004A9BDE /* SourceControlPreferencesView.swift in Sources */,
27732781
587B9E9029301D8F00AC7927 /* BitBucketTokenRouter.swift in Sources */,
2782+
B6C6A42E29771A8D00A3D28F /* TabBarItemButtonStyle.swift in Sources */,
27742783
58822525292C280D00E83CDE /* StatusBarMenuLabel.swift in Sources */,
27752784
58F2EB11292FB2B0004A9BDE /* PreferencesToolbar.swift in Sources */,
27762785
58F2EAF0292FB2B0004A9BDE /* PreviewThemeView.swift in Sources */,
@@ -2790,7 +2799,6 @@
27902799
58F2EAF9292FB2B0004A9BDE /* AccountSelectionDialog.swift in Sources */,
27912800
58F2EAE8292FB2B0004A9BDE /* TerminalPreferencesView.swift in Sources */,
27922801
58AFAA2F2933C69E00482B53 /* TabBarItemID.swift in Sources */,
2793-
6CDA84AB284C0E4A00C1CC3A /* TabBarItemButtonStyle.swift in Sources */,
27942802
28FFE1BF27E3A441001939DB /* NavigatorSidebarToolbarBottom.swift in Sources */,
27952803
58F2EAFA292FB2B0004A9BDE /* GitLabHostedLoginView.swift in Sources */,
27962804
);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// TabBarItemBackground.swift
3+
// CodeEdit
4+
//
5+
// Created by Austin Condiff on 1/17/23.
6+
//
7+
8+
import SwiftUI
9+
10+
struct TabBarItemBackground: View {
11+
var isActive: Bool
12+
var isPressing: Bool
13+
var isDragging: Bool
14+
15+
@Environment(\.colorScheme)
16+
private var colorScheme
17+
18+
@Environment(\.controlActiveState)
19+
private var activeState
20+
21+
private var inHoldingState: Bool {
22+
isPressing || isDragging
23+
}
24+
25+
var body: some View {
26+
ZStack {
27+
// Content background (visible if active)
28+
EffectView(.contentBackground)
29+
.opacity(isActive ? 1 : 0)
30+
31+
// Accent color (visible if active)
32+
Color(.controlAccentColor)
33+
.hueRotation(.degrees(-5))
34+
.opacity(
35+
isActive
36+
? colorScheme == .dark
37+
? activeState == .inactive ? 0.22 : inHoldingState ? 0.33 : 0.26
38+
: activeState == .inactive ? 0.1 : inHoldingState ? 0.27 : 0.2
39+
: 0
40+
)
41+
42+
// Highlight (if in dark mode)
43+
Color(.white)
44+
.blendMode(.plusLighter)
45+
.opacity(
46+
colorScheme == .dark
47+
? isActive
48+
? activeState == .inactive ? 0.04 : inHoldingState ? 0.14 : 0.09
49+
: isPressing ? 0.05 : 0
50+
: 0
51+
)
52+
53+
// Dragging color (if not active)
54+
Color(.unemphasizedSelectedTextBackgroundColor)
55+
.opacity(isDragging && !isActive ? 0.85 : 0)
56+
}
57+
}
58+
}
59+
60+
struct TabBarItemBackground_Previews: PreviewProvider {
61+
static var previews: some View {
62+
TabBarItemBackground(isActive: false, isPressing: false, isDragging: false)
63+
}
64+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//
2+
// TabBarItemCloseButton.swift
3+
// CodeEdit
4+
//
5+
// Created by Austin Condiff on 1/17/23.
6+
//
7+
8+
import SwiftUI
9+
10+
struct TabBarItemCloseButton: View {
11+
var isActive: Bool
12+
var isHoveringTab: Bool
13+
var isDragging: Bool
14+
var closeAction: () -> Void
15+
16+
@Environment(\.colorScheme)
17+
var colorScheme
18+
19+
@StateObject
20+
private var prefs: AppPreferencesModel = .shared
21+
22+
@State
23+
private var isPressingClose: Bool = false
24+
25+
@State
26+
private var isHoveringClose: Bool = false
27+
28+
let buttonSize: CGFloat = 16
29+
30+
var body: some View {
31+
HStack {
32+
if prefs.preferences.general.tabBarStyle == .xcode {
33+
Image(systemName: "xmark")
34+
.font(.system(size: 11.5, weight: .regular, design: .rounded))
35+
.foregroundColor(
36+
isActive
37+
? colorScheme == .dark ? .primary : Color(.controlAccentColor)
38+
: .secondary
39+
)
40+
.padding(.top, -0.5)
41+
} else {
42+
Image(systemName: "xmark")
43+
.font(.system(size: 9.5, weight: .medium, design: .rounded))
44+
}
45+
}
46+
.frame(width: buttonSize, height: buttonSize)
47+
.background(
48+
colorScheme == .dark
49+
? Color(nsColor: .white)
50+
.opacity(isPressingClose ? 0.10 : isHoveringClose ? 0.05 : 0)
51+
: (
52+
prefs.preferences.general.tabBarStyle == .xcode
53+
? Color(nsColor: isActive ? .controlAccentColor : .black)
54+
.opacity(
55+
isPressingClose
56+
? 0.25
57+
: (isHoveringClose ? (isActive ? 0.10 : 0.06) : 0)
58+
)
59+
: Color(nsColor: .black)
60+
.opacity(isPressingClose ? 0.29 : (isHoveringClose ? 0.11 : 0))
61+
)
62+
)
63+
.foregroundColor(isPressingClose ? .primary : .secondary)
64+
.cornerRadius(2)
65+
.contentShape(Rectangle())
66+
.highPriorityGesture(
67+
DragGesture(minimumDistance: 0)
68+
.onChanged({ _ in
69+
print("pressed")
70+
isPressingClose = true
71+
})
72+
.onEnded({ value in
73+
if value.location.x > 0
74+
&& value.location.x < buttonSize
75+
&& value.location.y > 0
76+
&& value.location.y < buttonSize {
77+
closeAction()
78+
}
79+
isPressingClose = false
80+
})
81+
, including: .gesture
82+
)
83+
.onHover { hover in
84+
isHoveringClose = hover
85+
}
86+
.accessibilityLabel(Text("Close"))
87+
// Only show when the mouse is hovering and there is no tab dragging.
88+
.opacity(isHoveringTab && !isDragging ? 1 : 0)
89+
.animation(.easeInOut(duration: 0.08), value: isHoveringTab)
90+
.padding(.leading, 4)
91+
}
92+
}
93+
94+
struct TabBarItemCloseButton_Previews: PreviewProvider {
95+
static var previews: some View {
96+
TabBarItemCloseButton(
97+
isActive: false,
98+
isHoveringTab: false,
99+
isDragging: false,
100+
closeAction: { print("Close tab") }
101+
)
102+
}
103+
}

0 commit comments

Comments
 (0)