VMConfigSerialView.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. //
  2. // Copyright © 2022 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 VMConfigSerialView: View {
  18. @Binding var config: UTMQemuConfigurationSerial
  19. @Binding var system: UTMQemuConfigurationSystem
  20. @State private var isFirstAppear: Bool = true
  21. @State private var isUnsupportedAlertShown: Bool = false
  22. @State private var hardware: any QEMUSerialDevice = AnyQEMUConstant(rawValue: "")!
  23. var body: some View {
  24. VStack {
  25. Form {
  26. Section(header: Text("Connection")) {
  27. VMConfigConstantPicker("Mode", selection: $config.mode)
  28. .onChange(of: config.mode) { newValue in
  29. if newValue == .builtin && config.terminal == nil {
  30. config.terminal = .init()
  31. }
  32. }
  33. VMConfigConstantPicker("Target", selection: $config.target)
  34. .onChange(of: config.target) { newValue in
  35. if newValue == .manualDevice && system.architecture.serialDeviceType.allRawValues.isEmpty {
  36. config.target = .autoDevice
  37. isUnsupportedAlertShown.toggle()
  38. }
  39. }
  40. if config.mode == .tcpServer {
  41. Toggle("Wait for Connection", isOn: $config.isWaitForConnection.bound)
  42. Toggle("Allow Remote Connection", isOn: $config.isRemoteConnectionAllowed.bound)
  43. }
  44. }
  45. if config.target == .manualDevice {
  46. Section(header: Text("Hardware")) {
  47. VMConfigConstantPicker("Emulated Serial Device", selection: $hardware, type: system.architecture.serialDeviceType)
  48. }
  49. .onAppear {
  50. if isFirstAppear {
  51. if let configHardware = config.hardware {
  52. hardware = configHardware
  53. } else if let `default` = system.architecture.serialDeviceType.allCases.first {
  54. hardware = `default`
  55. }
  56. }
  57. isFirstAppear = false
  58. }
  59. .onChange(of: hardware.rawValue) { newValue in
  60. config.hardware = hardware
  61. }
  62. .onChange(of: config.hardware?.rawValue) { newValue in
  63. if let configHardware = config.hardware {
  64. hardware = configHardware
  65. }
  66. }
  67. }
  68. if config.mode == .builtin {
  69. VMConfigDisplayConsoleView(config: $config.terminal.bound)
  70. } else if config.mode == .tcpClient || config.mode == .tcpServer {
  71. Section(header: Text("TCP")) {
  72. if config.mode == .tcpClient {
  73. DefaultTextField("Server Address", text: $config.tcpHostAddress.bound, prompt: "example.com")
  74. .keyboardType(.decimalPad)
  75. }
  76. NumberTextField("Port", number: $config.tcpPort.bound, prompt: "1234")
  77. }
  78. }
  79. }
  80. }.disableAutocorrection(true)
  81. .alert(isPresented: $isUnsupportedAlertShown) {
  82. Alert(title: Text("The target does not support hardware emulated serial connections."))
  83. }
  84. #if !os(macOS)
  85. .padding(.horizontal, 0)
  86. #endif
  87. }
  88. }
  89. struct VMConfigSerialView_Previews: PreviewProvider {
  90. @State static private var config = UTMQemuConfigurationSerial()
  91. @State static private var system = UTMQemuConfigurationSystem()
  92. static var previews: some View {
  93. VMConfigSerialView(config: $config, system: $system)
  94. #if os(macOS)
  95. .scrollable()
  96. #endif
  97. }
  98. }