Add docc documentation
5
.spi.yml
@ -1,3 +1,4 @@
|
||||
version: 1
|
||||
external_links:
|
||||
documentation: "https://david-swift.gitbook.io/adwaita"
|
||||
builder:
|
||||
configs:
|
||||
- documentation_targets: [Adwaita]
|
||||
|
@ -162,4 +162,5 @@ type_contents_order:
|
||||
- other_method
|
||||
|
||||
excluded:
|
||||
- Sources/Adwaita/View/Generated/
|
||||
- Sources/Adwaita/View/Generated/
|
||||
- Sources/Adwaita/Adwaita.docc/
|
||||
|
BIN
Icons/Screenshot 2024-03-29 at 21.17.17.png
Normal file
After Width: | Height: | Size: 411 KiB |
83
Sources/Adwaita/Adwaita.docc/Adwaita.md
Normal file
@ -0,0 +1,83 @@
|
||||
# ``Adwaita``
|
||||
|
||||
_Adwaita for Swift_ is a framework for creating user interfaces for GNOME with an API similar to SwiftUI.
|
||||
|
||||
## Overview
|
||||
|
||||
Write user interfaces in a declarative way.
|
||||
|
||||
As an example, the following code defines a _view_ (more information: ``View``).
|
||||
|
||||
```swift
|
||||
struct Counter: View {
|
||||
|
||||
@State private var count = 0
|
||||
|
||||
var view: Body {
|
||||
HStack {
|
||||
Button(icon: .default(icon: .goPrevious)) {
|
||||
count -= 1
|
||||
}
|
||||
Text("\(count)")
|
||||
.style("title-1")
|
||||
.frame(minWidth: 100)
|
||||
Button(icon: .default(icon: .goNext)) {
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
A view can be implemented in different ways, the following screenshot showing an example.
|
||||
|
||||
![Screenshot of the counter app](Counter.png)
|
||||
|
||||
## Goals
|
||||
|
||||
_Adwaita for Swift_'s main goal is to provide an easy-to-use interface for creating apps for the GNOME ecosystem.
|
||||
An article about the project's motivation is available on the [website of the Swift programming language](https://www.swift.org/blog/adwaita-swift/).
|
||||
|
||||
## Installation
|
||||
|
||||
### Dependencies
|
||||
|
||||
#### Flatpak
|
||||
|
||||
It is recommended to develop apps inside of a Flatpak.
|
||||
That way, you don't have to install Swift or any of the dependencies on your system, and you always have access to the latest versions.
|
||||
Take a look at the [template repository](https://github.com/AparokshaUI/AdwaitaTemplate).
|
||||
This works on Linux only.
|
||||
|
||||
#### Directly on system
|
||||
|
||||
You can also run your apps directly on the system.
|
||||
|
||||
If you are using a Linux distribution, install `libadwaita-devel` or `libadwaita` (or something similar, based on the package manager) as well as `gtk4-devel`, `gtk4` or similar.
|
||||
|
||||
On macOS, follow these steps:
|
||||
1. Install [Homebrew](https://brew.sh).
|
||||
2. Install Libadwaita (and thereby GTK 4):
|
||||
```
|
||||
brew install libadwaita
|
||||
```
|
||||
|
||||
### Swift package
|
||||
1. Open your Swift package in GNOME Builder, Xcode, or any other IDE.
|
||||
2. Open the `Package.swift` file.
|
||||
3. Into the `Package` initializer, under `dependencies`, paste:
|
||||
```swift
|
||||
.package(url: "https://github.com/AparokshaUI/Adwaita", from: "0.1.0")
|
||||
```
|
||||
|
||||
## Template repository
|
||||
|
||||
It is recommended to develop apps on Linux inside a Flatpak.
|
||||
Find more information in the [template repository](https://github.com/AparokshaUI/AdwaitaTemplate).
|
||||
|
||||
## Topics
|
||||
|
||||
### Tutorials
|
||||
|
||||
- <doc:Table-of-Contents>
|
156
Sources/Adwaita/Adwaita.docc/CreatingViews.md
Normal file
@ -0,0 +1,156 @@
|
||||
# Creating views
|
||||
|
||||
Views are the building blocks of your application.
|
||||
A view can be as simple as the ``Text`` widget, or as complex as the whole content of a single window.
|
||||
|
||||
## Add views to a window
|
||||
You can add views to a window:
|
||||
```swift
|
||||
import Adwaita
|
||||
|
||||
@main
|
||||
struct HelloWorld: App {
|
||||
|
||||
let id = "io.github.david_swift.HelloWorld"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
Window(id: "content") { _ in
|
||||
// These are the views:
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the widgets ``HeaderBar`` and ``Text`` are used.
|
||||
`padding` is a view modifier, a function that modifies a view, which adds some padding around the text.
|
||||
|
||||
## Create custom views
|
||||
While directly adding widgets into the `Window`'s body might work for very simple apps,
|
||||
it can get messy very quickly.
|
||||
Create custom views by declaring types that conform to the ``View`` protocol:
|
||||
```swift
|
||||
// A custom view named "ContentView":
|
||||
struct ContentView: View {
|
||||
|
||||
var view: Body {
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Properties
|
||||
As every structure in Swift, custom views can have properties:
|
||||
```swift
|
||||
struct HelloView: View {
|
||||
|
||||
// The property "text":
|
||||
var text: String
|
||||
var view: Body {
|
||||
Text("Hello, \(text)!")
|
||||
.padding()
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
This view can be called via `HelloView(text: "world")` in another view.
|
||||
|
||||
## State
|
||||
Whenever you want to modify a property that is stored in the view's structure from within your view,
|
||||
wrap the property with the ``State`` property wrapper:
|
||||
```swift
|
||||
struct MyView: View {
|
||||
|
||||
// This property can be modified form within the view:
|
||||
@State private var text = "world"
|
||||
var view: Body {
|
||||
Text("Hello, \(text)!")
|
||||
.padding()
|
||||
Button("Change Text") {
|
||||
text = Bool.random() ? "world" : "John"
|
||||
}
|
||||
.padding(10, .horizontal.add(.bottom))
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
In this example, the text property is set whenever you press the "Change Text" button.
|
||||
|
||||
## Change the state in child views
|
||||
You can access state properties in child views in the same way as you would access any other property
|
||||
if the child view cannot modify the state (`HelloView` is defined above):
|
||||
```swift
|
||||
struct MyView: View {
|
||||
|
||||
@State private var text = "world"
|
||||
var view: Body {
|
||||
// "HelloView" can read the "text" property:
|
||||
HelloView(text: text)
|
||||
Button("Change Text") {
|
||||
text = Bool.random() ? "world" : "John"
|
||||
}
|
||||
.padding(10, .horizontal.add(.bottom))
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
If the child view should be able to modify the state, use the ``Binding`` property wrapper in the child view
|
||||
and pass the property with a dollar sign (`$`) to that view.
|
||||
```swift
|
||||
struct MyView: View {
|
||||
|
||||
@State private var text = "world"
|
||||
var view: Body {
|
||||
HelloView(text: text)
|
||||
// Pass the editable text property to the child view:
|
||||
ChangeTextView(text: $text)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct ChangeTextView: View {
|
||||
|
||||
// Accept the editable text property:
|
||||
@Binding var text: String
|
||||
var view: Body {
|
||||
Button("Change Text") {
|
||||
// Binding properties can be used the same way as state properties:
|
||||
text = Bool.random() ? "world" : "John"
|
||||
}
|
||||
.padding(10, .horizontal.add(.bottom))
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
If you have a more complex type and want to pass a property of the type as a binding,
|
||||
you can simply access the property on the binding.
|
||||
|
||||
```swift
|
||||
HelloView(text: $complexType.text)
|
||||
```
|
||||
|
||||
Whenever you modify a state property (directly or indirectly through bindings),
|
||||
the user interface gets automatically updated to reflect that change.
|
||||
|
||||
## Save state values between app launches
|
||||
It's possible to automatically save a value that conforms to `Codable` whenever it changes to a file.
|
||||
The value in the file is read when the view containing the state value appears for the first time (e.g. when the user launches the app).
|
||||
|
||||
Use the following syntax, where `"text"` is a unique identifier.
|
||||
```swift
|
||||
@State("text") private var text = "world"
|
||||
```
|
||||
|
||||
You can organize your content by specifying a custom folder path which will be appended to the XDG data home directory.
|
||||
```swift
|
||||
@State("text", folder: "io.github.david_swift.HelloWorld/my-view") private var text = "world"
|
||||
```
|
82
Sources/Adwaita/Adwaita.docc/HelloWorld.tutorial
Normal file
@ -0,0 +1,82 @@
|
||||
@Tutorial {
|
||||
|
||||
@Intro(title: "The template") {
|
||||
This is a beginner tutorial. It shows how to create a simple "Hello, world!" app using ``Adwaita``.
|
||||
While there are instructions for building on macOS, _Adwaita for Swift_ works best on Linux.
|
||||
}
|
||||
|
||||
@Section(title: "Installation") {
|
||||
@ContentAndMedia {
|
||||
Learn how to set up your Linux system or your Mac.
|
||||
}
|
||||
@Steps {
|
||||
@Step {
|
||||
**If you are on Linux,** install the [GNOME Builder IDE](https://flathub.org/apps/org.gnome.Builder).
|
||||
@Image(source: "Builder.png", alt: "GNOME Builder in the GNOME Software app store.")
|
||||
}
|
||||
@Step {
|
||||
**If you are on macOS,** install [Xcode](https://developer.apple.com/xcode/).
|
||||
Open your terminal client and follow the [installation instructions for Homebrew](https://brew.sh).
|
||||
Then, run `brew install libadwaita`.
|
||||
@Image(source: "InstallLibadwaita.png", alt: "The macOS Terminal application.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Section(title: "Clone the template repository") {
|
||||
@ContentAndMedia {
|
||||
The template repository provides a simple, working app that can be used as a starting point for your own app.
|
||||
In this section, you'll create a simple "Hello, world!" app and run the app.
|
||||
}
|
||||
@Steps {
|
||||
@Step {
|
||||
Open your terminal client and navigate to a directory you want to create the package in (e.g. `~/Documents/`).
|
||||
@Image(source: "ChangeDirectory.png", alt: "The GNOME Console app.")
|
||||
}
|
||||
@Step {
|
||||
Clone the template repository into the `HelloWorld` directory using `git clone https://github.com/AparokshaUI/AdwaitaTemplate HelloWorld`.
|
||||
|
||||
This creates a directory `HelloWorld` containing the content of the [Adwaita Template](https://github.com/AparokshaUI/AdwaitaTemplate).
|
||||
@Image(source: "GitClone.png", alt: "The GNOME Console app.")
|
||||
}
|
||||
@Step {
|
||||
**If you are on Linux,** use the `Select a Folder...` button in the welcome window of GNOME Builder to open the `HelloWorld` directory.
|
||||
|
||||
It will start to install the dependencies automatically.
|
||||
@Image(source: "OpenFolder.png", alt: "GNOME Builder's welcome view.")
|
||||
}
|
||||
@Step {
|
||||
**If you are on macOS,** use the `Open Existing Project...` button in the welcome window of Xcode to open the `HelloWorld` directory.
|
||||
@Image(source: "OpenXcode.png", alt: "Xcode's welcome view.")
|
||||
}
|
||||
@Step {
|
||||
Select the `Package.swift` file in the sidebar.
|
||||
|
||||
This file defines that this Swift _package_ contains an executable, and lists the dependencies required by the executable.
|
||||
One can see that the Swift files that are part of the executable are located in the `Sources` folder.
|
||||
@Code(name: "Package.swift", file: "Package.swift")
|
||||
}
|
||||
@Step {
|
||||
Open the `io.github.AparokshaUI.AdwaitaTemplate.json` file.
|
||||
|
||||
This file is relevant for Linux only.
|
||||
It informs the GNOME Builder about the required dependencies of your app, and how to build and install your app.
|
||||
It is called a [Flatpak manifest](https://docs.flatpak.org/en/latest/manifests.html).
|
||||
@Code(name: "io.github.AparokshaUI.AdwaitaTemplate.json", file: "io.github.AparokshaUI.AdwaitaTemplate.json")
|
||||
}
|
||||
@Step {
|
||||
The `Sources` folder contains the actual Swift code of your app.
|
||||
Open the `AdwaitaTemplate.swift` file to see the definition of an app and its user interface.
|
||||
@Code(name: "AdwaitaTemplate.swift", file: "AdwaitaTemplate.swift")
|
||||
}
|
||||
@Step {
|
||||
Run the app using the play button in Xcode or GNOME Builder.
|
||||
A window should open.
|
||||
|
||||
On macOS, the window will look slightly different from the one in the screenshot. Note that libadwaita is built for Linux and therefore works best on Linux.
|
||||
@Image(source: "AdwaitaTemplate.png", alt: "The result.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
115
Sources/Adwaita/Adwaita.docc/KeyboardShortcuts.md
Normal file
@ -0,0 +1,115 @@
|
||||
# Keyboard shortcuts
|
||||
|
||||
Keyboard shortcuts can be attached to individual windows or whole applications.
|
||||
|
||||
## About keyboard shortcuts
|
||||
Keyboard shortcuts are represented as a `String`.
|
||||
You can add a single character by adding itself to the string, e.g. `"n"`.
|
||||
The F keys are written as `"F1"`, `"F2"`, etc.
|
||||
For character keys, write the lowercase name instead of the symbol, such as `"minus"` instead of `"-"`.
|
||||
|
||||
Add modifiers to the shortcut using the following string modifiers:
|
||||
- `.shift()`
|
||||
- `.ctrl()`
|
||||
- `.alt()`
|
||||
- `.meta()`
|
||||
- `.super()`
|
||||
- `.hyper()`
|
||||
|
||||
As an example, the following syntax represents the `Ctrl + N` shortcut: `"n".ctrl()`.
|
||||
|
||||
## Add shortcuts to a window
|
||||
Add a keyboard shortcut to an invividual window. It is only available in that window.
|
||||
```swift
|
||||
import Adwaita
|
||||
|
||||
@main
|
||||
struct HelloWorld: App {
|
||||
|
||||
let id = "io.github.david_swift.HelloWorld"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
Window(id: "content") { _ in
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
// Add the shortcut "Ctrl + W" for closing the window
|
||||
.keyboardShortcut("w".ctrl()) { window in
|
||||
window.close()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Add shortcuts to an app
|
||||
Add a keyboard to an app so that the shortcut is available in every top-level window.
|
||||
```swift
|
||||
import Adwaita
|
||||
|
||||
@main
|
||||
struct HelloWorld: App {
|
||||
|
||||
let id = "io.github.david_swift.HelloWorld"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
Window(id: "content") { _ in
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
// Add the shortcut "Ctrl + Q" for terminating the app
|
||||
.appKeyboardShortcut("q".ctrl()) { app in
|
||||
app.quit()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Create shortcuts from a menu
|
||||
The most elegant way for adding keyboard shortcuts is in many cases adding them via menus.
|
||||
Here is an example using a menu button:
|
||||
```swift
|
||||
struct TestView: View {
|
||||
|
||||
var app: GTUIApp
|
||||
|
||||
var view: Body {
|
||||
Menu(icon: .default(icon: .openMenu), app: app) {
|
||||
MenuButton("New Window", window: false) {
|
||||
app.addWindow("main")
|
||||
}
|
||||
// Add a keyboard shortcut to the app.
|
||||
.keyboardShortcut("n".ctrl())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
Add the keyboard shortcut to a single window by specifying the `window` parameter in the initializer of `Menu`,
|
||||
and removing `window: false` in the initializer of `MenuButton`.
|
||||
|
||||
## Create shortcuts from a button
|
||||
It's possible to easily create a keyboard shortcut from a button.
|
||||
Use `appKeyboardShortcut` instead of `keyboardShortcut` for shortcuts on an application level.
|
||||
Note that the shortcut gets activated after presenting the view for the first time.
|
||||
```swift
|
||||
struct HelloView: View {
|
||||
|
||||
var window: GTUIWindow
|
||||
|
||||
var view: Body {
|
||||
Button("New Item") {
|
||||
print("New Item")
|
||||
}
|
||||
// Add a keyboard shortcut to the window "window".
|
||||
.keyboardShortcut("n".ctrl().shift(), window: window)
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
BIN
Sources/Adwaita/Adwaita.docc/Resources/AdwaitaIcon.png
Normal file
After Width: | Height: | Size: 169 KiB |
23
Sources/Adwaita/Adwaita.docc/Resources/AdwaitaTemplate.swift
Normal file
@ -0,0 +1,23 @@
|
||||
// The Swift Programming Language
|
||||
// https://docs.swift.org/swift-book
|
||||
|
||||
import Adwaita
|
||||
|
||||
@main
|
||||
struct AdwaitaTemplate: App {
|
||||
|
||||
let id = "io.github.AparokshaUI.AdwaitaTemplate"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
Window(id: "main") { window in
|
||||
Text(Loc.helloWorld)
|
||||
.padding()
|
||||
.topToolbar {
|
||||
ToolbarView(app: app, window: window)
|
||||
}
|
||||
}
|
||||
.defaultSize(width: 450, height: 300)
|
||||
}
|
||||
|
||||
}
|
BIN
Sources/Adwaita/Adwaita.docc/Resources/Counter.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 10 KiB |
BIN
Sources/Adwaita/Adwaita.docc/Resources/HelloWorld/Builder.png
Normal file
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 21 KiB |
BIN
Sources/Adwaita/Adwaita.docc/Resources/HelloWorld/GitClone.png
Normal file
After Width: | Height: | Size: 53 KiB |
After Width: | Height: | Size: 240 KiB |
BIN
Sources/Adwaita/Adwaita.docc/Resources/HelloWorld/OpenFolder.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
Sources/Adwaita/Adwaita.docc/Resources/HelloWorld/OpenXcode.png
Normal file
After Width: | Height: | Size: 411 KiB |
@ -0,0 +1,31 @@
|
||||
// swift-tools-version: 5.8
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Adwaita Template",
|
||||
platforms: [
|
||||
.macOS(.v13)
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/AparokshaUI/Adwaita", from: "0.2.0"),
|
||||
.package(url: "https://github.com/AparokshaUI/Localized", from: "0.2.0")
|
||||
],
|
||||
targets: [
|
||||
.executableTarget(
|
||||
name: "AdwaitaTemplate",
|
||||
dependencies: [
|
||||
.product(name: "Adwaita", package: "Adwaita"),
|
||||
.product(name: "Localized", package: "Localized")
|
||||
],
|
||||
path: "Sources",
|
||||
resources: [
|
||||
.process("Localized.yml")
|
||||
],
|
||||
plugins: [
|
||||
.plugin(name: "GenerateLocalized", package: "Localized")
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
@ -0,0 +1,52 @@
|
||||
{
|
||||
"app-id": "io.github.AparokshaUI.AdwaitaTemplate",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "46",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"sdk-extensions": [
|
||||
"org.freedesktop.Sdk.Extension.swift5"
|
||||
],
|
||||
"command": "AdwaitaTemplate",
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--device=dri",
|
||||
"--socket=wayland"
|
||||
],
|
||||
"build-options": {
|
||||
"append-path": "/usr/lib/sdk/swift5/bin",
|
||||
"prepend-ld-library-path": "/usr/lib/sdk/swift5/lib"
|
||||
},
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig",
|
||||
"/man",
|
||||
"/share/doc",
|
||||
"/share/gtk-doc",
|
||||
"/share/man",
|
||||
"/share/pkgconfig",
|
||||
"*.la",
|
||||
"*.a"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "AdwaitaTemplate",
|
||||
"builddir": true,
|
||||
"buildsystem": "simple",
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"build-commands": [
|
||||
"swift build -c release --static-swift-stdlib",
|
||||
"install -Dm755 .build/release/AdwaitaTemplate /app/bin/AdwaitaTemplate",
|
||||
"install -Dm644 data/io.github.AparokshaUI.AdwaitaTemplate.metainfo.xml $DESTDIR/app/share/metainfo/io.github.AparokshaUI.AdwaitaTemplate.metainfo.xml",
|
||||
"install -Dm644 data/io.github.AparokshaUI.AdwaitaTemplate.desktop $DESTDIR/app/share/applications/io.github.AparokshaUI.AdwaitaTemplate.desktop",
|
||||
"install -Dm644 data/icons/io.github.AparokshaUI.AdwaitaTemplate.svg $DESTDIR/app/share/icons/hicolor/scalable/apps/io.github.AparokshaUI.AdwaitaTemplate.svg",
|
||||
"install -Dm644 data/icons/io.github.AparokshaUI.AdwaitaTemplate-symbolic.svg $DESTDIR/app/share/icons/hicolor/symbolic/apps/io.github.AparokshaUI.AdwaitaTemplate-symbolic.svg"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
13
Sources/Adwaita/Adwaita.docc/Table of Contents.tutorial
Normal file
@ -0,0 +1,13 @@
|
||||
@Tutorials(name: "Develop Apps for GNOME") {
|
||||
|
||||
@Intro(title: "Develop Apps for GNOME") {
|
||||
Learn the basics of _Adwaita for Swift_ to create beautiful apps for the GNOME desktop.
|
||||
}
|
||||
|
||||
@Chapter(name: "Adwaita for Swift essentials") {
|
||||
Get to know the most important principles of the _Adwaita for Swift_ framework.
|
||||
@TutorialReference(tutorial: "doc:HelloWorld")
|
||||
@Image(source: "AdwaitaIcon.png", alt: "The Adwaita for Swift icon.")
|
||||
}
|
||||
|
||||
}
|
137
Sources/Adwaita/Adwaita.docc/Windows.md
Normal file
@ -0,0 +1,137 @@
|
||||
# Windows
|
||||
|
||||
Windows in _Adwaita_ are not actually single windows in the user interface,
|
||||
but rather instructions on how to create one type of window.
|
||||
|
||||
## The simplest case
|
||||
A single window app is an app having exactly one window, and when this window is closed, the app terminates.
|
||||
We can add multiple windows to an app as well.
|
||||
Whenever the last one disappears, the app terminates.
|
||||
```swift
|
||||
@main
|
||||
struct HelloWorld: App {
|
||||
|
||||
let id = "io.github.david_swift.HelloWorld"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
Window(id: "content") { _ in
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
// Add a second window:
|
||||
Window(id: "window-2") { _ in
|
||||
HeaderBar.empty()
|
||||
Text("Window 2")
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Showing windows
|
||||
Every app contains the property `app`.
|
||||
You can use this property for running functions that affect the whole app, e.g. quitting the app.
|
||||
Another use case is showing a window:
|
||||
```swift
|
||||
@main
|
||||
struct HelloWorld: App {
|
||||
|
||||
let id = "io.github.david_swift.HelloWorld"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
Window(id: "content") { _ in
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
Window(id: "control") { _ in
|
||||
HeaderBar.empty()
|
||||
Button("Show Window") {
|
||||
// Show the window with the identifier "content":
|
||||
app.showWindow("content")
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
"Showing" a window means creating an instance of the window type if there isn't one,
|
||||
or focusing the window that already exists of that type otherwise.
|
||||
It should be used for opening windows that cannot be presented more than once
|
||||
and for moving a window that is already open into the foreground.
|
||||
|
||||
## Adding windows
|
||||
You can call the `addWindow(_:parent:)` function instead of `showWindow(_:)`
|
||||
if you want to add and focus another instance of a window type:
|
||||
```swift
|
||||
@main
|
||||
struct HelloWorld: App {
|
||||
|
||||
let id = "io.github.david_swift.HelloWorld"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
Window(id: "content") { _ in
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
Window(id: "control") { _ in
|
||||
HeaderBar.empty()
|
||||
Button("Add Window") {
|
||||
// Add a new instance of the "content" window type
|
||||
app.addWindow("content")
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
It can be used to add an overlay window to a certain instance of a window type
|
||||
by specifying the `parent` parameter, e.g. in the example above:
|
||||
```swift
|
||||
Window(id: "control") { window in
|
||||
HeaderBar.empty()
|
||||
Button("Add Child Window") {
|
||||
// Add the new instance as a child window of this window
|
||||
app.addWindow("content", parent: window)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
```
|
||||
|
||||
## Customizing the initial number of windows
|
||||
By default, every window type of the app's scene appears once when the app starts.
|
||||
It's possible to customize how many windows are being presented at the app's startup:
|
||||
```swift
|
||||
@main
|
||||
struct HelloWorld: App {
|
||||
|
||||
let id = "io.github.david_swift.HelloWorld"
|
||||
var app: GTUIApp!
|
||||
|
||||
var scene: Scene {
|
||||
// Open no window of the "content" type
|
||||
Window(id: "content", open: 0) { _ in
|
||||
HeaderBar.empty()
|
||||
Text("Hello, world!")
|
||||
.padding()
|
||||
}
|
||||
// Open two windows of the "control" type
|
||||
Window(id: "control", open: 2) { _ in
|
||||
HeaderBar.empty()
|
||||
Button("Show Window") {
|
||||
app.addWindow("content")
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|