44 lines
1.3 KiB
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
|
|
}
|
|
}
|