portico/Sources/Portico/Widgets/Button.swift

44 lines
1.3 KiB
Swift

import Gtk
/// A button with a click action, backed by `Gtk.Button`.
///
/// Supports text labels and icon-name variants. The `connectClicked`
/// ``SignalHandle`` is intentionally discarded in P0 the closure box
/// is retained by GObject for the widget's lifetime. Per-node teardown
/// is wired in P4.
@MainActor public struct Button: View {
private enum Kind {
case label(String)
case icon(String)
}
private let kind: Kind
@_spi(Portico) public let action: () -> Void
public var body: Never { fatalError() }
/// Creates a button with a text label and a click action.
public init(_ label: String, action: @escaping () -> Void) {
self.kind = .label(label)
self.action = action
}
/// Creates a button with a themed icon and a click action.
public init(iconName: String, action: @escaping () -> Void) {
self.kind = .icon(iconName)
self.action = action
}
}
@_spi(Portico) extension Button: Mountable {
@_spi(Portico) public func mount(_ ctx: MountContext) -> Gtk.Widget {
let button: Gtk.Button
switch kind {
case .label(let s): button = Gtk.Button(label: s)
case .icon(let s): button = Gtk.Button(iconName: s)
}
let action = self.action
_ = button.connectClicked { _ in action() }
return button
}
}