Add support for flow boxes
This commit is contained in:
parent
30482196b6
commit
5cf2be2f54
@ -34,6 +34,7 @@
|
|||||||
- [EntryRow](structs/EntryRow.md)
|
- [EntryRow](structs/EntryRow.md)
|
||||||
- [ExpanderRow](structs/ExpanderRow.md)
|
- [ExpanderRow](structs/ExpanderRow.md)
|
||||||
- [FileDialog](structs/FileDialog.md)
|
- [FileDialog](structs/FileDialog.md)
|
||||||
|
- [FlowBox](structs/FlowBox.md)
|
||||||
- [ForEach](structs/ForEach.md)
|
- [ForEach](structs/ForEach.md)
|
||||||
- [Form](structs/Form.md)
|
- [Form](structs/Form.md)
|
||||||
- [HStack](structs/HStack.md)
|
- [HStack](structs/HStack.md)
|
||||||
@ -111,6 +112,7 @@
|
|||||||
- [Clamp](extensions/Clamp.md)
|
- [Clamp](extensions/Clamp.md)
|
||||||
- [ComboRow](extensions/ComboRow.md)
|
- [ComboRow](extensions/ComboRow.md)
|
||||||
- [EntryRow](extensions/EntryRow.md)
|
- [EntryRow](extensions/EntryRow.md)
|
||||||
|
- [FlowBox](extensions/FlowBox.md)
|
||||||
- [FormSection](extensions/FormSection.md)
|
- [FormSection](extensions/FormSection.md)
|
||||||
- [HeaderBar](extensions/HeaderBar.md)
|
- [HeaderBar](extensions/HeaderBar.md)
|
||||||
- [Int](extensions/Int.md)
|
- [Int](extensions/Int.md)
|
||||||
|
|||||||
21
Documentation/Reference/extensions/FlowBox.md
Normal file
21
Documentation/Reference/extensions/FlowBox.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
**EXTENSION**
|
||||||
|
|
||||||
|
# `FlowBox`
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `selectionField`
|
||||||
|
|
||||||
|
The ID for the field storing the selection value.
|
||||||
|
|
||||||
|
### `elementsField`
|
||||||
|
|
||||||
|
The ID for the field storing the elements.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `init(_:selection:content:)`
|
||||||
|
|
||||||
|
Initialize `FlowBox`.
|
||||||
|
- Parameters:
|
||||||
|
- elements: The elements.
|
||||||
|
- selection: The identifier of the selected element. Selection disabled if `nil`.
|
||||||
|
- content: The view for an element.
|
||||||
290
Documentation/Reference/structs/FlowBox.md
Normal file
290
Documentation/Reference/structs/FlowBox.md
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
**STRUCT**
|
||||||
|
|
||||||
|
# `FlowBox`
|
||||||
|
|
||||||
|
A `GtkFlowBox` puts child widgets in reflowing grid.
|
||||||
|
|
||||||
|
For instance, with the horizontal orientation, the widgets will be
|
||||||
|
arranged from left to right, starting a new row under the previous
|
||||||
|
row when necessary. Reducing the width in this case will require more
|
||||||
|
rows, so a larger height will be requested.
|
||||||
|
|
||||||
|
Likewise, with the vertical orientation, the widgets will be arranged
|
||||||
|
from top to bottom, starting a new column to the right when necessary.
|
||||||
|
Reducing the height will require more columns, so a larger width will
|
||||||
|
be requested.
|
||||||
|
|
||||||
|
The size request of a `GtkFlowBox` alone may not be what you expect;
|
||||||
|
if you need to be able to shrink it along both axes and dynamically
|
||||||
|
reflow its children, you may have to wrap it in a `GtkScrolledWindow`
|
||||||
|
to enable that.
|
||||||
|
|
||||||
|
The children of a `GtkFlowBox` can be dynamically sorted and filtered.
|
||||||
|
|
||||||
|
Although a `GtkFlowBox` must have only `GtkFlowBoxChild` children, you
|
||||||
|
can add any kind of widget to it via [method@Gtk.FlowBox.insert], and a
|
||||||
|
`GtkFlowBoxChild` widget will automatically be inserted between the box
|
||||||
|
and the widget.
|
||||||
|
|
||||||
|
Also see [class@Gtk.ListBox].
|
||||||
|
|
||||||
|
# CSS nodes
|
||||||
|
|
||||||
|
```
|
||||||
|
flowbox
|
||||||
|
├── flowboxchild
|
||||||
|
│ ╰── <child>├── flowboxchild
|
||||||
|
│ ╰── <child>┊
|
||||||
|
╰── [rubberband]
|
||||||
|
```
|
||||||
|
|
||||||
|
`GtkFlowBox` uses a single CSS node with name flowbox. `GtkFlowBoxChild`
|
||||||
|
uses a single CSS node with name flowboxchild. For rubberband selection,
|
||||||
|
a subnode with name rubberband is used.
|
||||||
|
|
||||||
|
# Accessibility
|
||||||
|
|
||||||
|
`GtkFlowBox` uses the %GTK_ACCESSIBLE_ROLE_GRID role, and `GtkFlowBoxChild`
|
||||||
|
uses the %GTK_ACCESSIBLE_ROLE_GRID_CELL role.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `updateFunctions`
|
||||||
|
|
||||||
|
Additional update functions for type extensions.
|
||||||
|
|
||||||
|
### `appearFunctions`
|
||||||
|
|
||||||
|
Additional appear functions for type extensions.
|
||||||
|
|
||||||
|
### `acceptUnpairedRelease`
|
||||||
|
|
||||||
|
accept-unpaired-release
|
||||||
|
|
||||||
|
### `activateOnSingleClick`
|
||||||
|
|
||||||
|
Determines whether children can be activated with a single
|
||||||
|
click, or require a double-click.
|
||||||
|
|
||||||
|
### `columnSpacing`
|
||||||
|
|
||||||
|
The amount of horizontal space between two children.
|
||||||
|
|
||||||
|
### `homogeneous`
|
||||||
|
|
||||||
|
Determines whether all children should be allocated the
|
||||||
|
same size.
|
||||||
|
|
||||||
|
### `maxChildrenPerLine`
|
||||||
|
|
||||||
|
The maximum amount of children to request space for consecutively
|
||||||
|
in the given orientation.
|
||||||
|
|
||||||
|
### `minChildrenPerLine`
|
||||||
|
|
||||||
|
The minimum number of children to allocate consecutively
|
||||||
|
in the given orientation.
|
||||||
|
|
||||||
|
Setting the minimum children per line ensures
|
||||||
|
that a reasonably small height will be requested
|
||||||
|
for the overall minimum width of the box.
|
||||||
|
|
||||||
|
### `rowSpacing`
|
||||||
|
|
||||||
|
The amount of vertical space between two children.
|
||||||
|
|
||||||
|
### `activateCursorChild`
|
||||||
|
|
||||||
|
Emitted when the user activates the @box.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
### `childActivated`
|
||||||
|
|
||||||
|
Emitted when a child has been activated by the user.
|
||||||
|
|
||||||
|
### `moveCursor`
|
||||||
|
|
||||||
|
Emitted when the user initiates a cursor movement.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
Applications should not connect to it, but may emit it with
|
||||||
|
g_signal_emit_by_name() if they need to control the cursor
|
||||||
|
programmatically.
|
||||||
|
|
||||||
|
The default bindings for this signal come in two variants,
|
||||||
|
the variant with the Shift modifier extends the selection,
|
||||||
|
the variant without the Shift modifier does not.
|
||||||
|
There are too many key combinations to list them all here.
|
||||||
|
|
||||||
|
- <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd>
|
||||||
|
move by individual children
|
||||||
|
- <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box
|
||||||
|
- <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages
|
||||||
|
|
||||||
|
### `selectAll`
|
||||||
|
|
||||||
|
Emitted to select all children of the box,
|
||||||
|
if the selection mode permits it.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.
|
||||||
|
|
||||||
|
### `selectedChildrenChanged`
|
||||||
|
|
||||||
|
Emitted when the set of selected children changes.
|
||||||
|
|
||||||
|
Use [method@Gtk.FlowBox.selected_foreach] or
|
||||||
|
[method@Gtk.FlowBox.get_selected_children] to obtain the
|
||||||
|
selected children.
|
||||||
|
|
||||||
|
### `toggleCursorChild`
|
||||||
|
|
||||||
|
Emitted to toggle the selection of the child that has the focus.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>Space</kbd>.
|
||||||
|
|
||||||
|
### `unselectAll`
|
||||||
|
|
||||||
|
Emitted to unselect all children of the box,
|
||||||
|
if the selection mode permits it.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.
|
||||||
|
|
||||||
|
### `elements`
|
||||||
|
|
||||||
|
The dynamic widget elements.
|
||||||
|
|
||||||
|
### `content`
|
||||||
|
|
||||||
|
The dynamic widget content.
|
||||||
|
|
||||||
|
### `app`
|
||||||
|
|
||||||
|
The application.
|
||||||
|
|
||||||
|
### `window`
|
||||||
|
|
||||||
|
The window.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `init(_:content:)`
|
||||||
|
|
||||||
|
Initialize `FlowBox`.
|
||||||
|
|
||||||
|
### `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.
|
||||||
|
|
||||||
|
### `acceptUnpairedRelease(_:)`
|
||||||
|
|
||||||
|
accept-unpaired-release
|
||||||
|
|
||||||
|
### `activateOnSingleClick(_:)`
|
||||||
|
|
||||||
|
Determines whether children can be activated with a single
|
||||||
|
click, or require a double-click.
|
||||||
|
|
||||||
|
### `columnSpacing(_:)`
|
||||||
|
|
||||||
|
The amount of horizontal space between two children.
|
||||||
|
|
||||||
|
### `homogeneous(_:)`
|
||||||
|
|
||||||
|
Determines whether all children should be allocated the
|
||||||
|
same size.
|
||||||
|
|
||||||
|
### `maxChildrenPerLine(_:)`
|
||||||
|
|
||||||
|
The maximum amount of children to request space for consecutively
|
||||||
|
in the given orientation.
|
||||||
|
|
||||||
|
### `minChildrenPerLine(_:)`
|
||||||
|
|
||||||
|
The minimum number of children to allocate consecutively
|
||||||
|
in the given orientation.
|
||||||
|
|
||||||
|
Setting the minimum children per line ensures
|
||||||
|
that a reasonably small height will be requested
|
||||||
|
for the overall minimum width of the box.
|
||||||
|
|
||||||
|
### `rowSpacing(_:)`
|
||||||
|
|
||||||
|
The amount of vertical space between two children.
|
||||||
|
|
||||||
|
### `activateCursorChild(_:)`
|
||||||
|
|
||||||
|
Emitted when the user activates the @box.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
### `childActivated(_:)`
|
||||||
|
|
||||||
|
Emitted when a child has been activated by the user.
|
||||||
|
|
||||||
|
### `moveCursor(_:)`
|
||||||
|
|
||||||
|
Emitted when the user initiates a cursor movement.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
Applications should not connect to it, but may emit it with
|
||||||
|
g_signal_emit_by_name() if they need to control the cursor
|
||||||
|
programmatically.
|
||||||
|
|
||||||
|
The default bindings for this signal come in two variants,
|
||||||
|
the variant with the Shift modifier extends the selection,
|
||||||
|
the variant without the Shift modifier does not.
|
||||||
|
There are too many key combinations to list them all here.
|
||||||
|
|
||||||
|
- <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd>
|
||||||
|
move by individual children
|
||||||
|
- <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box
|
||||||
|
- <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages
|
||||||
|
|
||||||
|
### `selectAll(_:)`
|
||||||
|
|
||||||
|
Emitted to select all children of the box,
|
||||||
|
if the selection mode permits it.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.
|
||||||
|
|
||||||
|
### `selectedChildrenChanged(_:)`
|
||||||
|
|
||||||
|
Emitted when the set of selected children changes.
|
||||||
|
|
||||||
|
Use [method@Gtk.FlowBox.selected_foreach] or
|
||||||
|
[method@Gtk.FlowBox.get_selected_children] to obtain the
|
||||||
|
selected children.
|
||||||
|
|
||||||
|
### `toggleCursorChild(_:)`
|
||||||
|
|
||||||
|
Emitted to toggle the selection of the child that has the focus.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>Space</kbd>.
|
||||||
|
|
||||||
|
### `unselectAll(_:)`
|
||||||
|
|
||||||
|
Emitted to unselect all children of the box,
|
||||||
|
if the selection mode permits it.
|
||||||
|
|
||||||
|
This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
|
||||||
|
The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.
|
||||||
59
Sources/Adwaita/View/FlowBox+.swift
Normal file
59
Sources/Adwaita/View/FlowBox+.swift
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// FlowBox+.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 12.02.24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CAdw
|
||||||
|
|
||||||
|
extension FlowBox {
|
||||||
|
|
||||||
|
/// The ID for the field storing the selection value.
|
||||||
|
static var selectionField: String { "selection" }
|
||||||
|
/// The ID for the field storing the elements.
|
||||||
|
static var elementsField: String { "element" }
|
||||||
|
|
||||||
|
/// Initialize `FlowBox`.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - elements: The elements.
|
||||||
|
/// - selection: The identifier of the selected element. Selection disabled if `nil`.
|
||||||
|
/// - content: The view for an element.
|
||||||
|
public init(
|
||||||
|
_ elements: [Element],
|
||||||
|
selection: Binding<Element.ID>?,
|
||||||
|
@ViewBuilder content: @escaping (Element) -> Body
|
||||||
|
) {
|
||||||
|
self.init(elements, content: content)
|
||||||
|
let id: (ViewStorage, [Element]) -> Element.ID? = { storage, elements in
|
||||||
|
if let child = g_list_nth_data(gtk_flow_box_get_selected_children(storage.pointer), 0) {
|
||||||
|
let element = gtk_flow_box_child_get_child(child.cast())
|
||||||
|
return elements[safe: storage.content[.mainContent]?.firstIndex { $0.pointer?.cast() == element }]?.id
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if let selection {
|
||||||
|
appearFunctions.append { storage in
|
||||||
|
storage.fields[Self.selectionField] = selection
|
||||||
|
storage.connectSignal(name: "selected_children_changed", id: Self.selectionField) {
|
||||||
|
if let binding = storage.fields[Self.selectionField] as? Binding<Element.ID>,
|
||||||
|
let elements = storage.fields[Self.elementsField] as? [Element],
|
||||||
|
let id = id(storage, elements) {
|
||||||
|
binding.wrappedValue = id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateFunctions.append { storage in
|
||||||
|
if selection.wrappedValue != id(storage, elements),
|
||||||
|
let index = elements.firstIndex(where: { $0.id == selection.wrappedValue })?.cInt {
|
||||||
|
gtk_flow_box_select_child(storage.pointer, gtk_flow_box_get_child_at_index(storage.pointer, index))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appearFunctions.append { storage in
|
||||||
|
gtk_flow_box_set_selection_mode(storage.pointer, GTK_SELECTION_NONE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// ActionRow.swift
|
// ActionRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Avatar.swift
|
// Avatar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Banner.swift
|
// Banner.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Bin.swift
|
// Bin.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Box.swift
|
// Box.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Button.swift
|
// Button.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ButtonContent.swift
|
// ButtonContent.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Carousel.swift
|
// Carousel.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// CenterBox.swift
|
// CenterBox.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// CheckButton.swift
|
// CheckButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Clamp.swift
|
// Clamp.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ComboRow.swift
|
// ComboRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// EntryRow.swift
|
// EntryRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ExpanderRow.swift
|
// ExpanderRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
401
Sources/Adwaita/View/Generated/FlowBox.swift
Normal file
401
Sources/Adwaita/View/Generated/FlowBox.swift
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
//
|
||||||
|
// FlowBox.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by auto-generation on 12.02.24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import CAdw
|
||||||
|
import LevenshteinTransformations
|
||||||
|
|
||||||
|
/// A `GtkFlowBox` puts child widgets in reflowing grid.
|
||||||
|
///
|
||||||
|
/// For instance, with the horizontal orientation, the widgets will be
|
||||||
|
/// arranged from left to right, starting a new row under the previous
|
||||||
|
/// row when necessary. Reducing the width in this case will require more
|
||||||
|
/// rows, so a larger height will be requested.
|
||||||
|
///
|
||||||
|
/// Likewise, with the vertical orientation, the widgets will be arranged
|
||||||
|
/// from top to bottom, starting a new column to the right when necessary.
|
||||||
|
/// Reducing the height will require more columns, so a larger width will
|
||||||
|
/// be requested.
|
||||||
|
///
|
||||||
|
/// The size request of a `GtkFlowBox` alone may not be what you expect;
|
||||||
|
/// if you need to be able to shrink it along both axes and dynamically
|
||||||
|
/// reflow its children, you may have to wrap it in a `GtkScrolledWindow`
|
||||||
|
/// to enable that.
|
||||||
|
///
|
||||||
|
/// The children of a `GtkFlowBox` can be dynamically sorted and filtered.
|
||||||
|
///
|
||||||
|
/// Although a `GtkFlowBox` must have only `GtkFlowBoxChild` children, you
|
||||||
|
/// can add any kind of widget to it via [method@Gtk.FlowBox.insert], and a
|
||||||
|
/// `GtkFlowBoxChild` widget will automatically be inserted between the box
|
||||||
|
/// and the widget.
|
||||||
|
///
|
||||||
|
/// Also see [class@Gtk.ListBox].
|
||||||
|
///
|
||||||
|
/// # CSS nodes
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// flowbox
|
||||||
|
/// ├── flowboxchild
|
||||||
|
/// │ ╰── <child>├── flowboxchild
|
||||||
|
/// │ ╰── <child>┊
|
||||||
|
/// ╰── [rubberband]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// `GtkFlowBox` uses a single CSS node with name flowbox. `GtkFlowBoxChild`
|
||||||
|
/// uses a single CSS node with name flowboxchild. For rubberband selection,
|
||||||
|
/// a subnode with name rubberband is used.
|
||||||
|
///
|
||||||
|
/// # Accessibility
|
||||||
|
///
|
||||||
|
/// `GtkFlowBox` uses the %GTK_ACCESSIBLE_ROLE_GRID role, and `GtkFlowBoxChild`
|
||||||
|
/// uses the %GTK_ACCESSIBLE_ROLE_GRID_CELL role.
|
||||||
|
public struct FlowBox<Element>: Widget where Element: Identifiable {
|
||||||
|
|
||||||
|
/// Additional update functions for type extensions.
|
||||||
|
var updateFunctions: [(ViewStorage) -> Void] = []
|
||||||
|
/// Additional appear functions for type extensions.
|
||||||
|
var appearFunctions: [(ViewStorage) -> Void] = []
|
||||||
|
|
||||||
|
/// accept-unpaired-release
|
||||||
|
var acceptUnpairedRelease: Bool?
|
||||||
|
/// Determines whether children can be activated with a single
|
||||||
|
/// click, or require a double-click.
|
||||||
|
var activateOnSingleClick: Bool?
|
||||||
|
/// The amount of horizontal space between two children.
|
||||||
|
var columnSpacing: UInt?
|
||||||
|
/// Determines whether all children should be allocated the
|
||||||
|
/// same size.
|
||||||
|
var homogeneous: Bool?
|
||||||
|
/// The maximum amount of children to request space for consecutively
|
||||||
|
/// in the given orientation.
|
||||||
|
var maxChildrenPerLine: UInt?
|
||||||
|
/// The minimum number of children to allocate consecutively
|
||||||
|
/// in the given orientation.
|
||||||
|
///
|
||||||
|
/// Setting the minimum children per line ensures
|
||||||
|
/// that a reasonably small height will be requested
|
||||||
|
/// for the overall minimum width of the box.
|
||||||
|
var minChildrenPerLine: UInt?
|
||||||
|
/// The amount of vertical space between two children.
|
||||||
|
var rowSpacing: UInt?
|
||||||
|
/// Emitted when the user activates the @box.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
var activateCursorChild: (() -> Void)?
|
||||||
|
/// Emitted when a child has been activated by the user.
|
||||||
|
var childActivated: (() -> Void)?
|
||||||
|
/// Emitted when the user initiates a cursor movement.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
/// Applications should not connect to it, but may emit it with
|
||||||
|
/// g_signal_emit_by_name() if they need to control the cursor
|
||||||
|
/// programmatically.
|
||||||
|
///
|
||||||
|
/// The default bindings for this signal come in two variants,
|
||||||
|
/// the variant with the Shift modifier extends the selection,
|
||||||
|
/// the variant without the Shift modifier does not.
|
||||||
|
/// There are too many key combinations to list them all here.
|
||||||
|
///
|
||||||
|
/// - <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd>
|
||||||
|
/// move by individual children
|
||||||
|
/// - <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box
|
||||||
|
/// - <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages
|
||||||
|
var moveCursor: (() -> Void)?
|
||||||
|
/// Emitted to select all children of the box,
|
||||||
|
/// if the selection mode permits it.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
///
|
||||||
|
/// The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.
|
||||||
|
var selectAll: (() -> Void)?
|
||||||
|
/// Emitted when the set of selected children changes.
|
||||||
|
///
|
||||||
|
/// Use [method@Gtk.FlowBox.selected_foreach] or
|
||||||
|
/// [method@Gtk.FlowBox.get_selected_children] to obtain the
|
||||||
|
/// selected children.
|
||||||
|
var selectedChildrenChanged: (() -> Void)?
|
||||||
|
/// Emitted to toggle the selection of the child that has the focus.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
///
|
||||||
|
/// The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>Space</kbd>.
|
||||||
|
var toggleCursorChild: (() -> Void)?
|
||||||
|
/// Emitted to unselect all children of the box,
|
||||||
|
/// if the selection mode permits it.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
///
|
||||||
|
/// The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.
|
||||||
|
var unselectAll: (() -> Void)?
|
||||||
|
/// The dynamic widget elements.
|
||||||
|
var elements: [Element]
|
||||||
|
/// The dynamic widget content.
|
||||||
|
var content: (Element) -> Body
|
||||||
|
/// The application.
|
||||||
|
var app: GTUIApp?
|
||||||
|
/// The window.
|
||||||
|
var window: GTUIApplicationWindow?
|
||||||
|
|
||||||
|
/// Initialize `FlowBox`.
|
||||||
|
public init(_ elements: [Element], @ViewBuilder content: @escaping (Element) -> Body) {
|
||||||
|
self.elements = elements
|
||||||
|
self.content = content
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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_flow_box_new()?.opaque())
|
||||||
|
update(storage, modifiers: modifiers, updateProperties: true)
|
||||||
|
|
||||||
|
|
||||||
|
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 activateCursorChild {
|
||||||
|
storage.connectSignal(name: "activate-cursor-child", argCount: 0) {
|
||||||
|
activateCursorChild()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let childActivated {
|
||||||
|
storage.connectSignal(name: "child-activated", argCount: 1) {
|
||||||
|
childActivated()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let moveCursor {
|
||||||
|
storage.connectSignal(name: "move-cursor", argCount: 4) {
|
||||||
|
moveCursor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let selectAll {
|
||||||
|
storage.connectSignal(name: "select-all", argCount: 0) {
|
||||||
|
selectAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let selectedChildrenChanged {
|
||||||
|
storage.connectSignal(name: "selected-children-changed", argCount: 0) {
|
||||||
|
selectedChildrenChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let toggleCursorChild {
|
||||||
|
storage.connectSignal(name: "toggle-cursor-child", argCount: 0) {
|
||||||
|
toggleCursorChild()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let unselectAll {
|
||||||
|
storage.connectSignal(name: "unselect-all", argCount: 0) {
|
||||||
|
unselectAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storage.modify { widget in
|
||||||
|
if let activateOnSingleClick, updateProperties {
|
||||||
|
gtk_flow_box_set_activate_on_single_click(widget, activateOnSingleClick.cBool)
|
||||||
|
}
|
||||||
|
if let columnSpacing, updateProperties {
|
||||||
|
gtk_flow_box_set_column_spacing(widget, columnSpacing.cInt)
|
||||||
|
}
|
||||||
|
if let homogeneous, updateProperties {
|
||||||
|
gtk_flow_box_set_homogeneous(widget, homogeneous.cBool)
|
||||||
|
}
|
||||||
|
if let maxChildrenPerLine, updateProperties {
|
||||||
|
gtk_flow_box_set_max_children_per_line(widget, maxChildrenPerLine.cInt)
|
||||||
|
}
|
||||||
|
if let minChildrenPerLine, updateProperties {
|
||||||
|
gtk_flow_box_set_min_children_per_line(widget, minChildrenPerLine.cInt)
|
||||||
|
}
|
||||||
|
if let rowSpacing, updateProperties {
|
||||||
|
gtk_flow_box_set_row_spacing(widget, rowSpacing.cInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentStorage: [ViewStorage] = storage.content[.mainContent] ?? []
|
||||||
|
let old = storage.fields["element"] as? [Element] ?? []
|
||||||
|
old.identifiableTransform(
|
||||||
|
to: elements,
|
||||||
|
functions: .init { index, element in
|
||||||
|
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||||
|
gtk_flow_box_remove(widget, gtk_flow_box_get_child_at_index(widget, index.cInt)?.cast())
|
||||||
|
gtk_flow_box_insert(widget, child.pointer?.cast(), index.cInt)
|
||||||
|
contentStorage.remove(at: index)
|
||||||
|
contentStorage.insert(child, at: index)
|
||||||
|
} delete: { index in
|
||||||
|
gtk_flow_box_remove(widget, gtk_flow_box_get_child_at_index(widget, index.cInt)?.cast())
|
||||||
|
contentStorage.remove(at: index)
|
||||||
|
} insert: { index, element in
|
||||||
|
let child = content(element).widget(modifiers: modifiers).container(modifiers: modifiers)
|
||||||
|
gtk_flow_box_insert(widget, child.pointer?.cast(), index.cInt)
|
||||||
|
contentStorage.insert(child, at: index)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
storage.fields["element"] = elements
|
||||||
|
storage.content[.mainContent] = contentStorage
|
||||||
|
for (index, element) in elements.enumerated() {
|
||||||
|
content(element).widget(modifiers: modifiers).update(contentStorage[index], modifiers: modifiers, updateProperties: updateProperties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for function in updateFunctions {
|
||||||
|
function(storage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// accept-unpaired-release
|
||||||
|
public func acceptUnpairedRelease(_ acceptUnpairedRelease: Bool? = true) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.acceptUnpairedRelease = acceptUnpairedRelease
|
||||||
|
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines whether children can be activated with a single
|
||||||
|
/// click, or require a double-click.
|
||||||
|
public func activateOnSingleClick(_ activateOnSingleClick: Bool? = true) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.activateOnSingleClick = activateOnSingleClick
|
||||||
|
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The amount of horizontal space between two children.
|
||||||
|
public func columnSpacing(_ columnSpacing: UInt?) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.columnSpacing = columnSpacing
|
||||||
|
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines whether all children should be allocated the
|
||||||
|
/// same size.
|
||||||
|
public func homogeneous(_ homogeneous: Bool? = true) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.homogeneous = homogeneous
|
||||||
|
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The maximum amount of children to request space for consecutively
|
||||||
|
/// in the given orientation.
|
||||||
|
public func maxChildrenPerLine(_ maxChildrenPerLine: UInt?) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.maxChildrenPerLine = maxChildrenPerLine
|
||||||
|
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The minimum number of children to allocate consecutively
|
||||||
|
/// in the given orientation.
|
||||||
|
///
|
||||||
|
/// Setting the minimum children per line ensures
|
||||||
|
/// that a reasonably small height will be requested
|
||||||
|
/// for the overall minimum width of the box.
|
||||||
|
public func minChildrenPerLine(_ minChildrenPerLine: UInt?) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.minChildrenPerLine = minChildrenPerLine
|
||||||
|
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The amount of vertical space between two children.
|
||||||
|
public func rowSpacing(_ rowSpacing: UInt?) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.rowSpacing = rowSpacing
|
||||||
|
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emitted when the user activates the @box.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
public func activateCursorChild(_ activateCursorChild: @escaping () -> Void) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.activateCursorChild = activateCursorChild
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emitted when a child has been activated by the user.
|
||||||
|
public func childActivated(_ childActivated: @escaping () -> Void) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.childActivated = childActivated
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emitted when the user initiates a cursor movement.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
/// Applications should not connect to it, but may emit it with
|
||||||
|
/// g_signal_emit_by_name() if they need to control the cursor
|
||||||
|
/// programmatically.
|
||||||
|
///
|
||||||
|
/// The default bindings for this signal come in two variants,
|
||||||
|
/// the variant with the Shift modifier extends the selection,
|
||||||
|
/// the variant without the Shift modifier does not.
|
||||||
|
/// There are too many key combinations to list them all here.
|
||||||
|
///
|
||||||
|
/// - <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd>
|
||||||
|
/// move by individual children
|
||||||
|
/// - <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box
|
||||||
|
/// - <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages
|
||||||
|
public func moveCursor(_ moveCursor: @escaping () -> Void) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.moveCursor = moveCursor
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emitted to select all children of the box,
|
||||||
|
/// if the selection mode permits it.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
///
|
||||||
|
/// The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.
|
||||||
|
public func selectAll(_ selectAll: @escaping () -> Void) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.selectAll = selectAll
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emitted when the set of selected children changes.
|
||||||
|
///
|
||||||
|
/// Use [method@Gtk.FlowBox.selected_foreach] or
|
||||||
|
/// [method@Gtk.FlowBox.get_selected_children] to obtain the
|
||||||
|
/// selected children.
|
||||||
|
public func selectedChildrenChanged(_ selectedChildrenChanged: @escaping () -> Void) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.selectedChildrenChanged = selectedChildrenChanged
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emitted to toggle the selection of the child that has the focus.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
///
|
||||||
|
/// The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>Space</kbd>.
|
||||||
|
public func toggleCursorChild(_ toggleCursorChild: @escaping () -> Void) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.toggleCursorChild = toggleCursorChild
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emitted to unselect all children of the box,
|
||||||
|
/// if the selection mode permits it.
|
||||||
|
///
|
||||||
|
/// This is a [keybinding signal](class.SignalAction.html).
|
||||||
|
///
|
||||||
|
/// The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.
|
||||||
|
public func unselectAll(_ unselectAll: @escaping () -> Void) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.unselectAll = unselectAll
|
||||||
|
return newSelf
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
// HeaderBar.swift
|
// HeaderBar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Label.swift
|
// Label.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// LevelBar.swift
|
// LevelBar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// LinkButton.swift
|
// LinkButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ListBox.swift
|
// ListBox.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Menu.swift
|
// Menu.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Overlay.swift
|
// Overlay.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// OverlaySplitView.swift
|
// OverlaySplitView.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// PasswordEntryRow.swift
|
// PasswordEntryRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Popover.swift
|
// Popover.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// PreferencesGroup.swift
|
// PreferencesGroup.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// PreferencesPage.swift
|
// PreferencesPage.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// PreferencesRow.swift
|
// PreferencesRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ProgressBar.swift
|
// ProgressBar.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ScrolledWindow.swift
|
// ScrolledWindow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// SpinRow.swift
|
// SpinRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// Spinner.swift
|
// Spinner.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// SplitButton.swift
|
// SplitButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// StatusPage.swift
|
// StatusPage.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// SwitchRow.swift
|
// SwitchRow.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ToastOverlay.swift
|
// ToastOverlay.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ToggleButton.swift
|
// ToggleButton.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// ToolbarView.swift
|
// ToolbarView.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// WindowTitle.swift
|
// WindowTitle.swift
|
||||||
// Adwaita
|
// Adwaita
|
||||||
//
|
//
|
||||||
// Created by auto-generation on 10.02.24.
|
// Created by auto-generation on 12.02.24.
|
||||||
//
|
//
|
||||||
|
|
||||||
import CAdw
|
import CAdw
|
||||||
|
|||||||
@ -220,7 +220,16 @@ struct GenerationConfiguration {
|
|||||||
]
|
]
|
||||||
),
|
),
|
||||||
.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)
|
.init(class: "Popover", excludeProperties: ["pointing-to", "position"], cast: true),
|
||||||
|
.init(
|
||||||
|
class: "FlowBox",
|
||||||
|
dynamicWidget: .init(
|
||||||
|
insert: "gtk_flow_box_insert",
|
||||||
|
remove: "gtk_flow_box_remove",
|
||||||
|
getElement: "gtk_flow_box_get_child_at_index(widget, index.cInt)?.cast()"
|
||||||
|
),
|
||||||
|
excludeProperties: ["selection-mode"]
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
/// The unshortening map.
|
/// The unshortening map.
|
||||||
|
|||||||
49
Tests/FlowBoxDemo.swift
Normal file
49
Tests/FlowBoxDemo.swift
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// ListDemo.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 01.01.24.
|
||||||
|
//
|
||||||
|
|
||||||
|
// swiftlint:disable missing_docs no_magic_numbers
|
||||||
|
|
||||||
|
import Adwaita
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct FlowBoxDemo: View {
|
||||||
|
|
||||||
|
@State private var items: [ListDemo.Element] = []
|
||||||
|
@State private var selectedItem = ""
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
HStack {
|
||||||
|
Button("Add Element") {
|
||||||
|
let element = ListDemo.Element(id: UUID().uuidString)
|
||||||
|
items.append(element)
|
||||||
|
selectedItem = element.id
|
||||||
|
}
|
||||||
|
Button("Delete Selected Element") {
|
||||||
|
let index = items.firstIndex { $0.id == selectedItem }
|
||||||
|
items = items.filter { $0.id != selectedItem }
|
||||||
|
selectedItem = items[safe: index]?.id ?? items[safe: index ?? 0 - 1]?.id ?? items.first?.id ?? ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.style("linked")
|
||||||
|
.halign(.center)
|
||||||
|
if !items.isEmpty {
|
||||||
|
FlowBox(items, selection: $selectedItem) { item in
|
||||||
|
HStack {
|
||||||
|
Text(.init("\(item.id)".prefix(5)))
|
||||||
|
.hexpand()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
.valign(.center)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:enable missing_docs no_magic_numbers
|
||||||
@ -24,6 +24,7 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
|||||||
case viewSwitcher
|
case viewSwitcher
|
||||||
case form
|
case form
|
||||||
case popover
|
case popover
|
||||||
|
case flowBox
|
||||||
|
|
||||||
var id: Self {
|
var id: Self {
|
||||||
self
|
self
|
||||||
@ -35,6 +36,8 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
|||||||
return "Overlay Window"
|
return "Overlay Window"
|
||||||
case .viewSwitcher:
|
case .viewSwitcher:
|
||||||
return "View Switcher"
|
return "View Switcher"
|
||||||
|
case .flowBox:
|
||||||
|
return "Flow Box"
|
||||||
default:
|
default:
|
||||||
return rawValue.capitalized
|
return rawValue.capitalized
|
||||||
}
|
}
|
||||||
@ -77,6 +80,8 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
|||||||
return "Group controls used for data entry."
|
return "Group controls used for data entry."
|
||||||
case .popover:
|
case .popover:
|
||||||
return "Present content in a bubble-like context popup."
|
return "Present content in a bubble-like context popup."
|
||||||
|
case .flowBox:
|
||||||
|
return "Display views in a reflowing grid."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +115,8 @@ enum Page: String, Identifiable, CaseIterable, Codable {
|
|||||||
FormDemo(app: app)
|
FormDemo(app: app)
|
||||||
case .popover:
|
case .popover:
|
||||||
PopoverDemo()
|
PopoverDemo()
|
||||||
|
case .flowBox:
|
||||||
|
FlowBoxDemo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// swiftlint:enable cyclomatic_complexity
|
// swiftlint:enable cyclomatic_complexity
|
||||||
|
|||||||
@ -20,11 +20,11 @@ struct PopoverDemo: View {
|
|||||||
}
|
}
|
||||||
.style("suggested-action")
|
.style("suggested-action")
|
||||||
.frame(maxSize: 100)
|
.frame(maxSize: 100)
|
||||||
}
|
|
||||||
.popover(visible: $visible) {
|
.popover(visible: $visible) {
|
||||||
CounterDemo()
|
CounterDemo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user