VMConfigAppleDriveCreateView.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //
  2. // Copyright © 2021 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 VMConfigAppleDriveCreateView: View {
  18. private let mibToGib = 1024
  19. let minSizeMib = 1
  20. @Binding var config: UTMAppleConfigurationDrive
  21. @State private var isGiB: Bool = true
  22. private var isASIFSupported: Bool {
  23. if #available(macOS 26, *) {
  24. return UTMASIFImage.sharedInstance() != nil
  25. } else {
  26. return false
  27. }
  28. }
  29. var body: some View {
  30. Form {
  31. VStack(alignment: .leading) {
  32. Toggle(isOn: $config.isExternal.animation(), label: {
  33. Text("Removable")
  34. }).help("If checked, the drive image will be stored with the VM.")
  35. .onChange(of: config.isExternal) { newValue in
  36. if newValue {
  37. config.sizeMib = 0
  38. config.isReadOnly = true
  39. config.isNvme = false
  40. } else {
  41. config.sizeMib = 10240
  42. config.isReadOnly = false
  43. config.isASIF = isASIFSupported
  44. }
  45. }
  46. if #available(macOS 14, *), !config.isExternal {
  47. Toggle(isOn: $config.isNvme.animation(), label: {
  48. Text("Use NVMe Interface")
  49. }).help("If checked, use NVMe instead of virtio as the disk interface, available on macOS 14+ for Linux guests only. This interface is slower but less likely to encounter filesystem errors.")
  50. }
  51. if isASIFSupported {
  52. Toggle(isOn: $config.isASIF) {
  53. Text("Use Apple Sparse Image Format")
  54. }.help("ASIF is more efficient and performant but is not compatible with older versions of macOS hosts.")
  55. .onAppear {
  56. config.isASIF = isASIFSupported
  57. }
  58. }
  59. if !config.isExternal {
  60. SizeTextField($config.sizeMib)
  61. }
  62. }
  63. }
  64. }
  65. private func validateSize(editing: Bool) {
  66. guard !editing else {
  67. return
  68. }
  69. if config.sizeMib < minSizeMib {
  70. config.sizeMib = minSizeMib
  71. }
  72. }
  73. private func convertToMib(fromSize size: Int) -> Int {
  74. if isGiB {
  75. return size * mibToGib
  76. } else {
  77. return size
  78. }
  79. }
  80. private func convertToDisplay(fromSizeMib sizeMib: Int) -> Int {
  81. if isGiB {
  82. return sizeMib / mibToGib
  83. } else {
  84. return sizeMib
  85. }
  86. }
  87. }
  88. struct VMConfigAppleDriveCreateView_Previews: PreviewProvider {
  89. static var previews: some View {
  90. VMConfigAppleDriveCreateView(config: .constant(.init(newSize: 1024)))
  91. }
  92. }