瀏覽代碼

settings(qemu): new port forward UI for macOS 12+

osy 2 年之前
父節點
當前提交
b6493da8a9

+ 2 - 2
Platform/Shared/VMConfigNetworkView.swift

@@ -54,8 +54,8 @@ struct VMConfigNetworkView: View {
 
 
                 #if os(macOS)
                 #if os(macOS)
                 /// Bridged and shared networking doesn't support port forwarding
                 /// Bridged and shared networking doesn't support port forwarding
-                if config.mode == .emulated {
-                    VMConfigNetworkPortForwardView(config: $config)
+                if #unavailable(macOS 12), config.mode == .emulated {
+                    VMConfigNetworkPortForwardLegacyView(config: $config)
                 }
                 }
                 #else
                 #else
                 VMConfigNetworkPortForwardView(config: $config)
                 VMConfigNetworkPortForwardView(config: $config)

+ 61 - 3
Platform/macOS/VMConfigNetworkPortForwardView.swift

@@ -16,8 +16,62 @@
 
 
 import SwiftUI
 import SwiftUI
 
 
-@available(macOS 11, *)
+@available(macOS 12, *)
 struct VMConfigNetworkPortForwardView: View {
 struct VMConfigNetworkPortForwardView: View {
+    @Binding var config: UTMQemuConfigurationNetwork
+    @State private var isEditingNewPort = false
+    @State private var isEditingExistingPort = false
+    @State private var selectedId: UUID?
+    @State private var editPortForward: UTMQemuConfigurationPortForward?
+    
+    var body: some View {
+        VStack {
+            Table(config.portForward, selection: $selectedId) {
+                TableColumn("Protocol") { row in
+                    Text(row.protocol.prettyValue)
+                }
+                TableColumn("Guest Address") { row in
+                    Text(row.guestAddress ?? "")
+                }
+                TableColumn("Guest Port") { row in
+                    Text(String(row.guestPort))
+                }
+                TableColumn("Host Address") { row in
+                    Text(row.hostAddress ?? "")
+                }
+                TableColumn("Host Port") { row in
+                    Text(String(row.hostPort))
+                }
+            }.onDoubleClick {
+                editPortForward = config.portForward.first(where: { $0.id == selectedId })
+            }
+            HStack {
+                Spacer()
+                if let selectedId = selectedId {
+                    Button("Delete") {
+                        config.portForward.removeAll(where: { $0.id == selectedId })
+                        self.selectedId = nil
+                    }
+                    Button("Edit…") {
+                        editPortForward = config.portForward.first(where: { $0.id == selectedId })
+                    }.popover(item: $editPortForward, arrowEdge: .top) { item in
+                        PortForwardEdit(config: $config, forward: item).padding()
+                            .frame(width: 250)
+                    }
+                }
+                Button("New…") {
+                    isEditingNewPort.toggle()
+                }.popover(isPresented: $isEditingNewPort, arrowEdge: .top) {
+                    PortForwardEdit(config: $config, forward: .init()).padding()
+                        .frame(width: 250)
+                }
+            }.padding()
+        }
+    }
+}
+
+@available(macOS 11, *)
+struct VMConfigNetworkPortForwardLegacyView: View {
     @Binding var config: UTMQemuConfigurationNetwork
     @Binding var config: UTMQemuConfigurationNetwork
     @State private var editingNewPort = false
     @State private var editingNewPort = false
     @State private var selectedPortForward: UTMQemuConfigurationPortForward?
     @State private var selectedPortForward: UTMQemuConfigurationPortForward?
@@ -27,7 +81,7 @@ struct VMConfigNetworkPortForwardView: View {
                 Text("Port Forward")
                 Text("Port Forward")
                 Spacer()
                 Spacer()
                 Button(action: { editingNewPort = true }, label: {
                 Button(action: { editingNewPort = true }, label: {
-                    Text("New")
+                    Text("New")
                 }).popover(isPresented: $editingNewPort, arrowEdge: .bottom) {
                 }).popover(isPresented: $editingNewPort, arrowEdge: .bottom) {
                     PortForwardEdit(config: $config, forward: .init()).padding()
                     PortForwardEdit(config: $config, forward: .init()).padding()
                         .frame(width: 250)
                         .frame(width: 250)
@@ -106,7 +160,11 @@ struct VMConfigNetworkPortForwardView_Previews: PreviewProvider {
     static var previews: some View {
     static var previews: some View {
         Group {
         Group {
             Form {
             Form {
-                VMConfigNetworkPortForwardView(config: $config)
+                if #available(macOS 12, *) {
+                    VMConfigNetworkPortForwardView(config: $config)
+                } else {
+                    VMConfigNetworkPortForwardLegacyView(config: $config)
+                }
             }.onAppear {
             }.onAppear {
                 if config.portForward.count == 0 {
                 if config.portForward.count == 0 {
                     var newConfigPort = UTMQemuConfigurationPortForward()
                     var newConfigPort = UTMQemuConfigurationPortForward()

+ 6 - 0
Platform/macOS/VMQEMUSettingsView.swift

@@ -72,6 +72,12 @@ struct VMQEMUSettingsView: View {
                         config.networks.removeAll(where: { $0.id == network.id })
                         config.networks.removeAll(where: { $0.id == network.id })
                     }
                     }
                 }
                 }
+                if #available(macOS 12, *), network.mode == .emulated {
+                    NavigationLink(destination: VMConfigNetworkPortForwardView(config: $network)) {
+                        Label("Port Forward", systemImage: "point.topleft.down.curvedto.point.bottomright.up")
+                            .padding(.leading)
+                    }
+                }
             }
             }
             ForEach($config.sound) { $sound in
             ForEach($config.sound) { $sound in
                 NavigationLink(destination: VMConfigSoundView(config: $sound, system: $config.system).scrollable()) {
                 NavigationLink(destination: VMConfigSoundView(config: $sound, system: $config.system).scrollable()) {