Files
TUIkit/Sources/TUIkitExample/Pages/MainMenuPage.swift
T
phranck b3d563040a Feat: Add Image view with ASCII art rendering, bracketed paste, and input filtering
- Add Image view rendering local files and URLs as colored ASCII art
- Add CSTBImage C target wrapping stb_image for cross-platform image decoding
- Add ASCIIConverter with block, ASCII, and braille character sets
- Support trueColor, ANSI-256, grayscale, and mono color modes
- Add Floyd-Steinberg dithering for improved visual quality
- Add async image loading with URLImageCache for URL sources
- Add bracketed paste mode for bulk text insertion in text fields
- Add TextContentType modifier for input character filtering
- Add ContentMode enum and aspectRatio(_:contentMode:) View modifier
- Add text-input priority in key dispatch to prevent shortcut conflicts
- Add Image (File) and Image (URL) demo pages to example app
- Update DocC documentation with new symbols and layout table
2026-02-14 00:43:22 +01:00

118 lines
4.2 KiB
Swift

// 🖥️ TUIKit — Terminal UI Kit for Swift
// MainMenuPage.swift
//
// Created by LAYERED.work
// License: MIT
import TUIkit
/// A small feature highlight box with a bold title and subtitle.
///
/// Used on the main menu to showcase key framework properties.
/// Stateless and palette-driven — wrapped in `.equatable()` for
/// subtree memoization during Spinner/Pulse animation frames.
struct FeatureBox: View, Equatable {
/// The bold headline text.
let title: String
/// The secondary description text.
let subtitle: String
init(_ title: String, _ subtitle: String) {
self.title = title
self.subtitle = subtitle
}
var body: some View {
VStack {
Text(title)
.bold()
.foregroundStyle(.palette.accent)
Text(subtitle)
.foregroundStyle(.palette.foregroundSecondary)
}
.padding(EdgeInsets(horizontal: 2, vertical: 1))
.border(color: .palette.border)
}
}
/// The main menu page.
///
/// Displays a centered menu with all available demos and
/// feature highlight boxes at the bottom.
struct MainMenuPage: View {
@Binding var currentPage: DemoPage
@Binding var menuSelection: Int
var body: some View {
VStack(spacing: 1) {
Spacer(minLength: 1)
HStack {
Spacer()
Menu(
title: "Select a Demo",
items: [
MenuItem(label: "Text Styles", shortcut: "1"),
MenuItem(label: "Colors", shortcut: "2"),
MenuItem(label: "Container Views", shortcut: "3"),
MenuItem(label: "Overlays & Modals", shortcut: "4"),
MenuItem(label: "Layout System", shortcut: "5"),
MenuItem(label: "Buttons & Focus", shortcut: "6"),
MenuItem(label: "Toggles", shortcut: "7"),
MenuItem(label: "Text Fields", shortcut: "8"),
MenuItem(label: "Secure Fields", shortcut: "\\"),
MenuItem(label: "Radio Buttons", shortcut: "9"),
MenuItem(label: "Spinners", shortcut: "0"),
MenuItem(label: "Lists", shortcut: "-"),
MenuItem(label: "Tables", shortcut: "="),
MenuItem(label: "Sliders", shortcut: "["),
MenuItem(label: "Steppers", shortcut: "]"),
MenuItem(label: "Split View", shortcut: ";"),
MenuItem(label: "Image (File)", shortcut: "'"),
MenuItem(label: "Image (URL)", shortcut: ","),
],
selection: $menuSelection,
onSelect: { index in
// Navigate to the selected page
if let page = DemoPage(rawValue: index + 1) {
currentPage = page
}
},
selectedColor: .palette.accent,
// borderStyle uses appearance default
borderColor: .palette.border
)
Spacer()
}
Spacer(minLength: 1)
// Feature highlights (centered)
HStack {
Spacer()
HStack(spacing: 3) {
FeatureBox("Pure Swift", "No ncurses").equatable()
FeatureBox("Declarative", "SwiftUI-like").equatable()
FeatureBox("Composable", "View protocol").equatable()
}
Spacer()
}
Spacer()
}
.appHeader {
VStack {
HStack {
Text("TUIkit Example App").bold().foregroundStyle(.palette.accent)
Spacer()
Text("TUIkit v\(tuiKitVersion)").foregroundStyle(.palette.foregroundTertiary)
}
Text("A SwiftUI-like framework for Terminal User Interfaces")
.foregroundStyle(.palette.foregroundSecondary)
.italic()
}
}
}
}