VMSettingsView.swift 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. //
  2. // Copyright © 2020 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. @available(iOS 14, *)
  18. struct VMSettingsView: View {
  19. let vm: UTMVirtualMachine?
  20. @ObservedObject var config: UTMConfiguration
  21. @EnvironmentObject private var data: UTMData
  22. @Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
  23. var qemuConfig: UTMQemuConfiguration {
  24. config as! UTMQemuConfiguration
  25. }
  26. var body: some View {
  27. NavigationView {
  28. Form {
  29. List {
  30. NavigationLink(
  31. destination: VMConfigInfoView(config: qemuConfig).navigationTitle("Information"),
  32. label: {
  33. Label("Information", systemImage: "info.circle")
  34. .labelStyle(RoundRectIconLabelStyle())
  35. })
  36. NavigationLink(
  37. destination: VMConfigSystemView(config: qemuConfig).navigationTitle("System"),
  38. label: {
  39. Label("System", systemImage: "cpu")
  40. .labelStyle(RoundRectIconLabelStyle())
  41. })
  42. NavigationLink(
  43. destination: VMConfigQEMUView(config: qemuConfig).navigationTitle("QEMU"),
  44. label: {
  45. Label("QEMU", systemImage: "shippingbox")
  46. .labelStyle(RoundRectIconLabelStyle())
  47. })
  48. NavigationLink(
  49. destination: VMConfigDrivesView(config: qemuConfig).navigationTitle("Drives"),
  50. label: {
  51. Label("Drives", systemImage: "internaldrive")
  52. .labelStyle(RoundRectIconLabelStyle())
  53. })
  54. NavigationLink(
  55. destination: VMConfigDisplayView(config: qemuConfig).navigationTitle("Display"),
  56. label: {
  57. Label("Display", systemImage: "rectangle.on.rectangle")
  58. .labelStyle(RoundRectIconLabelStyle(color: .green))
  59. })
  60. NavigationLink(
  61. destination: VMConfigInputView(config: qemuConfig).navigationTitle("Input"),
  62. label: {
  63. Label("Input", systemImage: "keyboard")
  64. .labelStyle(RoundRectIconLabelStyle(color: .green))
  65. })
  66. NavigationLink(
  67. destination: VMConfigNetworkView(config: qemuConfig).navigationTitle("Network"),
  68. label: {
  69. Label("Network", systemImage: "network")
  70. .labelStyle(RoundRectIconLabelStyle(color: .green))
  71. })
  72. NavigationLink(
  73. destination: VMConfigSoundView(config: qemuConfig).navigationTitle("Sound"),
  74. label: {
  75. Label("Sound", systemImage: "speaker.wave.2")
  76. .labelStyle(RoundRectIconLabelStyle(color: .green))
  77. })
  78. NavigationLink(
  79. destination: VMConfigSharingView(config: qemuConfig).navigationTitle("Sharing"),
  80. label: {
  81. Label("Sharing", systemImage: "person.crop.circle.fill")
  82. .labelStyle(RoundRectIconLabelStyle(color: .yellow))
  83. })
  84. }
  85. }
  86. .navigationTitle("Settings")
  87. .navigationViewStyle(StackNavigationViewStyle())
  88. .navigationBarItems(leading: Button(action: cancel, label: {
  89. Text("Cancel")
  90. }), trailing: HStack {
  91. Button(action: save, label: {
  92. Text("Save")
  93. })
  94. })
  95. }.disabled(data.busy)
  96. .overlay(BusyOverlay())
  97. }
  98. func save() {
  99. presentationMode.wrappedValue.dismiss()
  100. data.busyWork {
  101. if let existing = self.vm {
  102. try data.save(vm: existing)
  103. } else {
  104. try data.create(config: self.config)
  105. }
  106. }
  107. }
  108. func cancel() {
  109. presentationMode.wrappedValue.dismiss()
  110. if let existing = self.vm {
  111. data.busyWork {
  112. try data.discardChanges(forVM: existing)
  113. }
  114. }
  115. }
  116. }
  117. @available(iOS 14, *)
  118. struct RoundRectIconLabelStyle: LabelStyle {
  119. var color: Color = .blue
  120. func makeBody(configuration: Configuration) -> some View {
  121. Label(
  122. title: { configuration.title },
  123. icon: {
  124. ZStack(alignment: .center) {
  125. RoundedRectangle(cornerRadius: 10.0, style: .circular)
  126. .frame(width: 32, height: 32)
  127. .foregroundColor(color)
  128. configuration.icon.foregroundColor(.white)
  129. }
  130. })
  131. }
  132. }
  133. @available(iOS 14, *)
  134. struct VMSettingsView_Previews: PreviewProvider {
  135. @State static private var config = UTMQemuConfiguration()
  136. static var previews: some View {
  137. VMSettingsView(vm: nil, config: config)
  138. }
  139. }