diff --git a/Documentation/Reference/README.md b/Documentation/Reference/README.md index fa93be1..1626991 100644 --- a/Documentation/Reference/README.md +++ b/Documentation/Reference/README.md @@ -13,6 +13,7 @@ ## Structs +- [AboutWindow](structs/AboutWindow.md) - [AppearObserver](structs/AppearObserver.md) - [Binding](structs/Binding.md) - [Button](structs/Button.md) diff --git a/Documentation/Reference/structs/AboutWindow.md b/Documentation/Reference/structs/AboutWindow.md new file mode 100644 index 0000000..bd5d39f --- /dev/null +++ b/Documentation/Reference/structs/AboutWindow.md @@ -0,0 +1,88 @@ +**STRUCT** + +# `AboutWindow` + +A structure representing an about window. + +## Properties +### `id` + +The window's identifier. + +### `open` + +Whether an instance of the window type should be opened when the app is starting up. + +### `parentID` + +The identifier of the window's parent. + +### `appShortcuts` + +The keyboard shortcuts on the app level. + +### `appName` + +The app's name. + +### `developer` + +The developer's name. + +### `version` + +The app version. + +### `icon` + +The app icon. + +### `website` + +The app's website. + +## Methods +### `init(id:appName:developer:version:)` + +Create a window type with a certain identifier and content. +- Parameters: + - id: The identifier. + - appName: The app's name. + - developer: The developer's name. + - version: The app version. + +### `icon(_:)` + +Set the app icon. +- Parameter icon: The app icon. +- Returns: The window. + +### `website(_:)` + +Set the app's website. +- Parameter url: The app's website. +- Returns: The window. + +### `createWindow(app:)` + +Get the storage for the window. +- Parameter app: The application. +- Returns: The storage. + +### `createGTUIWindow(app:)` + +Get the window. +- Parameter app: The application. +- Returns: The window. + +### `update(_:app:)` + +Update a window. +- Parameters: + - storage: The storage to update. + - app: The application. + +### `updateData(window:)` + +Update the data for a window. +- Parameter window: The window. diff --git a/Sources/Adwaita/Model/User Interface/Window/WindowStorage.swift b/Sources/Adwaita/Model/User Interface/Window/WindowStorage.swift index caf2c90..548bd5b 100644 --- a/Sources/Adwaita/Model/User Interface/Window/WindowStorage.swift +++ b/Sources/Adwaita/Model/User Interface/Window/WindowStorage.swift @@ -19,7 +19,7 @@ public class WindowStorage { /// The GTUI window. public var window: GTUIWindow /// The content's storage. - public var view: ViewStorage + public var view: ViewStorage? /// The file dialog for the window. public var fileDialog: FileDialog @@ -28,7 +28,7 @@ public class WindowStorage { /// - id: The window's identifier. /// - window: The GTUI window. /// - view: The content's storage. - public init(id: String, window: GTUIWindow, view: ViewStorage) { + public init(id: String, window: GTUIWindow, view: ViewStorage?) { self.id = id self.window = window self.view = view diff --git a/Sources/Adwaita/Window/AboutWindow.swift b/Sources/Adwaita/Window/AboutWindow.swift new file mode 100644 index 0000000..3ce0243 --- /dev/null +++ b/Sources/Adwaita/Window/AboutWindow.swift @@ -0,0 +1,101 @@ +// +// AboutWindow.swift +// Adwaita +// +// Created by david-swift on 05.12.23. +// + +import Foundation +import Libadwaita + +/// A structure representing an about window. +public struct AboutWindow: WindowScene { + + /// The window's identifier. + public var id: String + /// Whether an instance of the window type should be opened when the app is starting up. + public let `open` = 0 + /// The identifier of the window's parent. + public var parentID: String? + /// The keyboard shortcuts on the app level. + public var appShortcuts: [String: (GTUIApp) -> Void] = [:] + /// The app's name. + var appName: String + /// The developer's name. + var developer: String + /// The app version. + var version: String + /// The app icon. + var icon: Icon? + /// The app's website. + var website: URL? + + /// Create a window type with a certain identifier and content. + /// - Parameters: + /// - id: The identifier. + /// - appName: The app's name. + /// - developer: The developer's name. + /// - version: The app version. + public init(id: String, appName: String, developer: String, version: String) { + self.id = id + self.appName = appName + self.developer = developer + self.version = version + } + + /// Set the app icon. + /// - Parameter icon: The app icon. + /// - Returns: The window. + public func icon(_ icon: Icon) -> Self { + var newSelf = self + newSelf.icon = icon + return newSelf + } + + /// Set the app's website. + /// - Parameter url: The app's website. + /// - Returns: The window. + public func website(_ url: URL?) -> Self { + var newSelf = self + newSelf.website = url + return newSelf + } + + /// Get the storage for the window. + /// - Parameter app: The application. + /// - Returns: The storage. + public func createWindow(app: GTUIApp) -> WindowStorage { + let window = createGTUIWindow(app: app) + let windowStorage = WindowStorage(id: id, window: window, view: nil) + windowStorage.parentID = parentID + return windowStorage + } + + /// Get the window. + /// - Parameter app: The application. + /// - Returns: The window. + func createGTUIWindow(app: GTUIApp) -> Libadwaita.AboutWindow { + let window = Libadwaita.AboutWindow() + updateAppShortcuts(app: app) + updateData(window: window) + window.show() + return window + } + + /// Update a window. + /// - Parameters: + /// - storage: The storage to update. + /// - app: The application. + public func update(_ storage: WindowStorage, app: GTUIApp) { + updateAppShortcuts(app: app) + storage.destroy = true + } + + /// Update the data for a window. + /// - Parameter window: The window. + func updateData(window: Libadwaita.AboutWindow) { + _ = window.generalData(title: appName, icon: icon ?? .custom(name: ""), developer: developer, version: version) + if let website { _ = window.website(url: website.absoluteString) } + } + +} diff --git a/Sources/Adwaita/Window/Window.swift b/Sources/Adwaita/Window/Window.swift index 9a3b0ab..5e0b45c 100644 --- a/Sources/Adwaita/Window/Window.swift +++ b/Sources/Adwaita/Window/Window.swift @@ -103,7 +103,9 @@ public struct Window: WindowScene { public func update(_ storage: WindowStorage, app: GTUIApp) { if let window = storage.window as? GTUIApplicationWindow { let content = content(window) - content.widget(modifiers: []).updateStorage(storage.view, modifiers: []) + if let view = storage.view { + content.widget(modifiers: []).updateStorage(view, modifiers: []) + } updateShortcuts(window: window) updateAppShortcuts(app: app) } diff --git a/Tests/Demo.swift b/Tests/Demo.swift index 8346fab..20c841e 100644 --- a/Tests/Demo.swift +++ b/Tests/Demo.swift @@ -21,6 +21,9 @@ struct Demo: App { DemoContent(window: window, app: app) } .overlay { + AboutWindow(id: "about", appName: "Demo", developer: "david-swift", version: "Test") + .icon(.default(icon: .emojiNature)) + .website(.init(string: "david-swift.gitbook.io/adwaita")) Window(id: "overlay", open: 0) { window in OverlayWindowDemo.WindowContent(window: window) } @@ -73,10 +76,9 @@ struct Demo: App { } .keyboardShortcut("w".ctrl()) MenuSection { - MenuButton("Quit", window: false) { - app.quit() - } - .keyboardShortcut("q".ctrl()) + MenuButton("About", window: false) { app.showWindow("about") } + MenuButton("Quit", window: false) { app.quit() } + .keyboardShortcut("q".ctrl()) } } } diff --git a/user-manual/Information/Widgets.md b/user-manual/Information/Widgets.md index 31d19e8..762ecde 100644 --- a/user-manual/Information/Widgets.md +++ b/user-manual/Information/Widgets.md @@ -61,6 +61,7 @@ This is an overview of the available widgets and other components in _Adwaita_. | Name | Description | Widget | | -------------------- | ----------------------------------------------------------------- | ---------------------- | | Window | A simple application window. | AdwApplicationWindow | +| AboutWindow | A GNOME about window. | AdwAboutWindow | ### Window Modifiers | Syntax | Description | @@ -69,11 +70,19 @@ This is an overview of the available widgets and other components in _Adwaita_. | `quitShortcut()` | Create a keyboard shortcut for quitting the application with "Ctrl + q". | ### `Window` Modifiers -| Syntax | Description | -| ------------------------------- | --------------------------------------------------------------------------------------- | -| `keyboardShortcut(_:action:)` | Create a keyboard shortcut available in one window. | -| `closeShortcut()` | Create a keyboard shortcut for closing the window with "Ctrl + w". | -| `overlay(windows:)` | Add windows that attach to a window of this type when being presented. | +| Syntax | Description | +| ------------------------------------------------------------------ | --------------------------------------------------------------------------------------- | +| `keyboardShortcut(_:action:)` | Create a keyboard shortcut available in one window. | +| `closeShortcut()` | Create a keyboard shortcut for closing the window with "Ctrl + w". | +| `overlay(windows:)` | Add windows that attach to a window of this type when being presented. | +| `fileImporter(_:initialFolder:extensions:folders:onOpen:onClose:)` | Add an import file dialog. | +| `fileExporter(_:initialFolder:initialName:onSave:onClose:)` | Add an export file dialog. | + +### `AboutWindow` Modifiers +| Syntax | Description | +| --------------- | --------------------------------------------------------------------------------------- | +| `icon(_:)` | Set the app icon. | +| `website(_:)` | Set the app's website | ### Menu Widgets | Name | Description | Widget |