Add support for popovers
This commit is contained in:
parent
b4e88a4a42
commit
30482196b6
@ -51,6 +51,7 @@
|
||||
- [Overlay](structs/Overlay.md)
|
||||
- [OverlaySplitView](structs/OverlaySplitView.md)
|
||||
- [PasswordEntryRow](structs/PasswordEntryRow.md)
|
||||
- [Popover](structs/Popover.md)
|
||||
- [PreferencesGroup](structs/PreferencesGroup.md)
|
||||
- [PreferencesPage](structs/PreferencesPage.md)
|
||||
- [PreferencesRow](structs/PreferencesRow.md)
|
||||
@ -120,6 +121,7 @@
|
||||
- [OpaquePointer](extensions/OpaquePointer.md)
|
||||
- [OverlaySplitView](extensions/OverlaySplitView.md)
|
||||
- [PasswordEntryRow](extensions/PasswordEntryRow.md)
|
||||
- [Popover](extensions/Popover.md)
|
||||
- [ProgressBar](extensions/ProgressBar.md)
|
||||
- [ScrollView](extensions/ScrollView.md)
|
||||
- [Set](extensions/Set.md)
|
||||
|
||||
9
Documentation/Reference/extensions/Popover.md
Normal file
9
Documentation/Reference/extensions/Popover.md
Normal file
@ -0,0 +1,9 @@
|
||||
**EXTENSION**
|
||||
|
||||
# `Popover`
|
||||
|
||||
## Methods
|
||||
### `init(visible:)`
|
||||
|
||||
Initialize either a horizontal or vertical clamp.
|
||||
- Parameter vertical: Whether it is a vertical clamp.
|
||||
@ -158,6 +158,14 @@ Set the view's visibility.
|
||||
Remove all of the content modifiers for the wrapped views.
|
||||
- Returns: A view.
|
||||
|
||||
### `popover(visible:content:)`
|
||||
|
||||
Add a popover on top of the view.
|
||||
- Parameters:
|
||||
- visible: Whether the popover is displayed.
|
||||
- content: The popover's content.
|
||||
- Returns: The view.
|
||||
|
||||
### `toast(_:signal:)`
|
||||
|
||||
Present a toast when the signal gets activated.
|
||||
|
||||
172
Documentation/Reference/structs/Popover.md
Normal file
172
Documentation/Reference/structs/Popover.md
Normal file
@ -0,0 +1,172 @@
|
||||
**STRUCT**
|
||||
|
||||
# `Popover`
|
||||
|
||||
`GtkPopover` is a bubble-like context popup.
|
||||
|
||||

|
||||
|
||||
It is primarily meant to provide context-dependent information
|
||||
or options. Popovers are attached to a parent widget. By default,
|
||||
they point to the whole widget area, although this behavior can be
|
||||
changed with [method@Gtk.Popover.set_pointing_to].
|
||||
|
||||
The position of a popover relative to the widget it is attached to
|
||||
can also be changed with [method@Gtk.Popover.set_position]
|
||||
|
||||
By default, `GtkPopover` performs a grab, in order to ensure input
|
||||
events get redirected to it while it is shown, and also so the popover
|
||||
is dismissed in the expected situations (clicks outside the popover,
|
||||
or the Escape key being pressed). If no such modal behavior is desired
|
||||
on a popover, [method@Gtk.Popover.set_autohide] may be called on it to
|
||||
tweak its behavior.
|
||||
|
||||
## GtkPopover as menu replacement
|
||||
|
||||
`GtkPopover` is often used to replace menus. The best was to do this
|
||||
is to use the [class@Gtk.PopoverMenu] subclass which supports being
|
||||
populated from a `GMenuModel` with [ctor@Gtk.PopoverMenu.new_from_model].
|
||||
|
||||
```xml
|
||||
<section><attribute name="display-hint">horizontal-buttons</attribute><item><attribute name="label">Cut</attribute><attribute name="action">app.cut</attribute><attribute name="verb-icon">edit-cut-symbolic</attribute></item><item><attribute name="label">Copy</attribute><attribute name="action">app.copy</attribute><attribute name="verb-icon">edit-copy-symbolic</attribute></item><item><attribute name="label">Paste</attribute><attribute name="action">app.paste</attribute><attribute name="verb-icon">edit-paste-symbolic</attribute></item></section>
|
||||
```
|
||||
|
||||
# CSS nodes
|
||||
|
||||
```
|
||||
popover.background[.menu]
|
||||
├── arrow
|
||||
╰── contents
|
||||
╰── <child>
|
||||
```
|
||||
|
||||
`GtkPopover` has a main node with name `popover`, an arrow with name `arrow`,
|
||||
and another node for the content named `contents`. The `popover` node always
|
||||
gets the `.background` style class. It also gets the `.menu` style class
|
||||
if the popover is menu-like, e.g. is a [class@Gtk.PopoverMenu].
|
||||
|
||||
Particular uses of `GtkPopover`, such as touch selection popups or
|
||||
magnifiers in `GtkEntry` or `GtkTextView` get style classes like
|
||||
`.touch-selection` or `.magnifier` to differentiate from plain popovers.
|
||||
|
||||
When styling a popover directly, the `popover` node should usually
|
||||
not have any background. The visible part of the popover can have
|
||||
a shadow. To specify it in CSS, set the box-shadow of the `contents` node.
|
||||
|
||||
Note that, in order to accomplish appropriate arrow visuals, `GtkPopover`
|
||||
uses custom drawing for the `arrow` node. This makes it possible for the
|
||||
arrow to change its shape dynamically, but it also limits the possibilities
|
||||
of styling it using CSS. In particular, the `arrow` gets drawn over the
|
||||
`content` node's border and shadow, so they look like one shape, which
|
||||
means that the border width of the `content` node and the `arrow` node should
|
||||
be the same. The arrow also does not support any border shape other than
|
||||
solid, no border-radius, only one border width (border-bottom-width is
|
||||
used) and no box-shadow.
|
||||
|
||||
## Properties
|
||||
### `updateFunctions`
|
||||
|
||||
Additional update functions for type extensions.
|
||||
|
||||
### `appearFunctions`
|
||||
|
||||
Additional appear functions for type extensions.
|
||||
|
||||
### `autohide`
|
||||
|
||||
Whether to dismiss the popover on outside clicks.
|
||||
|
||||
### `cascadePopdown`
|
||||
|
||||
Whether the popover pops down after a child popover.
|
||||
|
||||
This is used to implement the expected behavior of submenus.
|
||||
|
||||
### `child`
|
||||
|
||||
The child widget.
|
||||
|
||||
### `defaultWidget`
|
||||
|
||||
The default widget inside the popover.
|
||||
|
||||
### `hasArrow`
|
||||
|
||||
Whether to draw an arrow.
|
||||
|
||||
### `mnemonicsVisible`
|
||||
|
||||
Whether mnemonics are currently visible in this popover.
|
||||
|
||||
### `activateDefault`
|
||||
|
||||
Emitted whend the user activates the default widget.
|
||||
|
||||
This is a [keybinding signal](class.SignalAction.html).
|
||||
|
||||
### `closed`
|
||||
|
||||
Emitted when the popover is closed.
|
||||
|
||||
### `app`
|
||||
|
||||
The application.
|
||||
|
||||
### `window`
|
||||
|
||||
The window.
|
||||
|
||||
## Methods
|
||||
### `init()`
|
||||
|
||||
Initialize `Popover`.
|
||||
|
||||
### `container(modifiers:)`
|
||||
|
||||
Get the widget's view storage.
|
||||
- Parameter modifiers: The view modifiers.
|
||||
- Returns: The view storage.
|
||||
|
||||
### `update(_:modifiers:updateProperties:)`
|
||||
|
||||
Update the widget's view storage.
|
||||
- Parameters:
|
||||
- storage: The view storage.
|
||||
- modifiers: The view modifiers.
|
||||
- updateProperties: Whether to update the view's properties.
|
||||
|
||||
### `autohide(_:)`
|
||||
|
||||
Whether to dismiss the popover on outside clicks.
|
||||
|
||||
### `cascadePopdown(_:)`
|
||||
|
||||
Whether the popover pops down after a child popover.
|
||||
|
||||
This is used to implement the expected behavior of submenus.
|
||||
|
||||
### `child(_:)`
|
||||
|
||||
The child widget.
|
||||
|
||||
### `defaultWidget(_:)`
|
||||
|
||||
The default widget inside the popover.
|
||||
|
||||
### `hasArrow(_:)`
|
||||
|
||||
Whether to draw an arrow.
|
||||
|
||||
### `mnemonicsVisible(_:)`
|
||||
|
||||
Whether mnemonics are currently visible in this popover.
|
||||
|
||||
### `activateDefault(_:)`
|
||||
|
||||
Emitted whend the user activates the default widget.
|
||||
|
||||
This is a [keybinding signal](class.SignalAction.html).
|
||||
|
||||
### `closed(_:)`
|
||||
|
||||
Emitted when the popover is closed.
|
||||
@ -2,7 +2,7 @@
|
||||
// ActionRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Avatar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Banner.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Bin.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Box.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Button.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ButtonContent.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Carousel.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// CenterBox.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// CheckButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Clamp.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ComboRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// EntryRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ExpanderRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// HeaderBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Label.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// LevelBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// LinkButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ListBox.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Menu.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Overlay.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// OverlaySplitView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// PasswordEntryRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
238
Sources/Adwaita/View/Generated/Popover.swift
Normal file
238
Sources/Adwaita/View/Generated/Popover.swift
Normal file
@ -0,0 +1,238 @@
|
||||
//
|
||||
// Popover.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
import LevenshteinTransformations
|
||||
|
||||
/// `GtkPopover` is a bubble-like context popup.
|
||||
///
|
||||
/// 
|
||||
///
|
||||
/// It is primarily meant to provide context-dependent information
|
||||
/// or options. Popovers are attached to a parent widget. By default,
|
||||
/// they point to the whole widget area, although this behavior can be
|
||||
/// changed with [method@Gtk.Popover.set_pointing_to].
|
||||
///
|
||||
/// The position of a popover relative to the widget it is attached to
|
||||
/// can also be changed with [method@Gtk.Popover.set_position]
|
||||
///
|
||||
/// By default, `GtkPopover` performs a grab, in order to ensure input
|
||||
/// events get redirected to it while it is shown, and also so the popover
|
||||
/// is dismissed in the expected situations (clicks outside the popover,
|
||||
/// or the Escape key being pressed). If no such modal behavior is desired
|
||||
/// on a popover, [method@Gtk.Popover.set_autohide] may be called on it to
|
||||
/// tweak its behavior.
|
||||
///
|
||||
/// ## GtkPopover as menu replacement
|
||||
///
|
||||
/// `GtkPopover` is often used to replace menus. The best was to do this
|
||||
/// is to use the [class@Gtk.PopoverMenu] subclass which supports being
|
||||
/// populated from a `GMenuModel` with [ctor@Gtk.PopoverMenu.new_from_model].
|
||||
///
|
||||
/// ```xml
|
||||
/// <section><attribute name="display-hint">horizontal-buttons</attribute><item><attribute name="label">Cut</attribute><attribute name="action">app.cut</attribute><attribute name="verb-icon">edit-cut-symbolic</attribute></item><item><attribute name="label">Copy</attribute><attribute name="action">app.copy</attribute><attribute name="verb-icon">edit-copy-symbolic</attribute></item><item><attribute name="label">Paste</attribute><attribute name="action">app.paste</attribute><attribute name="verb-icon">edit-paste-symbolic</attribute></item></section>
|
||||
/// ```
|
||||
///
|
||||
/// # CSS nodes
|
||||
///
|
||||
/// ```
|
||||
/// popover.background[.menu]
|
||||
/// ├── arrow
|
||||
/// ╰── contents
|
||||
/// ╰── <child>
|
||||
/// ```
|
||||
///
|
||||
/// `GtkPopover` has a main node with name `popover`, an arrow with name `arrow`,
|
||||
/// and another node for the content named `contents`. The `popover` node always
|
||||
/// gets the `.background` style class. It also gets the `.menu` style class
|
||||
/// if the popover is menu-like, e.g. is a [class@Gtk.PopoverMenu].
|
||||
///
|
||||
/// Particular uses of `GtkPopover`, such as touch selection popups or
|
||||
/// magnifiers in `GtkEntry` or `GtkTextView` get style classes like
|
||||
/// `.touch-selection` or `.magnifier` to differentiate from plain popovers.
|
||||
///
|
||||
/// When styling a popover directly, the `popover` node should usually
|
||||
/// not have any background. The visible part of the popover can have
|
||||
/// a shadow. To specify it in CSS, set the box-shadow of the `contents` node.
|
||||
///
|
||||
/// Note that, in order to accomplish appropriate arrow visuals, `GtkPopover`
|
||||
/// uses custom drawing for the `arrow` node. This makes it possible for the
|
||||
/// arrow to change its shape dynamically, but it also limits the possibilities
|
||||
/// of styling it using CSS. In particular, the `arrow` gets drawn over the
|
||||
/// `content` node's border and shadow, so they look like one shape, which
|
||||
/// means that the border width of the `content` node and the `arrow` node should
|
||||
/// be the same. The arrow also does not support any border shape other than
|
||||
/// solid, no border-radius, only one border width (border-bottom-width is
|
||||
/// used) and no box-shadow.
|
||||
public struct Popover: Widget {
|
||||
|
||||
/// Additional update functions for type extensions.
|
||||
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||
/// Additional appear functions for type extensions.
|
||||
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||
|
||||
/// Whether to dismiss the popover on outside clicks.
|
||||
var autohide: Bool?
|
||||
/// Whether the popover pops down after a child popover.
|
||||
///
|
||||
/// This is used to implement the expected behavior of submenus.
|
||||
var cascadePopdown: Bool?
|
||||
/// The child widget.
|
||||
var child: (() -> Body)?
|
||||
/// The default widget inside the popover.
|
||||
var defaultWidget: (() -> Body)?
|
||||
/// Whether to draw an arrow.
|
||||
var hasArrow: Bool?
|
||||
/// Whether mnemonics are currently visible in this popover.
|
||||
var mnemonicsVisible: Bool?
|
||||
/// Emitted whend the user activates the default widget.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
var activateDefault: (() -> Void)?
|
||||
/// Emitted when the popover is closed.
|
||||
var closed: (() -> Void)?
|
||||
/// The application.
|
||||
var app: GTUIApp?
|
||||
/// The window.
|
||||
var window: GTUIApplicationWindow?
|
||||
|
||||
/// Initialize `Popover`.
|
||||
public init() {
|
||||
}
|
||||
|
||||
/// Get the widget's view storage.
|
||||
/// - Parameter modifiers: The view modifiers.
|
||||
/// - Returns: The view storage.
|
||||
public func container(modifiers: [(View) -> View]) -> ViewStorage {
|
||||
let storage = ViewStorage(gtk_popover_new()?.opaque())
|
||||
update(storage, modifiers: modifiers, updateProperties: true)
|
||||
if let childStorage = child?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["child"] = [childStorage]
|
||||
gtk_popover_set_child(storage.pointer?.cast(), childStorage.pointer?.cast())
|
||||
}
|
||||
if let defaultWidgetStorage = defaultWidget?().widget(modifiers: modifiers).storage(modifiers: modifiers) {
|
||||
storage.content["defaultWidget"] = [defaultWidgetStorage]
|
||||
gtk_popover_set_default_widget(storage.pointer?.cast(), defaultWidgetStorage.pointer?.cast())
|
||||
}
|
||||
|
||||
|
||||
for function in appearFunctions {
|
||||
function(storage)
|
||||
}
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the widget's view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The view storage.
|
||||
/// - modifiers: The view modifiers.
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
public func update(_ storage: ViewStorage, modifiers: [(View) -> View], updateProperties: Bool) {
|
||||
if let activateDefault {
|
||||
storage.connectSignal(name: "activate-default", argCount: 0) {
|
||||
activateDefault()
|
||||
}
|
||||
}
|
||||
if let closed {
|
||||
storage.connectSignal(name: "closed", argCount: 0) {
|
||||
closed()
|
||||
}
|
||||
}
|
||||
storage.modify { widget in
|
||||
if let autohide, updateProperties {
|
||||
gtk_popover_set_autohide(widget?.cast(), autohide.cBool)
|
||||
}
|
||||
if let cascadePopdown, updateProperties {
|
||||
gtk_popover_set_cascade_popdown(widget?.cast(), cascadePopdown.cBool)
|
||||
}
|
||||
if let widget = storage.content["child"]?.first {
|
||||
child?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
}
|
||||
if let widget = storage.content["defaultWidget"]?.first {
|
||||
defaultWidget?().widget(modifiers: modifiers).update(widget, modifiers: modifiers, updateProperties: updateProperties)
|
||||
}
|
||||
if let hasArrow, updateProperties {
|
||||
gtk_popover_set_has_arrow(widget?.cast(), hasArrow.cBool)
|
||||
}
|
||||
if let mnemonicsVisible, updateProperties {
|
||||
gtk_popover_set_mnemonics_visible(widget?.cast(), mnemonicsVisible.cBool)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
for function in updateFunctions {
|
||||
function(storage)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to dismiss the popover on outside clicks.
|
||||
public func autohide(_ autohide: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.autohide = autohide
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether the popover pops down after a child popover.
|
||||
///
|
||||
/// This is used to implement the expected behavior of submenus.
|
||||
public func cascadePopdown(_ cascadePopdown: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.cascadePopdown = cascadePopdown
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The child widget.
|
||||
public func child(@ViewBuilder _ child: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.child = child
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// The default widget inside the popover.
|
||||
public func defaultWidget(@ViewBuilder _ defaultWidget: @escaping (() -> Body)) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.defaultWidget = defaultWidget
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether to draw an arrow.
|
||||
public func hasArrow(_ hasArrow: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.hasArrow = hasArrow
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Whether mnemonics are currently visible in this popover.
|
||||
public func mnemonicsVisible(_ mnemonicsVisible: Bool? = true) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.mnemonicsVisible = mnemonicsVisible
|
||||
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted whend the user activates the default widget.
|
||||
///
|
||||
/// This is a [keybinding signal](class.SignalAction.html).
|
||||
public func activateDefault(_ activateDefault: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.activateDefault = activateDefault
|
||||
return newSelf
|
||||
}
|
||||
|
||||
/// Emitted when the popover is closed.
|
||||
public func closed(_ closed: @escaping () -> Void) -> Self {
|
||||
var newSelf = self
|
||||
newSelf.closed = closed
|
||||
return newSelf
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
// PreferencesGroup.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// PreferencesPage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// PreferencesRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ProgressBar.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ScrolledWindow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// SpinRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// Spinner.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// SplitButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// StatusPage.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// SwitchRow.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ToastOverlay.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ToggleButton.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// ToolbarView.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// WindowTitle.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by auto-generation on 04.02.24.
|
||||
// Created by auto-generation on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
53
Sources/Adwaita/View/Modifiers/Popover+.swift
Normal file
53
Sources/Adwaita/View/Modifiers/Popover+.swift
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Popover+.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 10.02.24.
|
||||
//
|
||||
|
||||
import CAdw
|
||||
|
||||
extension Popover {
|
||||
|
||||
/// Initialize either a horizontal or vertical clamp.
|
||||
/// - Parameter vertical: Whether it is a vertical clamp.
|
||||
init(visible: Binding<Bool>) {
|
||||
self.init()
|
||||
appearFunctions.append { storage in
|
||||
storage.fields["visible"] = visible
|
||||
storage.connectSignal(name: "closed", id: "visible") {
|
||||
if let binding = storage.fields["visible"] as? Binding<Bool> {
|
||||
if binding.wrappedValue {
|
||||
binding.wrappedValue = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
updateFunctions.append { storage in
|
||||
if let binding = storage.fields["visible"] as? Binding<Bool> {
|
||||
if binding.wrappedValue {
|
||||
gtk_popover_popup(storage.pointer?.cast())
|
||||
} else {
|
||||
gtk_popover_popdown(storage.pointer?.cast())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension View {
|
||||
|
||||
/// Add a popover on top of the view.
|
||||
/// - Parameters:
|
||||
/// - visible: Whether the popover is displayed.
|
||||
/// - content: The popover's content.
|
||||
/// - Returns: The view.
|
||||
public func popover(visible: Binding<Bool>, @ViewBuilder content: @escaping () -> Body) -> View {
|
||||
overlay {
|
||||
Popover(visible: visible)
|
||||
.child(content)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -219,7 +219,8 @@ struct GenerationConfiguration {
|
||||
"window-placement"
|
||||
]
|
||||
),
|
||||
.init(class: "Overlay", staticWidgets: [.init(name: "overlay", add: "gtk_overlay_add_overlay")])
|
||||
.init(class: "Overlay", staticWidgets: [.init(name: "overlay", add: "gtk_overlay_add_overlay")]),
|
||||
.init(class: "Popover", excludeProperties: ["pointing-to", "position"], cast: true)
|
||||
]
|
||||
|
||||
/// The unshortening map.
|
||||
|
||||
@ -23,6 +23,7 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
||||
case carousel
|
||||
case viewSwitcher
|
||||
case form
|
||||
case popover
|
||||
|
||||
var id: Self {
|
||||
self
|
||||
@ -74,6 +75,8 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
||||
return "Switch the window's view."
|
||||
case .form:
|
||||
return "Group controls used for data entry."
|
||||
case .popover:
|
||||
return "Present content in a bubble-like context popup."
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,6 +108,8 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
||||
ViewSwitcherDemo(app: app)
|
||||
case .form:
|
||||
FormDemo(app: app)
|
||||
case .popover:
|
||||
PopoverDemo()
|
||||
}
|
||||
}
|
||||
// swiftlint:enable cyclomatic_complexity
|
||||
|
||||
31
Tests/PopoverDemo.swift
Normal file
31
Tests/PopoverDemo.swift
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// PopoverDemo.swift
|
||||
// Adwaita
|
||||
//
|
||||
// Created by david-swift on 10.02.24.
|
||||
//
|
||||
|
||||
// swiftlint:disable missing_docs
|
||||
|
||||
import Adwaita
|
||||
|
||||
struct PopoverDemo: View {
|
||||
|
||||
@State private var visible = false
|
||||
|
||||
var view: Body {
|
||||
VStack {
|
||||
Button("Present Popover") {
|
||||
visible = true
|
||||
}
|
||||
.style("suggested-action")
|
||||
.frame(maxSize: 100)
|
||||
}
|
||||
.popover(visible: $visible) {
|
||||
CounterDemo()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// swiftlint:enable missing_docs
|
||||
Loading…
x
Reference in New Issue
Block a user