From 954d745207cc82e16d3a0b7c39f6a14da726f84c Mon Sep 17 00:00:00 2001 From: david-swift Date: Thu, 31 Oct 2024 06:26:46 +0100 Subject: [PATCH] Expand navigation view support --- Sources/Core/View/Button.swift | 1 - Sources/Core/View/NavigationView.swift | 51 +++++++++++++++++++++++++- Sources/Core/Window/Window.swift | 24 ++++++++---- Sources/Demo/Demo.swift | 2 +- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/Sources/Core/View/Button.swift b/Sources/Core/View/Button.swift index cc50c40..8d262cf 100644 --- a/Sources/Core/View/Button.swift +++ b/Sources/Core/View/Button.swift @@ -77,7 +77,6 @@ public struct Button: WinUIWidget { let items = MenuCollection { menu }.container(data: data.noModifiers, type: MenuContext.self) storage.content["menu"] = [items] if let items = items.pointer as? [MenuFlyoutItemBase?] { - print(items) items.forEach { flyout.items.append($0) } } button.flyout = flyout diff --git a/Sources/Core/View/NavigationView.swift b/Sources/Core/View/NavigationView.swift index 251cce0..f320361 100644 --- a/Sources/Core/View/NavigationView.swift +++ b/Sources/Core/View/NavigationView.swift @@ -20,6 +20,10 @@ public struct NavigationView: WinUIWidget where Item: NavigationViewItem { var content: Body /// Whether the settings item is available. var settings = false + /// The custom content in the pane. + var paneCustomContent: Body? + /// The display mode of the navigation view. + var mode: NavigationViewMode = .sidebar /// Initialize the navigation view without the settings item. /// - Parameters: @@ -77,6 +81,11 @@ public struct NavigationView: WinUIWidget where Item: NavigationViewItem { let contentStorage = content.storage(data: data, type: type) let storage = ViewStorage(view, content: [.mainContent: [contentStorage]]) view.content = contentStorage.pointer + if let paneCustomContent { + let customStorage = paneCustomContent.storage(data: data, type: type) + storage.content["pane-custom-content"] = [customStorage] + view.paneCustomContent = customStorage.pointer as? UIElement + } if settings { view.isSettingsVisible = true } else { @@ -101,6 +110,9 @@ public struct NavigationView: WinUIWidget where Item: NavigationViewItem { if let content = storage.content[.mainContent]?.first { self.content.updateStorage(content, data: data, updateProperties: updateProperties, type: type) } + if let content = storage.content["pane-custom-content"]?.first { + paneCustomContent?.updateStorage(content, data: data, updateProperties: updateProperties, type: type) + } guard let navigationView = storage.pointer as? WinUI.NavigationView else { return } @@ -125,15 +137,32 @@ public struct NavigationView: WinUIWidget where Item: NavigationViewItem { } insert: { index, element in navigationView.menuItems.insertAt(.init(index), element.winItem) }) + if previousState?.mode != mode { + navigationView.paneDisplayMode = mode.winMode + } if case .settings = selectedItem { navigationView.isSettingsVisible = true } else if case let .custom(name) = selectedItem { navigationView.selectedItem = navigationView.menuItems - .first { ($0 as? WinUI.NavigationViewItem)?.name as? String == name.description } + .first { ($0 as? WinUI.NavigationViewItem)?.name as? String == name.description } as Any? } storage.previousState = self } + /// Set the view's navigation mode. + /// - Parameter mode: The mode. + /// - Returns: The view. + public func navigationMode(_ mode: NavigationViewMode) -> Self { + modify { $0.mode = mode } + } + + /// Set the view's custom content. + /// - Parameter content: The content. + /// - Returns: The view. + public func customContent(@ViewBuilder _ content: () -> Body) -> Self { + modify { $0.paneCustomContent = content() } + } + } /// The navigation selection type. @@ -147,6 +176,26 @@ public protocol NavigationViewItem: CustomStringConvertible, Equatable { } +/// The display modes of the navigation view. +public enum NavigationViewMode { + + /// The items are in a sidebar. + case sidebar + /// The items are at the top. + case top + + /// The WinUI display mode. + var winMode: NavigationViewPaneDisplayMode { + switch self { + case .sidebar: + .auto + case .top: + .top + } + } + +} + extension NavigationViewItem { /// The navigation view item for the backend. diff --git a/Sources/Core/Window/Window.swift b/Sources/Core/Window/Window.swift index fb19b1c..4f402fa 100644 --- a/Sources/Core/Window/Window.swift +++ b/Sources/Core/Window/Window.swift @@ -28,6 +28,8 @@ public struct Window: WinUISceneElement { var width: Meta.Binding? /// The window's height. var height: Meta.Binding? + /// Add a custom title. + var customTitle = false /// Create a window type with a certain identifier and user interface. /// - Parameters: @@ -50,17 +52,20 @@ public struct Window: WinUISceneElement { if extendContent ?? false { ModifierWrapper( view: Grid(columns: [.init()]) { - ModifierWrapper( - view: Text(title) - .style(.caption), - verticalAlignment: .center - ) + if customTitle { + ModifierWrapper( + view: Text(title) + .style(.caption), + verticalAlignment: .center + ) + } } .titleBar(), height: 48, margin: (48, 0, 0, 0), verticalAlignment: .top - ) } + ) + } content(window) } } @@ -142,11 +147,14 @@ public struct Window: WinUISceneElement { } /// Whether to extend the content into the title bar. - /// - Parameter enabled: Whether to extend the content. + /// - Parameters: + /// - enabled: Whether to extend the content. + /// - showTitle: Whether to add a custom title overlay. /// - Returns: The window. - public func extendContentIntoTitleBar(_ enabled: Bool? = true) -> Self { + public func extendContentIntoTitleBar(_ enabled: Bool? = true, showTitle: Bool = true) -> Self { var newSelf = self newSelf.extendContent = enabled + newSelf.customTitle = showTitle return newSelf } diff --git a/Sources/Demo/Demo.swift b/Sources/Demo/Demo.swift index 778612d..7c62c6e 100644 --- a/Sources/Demo/Demo.swift +++ b/Sources/Demo/Demo.swift @@ -22,7 +22,7 @@ struct Demo: App { Window("Demo", id: "main") { _ in ContentView(app: app) } - .extendContentIntoTitleBar() + .extendContentIntoTitleBar(showTitle: false) .frame(width: $width, height: $height) }