portico/Sources/Portico/Core/DynamicViewGroup.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)
}
}
}