diff --git a/Documentation/Reference/README.md b/Documentation/Reference/README.md index d82e793..514d294 100644 --- a/Documentation/Reference/README.md +++ b/Documentation/Reference/README.md @@ -33,6 +33,7 @@ - [MenuSection](structs/MenuSection.md) - [ModifierStopper](structs/ModifierStopper.md) - [NavigationSplitView](structs/NavigationSplitView.md) +- [Overlay](structs/Overlay.md) - [OverlaySplitView](structs/OverlaySplitView.md) - [ScrollView](structs/ScrollView.md) - [Signal](structs/Signal.md) diff --git a/Documentation/Reference/extensions/View.md b/Documentation/Reference/extensions/View.md index 2f4d80f..ea986f4 100644 --- a/Documentation/Reference/extensions/View.md +++ b/Documentation/Reference/extensions/View.md @@ -125,6 +125,13 @@ Run a function when the view gets an update. Remove all of the content modifiers for the wrapped views. - Returns: A view. +### `overlay(_:)` + +Add an overlay view. +- Parameters: + - overlay: The overlay view. +- Returns: A view. + ### `toast(_:signal:)` Present a toast when the signal gets activated. diff --git a/Documentation/Reference/structs/Overlay.md b/Documentation/Reference/structs/Overlay.md new file mode 100644 index 0000000..b412008 --- /dev/null +++ b/Documentation/Reference/structs/Overlay.md @@ -0,0 +1,32 @@ +**STRUCT** + +# `Overlay` + +A wrapper around a view for adding other views on top. + +## Properties +### `child` + +The child view. + +### `overlay` + +The overlay view. + +### `overlayID` + +The identifier for the overlay content. + +## Methods +### `container(modifiers:)` + +Get the overlay's view storage. +- Parameter modifiers: The view modifiers. +- Returns: The view storage. + +### `update(_:modifiers:)` + +Update the overlay's view storage. +- Parameters: + - storage: The view storage. + - modifiers: The view modifiers. diff --git a/Sources/Adwaita/View/Modifiers/Overlay.swift b/Sources/Adwaita/View/Modifiers/Overlay.swift new file mode 100644 index 0000000..9e95aaf --- /dev/null +++ b/Sources/Adwaita/View/Modifiers/Overlay.swift @@ -0,0 +1,56 @@ +// +// Overlay.swift +// Adwaita +// +// Created by david-swift on 03.01.24. +// + +import Libadwaita + +/// A wrapper around a view for adding other views on top. +struct Overlay: Widget { + + /// The child view. + var child: View + /// The overlay view. + var overlay: Body + + /// The identifier for the overlay content. + let overlayID = "overlay" + + /// Get the overlay's view storage. + /// - Parameter modifiers: The view modifiers. + /// - Returns: The view storage. + func container(modifiers: [(View) -> View]) -> ViewStorage { + let contentStorage = child.storage(modifiers: modifiers) + let overlayStorage = overlay.widget(modifiers: modifiers).storage(modifiers: modifiers) + let overlay = Libadwaita.Overlay().child(contentStorage.view).addOverlay(overlayStorage.view) + return .init(overlay, content: [.mainContent: [contentStorage], overlayID: [overlayStorage]]) + } + + /// Update the overlay's view storage. + /// - Parameters: + /// - storage: The view storage. + /// - modifiers: The view modifiers. + func update(_ storage: ViewStorage, modifiers: [(View) -> View]) { + if let storage = storage.content[.mainContent]?.first { + child.updateStorage(storage, modifiers: modifiers) + } + if let storage = storage.content[overlayID]?.first { + overlay.widget(modifiers: modifiers).update(storage, modifiers: modifiers) + } + } + +} + +extension View { + + /// Add an overlay view. + /// - Parameters: + /// - overlay: The overlay view. + /// - Returns: A view. + public func overlay(@ViewBuilder _ overlay: @escaping () -> Body) -> View { + Overlay(child: self, overlay: overlay()) + } + +} diff --git a/user-manual/Information/Widgets.md b/user-manual/Information/Widgets.md index a906cb0..be55d5c 100644 --- a/user-manual/Information/Widgets.md +++ b/user-manual/Information/Widgets.md @@ -46,6 +46,7 @@ This is an overview of the available widgets and other components in _Adwaita_. | `stopModifiers()` | Ignore all the `modifyContent(_:modify:)` modifiers from higher above in the view tree. | | `toast(_:signal:)` | Show a toast on top of the view whenever the signal gets activated. | | `toast(_:signal:button:handler:)` | Show a toast with a button on top of the view whenever the signal gets activated. | +| `overlay(_:)` | Overlay a view with another view. | ### `Button` Modifiers | Syntax | Description |