import Portico import Adw private struct ExamplePark: Hashable { let name: String } @main struct ExampleApp: App { var applicationId: String? { "dev.bscubed.PorticoExample" } @State private var count = 0 @State private var name = "Portico" @State private var darkMode = false @State private var convenienceBannerVisible = false @State private var selectedTheme = "Light" @State private var volume = 75.0 @State private var currentPage: UInt32 = 0 @WidgetRef private var pager: Adw.Carousel? @State private var parkPath: [ExamplePark] = [] @State private var uptime = 0 var body: some Scene { ApplicationWindow { _ in NavigationView(path: $parkPath) { VStack { HeaderBar() Carousel { introPage counterPage settingsPage AsyncDemoPage() EnvironmentDemoPage() BreakpointDemoPage() navigationDemoPage PresentationDemoPage() ClipboardDemoPage() conveniencePage } .onPageChanged { page in currentPage = page } .ref(_pager) CarouselIndicatorDots() .carousel($pager) .halign(.center) Label("Uptime: \(uptime)s, Page \(currentPage + 1) of 10") .dimmed() .halign(.center) .margin(8) .task(every: .seconds(1)) { uptime += 1 } } .navigationTitle("Portico Demo") .navigationDestination(for: ExamplePark.self) { park in VStack { HeaderBar() Label("Welcome to \(park.name)") .title1() .halign(.center) .margin(24) Label("This page was pushed programmatically via the path binding.") .dimmed() .halign(.center) } .hexpand(true) .vexpand(true) .navigationTitle(park.name) } } } .defaultSize(width: 1080, height: 720) } var introPage: some View { Clamp { StatusPage { VStack(spacing: 6) { Label("Declarative GTK apps in Swift") .title3() .marginTop(16) Label("A familiar SwiftUI-like API, zero GObject boilerplate") .marginBottom(16) } .card() } .title("Welcome to Portico") .description("Swipe to explore") .iconName("face-smile-symbolic") } .hexpand(true) .vexpand(true) } var counterPage: some View { Clamp { StatusPage { HStack(spacing: 12) { Button("-") { count -= 1 } .circular() Label("Count: \(count)") .title1() Button("+") { count += 1 } .circular() } .halign(.center) } .title("Reactive Counter") .description("@State + Binding drive targeted widget updates") .iconName("applications-engineering-symbolic") } .hexpand(true) .vexpand(true) } var settingsPage: some View { Clamp { StatusPage { VStack(spacing: 12) { Label("Name: \(name), Dark mode: \(darkMode), Volume: \(volume)") .title2() ListBox { EntryRow() .title("Your Name") .text($name) SwitchRow() .title("Dark Mode") .active($darkMode) SpinRow(min: 0, max: 100, step: 5) .title("Volume") .value($volume) } .boxedList() } } .title("Quick Settings") .description("Live GObject property bindings") .iconName("application-x-firmware-symbolic") } .hexpand(true) .vexpand(true) } var conveniencePage: some View { Clamp { VStack(spacing: 12) { Banner("Connection unavailable", revealed: $convenienceBannerVisible, buttonLabel: "Retry") PreferencesGroup("Convenience APIs", description: selectedTheme) { ActionRow("Mode", subtitle: "Select an option") SwitchRow("Show banner", active: $convenienceBannerVisible) ComboRow("Theme", items: ["Light", "Dark"]) { selectedTheme = $0 } ExpanderRow("Advanced", subtitle: "More controls") { ActionRow("First") ActionRow("Second") } ButtonRow("Reset", startIconName: "view-refresh") { convenienceBannerVisible = false selectedTheme = "Light" } } } } .hexpand(true) .vexpand(true) } var navigationDemoPage: some View { Clamp { StatusPage { ListBox { ButtonRow() .title("See Yosemite") .onActivated { parkPath.append(ExamplePark(name: "Yosemite")) } ButtonRow() .title("See Yellowstone") .onActivated { parkPath.append(ExamplePark(name: "Yellowstone")) } ButtonRow() .title("See Zion") .onActivated { parkPath.append(ExamplePark(name: "Zion")) } } .boxedList() } .title("Navigation") .description("Navigating is easy and reactive in Portico! Just bind an array to a NavigationView and it updates when changes are made in either direction!") } .valign(.center) .hexpand(true) .vexpand(true) } }