@@ -27,7 +27,7 @@ class WinUIApplication: SwiftApplication {
27
27
}
28
28
29
29
public final class WinUIBackend : AppBackend {
30
- public typealias Window = WinUI . Window
30
+ public typealias Window = CustomWindow
31
31
public typealias Widget = WinUI . FrameworkElement
32
32
public typealias Menu = Void
33
33
public typealias Alert = WinUI . ContentDialog
@@ -92,7 +92,7 @@ public final class WinUIBackend: AppBackend {
92
92
}
93
93
94
94
public func createWindow( withDefaultSize size: SIMD2 < Int > ? ) -> Window {
95
- let window = Window ( )
95
+ let window = CustomWindow ( )
96
96
windows. append ( window)
97
97
window. closed. addHandler { _, _ in
98
98
self . windows. removeAll { other in
@@ -145,7 +145,7 @@ public final class WinUIBackend: AppBackend {
145
145
let size = window. appWindow. clientSize
146
146
let out = SIMD2 (
147
147
Int ( size. width) ,
148
- Int ( size. height)
148
+ Int ( size. height) - CustomWindow . menuBarHeight
149
149
)
150
150
return out
151
151
}
@@ -158,7 +158,7 @@ public final class WinUIBackend: AppBackend {
158
158
public func setSize( ofWindow window: Window , to newSize: SIMD2 < Int > ) {
159
159
let size = UWP . SizeInt32 (
160
160
width: Int32 ( newSize. x) ,
161
- height: Int32 ( newSize. y)
161
+ height: Int32 ( newSize. y + CustomWindow . menuBarHeight )
162
162
)
163
163
try ! window. appWindow. resizeClient ( size)
164
164
}
@@ -174,7 +174,7 @@ public final class WinUIBackend: AppBackend {
174
174
window. sizeChanged. addHandler { _, args in
175
175
let size = SIMD2 (
176
176
Int ( args!. size. width. rounded ( . awayFromZero) ) ,
177
- Int ( args!. size. height. rounded ( . awayFromZero) )
177
+ Int ( args!. size. height. rounded ( . awayFromZero) ) - CustomWindow . menuBarHeight
178
178
)
179
179
action ( size)
180
180
}
@@ -189,7 +189,7 @@ public final class WinUIBackend: AppBackend {
189
189
}
190
190
191
191
public func setChild( ofWindow window: Window , to widget: Widget ) {
192
- window. content = widget
192
+ window. setChild ( widget)
193
193
try ! widget. updateLayout ( )
194
194
widget. actualThemeChanged. addHandler { _, _ in
195
195
self . internalState. themeChangeAction ? ( )
@@ -220,8 +220,43 @@ public final class WinUIBackend: AppBackend {
220
220
// print("missing: \(message)")
221
221
}
222
222
223
+ private func renderItems( _ items: [ ResolvedMenu . Item ] ) -> [ MenuFlyoutItemBase ] {
224
+ items. map { item in
225
+ switch item {
226
+ case . button( let label, let action) :
227
+ let widget = MenuFlyoutItem ( )
228
+ widget. text = label
229
+ widget. click. addHandler { _, _ in
230
+ action ? ( )
231
+ }
232
+ return widget
233
+ case . submenu( let submenu) :
234
+ let widget = MenuFlyoutSubItem ( )
235
+ widget. text = submenu. label
236
+ for subitem in renderItems ( submenu. content. items) {
237
+ widget. items. append ( subitem)
238
+ }
239
+ return widget
240
+ }
241
+ }
242
+ }
243
+
223
244
public func setApplicationMenu( _ submenus: [ ResolvedMenu . Submenu ] ) {
224
- missing ( " setApplicationMenu(_:) implementation " )
245
+ let items = submenus. map { submenu in
246
+ let item = MenuBarItem ( )
247
+ item. title = submenu. label
248
+ for subitem in renderItems ( submenu. content. items) {
249
+ item. items. append ( subitem)
250
+ }
251
+ return item
252
+ }
253
+
254
+ for window in windows {
255
+ window. menuBar. items. clear ( )
256
+ for item in items {
257
+ window. menuBar. items. append ( item)
258
+ }
259
+ }
225
260
}
226
261
227
262
public func computeRootEnvironment(
@@ -919,6 +954,50 @@ public final class WinUIBackend: AppBackend {
919
954
}
920
955
}
921
956
957
+ // public func showOpenDialog(
958
+ // fileDialogOptions: FileDialogOptions,
959
+ // openDialogOptions: OpenDialogOptions,
960
+ // window: Window?,
961
+ // resultHandler handleResult: @escaping (DialogResult<[URL]>) -> Void
962
+ // ) {
963
+ // let picker = FileOpenPicker()
964
+ // // TODO: Associate the picker with a window. Requires some janky WinUI
965
+ // // Win32 interop kinda stuff I believe.
966
+ // if openDialogOptions.allowMultipleSelections {
967
+ // let promise = try! picker.pickMultipleFilesAsync()!
968
+ // promise.completed = { operation, status in
969
+ // guard
970
+ // status == .completed,
971
+ // let operation,
972
+ // let result = try? operation.getResults()
973
+ // else {
974
+ // return
975
+ // }
976
+ // print(result)
977
+ // }
978
+ // } else {
979
+ // let promise = try! picker.pickSingleFileAsync()!
980
+ // promise.completed = { operation, status in
981
+ // guard
982
+ // status == .completed,
983
+ // let operation,
984
+ // let result = try? operation.getResults()
985
+ // else {
986
+ // return
987
+ // }
988
+ // print(result)
989
+ // }
990
+ // }
991
+ // }
992
+
993
+ // public func showSaveDialog(
994
+ // fileDialogOptions: FileDialogOptions,
995
+ // saveDialogOptions: SaveDialogOptions,
996
+ // window: Window?,
997
+ // resultHandler handleResult: @escaping (DialogResult<URL>) -> Void
998
+ // ) {
999
+ // }
1000
+
922
1001
public func createClickTarget( wrapping child: Widget ) -> Widget {
923
1002
let clickTarget = ClickTarget ( )
924
1003
addChild ( child, to: clickTarget)
@@ -1084,3 +1163,37 @@ final class ClickTarget: WinUI.Canvas {
1084
1163
var clickHandler : ( ( ) -> Void ) ?
1085
1164
var child : WinUI . FrameworkElement ?
1086
1165
}
1166
+
1167
+ public class CustomWindow : WinUI . Window {
1168
+ /// Hardcoded menu bar height from MenuBar_themeresources.xaml in the
1169
+ /// microsoft-ui-xaml repository.
1170
+ static let menuBarHeight = 40
1171
+
1172
+ var menuBar = WinUI . MenuBar ( )
1173
+ var child : WinUIBackend . Widget ?
1174
+ var grid : WinUI . Grid
1175
+
1176
+ public override init ( ) {
1177
+ grid = WinUI . Grid ( )
1178
+
1179
+ super. init ( )
1180
+
1181
+ let menuBarRowDefinition = WinUI . RowDefinition ( )
1182
+ menuBarRowDefinition. height = WinUI . GridLength (
1183
+ value: Double ( Self . menuBarHeight) ,
1184
+ gridUnitType: . pixel
1185
+ )
1186
+ let contentRowDefinition = WinUI . RowDefinition ( )
1187
+ grid. rowDefinitions. append ( menuBarRowDefinition)
1188
+ grid. rowDefinitions. append ( contentRowDefinition)
1189
+ grid. children. append ( menuBar)
1190
+ WinUI . Grid. setRow ( menuBar, 0 )
1191
+ self . content = grid
1192
+ }
1193
+
1194
+ public func setChild( _ child: WinUIBackend . Widget ) {
1195
+ self . child = child
1196
+ grid. children. append ( child)
1197
+ WinUI . Grid. setRow ( child, 1 )
1198
+ }
1199
+ }
0 commit comments