VMWizardOSClassicMacView.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //
  2. // Copyright © 2025 osy. All rights reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. import SwiftUI
  17. struct VMWizardOSClassicMacView: View {
  18. private enum PpcVia: CaseIterable, Identifiable {
  19. case pmu
  20. case pmuAdb
  21. case cuda
  22. var id: Self { self }
  23. var title: LocalizedStringKey {
  24. switch self {
  25. case .pmu: return "PMU"
  26. case .pmuAdb: return "PMU-ADB"
  27. case .cuda: return "CUDA"
  28. }
  29. }
  30. var machineProperties: String {
  31. switch self {
  32. case .pmu: return "via=pmu"
  33. case .pmuAdb: return "via=pmu-adb"
  34. case .cuda: return "via=cuda"
  35. }
  36. }
  37. }
  38. private enum SelectImage {
  39. case bios
  40. case bootImage
  41. }
  42. @ObservedObject var wizardState: VMWizardState
  43. @State private var isFileImporterPresented: Bool = false
  44. @State private var ppcVia: PpcVia = .pmu
  45. @State private var selectImage: SelectImage = .bootImage
  46. var body: some View {
  47. VMWizardContent("Classic Mac OS") {
  48. DetailedSection("Boot ISO Image") {
  49. FileBrowseField(url: $wizardState.bootImageURL, isFileImporterPresented: $isFileImporterPresented, hasClearButton: false) {
  50. selectImage = .bootImage
  51. }
  52. }
  53. if wizardState.systemTarget.rawValue == QEMUTarget_m68k.q800.rawValue {
  54. DetailedSection("Quadra 800 ROM") {
  55. FileBrowseField(url: $wizardState.quadra800RomUrl, isFileImporterPresented: $isFileImporterPresented, hasClearButton: false) {
  56. selectImage = .bios
  57. }
  58. }
  59. }
  60. if wizardState.systemArchitecture == .ppc || wizardState.systemArchitecture == .ppc64 {
  61. DetailedSection("Advanced Options") {
  62. Picker("PMU", selection: $ppcVia) {
  63. ForEach(PpcVia.allCases) { item in
  64. Text(item.title).tag(item)
  65. }
  66. }
  67. #if os(macOS)
  68. .pickerStyle(.inline)
  69. #endif
  70. .help("Different versions of Mac OS require different VIA option.")
  71. .onChange(of: ppcVia) { newValue in
  72. wizardState.machineProperties = newValue.machineProperties
  73. }
  74. .onAppear {
  75. wizardState.machineProperties = ppcVia.machineProperties
  76. }
  77. }
  78. }
  79. if wizardState.isBusy {
  80. Spinner(size: .large)
  81. }
  82. }
  83. .fileImporter(isPresented: $isFileImporterPresented, allowedContentTypes: [.data]) { result in
  84. wizardState.busyWorkAsync {
  85. let url = try result.get()
  86. await MainActor.run {
  87. switch selectImage {
  88. case .bios:
  89. wizardState.quadra800RomUrl = url
  90. case .bootImage:
  91. wizardState.bootImageURL = url
  92. }
  93. }
  94. }
  95. }
  96. .onAppear {
  97. wizardState.bootDevice = .cd
  98. }
  99. }
  100. }
  101. #Preview {
  102. VMWizardOSClassicMacView(wizardState: VMWizardState())
  103. }