Skip to content

Commit 46e5e3d

Browse files
egorzhdancompnerd
authored andcommitted
Menus and Shortcuts: support window menus
This adds support for window-level menus, shown on the top of a window. `_MenuBuilder` is used to construct the menus.
1 parent beb933f commit 46e5e3d

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

Sources/SwiftWin32/Platform/Win32+Menu.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ internal final class _MenuBuilder: MenuSystem {
5858

5959
// Create the new submenus and add them to the root menu:
6060
append(self.menus, to: self.hMenu)
61+
62+
if let window = view as? Window {
63+
window.hWindowMenu = self.hMenu
64+
SetMenu(window.hWnd, window.hWindowMenu?.value)
65+
}
6166
}
6267
}
6368

Sources/SwiftWin32/Windows and Screens/Window.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,18 @@ public class Window: View {
144144

145145
// MARK - Configuring the Window
146146

147+
internal var hWindowMenu: MenuHandle?
148+
147149
/// The root view controller for the window.
148150
public var rootViewController: ViewController? {
149-
didSet { self.rootViewController?.view = self }
151+
didSet {
152+
self.rootViewController?.view = self
153+
154+
if let builder = _MenuBuilder(for: self) {
155+
self.rootViewController?.buildMenu(with: builder)
156+
builder.setNeedsRebuild()
157+
}
158+
}
150159
}
151160

152161
/// The position of the window in the z-axis.

Tests/UICoreTests/WindowTests.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
import XCTest
5+
import WinSDK
6+
@testable import SwiftWin32
7+
8+
final class WindowTests: XCTestCase {
9+
func testWindowMenuEmpty() {
10+
let viewController = ViewController()
11+
viewController.view = View(frame: Rect(x: 0, y: 0, width: 100, height: 100))
12+
13+
let window = Window(frame: Rect(x: 0, y: 0, width: 200, height: 200))
14+
XCTAssertNil(GetMenu(window.hWnd))
15+
16+
window.rootViewController = viewController
17+
18+
let hMenu = GetMenu(window.hWnd)
19+
XCTAssertEqual(GetMenuItemCount(hMenu), 0)
20+
}
21+
22+
func testWindowMenuWithSubmenus() {
23+
// TODO: uncomment when ViewController is `open`
24+
/*
25+
class ViewControllerWithWindowMenu: ViewController {
26+
override func buildMenu(with builder: MenuBuilder) {
27+
builder.insertSibling(Menu(title: "title1", children: [Action(title: "action", handler: { _ in })]),
28+
afterMenu: .root)
29+
builder.insertSibling(Menu(title: "title2", children: [Command(title: "command", action: { _ in })]),
30+
afterMenu: .root)
31+
}
32+
}
33+
34+
let viewController = ViewControllerWithWindowMenu()
35+
viewController.view = View(frame: Rect(x: 0, y: 0, width: 100, height: 100))
36+
37+
let window = Window(frame: Rect(x: 0, y: 0, width: 200, height: 200))
38+
window.rootViewController = viewController
39+
40+
let hMenu = GetMenu(window.hWnd)
41+
XCTAssertEqual(GetMenuItemCount(hMenu), 2)
42+
*/
43+
}
44+
45+
static var allTests = [
46+
("testWindowMenu", testWindowMenuEmpty),
47+
("testWindowMenuWithSubmenus", testWindowMenuWithSubmenus),
48+
]
49+
}

0 commit comments

Comments
 (0)