Add support for popovers
This commit is contained in:
parent
b4e88a4a42
commit
30482196b6
@ -51,6 +51,7 @@
|
|||||||
- [Overlay](structs/Overlay.md)
|
- [Overlay](structs/Overlay.md)
|
||||||
- [OverlaySplitView](structs/OverlaySplitView.md)
|
- [OverlaySplitView](structs/OverlaySplitView.md)
|
||||||
- [PasswordEntryRow](structs/PasswordEntryRow.md)
|
- [PasswordEntryRow](structs/PasswordEntryRow.md)
|
||||||
|
- [Popover](structs/Popover.md)
|
||||||
- [PreferencesGroup](structs/PreferencesGroup.md)
|
- [PreferencesGroup](structs/PreferencesGroup.md)
|
||||||
- [PreferencesPage](structs/PreferencesPage.md)
|
- [PreferencesPage](structs/PreferencesPage.md)
|
||||||
- [PreferencesRow](structs/PreferencesRow.md)
|
- [PreferencesRow](structs/PreferencesRow.md)
|
||||||
@ -120,6 +121,7 @@
|
|||||||
- [OpaquePointer](extensions/OpaquePointer.md)
|
- [OpaquePointer](extensions/OpaquePointer.md)
|
||||||
- [OverlaySplitView](extensions/OverlaySplitView.md)
|
- [OverlaySplitView](extensions/OverlaySplitView.md)
|
||||||
- [PasswordEntryRow](extensions/PasswordEntryRow.md)
|
- [PasswordEntryRow](extensions/PasswordEntryRow.md)
|
||||||
|
- [Popover](extensions/Popover.md)
|
||||||
- [ProgressBar](extensions/ProgressBar.md)
|
- [ProgressBar](extensions/ProgressBar.md)
|
||||||
- [ScrollView](extensions/ScrollView.md)
|
- [ScrollView](extensions/ScrollView.md)
|
||||||
- [Set](extensions/Set.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.
|
Remove all of the content modifiers for the wrapped views.
|
||||||
- Returns: A view.
|
- 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:)`
|
### `toast(_:signal:)`
|
||||||
|
|
||||||
Present a toast when the signal gets activated.
|
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
|
// ActionRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Avatar.swift
|
// Avatar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Banner.swift
|
// Banner.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Bin.swift
|
// Bin.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Box.swift
|
// Box.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Button.swift
|
// Button.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ButtonContent.swift
|
// ButtonContent.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Carousel.swift
|
// Carousel.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// CenterBox.swift
|
// CenterBox.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// CheckButton.swift
|
// CheckButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Clamp.swift
|
// Clamp.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ComboRow.swift
|
// ComboRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// EntryRow.swift
|
// EntryRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ExpanderRow.swift
|
// ExpanderRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// HeaderBar.swift
|
// HeaderBar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Label.swift
|
// Label.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// LevelBar.swift
|
// LevelBar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// LinkButton.swift
|
// LinkButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ListBox.swift
|
// ListBox.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Menu.swift
|
// Menu.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Overlay.swift
|
// Overlay.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// OverlaySplitView.swift
|
// OverlaySplitView.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// PasswordEntryRow.swift
|
// PasswordEntryRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
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
|
// PreferencesGroup.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// PreferencesPage.swift
|
// PreferencesPage.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// PreferencesRow.swift
|
// PreferencesRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ProgressBar.swift
|
// ProgressBar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ScrolledWindow.swift
|
// ScrolledWindow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// SpinRow.swift
|
// SpinRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Spinner.swift
|
// Spinner.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// SplitButton.swift
|
// SplitButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// StatusPage.swift
|
// StatusPage.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// SwitchRow.swift
|
// SwitchRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ToastOverlay.swift
|
// ToastOverlay.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ToggleButton.swift
|
// ToggleButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ToolbarView.swift
|
// ToolbarView.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// WindowTitle.swift
|
// WindowTitle.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 04.02.24.
|
// Created by auto-generation on 10.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
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"
|
"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.
|
/// The unshortening map.
|
||||||
|
|||||||
@ -23,6 +23,7 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
|||||||
case carousel
|
case carousel
|
||||||
case viewSwitcher
|
case viewSwitcher
|
||||||
case form
|
case form
|
||||||
|
case popover
|
||||||
|
|
||||||
var id: Self {
|
var id: Self {
|
||||||
self
|
self
|
||||||
@ -74,6 +75,8 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
|||||||
return "Switch the window's view."
|
return "Switch the window's view."
|
||||||
case .form:
|
case .form:
|
||||||
return "Group controls used for data entry."
|
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)
|
ViewSwitcherDemo(app: app)
|
||||||
case .form:
|
case .form:
|
||||||
FormDemo(app: app)
|
FormDemo(app: app)
|
||||||
|
case .popover:
|
||||||
|
PopoverDemo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// swiftlint:enable cyclomatic_complexity
|
// 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