40 lines
1.3 KiB
Swift
40 lines
1.3 KiB
Swift
import Gtk
|
|
|
|
/// SPI protocol for views that can mount multiple widgets into one parent region.
|
|
@_spi(Portico) @MainActor public protocol DynamicViewGroup {
|
|
/// Mounts the group's widgets into `region` and registers its reactive resources.
|
|
func mountRegion(_ region: ChildRegion, ctx: MountContext)
|
|
}
|
|
|
|
/// Mounts static views and dynamic groups into an ordered parent container.
|
|
///
|
|
/// A ledger is allocated only when at least one view can spread and the parent
|
|
/// conforms to ``DynamicChildHost``. Otherwise every view uses the ordinary
|
|
/// single-widget mount path.
|
|
@_spi(Portico) @MainActor
|
|
public func mountChildren(
|
|
_ views: [AnyView],
|
|
into host: Gtk.Widget,
|
|
_ ctx: MountContext,
|
|
append: (Gtk.Widget) -> Void
|
|
) {
|
|
guard views.contains(where: { $0.group != nil }),
|
|
let dynamicHost = host as? any DynamicChildHost
|
|
else {
|
|
for view in views {
|
|
append(view.makeWidget(ctx))
|
|
}
|
|
return
|
|
}
|
|
|
|
let ledger = ChildLedger(host: dynamicHost)
|
|
for view in views {
|
|
if let group = view.group {
|
|
group.mountRegion(ledger.addRegion(), ctx: ctx)
|
|
} else {
|
|
let widget = view.makeWidget(ctx)
|
|
append(widget)
|
|
ledger.appendStatic(widget)
|
|
}
|
|
}
|
|
}
|