Skip to content

Commit

Permalink
add accent color preference and adoption across most elements
Browse files Browse the repository at this point in the history
  • Loading branch information
drewvolz committed Mar 3, 2024
1 parent 78eb269 commit 25030da
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 9 deletions.
4 changes: 4 additions & 0 deletions ClassDumper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
3A5863712B84564F00487B13 /* URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A5863702B84564F00487B13 /* URL.swift */; };
3A5863F02B8C069C00487B13 /* FilterScopeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A5863EF2B8C069C00487B13 /* FilterScopeView.swift */; };
3A5863F22B8C14A400487B13 /* FilePathView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A5863F12B8C14A400487B13 /* FilePathView.swift */; };
3A67A98E2B94F0A700961FF9 /* CodableColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A67A98D2B94F0A700961FF9 /* CodableColor.swift */; };
3A67D7642A511F7600516FF2 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A67D7632A511F7600516FF2 /* App.swift */; };
3A67D7662A511FFA00516FF2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A67D7652A511FFA00516FF2 /* AppDelegate.swift */; };
3A67D7682A51566B00516FF2 /* String+ConsoleOutput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A67D7672A51566B00516FF2 /* String+ConsoleOutput.swift */; };
Expand Down Expand Up @@ -95,6 +96,7 @@
3A5863702B84564F00487B13 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
3A5863EF2B8C069C00487B13 /* FilterScopeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterScopeView.swift; sourceTree = "<group>"; };
3A5863F12B8C14A400487B13 /* FilePathView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePathView.swift; sourceTree = "<group>"; };
3A67A98D2B94F0A700961FF9 /* CodableColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableColor.swift; sourceTree = "<group>"; };
3A67D7632A511F7600516FF2 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
3A67D7652A511FFA00516FF2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
3A67D7672A51566B00516FF2 /* String+ConsoleOutput.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+ConsoleOutput.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -282,6 +284,7 @@
3A91CDC22A577B0E00C85A27 /* Binding.swift */,
3A827B002A342ABF006A1A96 /* Endpoint.swift */,
3A5863702B84564F00487B13 /* URL.swift */,
3A67A98D2B94F0A700961FF9 /* CodableColor.swift */,
);
path = Extension;
sourceTree = "<group>";
Expand Down Expand Up @@ -480,6 +483,7 @@
3AA565472A25BD4900EBD7FB /* Notification.swift in Sources */,
3AA564FF2A232B4C00EBD7FB /* SettingsView.swift in Sources */,
3A67D7642A511F7600516FF2 /* App.swift in Sources */,
3A67A98E2B94F0A700961FF9 /* CodableColor.swift in Sources */,
3A2F8F752A397CF100D9FB26 /* DatabaseButtons.swift in Sources */,
3A91CDDA2A57BEDE00C85A27 /* Keys.swift in Sources */,
3A67D7682A51566B00516FF2 /* String+ConsoleOutput.swift in Sources */,
Expand Down
4 changes: 3 additions & 1 deletion ClassDumper/AppView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ typealias FileDatabase = Array<File>

struct AppView: View {
@Environment(\.fileRepository) private var fileRepository
@AppStorage("accent") var accent = CodableColor(.accentColor)

@Query(FileCountRequest())
fileprivate var fileCount: Int
Expand Down Expand Up @@ -44,6 +45,7 @@ struct AppView: View {
parseDirectory()
}
.navigationTitle(NSApplication.bundleName)
.tint(accent.toColor())
}
}

Expand All @@ -58,7 +60,7 @@ extension AppView {
}
}, label: {
Label("Edit files", systemImage: "pencil")
.foregroundColor(deletionEnabled ? .accentColor : .none)
.foregroundColor(deletionEnabled ? accent.toColor() : .none)
})
.keyboardShortcut("e", modifiers: [.command])
}
Expand Down
3 changes: 2 additions & 1 deletion ClassDumper/ClassDumperApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import SwiftUI
struct ClassDumperApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@StateObject private var alertController = AlertController()

@AppStorage("accent") var accent = CodableColor(.accentColor)

var body: some Scene {
WindowGroup {
AppView()
Expand Down
45 changes: 45 additions & 0 deletions ClassDumper/Extension/CodableColor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import SwiftUI

struct AccentColor: Identifiable {
var id: String { name }
var color: CodableColor
var name: String
}

var accents: [AccentColor] = [
.init(color: CodableColor(.blue), name: "Blue"),
.init(color: CodableColor(.purple), name: "Purple"),
.init(color: CodableColor(.pink), name: "Pink"),
.init(color: CodableColor(.red), name: "Red"),
.init(color: CodableColor(.orange), name: "Orange"),
.init(color: CodableColor(.yellow), name: "Yellow"),
.init(color: CodableColor(.green), name: "Green"),
.init(color: CodableColor(.gray), name: "Gray"),
]

struct CodableColor: RawRepresentable, Codable {
let rawValue: String

init(rawValue: String) {
self.rawValue = rawValue
}

init(_ color: Color) {
let nsColor = NSColor(color).usingColorSpace(.deviceRGB)!
let red = Int(nsColor.redComponent * 255)
let green = Int(nsColor.greenComponent * 255)
let blue = Int(nsColor.blueComponent * 255)
let alpha = Int(nsColor.alphaComponent * 255)

self.rawValue = String(format: "%02X%02X%02X%02X", red, green, blue, alpha)
}

func toColor() -> Color {
let red = Double(Int(rawValue.prefix(2), radix: 16)!) / 255.0
let green = Double(Int(rawValue.dropFirst(2).prefix(2), radix: 16)!) / 255.0
let blue = Double(Int(rawValue.dropFirst(4).prefix(2), radix: 16)!) / 255.0
let alpha = Double(Int(rawValue.dropFirst(6).prefix(2), radix: 16)!) / 255.0

return Color(NSColor(calibratedRed: CGFloat(red), green: CGFloat(green), blue: CGFloat(blue), alpha: CGFloat(alpha)))
}
}
4 changes: 4 additions & 0 deletions ClassDumper/Shared/Keys.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ struct Keys {
static let PathBarFile = "PathBarFile"
}

struct Settings {
static let AccentColorButton = "AccentColorButton"
}

struct Filters {
static let FilterFiles = "FilterFiles"
}
Expand Down
6 changes: 4 additions & 2 deletions ClassDumper/Views/FilePathView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import SwiftUI

struct FilePathView: View {
@AppStorage("accent") var accent = CodableColor(.accentColor)

var folderName: String
var fileName: String

Expand All @@ -9,7 +11,7 @@ struct FilePathView: View {
HStack {
HStack(spacing: 4) {
Image(systemName: "folder.fill")
.foregroundColor(.accentColor)
.foregroundColor(accent.toColor())
Text(folderName)
}

Expand All @@ -18,7 +20,7 @@ struct FilePathView: View {

HStack(spacing: 4) {
Image(systemName: "doc.fill")
.foregroundColor(.accentColor)
.foregroundColor(accent.toColor())
Text(fileName)
.accessibilityIdentifier(Keys.Detail.PathBarFile)
}
Expand Down
3 changes: 2 additions & 1 deletion ClassDumper/Views/FileRowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct FileRowRequest: Queryable {

struct FileRowView: View {
@AppStorage("scopedSearchPreference") var scopedSearchPreference = Preferences.Defaults.scopedSearch
@AppStorage("accent") var accent = CodableColor(.accentColor)

// query to fetch all data
@Query(FileRowRequest())
Expand Down Expand Up @@ -64,7 +65,7 @@ struct FileRowView: View {
} icon: {
Image(systemName: "doc")
.symbolVariant(.fill)
.foregroundColor(.accentColor)
.foregroundColor(accent.toColor())
}
}
.accessibilityIdentifier(Keys.Middle.Row)
Expand Down
4 changes: 3 additions & 1 deletion ClassDumper/Views/FolderRowView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ struct FolderRowRequest: Queryable {
extension AppView {

struct FolderRowView: View {
@AppStorage("accent") var accent = CodableColor(.accentColor)

@Query(FolderRowRequest())
var folderRows: FolderRowResponse

Expand All @@ -38,7 +40,7 @@ extension AppView {
}
} icon: {
Image(systemName: "folder")
.foregroundColor(.accentColor)
.foregroundColor(accent.toColor())
}
.badge(badge)
}
Expand Down
10 changes: 7 additions & 3 deletions ClassDumper/Views/InformationStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,27 @@ import SwiftUI

/// The style for information text
struct InformationStyle: ViewModifier {
@AppStorage("accent") var accent = CodableColor(.accentColor)

func body(content: Content) -> some View {
content
.frame(maxWidth: .infinity, alignment: .leading)
.foregroundColor(.accentColor)
.foregroundColor(accent.toColor())
.font(.callout)
}
}

/// The style for information boxes
struct InformationBox: ViewModifier {
@AppStorage("accent") var accent = CodableColor(.accentColor)

func body(content: Content) -> some View {
content
.padding()
.frame(maxWidth: .infinity, alignment: .center)
.background(Color.accentColor.opacity(0.07))
.background(accent.toColor().opacity(0.07))
.buttonStyle(.borderedProminent)
.tint(.accentColor)
.tint(accent.toColor())
.cornerRadius(10)
.padding()
}
Expand Down
2 changes: 2 additions & 0 deletions ClassDumper/Views/Settings/DebugTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import SwiftUI
struct DebugSettingsView: View {
@AppStorage("enableVerboseImportErrorLogging") var enableVerboseImportErrorLogging = Preferences.Defaults.verboseErrors
@AppStorage("dialogLengthImportErrorLogging") var dialogLengthImportErrorLogging = Preferences.Defaults.dialogLength
@AppStorage("accent") var accent = CodableColor(.accentColor)

let helpLogging = """
This setting could be useful if you need to see the original message.
Expand Down Expand Up @@ -51,6 +52,7 @@ Note that verbose error dialogs will disable this setting.
}
.help(helpErrorLength)
}
.tint(accent.toColor())
.modifier(PreferencesTabViewModifier(sectionTitle: "Errors"))
}
}
Expand Down
41 changes: 41 additions & 0 deletions ClassDumper/Views/Settings/GeneralTabView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import SwiftUI
import CodeEditor

struct GeneralSettingsView: View {
@AppStorage("accent") var accent = CodableColor(.accentColor)
@AppStorage("codeViewerTheme") var theme: CodeEditor.ThemeName = Preferences.Defaults.themeName
@AppStorage("codeViewerFontSize") var fontSize: Int = Preferences.Defaults.fontSize

var body: some View {
VStack(alignment: .leading, spacing: 20) {
AccentColor()
ThemePicker()
FontSizePicker()
ResetDataButton()
Expand All @@ -16,6 +18,43 @@ struct GeneralSettingsView: View {

extension GeneralSettingsView {

@ViewBuilder
func AccentColor() -> some View {
LazyHGrid(rows: [GridItem(.flexible(minimum: 30, maximum: .infinity))], alignment: .top, spacing: 1) {
ForEach(accents) { option in
Button {
accent = option.color
} label: {
VStack {
Circle()
.fill(option.color.toColor())
.frame(width: 15, height: 15)
.padding(5)
.accessibilityIdentifier("\(Keys.Settings.AccentColorButton)-\(option.name)")
.overlay(content: {
if accent == option.color {
Circle()
.fill(.white)
.frame(width: 6, height: 6, alignment: .center)
.accessibilityLabel("Selected accent color")
}
})

Text(accent == option.color ? option.name : "")
.frame(minHeight: 5)
.fixedSize(horizontal: true, vertical: false)
.frame(width: 35)
.focusable(false)
.accessibilityLabel(option.name)
}
.tag(option.id)
}
.buttonStyle(.plain)
}
}
.modifier(PreferencesTabViewModifier(sectionTitle: "Accent color"))
}

@ViewBuilder
func ThemePicker() -> some View {
Picker("", selection: $theme) {
Expand All @@ -27,6 +66,7 @@ extension GeneralSettingsView {
.labelsHidden()
.pickerStyle(.menu)
.fixedSize()
.tint(accent.toColor())
.modifier(PreferencesTabViewModifier(sectionTitle: "Code theme"))
}

Expand All @@ -40,6 +80,7 @@ extension GeneralSettingsView {
.frame(minWidth: 55, maxWidth: 85)
.fixedSize()
}
.tint(accent.toColor())
.modifier(PreferencesTabViewModifier(sectionTitle: "Font size"))
}

Expand Down
3 changes: 3 additions & 0 deletions ClassDumper/Views/Settings/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ struct SettingsView: View {
}

var body: some View {
@AppStorage("accent") var accent = CodableColor(.accentColor)

TabView {
GeneralSettingsView()
.tabItem {
Expand All @@ -20,6 +22,7 @@ struct SettingsView: View {
}
.tag(Tabs.debug)
}
.tint(accent.toColor())
.padding(20)
.frame(width: 500, alignment: .leading)
}
Expand Down
1 change: 1 addition & 0 deletions ClassDumperUITests/ClassDumperUITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ final class ClassDumperUITests: UITestCase {
.tapFirst(.filterToggle, containing: "Show selected")
// TODO: CI is failing this test although it is working locally
// .selectPopupButton("Show all")
.checkAccentColorTappable()
}
}
14 changes: 14 additions & 0 deletions ClassDumperUITests/ImportFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct ImportFlow: Screen {
}
}

@discardableResult
func check(_ element: Component, exists: Bool) -> Self {
let forElement = getComponent(for: element)

Expand Down Expand Up @@ -126,6 +127,19 @@ struct ImportFlow: Screen {

return self
}

@discardableResult
func checkAccentColorTappable() -> Self {
open(.settings)

app.windows.buttons["General"].tap()

let blueAccentButton = app.buttons["\(Keys.Settings.AccentColorButton)-Blue"]
XCTAssert(blueAccentButton.exists)
blueAccentButton.tap()

return self
}

fileprivate func open(_ shortcut: Shortcut) {
app.typeKey(shortcut.rawValue, modifierFlags: .command)
Expand Down

0 comments on commit 25030da

Please sign in to comment.