2
0

VMKeyboardShortcutsView.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 VMKeyboardShortcutsView: View {
  18. let onShortcut: ([QEMUKeyCode]) -> Void
  19. @Environment(\.presentationMode) var presentationMode
  20. @State private var keyboardShortcuts: [[QEMUKeyCode]] = []
  21. var body: some View {
  22. NavigationView {
  23. List {
  24. ForEach(keyboardShortcuts, id: \.self) { element in
  25. Button(element.title) {
  26. onShortcut(element)
  27. presentationMode.wrappedValue.dismiss()
  28. }
  29. }.onDelete { indexSet in
  30. keyboardShortcuts.remove(atOffsets: indexSet)
  31. }.onMove { indexSet, offset in
  32. keyboardShortcuts.move(fromOffsets: indexSet, toOffset: offset)
  33. }
  34. NavigationLink("Add…") {
  35. NewKeyboardShortcutView(keyboardShortcuts: $keyboardShortcuts)
  36. }
  37. }.navigationTitle("Keyboard Shortcut")
  38. .toolbar {
  39. ToolbarItemGroup(placement: .navigationBarTrailing) {
  40. EditButton()
  41. Button("Close") {
  42. presentationMode.wrappedValue.dismiss()
  43. }
  44. }
  45. }
  46. }
  47. .onAppear {
  48. keyboardShortcuts = UTMKeyboardShortcuts.shared.loadKeyboardShortcuts()
  49. }
  50. .onChange(of: keyboardShortcuts) { newValue in
  51. UTMKeyboardShortcuts.shared.saveKeyboardShortcuts(newValue)
  52. }
  53. }
  54. }
  55. private struct NewKeyboardShortcutView: View {
  56. @Environment(\.presentationMode) var presentationMode
  57. @Binding var keyboardShortcuts: [[QEMUKeyCode]]
  58. @State private var newShortcut: [QEMUKeyCode] = []
  59. @State private var newKey: QEMUKeyCode?
  60. var body: some View {
  61. List {
  62. DetailedSection("Keys") {
  63. ForEach(newShortcut, id: \.self) { element in
  64. Text(element.title)
  65. }.onDelete { indexSet in
  66. newShortcut.remove(atOffsets: indexSet)
  67. }.onMove { indexSet, offset in
  68. newShortcut.move(fromOffsets: indexSet, toOffset: offset)
  69. }
  70. }
  71. DetailedSection("New Key") {
  72. Picker("", selection: $newKey) {
  73. Text("").tag(nil as QEMUKeyCode?)
  74. ForEach(QEMUKeyCode.allCases) { keyCode in
  75. if !newShortcut.contains(keyCode) {
  76. Text(keyCode.title).tag(keyCode)
  77. }
  78. }
  79. }.pickerStyle(.wheel)
  80. Button("Add") {
  81. if let key = newKey {
  82. newShortcut.append(key)
  83. }
  84. newKey = nil
  85. }.disabled(newKey == nil)
  86. }
  87. }.navigationTitle("New Keyboard Shortcut")
  88. .toolbar {
  89. ToolbarItemGroup(placement: .navigationBarTrailing) {
  90. EditButton()
  91. Button("Save") {
  92. if !newShortcut.isEmpty {
  93. keyboardShortcuts.append(newShortcut)
  94. }
  95. presentationMode.wrappedValue.dismiss()
  96. }.disabled(newShortcut.isEmpty)
  97. }
  98. }
  99. .onAppear {
  100. newShortcut = []
  101. newKey = nil
  102. }
  103. }
  104. }
  105. #Preview {
  106. VMKeyboardShortcutsView() { _ in }
  107. }