Skip to content
This repository has been archived by the owner on Oct 17, 2024. It is now read-only.

Commit

Permalink
Add docc documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
david-swift committed Mar 29, 2024
1 parent 409dfb6 commit e5783e9
Show file tree
Hide file tree
Showing 21 changed files with 697 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .spi.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
version: 1
external_links:
documentation: "https://david-swift.gitbook.io/adwaita"
builder:
configs:
- documentation_targets: [Adwaita]
3 changes: 2 additions & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,5 @@ type_contents_order:
- other_method

excluded:
- Sources/Adwaita/View/Generated/
- Sources/Adwaita/View/Generated/
- Sources/Adwaita/Adwaita.docc/
Binary file added Icons/Screenshot 2024-03-29 at 21.17.17.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions Sources/Adwaita/Adwaita.docc/Adwaita.md
Original file line number Diff line number Diff line change
@@ -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 changes: 156 additions & 0 deletions Sources/Adwaita/Adwaita.docc/CreatingViews.md
Original file line number Diff line number Diff line change
@@ -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 changes: 82 additions & 0 deletions Sources/Adwaita/Adwaita.docc/HelloWorld.tutorial
Original file line number Diff line number Diff line change
@@ -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.")
}
}
}

}
Loading

0 comments on commit e5783e9

Please sign in to comment.