term-kit-backend/Sources/TestApp/TestApp.swift

157 lines
3.5 KiB
Swift
Raw Normal View History

2024-07-10 14:41:11 +02:00
//
// TestApp.swift
// TermKitBackend
//
// Created by david-swift on 01.07.2024.
//
import Meta
2024-07-10 14:41:11 +02:00
import TermKitBackend
@main
struct TestApp: App {
@State private var about: Signal = .init()
let id = "io.github.AparokshaUI.TestApp"
var app: TermKitApp!
var scene: Scene {
Window {
VStack {
Demos()
.hcenter()
Controls()
.hcenter()
}
.frame(height: 14)
.vcenter()
.infoBox("About TermKitBackend", message: aboutInfo, signal: about)
}
2024-07-19 23:41:19 +02:00
.menuBar {
2024-07-18 16:07:37 +02:00
fileMenu
2024-07-10 14:41:11 +02:00
Menu("_Actions") {
Button("_Hello, world!") { }
}
}
}
2024-07-18 16:07:37 +02:00
@ViewBuilder
var fileMenu: Body {
Menu("File") {
Button("_About TermKitBackend") {
about.signal()
}
Button("_Quit") {
app.quit()
}
}
}
2024-07-10 14:41:11 +02:00
var aboutInfo: String {
"""
This is a sample backend for the Meta package of the Aparoksha project.
It is based on TermKit, the terminal UI toolkit for Swift.
"""
}
}
struct Demos: View {
@State private var state = false
@State private var dialog: Signal = .init()
@State private var error: Signal = .init()
let demos = Demo.allCases
var view: Body {
Frame("Demos (state \(state ? 2 : 1))") {
ListView(demos) { $0.action(state: $state, dialog: $dialog, error: $error) }
}
.frame(width: 40, height: 7)
.queryBox("Dialog Demo", message: "Choose wisely", signal: dialog) {
Button("Yes") {
state.toggle()
}
Button("No") { }
}
.errorBox("Error Demo", message: "This is an error message", signal: error) {
Button("Close") { }
}
}
}
2024-07-19 23:41:19 +02:00
struct ControlsModel: Model {
var isOn = false
var fraction = 0
var text = "Controls"
var model: ModelData?
func increaseFraction() {
Task { @MainActor in
setModel { $0.fraction += 1 }
}
}
}
2024-07-10 14:41:11 +02:00
struct Controls: View {
2024-07-19 23:41:19 +02:00
@State private var model = ControlsModel()
2024-07-10 14:41:11 +02:00
var view: Body {
2024-07-19 23:41:19 +02:00
Frame(model.text) {
2024-07-10 14:41:11 +02:00
HStack {
Button("Button (progress)") {
2024-07-19 23:41:19 +02:00
if model.fraction == 10 {
model.fraction = 0
2024-07-10 14:41:11 +02:00
} else {
2024-07-19 23:41:19 +02:00
model.increaseFraction()
2024-07-10 14:41:11 +02:00
}
}
Button("Button (text)") {
2024-07-19 23:41:19 +02:00
model.text = "Hello"
2024-07-10 14:41:11 +02:00
}
}
.frame(height: 1)
2024-07-19 23:41:19 +02:00
Checkbox(model.isOn ? "On" : "Off", isOn: $model.isOn)
TextField(text: $model.text)
.secret(model.isOn)
ProgressBar(value: .init(model.fraction), max: 10)
2024-07-10 14:41:11 +02:00
}
.frame(width: 40, height: 7)
}
}
enum Demo: String, CaseIterable, CustomStringConvertible {
case state
case dialog
case error
var description: String {
switch self {
case .state:
"Toggle State"
default:
rawValue.capitalized
}
}
func action(state: Binding<Bool>, dialog: Binding<Signal>, error: Binding<Signal>) {
switch self {
case .state:
state.wrappedValue.toggle()
case .dialog:
dialog.wrappedValue.signal()
case .error:
error.wrappedValue.signal()
}
}
}