Skip to content

Instantly share code, notes, and snippets.

@johnsusek
Created December 25, 2025 01:33
Show Gist options
  • Select an option

  • Save johnsusek/fbd702f1abc26e9f3518f4c52bc46bdb to your computer and use it in GitHub Desktop.

Select an option

Save johnsusek/fbd702f1abc26e9f3518f4c52bc46bdb to your computer and use it in GitHub Desktop.
KitchenSinkView.swift
import SwiftGodot
import SwiftGodotBuilder
struct ExampleType {
var name: String
var value: Int
}
struct KitchenSinkView: View {
@State var shake = true
@State var dismiss = true
@State var acceptDialog: AcceptDialog?
@State var fileDialog: FileDialog?
@State var graphEdit: GraphEdit?
var body: some View {
CanvasLayer$ {
SafeArea(top: 10, right: 10, bottom: 10, left: 10) {
TabContainer$ {
Tab("Buttons") {
VBoxContainer$ {
HBoxContainer$ {
Button$()
.text("Button")
.onSignal(\.pressed) { _ in print("Button pressed") }
CheckBox$()
.text("CheckBox")
.onSignal(\.toggled) { _, pressed in print("CheckBox: \(pressed)") }
CheckButton$()
.text("CheckButton")
.onSignal(\.toggled) { _, pressed in print("CheckButton: \(pressed)") }
}
}
}
Tab("Text Input") {
VBoxContainer$ {
LineEdit$()
.placeholderText("LineEdit - single line text...")
.onSignal(\.textChanged) { _, text in print("LineEdit: \(text)") }
TextEdit$()
.placeholderText("TextEdit - multi-line text...")
.minSize([0, 80])
.onSignal(\.textChanged) { _ in print("TextEdit changed") }
SpinBox$()
.minValue(0)
.maxValue(100)
.value(50)
.onSignal(\.valueChanged) { _, val in print("SpinBox: \(val)") }
}
}
Tab("Sliders & Ranges") {
VBoxContainer$ {
HBoxContainer$ {
Label$().text("HSlider:")
HSlider$()
.minValue(0)
.maxValue(100)
.value(50)
.sizeH(.expandFill)
.onSignal(\.valueChanged) { _, val in print("HSlider: \(val)") }
}
HBoxContainer$ {
Label$().text("VSlider:")
VSlider$()
.minValue(0)
.maxValue(100)
.value(75)
.minSize([0, 80])
.onSignal(\.valueChanged) { _, val in print("VSlider: \(val)") }
}
HBoxContainer$ {
Label$().text("ProgressBar:")
ProgressBar$()
.minValue(0)
.maxValue(100)
.value(65)
.showPercentage(true)
.sizeH(.expandFill)
}
HBoxContainer$ {
Label$().text("HScrollBar:")
HScrollBar$()
.minValue(0)
.maxValue(100)
.value(30)
.sizeH(.expandFill)
}
}
}
Tab("Themes") {
VBoxContainer$ {
Label$()
.text("This label uses a custom theme")
}
.theme(Theme([
"Label": [
"colors": ["fontColor": Color.purple],
"fontSizes": ["fontSize": 32],
],
]))
}
Tab("StyleBox") {
VBoxContainer$ {
PanelContainer$ {
Label$().text("Styled Panel")
}
.panelStyle(
StyleBoxFlat$()
.bgColor(.black.withAlpha(0.9))
.borderColor(.cyan)
.borderWidth(2)
.cornerRadius(8)
.shadowColor(.black.withAlpha(0.5))
.shadowSize(12)
)
}
}
Tab("Misc") {
VBoxContainer$ {
HBoxContainer$ {
Label$().text("ColorRect")
ColorRect$()
.color(.red)
.minSize([50, 30])
}
PanelContainer$ {
Label$().text("Content inside PanelContainer")
}
HSeparator$()
}
}
Tab("Containers") {
ScrollContainer$ {
VBoxContainer$ {
HSplitContainer$ {
Label$().text("Left Pane")
Label$().text("Right Pane")
}
.minSize([200, 0])
HSeparator$()
VSplitContainer$ {
Label$().text("Top Pane")
Label$().text("Bottom Pane")
}
.minSize([0, 80])
HSeparator$()
CenterContainer$ {
Button$().text("Centered Button")
}
.minSize([0, 50])
HSeparator$()
GridContainer$ {
Button$().text("1")
Button$().text("2")
Button$().text("3")
Button$().text("4")
Button$().text("5")
Button$().text("6")
}
.columns(3)
HSeparator$()
HFlowContainer$ {
Button$().text("One")
Button$().text("Two")
Button$().text("Three")
Button$().text("Four")
Button$().text("Five")
}
HSeparator$()
VBoxContainer$ {
VFlowContainer$ {
Button$().text("A")
Button$().text("B")
Button$().text("C")
}
.minSize([0, 80])
}
}
}
.size(.expandFill)
}
Tab("ContextMenu") {
CenterContainer$ {
Label$().text("Right-click me")
.contextMenu {
MenuItem("Cut", id: 0)
MenuItem("Copy", id: 1)
MenuItem("Paste", id: 2)
MenuSeparator()
MenuItem("Delete", id: 10)
} onItemPressed: { id in
print("Context action: \(id)")
}
}
}
Tab("Tree") {
Tree$ {
TreeNode("Root") {
TreeNode("Child 1")
TreeNode("Child 2", editable: true) {
TreeNode("Grandchild")
}
}
}
.onItemSelected { print("Selected") }
.onItemActivated { print("Double-clicked") }
}
Tab("Item List") {
ItemList$ {
ListItem("Apple")
ListItem("Banana")
ListItem("Cherry", disabled: true)
}
.onItemSelected { index in print("Selected: \(index)") }
.onItemActivated { index in print("Activated: \(index)") }
}
Tab("OptionButton") {
VBoxContainer$ {
OptionButton$ {
Option("Small", id: 0)
Option("Medium", id: 1)
Option("Large", id: 2)
OptionSeparator()
Option("Custom...", id: 99)
}
.onItemSelected { id in print("Selected: \(id)") }
}
}
Tab("ColorPicker") {
ScrollContainer$ {
ColorPicker$ {
Preset(.red)
Preset(.green)
Preset(.blue)
Preset(hex: "#FF6600")
Preset(r: 128, g: 0, b: 255)
}
.onColorChanged { color in print("Color: \(color)") }
}
}
Tab("Dialogs") {
VBoxContainer$ {
Button$()
.text("Show Accept")
.onSignal(\.pressed) { _ in
acceptDialog?.popupCentered()
}
Button$()
.text("Show File")
.onSignal(\.pressed) { _ in
fileDialog?.popupCentered()
}
}
}
Tab("RichTextLabel") {
RichTextLabel$ {
Bold("Important: ")
"Normal text "
Colored(.red, "Warning!")
Newline()
Italic {
"Nested "
Bold("formatting")
}
Newline()
Paragraph {
FontSize(24, "Large text")
}
}
}
Tab("GraphEdit") {
GraphEdit$ {
GraphNode$(name: "add", title: "Add") {
Slot("A", left: Port(.blue, type: Float.self))
Slot("B", left: Port(.green, type: Float.self))
// Custom content in slots
Slot(right: Port(.red, type: Float.self)) {
SpinBox$().value(1.0).minValue(0).maxValue(100)
}
}
.positionOffset([100, 100])
.onSignal(\.slotUpdated) { _, slotIndex in
GD.print("Slot A updated on node 'add', slot index: \(slotIndex)")
}
GraphNode$(name: "subtract", title: "Subtract") {
Slot("Value", left: Port(.green, type: Int.self))
}
.positionOffset([300, 100])
}
.showGrid(false)
.showMenu(false)
.minimapEnabled(false)
.rightDisconnects(true)
.ref($graphEdit)
.onSignal(\.nodeSelected) { _, n in
guard let n else { return }
GD.print("Node selected: \(n)")
}
.onSignal(\.connectionRequest) { _, fromNode, fromPort, toNode, toPort in
GD.print("Connect request from \(fromNode) port \(fromPort) to \(toNode) port \(toPort)")
_ = graphEdit?.connectNode(fromNode: fromNode, fromPort: Int32(fromPort), toNode: toNode, toPort: Int32(toPort))
}
.onSignal(\.disconnectionRequest) { _, fromNode, fromPort, toNode, toPort in
GD.print("Disconnect request from \(fromNode) port \(fromPort) to \(toNode) port \(toPort)")
_ = graphEdit?.disconnectNode(fromNode: fromNode, fromPort: Int32(fromPort), toNode: toNode, toPort: Int32(toPort))
}
}
}
}
FileDialog$()
.filter("Images", "*.png,*.jpg")
.filter("All Files", "*")
.onFileSelected { path in print(path) }
.ref($fileDialog)
AcceptDialog$ {
DialogButton("Save", action: "save")
DialogButton("Don't Save", action: "discard")
CancelButton()
}
.title("Unsaved Changes")
.dialogText("Save before closing?")
.onConfirmed { print("OK") }
.onCustomAction { action in
print("Custom action: \(action)")
}
.ref($acceptDialog)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment