From 69d85a9478963ca31ec44c67a8c58ed7e0b77338 Mon Sep 17 00:00:00 2001 From: Brandon Evans Date: Wed, 30 Dec 2020 09:03:56 -0700 Subject: [PATCH] Extract XcodeListViewRow --- Xcodes.xcodeproj/project.pbxproj | 4 + Xcodes/Frontend/XcodeList/XcodeListView.swift | 68 +----------- .../Frontend/XcodeList/XcodeListViewRow.swift | 102 ++++++++++++++++++ 3 files changed, 107 insertions(+), 67 deletions(-) create mode 100644 Xcodes/Frontend/XcodeList/XcodeListViewRow.swift diff --git a/Xcodes.xcodeproj/project.pbxproj b/Xcodes.xcodeproj/project.pbxproj index b5e9823..f3178bb 100644 --- a/Xcodes.xcodeproj/project.pbxproj +++ b/Xcodes.xcodeproj/project.pbxproj @@ -77,6 +77,7 @@ CAFBDC4E2599B33D003DCC5A /* MainToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFBDC4D2599B33D003DCC5A /* MainToolbar.swift */; }; CAFBDC68259A308B003DCC5A /* InspectorPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFBDC67259A308B003DCC5A /* InspectorPane.swift */; }; CAFBDC6C259A3098003DCC5A /* View+Conditional.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFBDC6B259A3098003DCC5A /* View+Conditional.swift */; }; + CAFFFED8259CDA5000903F81 /* XcodeListViewRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -201,6 +202,7 @@ CAFBDC4D2599B33D003DCC5A /* MainToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainToolbar.swift; sourceTree = ""; }; CAFBDC67259A308B003DCC5A /* InspectorPane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorPane.swift; sourceTree = ""; }; CAFBDC6B259A3098003DCC5A /* View+Conditional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Conditional.swift"; sourceTree = ""; }; + CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeListViewRow.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -310,6 +312,7 @@ CA44901E2463AD34003D8213 /* Tag.swift */, CAE42486259A68A300B8B246 /* XcodeListCategory.swift */, CAD2E7A32449574E00113D76 /* XcodeListView.swift */, + CAFFFED7259CDA5000903F81 /* XcodeListViewRow.swift */, ); path = XcodeList; sourceTree = ""; @@ -655,6 +658,7 @@ CAA1CB4D255A5CFD003FD669 /* SignInPhoneListView.swift in Sources */, CAFBDC6C259A3098003DCC5A /* View+Conditional.swift in Sources */, CABFA9CF2592EEEA00380FEE /* Process.swift in Sources */, + CAFFFED8259CDA5000903F81 /* XcodeListViewRow.swift in Sources */, CABFA9C72592EEEA00380FEE /* Entry+.swift in Sources */, CAE42487259A68A300B8B246 /* XcodeListCategory.swift in Sources */, CABFAA2C2592FBFC00380FEE /* SettingsView.swift in Sources */, diff --git a/Xcodes/Frontend/XcodeList/XcodeListView.swift b/Xcodes/Frontend/XcodeList/XcodeListView.swift index e4ea9de..c3c564f 100644 --- a/Xcodes/Frontend/XcodeList/XcodeListView.swift +++ b/Xcodes/Frontend/XcodeList/XcodeListView.swift @@ -32,73 +32,7 @@ struct XcodeListView: View { var body: some View { List(visibleXcodes, selection: $selectedXcodeID) { xcode in - HStack { - appIconView(for: xcode) - - VStack(alignment: .leading) { - Text(xcode.description) - .font(.body) - - Text(verbatim: xcode.path ?? "") - .font(.caption) - .foregroundColor(.secondary) - } - - Spacer() - - selectControl(for: xcode) - installControl(for: xcode) - } - .contextMenu { - InstallButton(xcode: xcode) - - Divider() - - if xcode.installed { - SelectButton(xcode: xcode) - OpenButton(xcode: xcode) - RevealButton(xcode: xcode) - CopyPathButton(xcode: xcode) - } - } - } - } - - @ViewBuilder - func appIconView(for xcode: Xcode) -> some View { - if let icon = xcode.icon { - Image(nsImage: icon) - } else { - Color.clear - .frame(width: 32, height: 32) - .foregroundColor(.secondary) - } - } - - @ViewBuilder - private func selectControl(for xcode: Xcode) -> some View { - if xcode.selected { - Image(systemName: "checkmark.circle.fill") - .foregroundColor(.green) - .help("This version is selected as the default") - } - } - - @ViewBuilder - private func installControl(for xcode: Xcode) -> some View { - if xcode.selected { - Button("DEFAULT") { appState.select(id: xcode.id) } - .buttonStyle(AppStoreButtonStyle(primary: false, highlighted: selectedXcodeID == xcode.id)) - .disabled(true) - .help("This version is selected as the default") - } else if xcode.installed { - Button("SELECT") { appState.select(id: xcode.id) } - .buttonStyle(AppStoreButtonStyle(primary: false, highlighted: selectedXcodeID == xcode.id)) - .help("Select this version as the default") - } else { - Button("INSTALL") { print("Installing...") } - .buttonStyle(AppStoreButtonStyle(primary: true, highlighted: selectedXcodeID == xcode.id)) - .help("Install this version") + XcodeListViewRow(xcode: xcode, selected: selectedXcodeID == xcode.id) } } } diff --git a/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift b/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift new file mode 100644 index 0000000..54e2a79 --- /dev/null +++ b/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift @@ -0,0 +1,102 @@ +import SwiftUI +import Version + +struct XcodeListViewRow: View { + @EnvironmentObject var appState: AppState + let xcode: Xcode + let selected: Bool + + var body: some View { + HStack { + appIconView(for: xcode) + + VStack(alignment: .leading) { + Text(xcode.description) + .font(.body) + + Text(verbatim: xcode.path ?? "") + .font(.caption) + .foregroundColor(.secondary) + } + + Spacer() + + selectControl(for: xcode) + installControl(for: xcode) + } + .contextMenu { + InstallButton(xcode: xcode) + + Divider() + + if xcode.installed { + SelectButton(xcode: xcode) + OpenButton(xcode: xcode) + RevealButton(xcode: xcode) + CopyPathButton(xcode: xcode) + } + } + } + + @ViewBuilder + func appIconView(for xcode: Xcode) -> some View { + if let icon = xcode.icon { + Image(nsImage: icon) + } else { + Color.clear + .frame(width: 32, height: 32) + .foregroundColor(.secondary) + } + } + + @ViewBuilder + private func selectControl(for xcode: Xcode) -> some View { + if xcode.selected { + Image(systemName: "checkmark.circle.fill") + .foregroundColor(.green) + .help("This version is selected as the default") + } + } + + @ViewBuilder + private func installControl(for xcode: Xcode) -> some View { + if xcode.selected { + Button("DEFAULT") { appState.select(id: xcode.id) } + .buttonStyle(AppStoreButtonStyle(primary: false, highlighted: selected)) + .disabled(true) + } else if xcode.installed { + Button("SELECT") { appState.select(id: xcode.id) } + .buttonStyle(AppStoreButtonStyle(primary: false, highlighted: selected)) + } else { + Button("INSTALL") { print("Installing...") } + .buttonStyle(AppStoreButtonStyle(primary: true, highlighted: selected)) + } + } +} + +struct XcodeListViewRow_Previews: PreviewProvider { + static var previews: some View { + Group { + XcodeListViewRow( + xcode: Xcode(version: Version("12.3.0")!, installState: .installed, selected: true, path: "/Applications/Xcode-12.3.0.app", icon: nil), + selected: false + ) + + XcodeListViewRow( + xcode: Xcode(version: Version("12.2.0")!, installState: .notInstalled, selected: false, path: nil, icon: nil), + selected: false + ) + + XcodeListViewRow( + xcode: Xcode(version: Version("12.1.0")!, installState: .notInstalled, selected: false, path: nil, icon: nil), + selected: false + ) + + XcodeListViewRow( + xcode: Xcode(version: Version("12.0.0")!, installState: .installed, selected: false, path: "/Applications/Xcode-12.3.0.app", icon: nil), + selected: false + ) + } + .environmentObject(AppState()) + } +}