diff --git a/Info.plist b/Info.plist
index cdc82fc..034ea6c 100644
--- a/Info.plist
+++ b/Info.plist
@@ -5,6 +5,7 @@
UIAppFonts
Nunito-Regular.ttf
+ Nunito-SemiBold.ttf
NunitoSans_7pt_Condensed-Bold.ttf
diff --git a/MoreChess.xcodeproj/project.pbxproj b/MoreChess.xcodeproj/project.pbxproj
index 51c6aa4..6cc2e50 100644
--- a/MoreChess.xcodeproj/project.pbxproj
+++ b/MoreChess.xcodeproj/project.pbxproj
@@ -44,7 +44,7 @@
B9FAC92E2BB04A01002A20F7 /* PlayCondition.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC92D2BB04A01002A20F7 /* PlayCondition.swift */; };
B9FAC9302BB05325002A20F7 /* GameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC92F2BB05325002A20F7 /* GameView.swift */; };
B9FAC9342BB053CC002A20F7 /* LobbyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC9332BB053CC002A20F7 /* LobbyView.swift */; };
- B9FAC9372BB054C2002A20F7 /* SolidButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC9362BB054C2002A20F7 /* SolidButtonStyle.swift */; };
+ B9FAC9372BB054C2002A20F7 /* ButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC9362BB054C2002A20F7 /* ButtonStyles.swift */; };
B9FAC9392BB0586C002A20F7 /* LobbyState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC9382BB0586C002A20F7 /* LobbyState.swift */; };
B9FAC93D2BB058DB002A20F7 /* ServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC93C2BB058DB002A20F7 /* ServiceType.swift */; };
B9FAC93F2BB059CD002A20F7 /* GameService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC93E2BB059CD002A20F7 /* GameService.swift */; };
@@ -62,6 +62,10 @@
B9FAC9592BB2F92E002A20F7 /* Nunito-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B9FAC9572BB2F92E002A20F7 /* Nunito-Regular.ttf */; };
B9FAC95B2BB2FD0C002A20F7 /* Typography.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC95A2BB2FD0C002A20F7 /* Typography.swift */; };
B9FAC95C2BB2FD0C002A20F7 /* Typography.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC95A2BB2FD0C002A20F7 /* Typography.swift */; };
+ B9FAC9602BB30D8F002A20F7 /* StyleConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC95F2BB30D8F002A20F7 /* StyleConstants.swift */; };
+ B9FAC9612BB30D8F002A20F7 /* StyleConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAC95F2BB30D8F002A20F7 /* StyleConstants.swift */; };
+ B9FAC9632BB30F40002A20F7 /* Nunito-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B9FAC9622BB30F40002A20F7 /* Nunito-SemiBold.ttf */; };
+ B9FAC9642BB30F40002A20F7 /* Nunito-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B9FAC9622BB30F40002A20F7 /* Nunito-SemiBold.ttf */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -116,7 +120,7 @@
B9FAC92D2BB04A01002A20F7 /* PlayCondition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayCondition.swift; sourceTree = ""; };
B9FAC92F2BB05325002A20F7 /* GameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameView.swift; sourceTree = ""; };
B9FAC9332BB053CC002A20F7 /* LobbyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LobbyView.swift; sourceTree = ""; };
- B9FAC9362BB054C2002A20F7 /* SolidButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SolidButtonStyle.swift; sourceTree = ""; };
+ B9FAC9362BB054C2002A20F7 /* ButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonStyles.swift; sourceTree = ""; };
B9FAC9382BB0586C002A20F7 /* LobbyState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LobbyState.swift; sourceTree = ""; };
B9FAC93C2BB058DB002A20F7 /* ServiceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceType.swift; sourceTree = ""; };
B9FAC93E2BB059CD002A20F7 /* GameService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameService.swift; sourceTree = ""; };
@@ -132,6 +136,8 @@
B9FAC9572BB2F92E002A20F7 /* Nunito-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-Regular.ttf"; sourceTree = ""; };
B9FAC95A2BB2FD0C002A20F7 /* Typography.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Typography.swift; sourceTree = ""; };
B9FAC95E2BB2FE66002A20F7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ B9FAC95F2BB30D8F002A20F7 /* StyleConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleConstants.swift; sourceTree = ""; };
+ B9FAC9622BB30F40002A20F7 /* Nunito-SemiBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Nunito-SemiBold.ttf"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -325,7 +331,7 @@
B9FAC9352BB054A2002A20F7 /* Elements */ = {
isa = PBXGroup;
children = (
- B9FAC9362BB054C2002A20F7 /* SolidButtonStyle.swift */,
+ B9FAC9362BB054C2002A20F7 /* ButtonStyles.swift */,
B9FAC9482BB06C91002A20F7 /* SimpleNavigationBackButton.swift */,
B9FAC94A2BB06FB2002A20F7 /* WaitingView.swift */,
);
@@ -361,6 +367,7 @@
B9FAC94E2BB2E833002A20F7 /* Color.swift */,
B9FAC95A2BB2FD0C002A20F7 /* Typography.swift */,
B9FAC9502BB2F46D002A20F7 /* Style.swift */,
+ B9FAC95F2BB30D8F002A20F7 /* StyleConstants.swift */,
);
path = Resources;
sourceTree = "";
@@ -369,6 +376,7 @@
isa = PBXGroup;
children = (
B9FAC9572BB2F92E002A20F7 /* Nunito-Regular.ttf */,
+ B9FAC9622BB30F40002A20F7 /* Nunito-SemiBold.ttf */,
B9FAC9532BB2F706002A20F7 /* NunitoSans_7pt_Condensed-Bold.ttf */,
);
path = Fonts;
@@ -503,6 +511,7 @@
B9FAC9192BAF070C002A20F7 /* Launch Screen.storyboard in Resources */,
B9FAC9582BB2F92E002A20F7 /* Nunito-Regular.ttf in Resources */,
B95CE53B2AD4CB5E00978591 /* Assets.xcassets in Resources */,
+ B9FAC9632BB30F40002A20F7 /* Nunito-SemiBold.ttf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -510,6 +519,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ B9FAC9642BB30F40002A20F7 /* Nunito-SemiBold.ttf in Resources */,
B9FAC9592BB2F92E002A20F7 /* Nunito-Regular.ttf in Resources */,
B95CE53C2AD4CB5E00978591 /* Assets.xcassets in Resources */,
B9FAC9552BB2F706002A20F7 /* NunitoSans_7pt_Condensed-Bold.ttf in Resources */,
@@ -546,10 +556,11 @@
B9FAC92E2BB04A01002A20F7 /* PlayCondition.swift in Sources */,
B9FAC9392BB0586C002A20F7 /* LobbyState.swift in Sources */,
B9FAC9112BAEF492002A20F7 /* PositioningState.swift in Sources */,
- B9FAC9372BB054C2002A20F7 /* SolidButtonStyle.swift in Sources */,
+ B9FAC9372BB054C2002A20F7 /* ButtonStyles.swift in Sources */,
B9FAC9412BB05A63002A20F7 /* LobbyInteractor.swift in Sources */,
B94B61B32B461DD200C998F3 /* GridCoordinate.swift in Sources */,
B9FAC9242BAF1E9F002A20F7 /* Board.swift in Sources */,
+ B9FAC9602BB30D8F002A20F7 /* StyleConstants.swift in Sources */,
B9FAC9472BB06C0C002A20F7 /* ClientView.swift in Sources */,
B95CE5392AD4CB5E00978591 /* ContentView.swift in Sources */,
B9FAC92C2BAF3102002A20F7 /* MoveValidator.swift in Sources */,
@@ -586,6 +597,7 @@
B90F55AD2BA6289800874F00 /* PieceView.swift in Sources */,
B94B61B12B461D3200C998F3 /* Piece.swift in Sources */,
B90F55AA2BA61F6E00874F00 /* MovesView.swift in Sources */,
+ B9FAC9612BB30D8F002A20F7 /* StyleConstants.swift in Sources */,
B9FAC95C2BB2FD0C002A20F7 /* Typography.swift in Sources */,
B94B61F62B68F8D700C998F3 /* PieceGenerator.swift in Sources */,
);
diff --git a/Shared/Assets.xcassets/Gray.colorset/Contents.json b/Shared/Assets.xcassets/Gray.colorset/Contents.json
new file mode 100644
index 0000000..d8a6892
--- /dev/null
+++ b/Shared/Assets.xcassets/Gray.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.664",
+ "green" : "0.664",
+ "red" : "0.664"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.921",
+ "green" : "0.921",
+ "red" : "0.921"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Shared/MoreChessApp.swift b/Shared/MoreChessApp.swift
index ec03438..da21145 100644
--- a/Shared/MoreChessApp.swift
+++ b/Shared/MoreChessApp.swift
@@ -10,7 +10,7 @@ import SwiftUI
@main
struct MoreChessApp: App {
- /*
+
init() {
for family in UIFont.familyNames {
print("\(family)")
@@ -19,7 +19,7 @@ struct MoreChessApp: App {
}
}
}
- */
+
var body: some Scene {
WindowGroup {
diff --git a/Shared/Presentation/Elements/ButtonStyles.swift b/Shared/Presentation/Elements/ButtonStyles.swift
new file mode 100644
index 0000000..7ed225e
--- /dev/null
+++ b/Shared/Presentation/Elements/ButtonStyles.swift
@@ -0,0 +1,154 @@
+//
+// ButtonStyles.swift
+// MoreChess (iOS)
+//
+// Created by Richard Adem on 3/24/24.
+//
+
+import SwiftUI
+
+struct PrimaryButtonStyle: ButtonStyle {
+ @Environment(\.isEnabled) private var isEnabled
+
+ func makeBody(configuration: Configuration) -> some View {
+
+ var backgroundColor: Color {
+ if isEnabled == false {
+ // Disabled
+ Color.disabled
+ } else if configuration.isPressed {
+ // Highlighted, just the background changes.
+ Color.accentColor.opacity(StyleConstants.highlightedOpacity)
+ } else {
+ // Normal
+ Color.accentColor
+ }
+ }
+
+ configuration.label
+ .padding(12)
+ .font(StyleFont.button)
+ .strikethrough(isEnabled == false, color: Color.disabled)
+ .foregroundStyle(Color.background)
+ .background{
+ RoundedRectangle(cornerRadius: StyleConstants.cornerRadius)
+ .fill(backgroundColor)
+ .animation(.easeOut(duration: StyleConstants.animationTime),
+ value: configuration.isPressed)
+ }
+ }
+}
+
+struct SecondaryButtonStyle: ButtonStyle {
+ @Environment(\.isEnabled) private var isEnabled
+
+ func makeBody(configuration: Configuration) -> some View {
+
+ var backgroundColor: Color {
+ if isEnabled == false {
+ // Disabled
+ Color.disabled
+ } else if configuration.isPressed {
+ // Highlighted
+ Color.accentColor
+ } else {
+ // Normal
+ Color.accentColor
+ }
+ }
+
+ configuration.label
+ .padding(10)
+ .font(StyleFont.button)
+ .strikethrough(isEnabled == false, color: Color.disabled)
+ .foregroundStyle(Color.accentColor)
+ .background{
+ RoundedRectangle(cornerRadius: StyleConstants.cornerRadius)
+ .stroke(backgroundColor, lineWidth: StyleConstants.lineWidth)
+ .animation(.easeOut(duration: StyleConstants.animationTime),
+ value: configuration.isPressed)
+ }
+ // Change whole button on pressed.
+ .opacity(configuration.isPressed ? StyleConstants.highlightedOpacity : 1.0)
+ }
+}
+
+struct SolidButtonStyle: ButtonStyle {
+ func makeBody(configuration: Configuration) -> some View {
+ configuration.label
+ .padding()
+ .background(Color.accentColor)
+ .foregroundStyle(Color.background)
+ .font(.headline)
+ .clipShape(Capsule())
+ .scaleEffect(configuration.isPressed ? 1.2 : 1)
+ .animation(.easeOut(duration: StyleConstants.animationTime), value: configuration.isPressed)
+ }
+}
+
+struct FunkyButtonStyle: ButtonStyle {
+
+ @Environment(\.colorScheme) var colorScheme
+
+ fileprivate struct CurvedLine: Shape {
+ func path(in rect: CGRect) -> Path {
+ Path { path in
+ path.move(to: CGPoint(x: rect.minX, y: rect.minY))
+ path.addQuadCurve(to: CGPoint(x: rect.maxX, y: rect.midY),
+ control: CGPoint(x: rect.width * 1.0, y: rect.height * -0.4))
+
+ }
+ }
+ }
+
+ func makeBody(configuration: Configuration) -> some View {
+ let foregroundColor = colorScheme == .dark ? Color.foreground : Color.background
+
+ configuration.label
+ .padding()
+ .background(LinearGradient(gradient: Gradient(colors: [.accentColor, .black]),
+ startPoint: .top,
+ endPoint: .bottom))
+ .overlay{
+ VStack {
+ CurvedLine()
+ .stroke(.white, style: StrokeStyle(lineWidth: 4, lineCap: .round))
+ .frame(height: 10)
+ .padding(.vertical, 6)
+ .padding(.leading, 19)
+ .padding(.trailing, 14)
+ Spacer()
+ }
+ }
+ .foregroundStyle(foregroundColor)
+ .font(.headline)
+ .clipShape(Capsule())
+ .scaleEffect(configuration.isPressed ? 1.2 : 1)
+ .rotationEffect(.degrees(configuration.isPressed ? 30 : 0))
+ .animation(.easeOut(duration: StyleConstants.animationTime), value: configuration.isPressed)
+ }
+}
+
+#Preview {
+ VStack {
+
+ Button("Button") { }.buttonStyle(PrimaryButtonStyle())
+ Button("Disabled") { }.buttonStyle(PrimaryButtonStyle())
+ .disabled(true)
+
+ Button("Button") { }.buttonStyle(SecondaryButtonStyle())
+ Button("Disabled") { }.buttonStyle(SecondaryButtonStyle())
+ .disabled(true)
+
+
+ Button("Press Me") { }
+ .buttonStyle(SolidButtonStyle())
+
+ Button("Press Me") { }
+ .buttonStyle(FunkyButtonStyle())
+
+ Button("Very long text for a button") { }
+ .buttonStyle(FunkyButtonStyle())
+ }
+ .style()
+}
diff --git a/Shared/Presentation/Elements/SolidButtonStyle.swift b/Shared/Presentation/Elements/SolidButtonStyle.swift
deleted file mode 100644
index 318ef79..0000000
--- a/Shared/Presentation/Elements/SolidButtonStyle.swift
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// SolidButtonStyle.swift
-// MoreChess (iOS)
-//
-// Created by Richard Adem on 3/24/24.
-//
-
-import SwiftUI
-
-struct SolidButtonStyle: ButtonStyle {
- func makeBody(configuration: Configuration) -> some View {
- configuration.label
- .padding()
- .background(.tint)
- .foregroundStyle(Color.background)
- .font(.headline)
- .clipShape(Capsule())
- .scaleEffect(configuration.isPressed ? 1.2 : 1)
- .animation(.easeOut(duration: 0.2), value: configuration.isPressed)
- }
-}
-
-#Preview {
- Button("Press Me") {
- }
- .buttonStyle(SolidButtonStyle())
- .style()
-}
diff --git a/Shared/Presentation/Lobby/LobbyView.swift b/Shared/Presentation/Lobby/LobbyView.swift
index 5381498..e219088 100644
--- a/Shared/Presentation/Lobby/LobbyView.swift
+++ b/Shared/Presentation/Lobby/LobbyView.swift
@@ -38,12 +38,12 @@ struct LobbyView: View {
Button("Host") {
lobbyInteractor.select(serviceType: .host)
}
- .buttonStyle(SolidButtonStyle())
+ .buttonStyle(PrimaryButtonStyle())
Button("Join") {
lobbyInteractor.select(serviceType: .client)
}
- .buttonStyle(SolidButtonStyle())
+ .buttonStyle(PrimaryButtonStyle())
} // HStack
}
.style()
diff --git a/Shared/Resources/Color.swift b/Shared/Resources/Color.swift
index 2bca157..6a94cb5 100644
--- a/Shared/Resources/Color.swift
+++ b/Shared/Resources/Color.swift
@@ -8,6 +8,12 @@
import SwiftUI
extension Color {
+
+ // Functional Colors
static let foreground = Color("Foreground")
static let background = Color("Background")
+ static let disabled = Color.brandedGray
+
+ // Defined Colors
+ static let brandedGray = Color("Gray")
}
diff --git a/Shared/Resources/Fonts/Nunito-SemiBold.ttf b/Shared/Resources/Fonts/Nunito-SemiBold.ttf
new file mode 100644
index 0000000..1326a7d
Binary files /dev/null and b/Shared/Resources/Fonts/Nunito-SemiBold.ttf differ
diff --git a/Shared/Resources/StyleConstants.swift b/Shared/Resources/StyleConstants.swift
new file mode 100644
index 0000000..19a4ca7
--- /dev/null
+++ b/Shared/Resources/StyleConstants.swift
@@ -0,0 +1,18 @@
+//
+// StyleConstants.swift
+// MoreChess
+//
+// Created by Richard Adem on 3/26/24.
+//
+
+import Foundation
+
+enum StyleConstants {
+ // Layout
+ static let lineWidth: CGFloat = 2
+ static let highlightedOpacity: CGFloat = 0.25
+ static let cornerRadius: CGFloat = 8
+
+ // Animation
+ static let animationTime: TimeInterval = 0.2
+}
diff --git a/Shared/Resources/Typography.swift b/Shared/Resources/Typography.swift
index 7b8aa1a..ba61b31 100644
--- a/Shared/Resources/Typography.swift
+++ b/Shared/Resources/Typography.swift
@@ -10,6 +10,7 @@ import SwiftUI
enum CustomFontNames {
static let nunitoSansCondensedBold = "NunitoSans7ptCondensed-Bold"
static let nunitoRegular = "Nunito-Regular"
+ static let nunitoSemiBold = "Nunito-SemiBold"
}
struct StyleFont {
@@ -21,4 +22,8 @@ struct StyleFont {
let scaledSize = UIFontMetrics.default.scaledValue(for: 16)
return Font.custom(CustomFontNames.nunitoRegular, size: scaledSize)
}
+ static let button: Font = {
+ let scaledSize = UIFontMetrics.default.scaledValue(for: 18)
+ return Font.custom(CustomFontNames.nunitoSemiBold, size: scaledSize)
+ }()
}