import Gtk /// SPI protocol for containers that manage an ordered list of children. @_spi(Portico) @MainActor public protocol SequentialContainer { /// Appends a child widget to the end of the container. func appendChild(_ child: Gtk.Widget) /// Removes a previously added child widget. func removeChild(_ child: Gtk.Widget) } /// How a conditional slot deactivates a branch in a host. @_spi(Portico) public enum ConditionalStrategy { /// Hide the branch's widgets while keeping them parented. case visibility /// Detach inactive widgets and reinsert them on activation. case insertion } /// SPI capability for containers that support indexed insertion. @_spi(Portico) @MainActor public protocol DynamicChildHost: SequentialContainer { /// Inserts a child at the target position. func insertChild(_ child: Gtk.Widget, at index: Int, after sibling: Gtk.Widget?) /// Moves a child to the target position. func moveChild(_ child: Gtk.Widget, to index: Int, after sibling: Gtk.Widget?) /// Selects visibility or insertion semantics for conditional branches. var conditionalStrategy: ConditionalStrategy { get } /// Returns the widget whose visibility controls layout participation. func visibilityTarget(for child: Gtk.Widget) -> Gtk.Widget } @_spi(Portico) extension DynamicChildHost { /// Hides inactive branches by default. public var conditionalStrategy: ConditionalStrategy { .visibility } /// Uses the child itself as the layout visibility target by default. public func visibilityTarget(for child: Gtk.Widget) -> Gtk.Widget { child } /// Moves a child using remove-then-insert. @_spi(Portico) public func moveChild(_ child: Gtk.Widget, to index: Int, after sibling: Gtk.Widget?) { removeChild(child) insertChild(child, at: index, after: sibling) } }