diff --git a/Xcodes.xcodeproj/project.pbxproj b/Xcodes.xcodeproj/project.pbxproj index e822983..ffdde88 100644 --- a/Xcodes.xcodeproj/project.pbxproj +++ b/Xcodes.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ B0C6AD042AD6E65700E64698 /* ReleaseDateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C6AD032AD6E65700E64698 /* ReleaseDateView.swift */; }; B0C6AD0B2AD9178E00E64698 /* IdenticalBuildView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */; }; B0C6AD0D2AD91D7900E64698 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C6AD0C2AD91D7900E64698 /* IconView.swift */; }; + BDBAB7452B9FF55800694B0B /* TrailingIconLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBAB7442B9FF55800694B0B /* TrailingIconLabelStyle.swift */; }; CA11E7BA2598476C00D2EE1C /* XcodeCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA11E7B92598476C00D2EE1C /* XcodeCommands.swift */; }; CA2518EC25A7FF2B00F08414 /* AppStateUpdateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA2518EB25A7FF2B00F08414 /* AppStateUpdateTests.swift */; }; CA25192A25A9644800F08414 /* XcodeInstallState.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA25192925A9644800F08414 /* XcodeInstallState.swift */; }; @@ -209,6 +210,7 @@ B0C6AD032AD6E65700E64698 /* ReleaseDateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReleaseDateView.swift; sourceTree = ""; }; B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdenticalBuildView.swift; sourceTree = ""; }; B0C6AD0C2AD91D7900E64698 /* IconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = ""; }; + BDBAB7442B9FF55800694B0B /* TrailingIconLabelStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrailingIconLabelStyle.swift; sourceTree = ""; }; CA11E7B92598476C00D2EE1C /* XcodeCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeCommands.swift; sourceTree = ""; }; CA2518EB25A7FF2B00F08414 /* AppStateUpdateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStateUpdateTests.swift; sourceTree = ""; }; CA25192925A9644800F08414 /* XcodeInstallState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeInstallState.swift; sourceTree = ""; }; @@ -380,6 +382,7 @@ 536CFDD3263C9A8000026CE0 /* XcodesSheet.swift */, 53CBAB2B263DCC9100410495 /* XcodesAlert.swift */, E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */, + BDBAB7442B9FF55800694B0B /* TrailingIconLabelStyle.swift */, ); path = Common; sourceTree = ""; @@ -919,6 +922,7 @@ CA9FF84E2595079F00E47BAF /* ScrollingTextView.swift in Sources */, E832EAF82B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift in Sources */, CABFA9C12592EEEA00380FEE /* Version+.swift in Sources */, + BDBAB7452B9FF55800694B0B /* TrailingIconLabelStyle.swift in Sources */, E8D655C0288DD04700A139C2 /* SelectedActionType.swift in Sources */, 36741BFD291E4FDB00A85AAE /* DownloadPreferencePane.swift in Sources */, E84E4F542B333864003F3959 /* PlatformsListView.swift in Sources */, diff --git a/Xcodes/Frontend/Common/NavigationSplitViewWrapper.swift b/Xcodes/Frontend/Common/NavigationSplitViewWrapper.swift index 24bfeda..92dafff 100644 --- a/Xcodes/Frontend/Common/NavigationSplitViewWrapper.swift +++ b/Xcodes/Frontend/Common/NavigationSplitViewWrapper.swift @@ -23,7 +23,7 @@ struct NavigationSplitViewWrapper: View where Sidebar: View, De NavigationSplitView { if #available(macOS 14, *) { sidebar - .navigationSplitViewColumnWidth(min: 250, ideal: 300) + .navigationSplitViewColumnWidth(min: 290, ideal: 290) } else { sidebar } diff --git a/Xcodes/Frontend/Common/TrailingIconLabelStyle.swift b/Xcodes/Frontend/Common/TrailingIconLabelStyle.swift new file mode 100644 index 0000000..19b07fc --- /dev/null +++ b/Xcodes/Frontend/Common/TrailingIconLabelStyle.swift @@ -0,0 +1,22 @@ +// +// TrailingIconLabelStyle.swift +// Xcodes +// +// Created by Daniel Chick on 3/11/24. +// Copyright © 2024 Robots and Pencils. All rights reserved. +// + +import SwiftUI + +struct TrailingIconLabelStyle: LabelStyle { + func makeBody(configuration: Configuration) -> some View { + HStack { + configuration.title + configuration.icon + } + } +} + +extension LabelStyle where Self == TrailingIconLabelStyle { + static var trailingIcon: Self { Self() } +} diff --git a/Xcodes/Frontend/MainWindow.swift b/Xcodes/Frontend/MainWindow.swift index 7b020ad..e89c4b3 100644 --- a/Xcodes/Frontend/MainWindow.swift +++ b/Xcodes/Frontend/MainWindow.swift @@ -16,7 +16,7 @@ struct MainWindow: View { @AppStorage("isShowingInfoPane") private var isShowingInfoPane = false @AppStorage("xcodeListCategory") private var category: XcodeListCategory = .all @AppStorage("isInstalledOnly") private var isInstalledOnly = false - + var body: some View { NavigationSplitViewWrapper { XcodeListView(selectedXcodeID: $selectedXcodeID, searchText: searchText, category: category, isInstalledOnly: isInstalledOnly) diff --git a/Xcodes/Frontend/XcodeList/MainToolbar.swift b/Xcodes/Frontend/XcodeList/MainToolbar.swift index c64c1dd..24b5193 100644 --- a/Xcodes/Frontend/XcodeList/MainToolbar.swift +++ b/Xcodes/Frontend/XcodeList/MainToolbar.swift @@ -5,7 +5,7 @@ struct MainToolbarModifier: ViewModifier { @Binding var category: XcodeListCategory @Binding var isInstalledOnly: Bool @Binding var isShowingInfoPane: Bool - + func body(content: Content) -> some View { content .toolbar { toolbar } @@ -13,9 +13,8 @@ struct MainToolbarModifier: ViewModifier { private var toolbar: some ToolbarContent { ToolbarItemGroup { - ProgressButton( - isInProgress: appState.isUpdating, + isInProgress: appState.isUpdating, action: appState.update ) { Label("Refresh", systemImage: "arrow.clockwise") @@ -23,6 +22,7 @@ struct MainToolbarModifier: ViewModifier { .keyboardShortcut(KeyEquivalent("r")) .help("RefreshDescription") Spacer() + Button(action: { switch category { case .all: category = .release @@ -34,29 +34,17 @@ struct MainToolbarModifier: ViewModifier { case .all: Label("All", systemImage: "line.horizontal.3.decrease.circle") case .release: - if #available(macOS 11.3, *) { Label("ReleaseOnly", systemImage: "line.horizontal.3.decrease.circle.fill") - .labelStyle(TitleAndIconLabelStyle()) + .labelStyle(.trailingIcon) .foregroundColor(.accentColor) - } else { - Label("ReleaseOnly", systemImage: "line.horizontal.3.decrease.circle.fill") - .labelStyle(TitleOnlyLabelStyle()) - .foregroundColor(.accentColor) - } case .beta: - if #available(macOS 11.3, *) { - Label("BetaOnly", systemImage: "line.horizontal.3.decrease.circle.fill") - .labelStyle(TitleAndIconLabelStyle()) - .foregroundColor(.accentColor) - } else { - Label("BetaOnly", systemImage: "line.horizontal.3.decrease.circle.fill") - .labelStyle(TitleOnlyLabelStyle()) - .foregroundColor(.accentColor) - } + Label("BetaOnly", systemImage: "line.horizontal.3.decrease.circle.fill") + .labelStyle(.trailingIcon) + .foregroundColor(.accentColor) } } .help("FilterAvailableDescription") - + Button(action: { isInstalledOnly.toggle() }) { @@ -65,11 +53,9 @@ struct MainToolbarModifier: ViewModifier { .foregroundColor(.accentColor) } else { Label("Filter", systemImage: "arrow.down.app") - } } .help("FilterInstalledDescription") - } } } @@ -80,7 +66,7 @@ extension View { isInstalledOnly: Binding, isShowingInfoPane: Binding ) -> some View { - self.modifier( + modifier( MainToolbarModifier( category: category, isInstalledOnly: isInstalledOnly, diff --git a/Xcodes/Frontend/XcodeList/XcodeListView.swift b/Xcodes/Frontend/XcodeList/XcodeListView.swift index d68936d..e2ce3b6 100644 --- a/Xcodes/Frontend/XcodeList/XcodeListView.swift +++ b/Xcodes/Frontend/XcodeList/XcodeListView.swift @@ -45,7 +45,8 @@ struct XcodeListView: View { .listStyle(.sidebar) .safeAreaInset(edge: .bottom, spacing: 0) { PlatformsPocket() - .padding() + .padding(.horizontal) + .padding(.vertical, 8) } } } @@ -54,19 +55,21 @@ struct PlatformsPocket: View { @SwiftUI.Environment(\.openWindow) private var openWindow var body: some View { - Button(action: { - openWindow(id: "platforms") } + Button(action: { + openWindow(id: "platforms") + } ) { - VStack(spacing: 5) { + HStack(spacing: 5) { Image(systemName: "square.3.layers.3d") - .font(.title) - Text("Platforms") - .font(.callout) + .font(.title3.weight(.medium)) + Text("PlatformsDescription") } - .frame(width: 70, height: 70) - .background(.quaternary) - .clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous)) - + .font(.body.weight(.medium)) + .padding(.horizontal) + .padding(.vertical, 12) + .frame(maxWidth: .infinity, alignment: .leading) + .background(.quaternary.opacity(0.75)) + .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) } .buttonStyle(.plain) } diff --git a/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift b/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift index 55f431c..60777d7 100644 --- a/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift +++ b/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift @@ -30,9 +30,6 @@ struct XcodeListViewRow: View { Text(verbatim: path.string) .font(.caption) .foregroundColor(.secondary) - } else { - Text(verbatim: "") - .font(.caption) } } @@ -42,6 +39,7 @@ struct XcodeListViewRow: View { .padding(.trailing, 16) installControl(for: xcode) } + .padding(.vertical, 4) .contextMenu { switch xcode.installState { case .notInstalled: @@ -75,9 +73,10 @@ struct XcodeListViewRow: View { if let icon = xcode.icon { Image(nsImage: icon) } else { - Color.clear + Image(xcode.version.isPrerelease ? "xcode-beta" : "xcode") + .resizable() .frame(width: 32, height: 32) - .foregroundColor(.secondary) + .opacity(0.2) } } diff --git a/Xcodes/Resources/Assets.xcassets/xcode-beta.imageset/Contents.json b/Xcodes/Resources/Assets.xcassets/xcode-beta.imageset/Contents.json new file mode 100644 index 0000000..62beec5 --- /dev/null +++ b/Xcodes/Resources/Assets.xcassets/xcode-beta.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Image.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Xcodes/Resources/Assets.xcassets/xcode-beta.imageset/Image.png b/Xcodes/Resources/Assets.xcassets/xcode-beta.imageset/Image.png new file mode 100644 index 0000000..2bc9d7a Binary files /dev/null and b/Xcodes/Resources/Assets.xcassets/xcode-beta.imageset/Image.png differ diff --git a/Xcodes/Resources/Assets.xcassets/xcode.imageset/Contents.json b/Xcodes/Resources/Assets.xcassets/xcode.imageset/Contents.json new file mode 100644 index 0000000..4c2a7f7 --- /dev/null +++ b/Xcodes/Resources/Assets.xcassets/xcode.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "xcode.png", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Xcodes/Resources/Assets.xcassets/xcode.imageset/xcode.png b/Xcodes/Resources/Assets.xcassets/xcode.imageset/xcode.png new file mode 100644 index 0000000..d8b43ba Binary files /dev/null and b/Xcodes/Resources/Assets.xcassets/xcode.imageset/xcode.png differ diff --git a/Xcodes/Resources/Localizable.xcstrings b/Xcodes/Resources/Localizable.xcstrings index c63266b..f93f2da 100644 --- a/Xcodes/Resources/Localizable.xcstrings +++ b/Xcodes/Resources/Localizable.xcstrings @@ -15542,6 +15542,16 @@ } } }, + "PlatformsDescription" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Installed Platforms" + } + } + } + }, "PlatformsList.Title" : { "extractionState" : "manual", "localizations" : {