forked from aparoksha/adwaita-swift
Update demo and fix bugs
- Fix build optional in ViewBuilder - Fix maximum size frame modifier - Improve inspector wrapper - Improve header bar - Improve status page - Improve the naming of some elements
This commit is contained in:
parent
22c10d6ff3
commit
921f025e39
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
- [Binding](structs/Binding.md)
|
- [Binding](structs/Binding.md)
|
||||||
- [Button](structs/Button.md)
|
- [Button](structs/Button.md)
|
||||||
|
- [Clamp](structs/Clamp.md)
|
||||||
- [EitherView](structs/EitherView.md)
|
- [EitherView](structs/EitherView.md)
|
||||||
- [HStack](structs/HStack.md)
|
- [HStack](structs/HStack.md)
|
||||||
- [HeaderBar](structs/HeaderBar.md)
|
- [HeaderBar](structs/HeaderBar.md)
|
||||||
@ -57,6 +58,7 @@
|
|||||||
## Typealiases
|
## Typealiases
|
||||||
|
|
||||||
- [Body](typealiases/Body.md)
|
- [Body](typealiases/Body.md)
|
||||||
|
- [GTUIWindow](typealiases/GTUIWindow.md)
|
||||||
- [Scene](typealiases/Scene.md)
|
- [Scene](typealiases/Scene.md)
|
||||||
- [SceneBuilder](typealiases/SceneBuilder.md)
|
- [SceneBuilder](typealiases/SceneBuilder.md)
|
||||||
|
|
||||||
|
|||||||
@ -18,9 +18,15 @@ Update a storage to a view.
|
|||||||
Get a storage.
|
Get a storage.
|
||||||
- Returns: The storage.
|
- Returns: The storage.
|
||||||
|
|
||||||
|
### `frame(maxSize:)`
|
||||||
|
|
||||||
|
Set the view's maximal size.
|
||||||
|
- Parameter maxSize: The maximal size.
|
||||||
|
- Returns: A view.
|
||||||
|
|
||||||
### `inspect(_:)`
|
### `inspect(_:)`
|
||||||
|
|
||||||
Modify a GTUI widget before being displayed.
|
Modify a GTUI widget before being displayed and when being updated.
|
||||||
- Parameter modify: Modify the widget.
|
- Parameter modify: Modify the widget.
|
||||||
- Returns: A view.
|
- Returns: A view.
|
||||||
|
|
||||||
@ -64,12 +70,6 @@ Set the view's minimal width or height.
|
|||||||
- minHeight: The minimal height.
|
- minHeight: The minimal height.
|
||||||
- Returns: A view.
|
- Returns: A view.
|
||||||
|
|
||||||
### `frame(maxSize:)`
|
|
||||||
|
|
||||||
Set the view's maximal size.
|
|
||||||
- Parameter maxSize: The maximal size.
|
|
||||||
- Returns: A view.
|
|
||||||
|
|
||||||
### `transition(_:)`
|
### `transition(_:)`
|
||||||
|
|
||||||
Set the view's transition.
|
Set the view's transition.
|
||||||
|
|||||||
@ -3,6 +3,6 @@
|
|||||||
# `WindowScene`
|
# `WindowScene`
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
### `body`
|
### `scene`
|
||||||
|
|
||||||
The window scene's body is itself.
|
The window scene's body is itself.
|
||||||
|
|||||||
@ -5,6 +5,6 @@
|
|||||||
A structure conforming to `WindowScene` can be added to an app's `scene`.
|
A structure conforming to `WindowScene` can be added to an app's `scene`.
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
### `body`
|
### `scene`
|
||||||
|
|
||||||
The group's content.
|
The group's content.
|
||||||
|
|||||||
25
Documentation/Reference/structs/Clamp.md
Normal file
25
Documentation/Reference/structs/Clamp.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
**STRUCT**
|
||||||
|
|
||||||
|
# `Clamp`
|
||||||
|
|
||||||
|
A horizontal AdwClamp equivalent.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
### `content`
|
||||||
|
|
||||||
|
The content.
|
||||||
|
|
||||||
|
### `maxSize`
|
||||||
|
|
||||||
|
The maximum size.
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
### `update(_:)`
|
||||||
|
|
||||||
|
Update a view storage.
|
||||||
|
- Parameter storage: The view storage.
|
||||||
|
|
||||||
|
### `container()`
|
||||||
|
|
||||||
|
Get a view storage.
|
||||||
|
- Returns: The view storage.
|
||||||
@ -13,6 +13,14 @@ The start content of the header bar.
|
|||||||
|
|
||||||
The end content of the header bar.
|
The end content of the header bar.
|
||||||
|
|
||||||
|
### `titleButtons`
|
||||||
|
|
||||||
|
Whether the title buttons are visible.
|
||||||
|
|
||||||
|
### `headerBarTitle`
|
||||||
|
|
||||||
|
The view acting as the title of the header bar.
|
||||||
|
|
||||||
### `startID`
|
### `startID`
|
||||||
|
|
||||||
The start content's id.
|
The start content's id.
|
||||||
@ -21,11 +29,16 @@ The start content's id.
|
|||||||
|
|
||||||
The end content's id.
|
The end content's id.
|
||||||
|
|
||||||
|
### `titleID`
|
||||||
|
|
||||||
|
The title's id.
|
||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
### `init(start:end:)`
|
### `init(titleButtons:start:end:)`
|
||||||
|
|
||||||
Initialize a header bar.
|
Initialize a header bar.
|
||||||
- Parameters:
|
- Parameters:
|
||||||
|
- titleButtons: Whether the title buttons (e.g. close button) are visible.
|
||||||
- start: The start content.
|
- start: The start content.
|
||||||
- end: The end content.
|
- end: The end content.
|
||||||
|
|
||||||
@ -55,3 +68,9 @@ Update a header bar's view storage.
|
|||||||
|
|
||||||
Get the container for a header bar.
|
Get the container for a header bar.
|
||||||
- Returns: The view storage.
|
- Returns: The view storage.
|
||||||
|
|
||||||
|
### `headerBarTitle(view:)`
|
||||||
|
|
||||||
|
Set the title widget for the header bar.
|
||||||
|
- Parameter view: The widget in the header bar.
|
||||||
|
- Returns: The header bar.
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# `InspectorWrapper`
|
# `InspectorWrapper`
|
||||||
|
|
||||||
A widget which executes a custom code on the GTUI widget when being created.
|
A widget which executes a custom code on the GTUI widget when being created and updated.
|
||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
### `modify`
|
### `modify`
|
||||||
|
|||||||
@ -20,7 +20,7 @@ The identifier of the selected element.
|
|||||||
## Methods
|
## Methods
|
||||||
### `init(_:selection:content:)`
|
### `init(_:selection:content:)`
|
||||||
|
|
||||||
Initialize `ForEach`.
|
Initialize `List`.
|
||||||
- Parameters:
|
- Parameters:
|
||||||
- elements: The elements.
|
- elements: The elements.
|
||||||
- selection: The identifier of the selected element.
|
- selection: The identifier of the selected element.
|
||||||
|
|||||||
5
Documentation/Reference/typealiases/GTUIWindow.md
Normal file
5
Documentation/Reference/typealiases/GTUIWindow.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
**TYPEALIAS**
|
||||||
|
|
||||||
|
# `GTUIWindow`
|
||||||
|
|
||||||
|
A GTUI window.
|
||||||
BIN
Icons/Demo.png
BIN
Icons/Demo.png
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 26 KiB |
11
Sources/Adwaita/Model/User Interface/GTUIWindow.swift
Normal file
11
Sources/Adwaita/Model/User Interface/GTUIWindow.swift
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// GTUIWindow.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 12.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A GTUI window.
|
||||||
|
public typealias GTUIWindow = GTUI.Window
|
||||||
@ -57,7 +57,11 @@ public enum ViewBuilder {
|
|||||||
/// - Parameter component: An optional component.
|
/// - Parameter component: An optional component.
|
||||||
/// - Returns: A nonoptional component.
|
/// - Returns: A nonoptional component.
|
||||||
public static func buildOptional(_ component: Component?) -> Component {
|
public static func buildOptional(_ component: Component?) -> Component {
|
||||||
component ?? .components([])
|
if let component {
|
||||||
|
return .element(EitherView(true, { buildFinalResult(component) }, else: nil))
|
||||||
|
} else {
|
||||||
|
return .element(EitherView(false, nil) { [] })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables support for `if`-`else` and `switch` statements.
|
/// Enables support for `if`-`else` and `switch` statements.
|
||||||
|
|||||||
@ -27,6 +27,6 @@ public protocol WindowScene: WindowSceneGroup {
|
|||||||
extension WindowScene {
|
extension WindowScene {
|
||||||
|
|
||||||
/// The window scene's body is itself.
|
/// The window scene's body is itself.
|
||||||
@SceneBuilder public var body: Scene { self }
|
@SceneBuilder public var scene: Scene { self }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
public protocol WindowSceneGroup {
|
public protocol WindowSceneGroup {
|
||||||
|
|
||||||
/// The group's content.
|
/// The group's content.
|
||||||
@SceneBuilder var body: Scene { get }
|
@SceneBuilder var scene: Scene { get }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ extension WindowSceneGroup {
|
|||||||
/// - Returns: The windows.
|
/// - Returns: The windows.
|
||||||
func windows() -> [WindowScene] {
|
func windows() -> [WindowScene] {
|
||||||
var content: [WindowScene] = []
|
var content: [WindowScene] = []
|
||||||
for element in body {
|
for element in scene {
|
||||||
if let window = element as? WindowScene {
|
if let window = element as? WindowScene {
|
||||||
content.append(window)
|
content.append(window)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ public class WindowStorage {
|
|||||||
/// Whether the reference to the window should disappear in the next update.
|
/// Whether the reference to the window should disappear in the next update.
|
||||||
public var destroy = false
|
public var destroy = false
|
||||||
/// The GTUI window.
|
/// The GTUI window.
|
||||||
public var window: GTUI.Window
|
public var window: GTUIWindow
|
||||||
/// The content's storage.
|
/// The content's storage.
|
||||||
public var view: ViewStorage
|
public var view: ViewStorage
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ public class WindowStorage {
|
|||||||
/// - id: The window's identifier.
|
/// - id: The window's identifier.
|
||||||
/// - window: The GTUI window.
|
/// - window: The GTUI window.
|
||||||
/// - view: The content's storage.
|
/// - view: The content's storage.
|
||||||
public init(id: String, window: GTUI.Window, view: ViewStorage) {
|
public init(id: String, window: GTUIWindow, view: ViewStorage) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.window = window
|
self.window = window
|
||||||
self.view = view
|
self.view = view
|
||||||
|
|||||||
@ -14,17 +14,25 @@ public struct HeaderBar: Widget {
|
|||||||
var start: Body
|
var start: Body
|
||||||
/// The end content of the header bar.
|
/// The end content of the header bar.
|
||||||
var end: Body
|
var end: Body
|
||||||
|
/// Whether the title buttons are visible.
|
||||||
|
var titleButtons: Bool
|
||||||
|
/// The view acting as the title of the header bar.
|
||||||
|
var headerBarTitle: Body?
|
||||||
|
|
||||||
/// The start content's id.
|
/// The start content's id.
|
||||||
let startID = "start"
|
let startID = "start"
|
||||||
/// The end content's id.
|
/// The end content's id.
|
||||||
let endID = "end"
|
let endID = "end"
|
||||||
|
/// The title's id.
|
||||||
|
let titleID = "title"
|
||||||
|
|
||||||
/// Initialize a header bar.
|
/// Initialize a header bar.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
|
/// - titleButtons: Whether the title buttons (e.g. close button) are visible.
|
||||||
/// - start: The start content.
|
/// - start: The start content.
|
||||||
/// - end: The end content.
|
/// - end: The end content.
|
||||||
public init(@ViewBuilder start: () -> Body, @ViewBuilder end: () -> Body) {
|
public init(titleButtons: Bool = true, @ViewBuilder start: () -> Body, @ViewBuilder end: () -> Body) {
|
||||||
|
self.titleButtons = titleButtons
|
||||||
self.start = start()
|
self.start = start()
|
||||||
self.end = end()
|
self.end = end()
|
||||||
}
|
}
|
||||||
@ -52,8 +60,14 @@ public struct HeaderBar: Widget {
|
|||||||
/// Update a header bar's view storage.
|
/// Update a header bar's view storage.
|
||||||
/// - Parameter storage: The view storage.
|
/// - Parameter storage: The view storage.
|
||||||
public func update(_ storage: ViewStorage) {
|
public func update(_ storage: ViewStorage) {
|
||||||
|
if let bar = storage.view as? GTUI.HeaderBar {
|
||||||
|
_ = bar.showTitleButtons(titleButtons)
|
||||||
|
}
|
||||||
start.update(storage.content[startID] ?? [])
|
start.update(storage.content[startID] ?? [])
|
||||||
end.update(storage.content[endID] ?? [])
|
end.update(storage.content[endID] ?? [])
|
||||||
|
if let first = storage.content[titleID]?.first {
|
||||||
|
headerBarTitle?.widget().update(first)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the container for a header bar.
|
/// Get the container for a header bar.
|
||||||
@ -72,7 +86,25 @@ public struct HeaderBar: Widget {
|
|||||||
_ = bar.packEnd(element.view)
|
_ = bar.packEnd(element.view)
|
||||||
endContent.append(element)
|
endContent.append(element)
|
||||||
}
|
}
|
||||||
return .init(bar, content: [startID: startContent, endID: endContent])
|
let title = headerBarTitle?.widget().container()
|
||||||
|
let titleStorage: [ViewStorage]
|
||||||
|
if let title {
|
||||||
|
_ = bar.titleWidget(title.view)
|
||||||
|
titleStorage = [title]
|
||||||
|
} else {
|
||||||
|
titleStorage = []
|
||||||
|
}
|
||||||
|
_ = bar.showTitleButtons(titleButtons)
|
||||||
|
return .init(bar, content: [startID: startContent, endID: endContent, titleID: titleStorage])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the title widget for the header bar.
|
||||||
|
/// - Parameter view: The widget in the header bar.
|
||||||
|
/// - Returns: The header bar.
|
||||||
|
public func headerBarTitle(@ViewBuilder view: () -> Body) -> Self {
|
||||||
|
var newSelf = self
|
||||||
|
newSelf.headerBarTitle = view()
|
||||||
|
return newSelf
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ public struct List<Element>: Widget where Element: Identifiable {
|
|||||||
/// The identifier of the selected element.
|
/// The identifier of the selected element.
|
||||||
@Binding var selection: Element.ID
|
@Binding var selection: Element.ID
|
||||||
|
|
||||||
/// Initialize `ForEach`.
|
/// Initialize `List`.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - elements: The elements.
|
/// - elements: The elements.
|
||||||
/// - selection: The identifier of the selected element.
|
/// - selection: The identifier of the selected element.
|
||||||
|
|||||||
49
Sources/Adwaita/View/Modifiers/Clamp.swift
Normal file
49
Sources/Adwaita/View/Modifiers/Clamp.swift
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Clamp.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 12.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import GTUI
|
||||||
|
|
||||||
|
/// A horizontal AdwClamp equivalent.
|
||||||
|
struct Clamp: Widget {
|
||||||
|
|
||||||
|
/// The content.
|
||||||
|
var content: View
|
||||||
|
/// The maximum size.
|
||||||
|
var maxSize: Int
|
||||||
|
|
||||||
|
/// Update a view storage.
|
||||||
|
/// - Parameter storage: The view storage.
|
||||||
|
func update(_ storage: ViewStorage) {
|
||||||
|
if let clamp = storage.view as? GTUI.Clamp {
|
||||||
|
_ = clamp.maximumSize(maxSize)
|
||||||
|
}
|
||||||
|
if let storage = storage.content[.mainContent]?[safe: 0] {
|
||||||
|
content.widget().update(storage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a view storage.
|
||||||
|
/// - Returns: The view storage.
|
||||||
|
func container() -> ViewStorage {
|
||||||
|
let container = content.storage()
|
||||||
|
let clamp: GTUI.Clamp = .init(container.view)
|
||||||
|
_ = clamp.maximumSize(maxSize)
|
||||||
|
return .init(clamp, content: [.mainContent: [container]])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
|
||||||
|
/// Set the view's maximal size.
|
||||||
|
/// - Parameter maxSize: The maximal size.
|
||||||
|
/// - Returns: A view.
|
||||||
|
public func frame(maxSize: Int? = nil) -> View {
|
||||||
|
Clamp(content: self, maxSize: maxSize ?? -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import GTUI
|
import GTUI
|
||||||
|
|
||||||
/// A widget which executes a custom code on the GTUI widget when being created.
|
/// A widget which executes a custom code on the GTUI widget when being created and updated.
|
||||||
struct InspectorWrapper: Widget {
|
struct InspectorWrapper: Widget {
|
||||||
|
|
||||||
/// The custom code to edit the widget.
|
/// The custom code to edit the widget.
|
||||||
@ -27,13 +27,14 @@ struct InspectorWrapper: Widget {
|
|||||||
/// - Parameter storage: The content's storage.
|
/// - Parameter storage: The content's storage.
|
||||||
func update(_ storage: ViewStorage) {
|
func update(_ storage: ViewStorage) {
|
||||||
content.updateStorage(storage)
|
content.updateStorage(storage)
|
||||||
|
modify(storage.view)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
|
|
||||||
/// Modify a GTUI widget before being displayed.
|
/// Modify a GTUI widget before being displayed and when being updated.
|
||||||
/// - Parameter modify: Modify the widget.
|
/// - Parameter modify: Modify the widget.
|
||||||
/// - Returns: A view.
|
/// - Returns: A view.
|
||||||
public func inspect(_ modify: @escaping (NativeWidgetPeer?) -> Void) -> View {
|
public func inspect(_ modify: @escaping (NativeWidgetPeer?) -> Void) -> View {
|
||||||
@ -86,13 +87,6 @@ extension View {
|
|||||||
inspect { _ = $0?.frame(minWidth: minWidth, minHeight: minHeight) }
|
inspect { _ = $0?.frame(minWidth: minWidth, minHeight: minHeight) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the view's maximal size.
|
|
||||||
/// - Parameter maxSize: The maximal size.
|
|
||||||
/// - Returns: A view.
|
|
||||||
public func frame(maxSize: Int? = nil) -> View {
|
|
||||||
inspect { _ = $0?.frame(maxSize: maxSize) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the view's transition.
|
/// Set the view's transition.
|
||||||
/// - Parameter transition: The transition.
|
/// - Parameter transition: The transition.
|
||||||
/// - Returns: A view.
|
/// - Returns: A view.
|
||||||
|
|||||||
@ -25,10 +25,15 @@ public struct StatusPage: Widget {
|
|||||||
/// - icon: The icon.
|
/// - icon: The icon.
|
||||||
/// - description: Additional details.
|
/// - description: Additional details.
|
||||||
/// - content: Additional content.
|
/// - content: Additional content.
|
||||||
public init(_ title: String, icon: Icon, description: String = "", @ViewBuilder content: () -> Body = { [] }) {
|
public init(
|
||||||
|
_ title: String,
|
||||||
|
icon: Icon? = nil,
|
||||||
|
description: String = "",
|
||||||
|
@ViewBuilder content: () -> Body = { [] }
|
||||||
|
) {
|
||||||
self.title = title
|
self.title = title
|
||||||
self.description = description
|
self.description = description
|
||||||
self.icon = icon
|
self.icon = icon ?? .custom(name: "")
|
||||||
self.content = content()
|
self.content = content()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ public struct Window: WindowScene {
|
|||||||
/// The window's identifier.
|
/// The window's identifier.
|
||||||
public var id: String
|
public var id: String
|
||||||
/// The window's content.
|
/// The window's content.
|
||||||
var content: (GTUI.Window) -> Body
|
var content: (GTUIWindow) -> Body
|
||||||
/// Whether an instance of the window type should be opened when the app is starting up.
|
/// Whether an instance of the window type should be opened when the app is starting up.
|
||||||
public var `open`: Int
|
public var `open`: Int
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ public struct Window: WindowScene {
|
|||||||
/// - id: The identifier.
|
/// - id: The identifier.
|
||||||
/// - open: The number of instances of the window type when the app is starting.
|
/// - open: The number of instances of the window type when the app is starting.
|
||||||
/// - content: The window's content.
|
/// - content: The window's content.
|
||||||
public init(id: String, `open`: Int = 1, @ViewBuilder content: @escaping (GTUI.Window) -> Body) {
|
public init(id: String, `open`: Int = 1, @ViewBuilder content: @escaping (GTUIWindow) -> Body) {
|
||||||
self.content = content
|
self.content = content
|
||||||
self.id = id
|
self.id = id
|
||||||
self.open = open
|
self.open = open
|
||||||
@ -47,8 +47,8 @@ public struct Window: WindowScene {
|
|||||||
/// Get the window.
|
/// Get the window.
|
||||||
/// - Parameter app: The application.
|
/// - Parameter app: The application.
|
||||||
/// - Returns: The window.
|
/// - Returns: The window.
|
||||||
func createGTUIWindow(app: GTUIApp) -> GTUI.Window {
|
func createGTUIWindow(app: GTUIApp) -> GTUIWindow {
|
||||||
let window = GTUI.Window(app: app)
|
let window = GTUIWindow(app: app)
|
||||||
window.show()
|
window.show()
|
||||||
return window
|
return window
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ public struct Window: WindowScene {
|
|||||||
/// Get the storage of the content view.
|
/// Get the storage of the content view.
|
||||||
/// - Parameter window: The window.
|
/// - Parameter window: The window.
|
||||||
/// - Returns: The storage of the content of the window.
|
/// - Returns: The storage of the content of the window.
|
||||||
func getViewStorage(window: GTUI.Window) -> ViewStorage {
|
func getViewStorage(window: GTUIWindow) -> ViewStorage {
|
||||||
let storage = content(window).widget().container()
|
let storage = content(window).widget().container()
|
||||||
window.setChild(storage.view)
|
window.setChild(storage.view)
|
||||||
return storage
|
return storage
|
||||||
|
|||||||
@ -8,28 +8,39 @@
|
|||||||
// swiftlint:disable missing_docs
|
// swiftlint:disable missing_docs
|
||||||
|
|
||||||
import Adwaita
|
import Adwaita
|
||||||
|
import GTUI
|
||||||
|
|
||||||
struct CounterDemo: View {
|
struct CounterDemo: View {
|
||||||
|
|
||||||
@State private var count = 0
|
@State private var count = 0
|
||||||
|
|
||||||
var view: Body {
|
var view: Body {
|
||||||
description
|
VStack {
|
||||||
.topToolbar {
|
HStack {
|
||||||
HeaderBar.start {
|
CountButton(count: $count, icon: .goPrevious) { $0 -= 1 }
|
||||||
Button(icon: .default(icon: .goPrevious)) {
|
|
||||||
count -= 1
|
|
||||||
}
|
|
||||||
Button(icon: .default(icon: .goNext)) {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ViewBuilder private var description: Body {
|
|
||||||
Text("\(count)")
|
Text("\(count)")
|
||||||
.style("title-1")
|
.style("title-1")
|
||||||
|
.frame(minWidth: 100)
|
||||||
|
CountButton(count: $count, icon: .goNext) { $0 += 1 }
|
||||||
|
}
|
||||||
|
.halign(.center)
|
||||||
|
}
|
||||||
|
.valign(.center)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct CountButton: View {
|
||||||
|
|
||||||
|
@Binding var count: Int
|
||||||
|
var icon: Icon.DefaultIcon
|
||||||
|
var action: (inout Int) -> Void
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
Button(icon: .default(icon: icon)) {
|
||||||
|
action(&count)
|
||||||
|
}
|
||||||
|
.style("circular")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
// swiftlint:disable missing_docs implicitly_unwrapped_optional no_magic_numbers
|
// swiftlint:disable missing_docs implicitly_unwrapped_optional no_magic_numbers
|
||||||
|
|
||||||
import Adwaita
|
import Adwaita
|
||||||
import GTUI
|
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct Demo: App {
|
struct Demo: App {
|
||||||
@ -21,22 +20,26 @@ struct Demo: App {
|
|||||||
Window(id: "main") { window in
|
Window(id: "main") { window in
|
||||||
DemoContent(window: window, app: app)
|
DemoContent(window: window, app: app)
|
||||||
}
|
}
|
||||||
|
HelperWindows()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct HelperWindows: WindowSceneGroup {
|
||||||
|
|
||||||
|
var scene: Scene {
|
||||||
Window(id: "content", open: 0) { window in
|
Window(id: "content", open: 0) { window in
|
||||||
Text("This window exists at most once.")
|
WindowsDemo.WindowContent(window: window)
|
||||||
.padding()
|
|
||||||
.topToolbar {
|
|
||||||
HeaderBar.empty()
|
|
||||||
}
|
}
|
||||||
.onAppear {
|
Window(id: "toolbar-demo", open: 0) { window in
|
||||||
window.setDefaultSize(width: 400, height: 250)
|
ToolbarDemo.WindowContent(window: window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DemoContent: View {
|
struct DemoContent: View {
|
||||||
|
|
||||||
@State private var selection: Page = .welcome
|
@State private var selection: Page = .welcome
|
||||||
var window: GTUI.Window
|
var window: GTUIWindow
|
||||||
var app: GTUIApp!
|
var app: GTUIApp!
|
||||||
|
|
||||||
var view: Body {
|
var view: Body {
|
||||||
@ -54,8 +57,17 @@ struct Demo: App {
|
|||||||
}
|
}
|
||||||
.navigationTitle("Demo")
|
.navigationTitle("Demo")
|
||||||
} content: {
|
} content: {
|
||||||
|
StatusPage(
|
||||||
|
selection.label,
|
||||||
|
icon: selection.icon,
|
||||||
|
description: selection.description
|
||||||
|
) {
|
||||||
selection.view(app: app)
|
selection.view(app: app)
|
||||||
}
|
}
|
||||||
|
.topToolbar {
|
||||||
|
HeaderBar.empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
window.setDefaultSize(width: 650, height: 450)
|
window.setDefaultSize(width: 650, height: 450)
|
||||||
}
|
}
|
||||||
|
|||||||
39
Tests/DiceDemo.swift
Normal file
39
Tests/DiceDemo.swift
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// DiceDemo.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 12.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
// swiftlint:disable missing_docs no_magic_numbers
|
||||||
|
|
||||||
|
import Adwaita
|
||||||
|
|
||||||
|
struct DiceDemo: View {
|
||||||
|
|
||||||
|
@State private var number: Int?
|
||||||
|
|
||||||
|
private var label: String {
|
||||||
|
if let number {
|
||||||
|
return "\(number)"
|
||||||
|
} else {
|
||||||
|
return "Roll the Dice!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
VStack {
|
||||||
|
Button(label) {
|
||||||
|
number = .random(in: 1...6)
|
||||||
|
}
|
||||||
|
.style("pill")
|
||||||
|
.style("suggested-action")
|
||||||
|
.frame(maxSize: 100)
|
||||||
|
}
|
||||||
|
.valign(.center)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:enable missing_docs no_magic_numbers
|
||||||
@ -8,12 +8,16 @@
|
|||||||
// swiftlint:disable missing_docs implicitly_unwrapped_optional
|
// swiftlint:disable missing_docs implicitly_unwrapped_optional
|
||||||
|
|
||||||
import Adwaita
|
import Adwaita
|
||||||
|
import GTUI
|
||||||
|
|
||||||
enum Page: String, Identifiable, CaseIterable {
|
enum Page: String, Identifiable, CaseIterable {
|
||||||
|
|
||||||
case welcome
|
case welcome
|
||||||
case counter
|
case counter
|
||||||
case windows
|
case windows
|
||||||
|
case toolbar
|
||||||
|
case transition
|
||||||
|
case dice
|
||||||
|
|
||||||
var id: Self {
|
var id: Self {
|
||||||
self
|
self
|
||||||
@ -23,15 +27,47 @@ enum Page: String, Identifiable, CaseIterable {
|
|||||||
rawValue.capitalized
|
rawValue.capitalized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var icon: GTUI.Icon? {
|
||||||
|
switch self {
|
||||||
|
case .welcome:
|
||||||
|
return .default(icon: .gnomeAdwaita1Demo)
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .welcome:
|
||||||
|
return "This is a collection of examples for the Swift Adwaita package."
|
||||||
|
case .counter:
|
||||||
|
return "A simple sample view."
|
||||||
|
case .windows:
|
||||||
|
return "Showcase window management."
|
||||||
|
case .toolbar:
|
||||||
|
return "Toggle the bottom toolbar."
|
||||||
|
case .transition:
|
||||||
|
return "A slide transition between two views."
|
||||||
|
case .dice:
|
||||||
|
return "Roll the dice."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func view(app: GTUIApp!) -> Body {
|
func view(app: GTUIApp!) -> Body {
|
||||||
switch self {
|
switch self {
|
||||||
case .welcome:
|
case .welcome:
|
||||||
WelcomeDemo()
|
[]
|
||||||
case .counter:
|
case .counter:
|
||||||
CounterDemo()
|
CounterDemo()
|
||||||
case .windows:
|
case .windows:
|
||||||
WindowsDemo(app: app)
|
WindowsDemo(app: app)
|
||||||
|
case .toolbar:
|
||||||
|
ToolbarDemo(app: app)
|
||||||
|
case .transition:
|
||||||
|
TransitionDemo()
|
||||||
|
case .dice:
|
||||||
|
DiceDemo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
68
Tests/ToolbarDemo.swift
Normal file
68
Tests/ToolbarDemo.swift
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//
|
||||||
|
// ToolbarDemo.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 12.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
// swiftlint:disable missing_docs no_magic_numbers
|
||||||
|
|
||||||
|
import Adwaita
|
||||||
|
|
||||||
|
struct ToolbarDemo: View {
|
||||||
|
|
||||||
|
var app: GTUIApp
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
VStack {
|
||||||
|
Button("View Demo") {
|
||||||
|
app.showWindow("toolbar-demo")
|
||||||
|
}
|
||||||
|
.style("suggested-action")
|
||||||
|
.frame(maxSize: 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WindowContent: View {
|
||||||
|
|
||||||
|
@State private var visible = false
|
||||||
|
@State private var moreContent = false
|
||||||
|
var window: GTUIWindow
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
VStack {
|
||||||
|
Button("Toggle Toolbar") {
|
||||||
|
visible.toggle()
|
||||||
|
}
|
||||||
|
.style("suggested-action")
|
||||||
|
.frame(maxSize: 100)
|
||||||
|
.padding(15)
|
||||||
|
}
|
||||||
|
.valign(.center)
|
||||||
|
.bottomToolbar(visible: visible) {
|
||||||
|
HeaderBar(titleButtons: false) {
|
||||||
|
Button(icon: .default(icon: .audioInputMicrophone)) { }
|
||||||
|
} end: {
|
||||||
|
Button(icon: .default(icon: .userTrash)) { }
|
||||||
|
}
|
||||||
|
.headerBarTitle { }
|
||||||
|
}
|
||||||
|
.topToolbar {
|
||||||
|
HeaderBar.empty()
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
window.setDefaultSize(width: 400, height: 250)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int: Identifiable {
|
||||||
|
|
||||||
|
public var id: Self { self }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:enable missing_docs no_magic_numbers
|
||||||
47
Tests/TransitionDemo.swift
Normal file
47
Tests/TransitionDemo.swift
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// TransitionDemo.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 12.10.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
// swiftlint:disable missing_docs no_magic_numbers
|
||||||
|
|
||||||
|
import Adwaita
|
||||||
|
|
||||||
|
struct TransitionDemo: View {
|
||||||
|
|
||||||
|
@State private var firstView = true
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
VStack {
|
||||||
|
if firstView {
|
||||||
|
content("First View")
|
||||||
|
.transition(.slideDown)
|
||||||
|
.style("accent")
|
||||||
|
} else {
|
||||||
|
content("Second View")
|
||||||
|
.transition(.slideUp)
|
||||||
|
.style("success")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.style("card")
|
||||||
|
.frame(maxSize: 200)
|
||||||
|
.padding()
|
||||||
|
Button("Toggle View") {
|
||||||
|
firstView.toggle()
|
||||||
|
}
|
||||||
|
.style("pill")
|
||||||
|
.padding()
|
||||||
|
.frame(maxSize: 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func content(_ text: String) -> View {
|
||||||
|
Text(text)
|
||||||
|
.style("title-2")
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:enable missing_docs no_magic_numbers
|
||||||
@ -1,29 +0,0 @@
|
|||||||
//
|
|
||||||
// WelcomeDemo.swift
|
|
||||||
// Adwaita
|
|
||||||
//
|
|
||||||
// Created by david-swift on 25.09.23.
|
|
||||||
//
|
|
||||||
|
|
||||||
// swiftlint:disable missing_docs
|
|
||||||
|
|
||||||
import Adwaita
|
|
||||||
|
|
||||||
struct WelcomeDemo: View {
|
|
||||||
|
|
||||||
@State private var test = false
|
|
||||||
|
|
||||||
var view: Body {
|
|
||||||
StatusPage(
|
|
||||||
"Swift Adwaita Demo",
|
|
||||||
icon: .default(icon: .gnomeAdwaita1Demo),
|
|
||||||
description: "This is a collection of examples for the Swift Adwaita package."
|
|
||||||
)
|
|
||||||
.topToolbar {
|
|
||||||
HeaderBar.empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// swiftlint:enable missing_docs
|
|
||||||
@ -14,19 +14,39 @@ struct WindowsDemo: View {
|
|||||||
var app: GTUIApp!
|
var app: GTUIApp!
|
||||||
|
|
||||||
var view: Body {
|
var view: Body {
|
||||||
|
HStack {
|
||||||
VStack {
|
VStack {
|
||||||
Button("Show Window") {
|
Button("Show Window") {
|
||||||
app.showWindow("content")
|
app.showWindow("content")
|
||||||
}
|
}
|
||||||
.padding()
|
.hexpand()
|
||||||
Button("Add Window") {
|
Button("Add Window") {
|
||||||
app.addWindow("main")
|
app.addWindow("main")
|
||||||
}
|
}
|
||||||
.padding(10, .horizontal.add(.bottom))
|
.hexpand()
|
||||||
}
|
}
|
||||||
|
.valign(.center)
|
||||||
|
.style("linked")
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
.frame(maxSize: 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WindowContent: View {
|
||||||
|
|
||||||
|
var window: GTUIWindow
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
Text("This window exists at most once.")
|
||||||
|
.padding()
|
||||||
.topToolbar {
|
.topToolbar {
|
||||||
HeaderBar.empty()
|
HeaderBar.empty()
|
||||||
}
|
}
|
||||||
|
.onAppear {
|
||||||
|
window.setDefaultSize(width: 400, height: 250)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user