Skip to content

Commit

Permalink
Improve window management
Browse files Browse the repository at this point in the history
  • Loading branch information
david-swift committed Sep 24, 2023
1 parent 81426e2 commit f1e4537
Show file tree
Hide file tree
Showing 24 changed files with 663 additions and 74 deletions.
4 changes: 4 additions & 0 deletions Documentation/Reference/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [View](protocols/View.md)
- [Widget](protocols/Widget.md)
- [WindowScene](protocols/WindowScene.md)
- [WindowSceneGroup](protocols/WindowSceneGroup.md)

## Structs

Expand All @@ -19,6 +20,7 @@
- [Text](structs/Text.md)
- [UpdateObserver](structs/UpdateObserver.md)
- [VStack](structs/VStack.md)
- [Window](structs/Window.md)

## Classes

Expand All @@ -42,6 +44,8 @@
- [String](extensions/String.md)
- [View](extensions/View.md)
- [Widget](extensions/Widget.md)
- [WindowScene](extensions/WindowScene.md)
- [WindowSceneGroup](extensions/WindowSceneGroup.md)

## Typealiases

Expand Down
12 changes: 12 additions & 0 deletions Documentation/Reference/classes/GTUIApp.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,15 @@ Initialize the GTUI application.
### `onActivate()`

The entry point of the application.

### `showWindow(_:)`

Focus the window with a certain id. Create the window if it doesn't already exist.
- Parameters:
- id: The window's id.

### `addWindow(_:)`

Add a new window with the content of the window with a certain id.
- Parameters:
- id: The window's id.
11 changes: 10 additions & 1 deletion Documentation/Reference/classes/WindowStorage.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
A storage for an app's window.

## Properties
### `id`

The window's identifier.

### `destroy`

Whether the reference to the window should disappear in the next update.

### `window`

The GTUI window.
Expand All @@ -14,9 +22,10 @@ The GTUI window.
The content's storage.

## Methods
### `init(window:view:)`
### `init(id:window:view:)`

Initialize a window storage.
- Parameters:
- id: The window's identifier.
- window: The GTUI window.
- view: The content's storage.
5 changes: 5 additions & 0 deletions Documentation/Reference/extensions/Array.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ Update a collection of views with a collection of view storages.
- Parameters:
- storage: The collection of view storages.

### `windows()`

Get the content of an array of window scene groups.
- Returns: The array of windows.

### `checkIndex(_:)`

Check if a given index is valid for the array.
Expand Down
9 changes: 3 additions & 6 deletions Documentation/Reference/extensions/WindowScene.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

# `WindowScene`

## Methods
### `getWindow(app:)`
## Properties
### `body`

Get the `GTUI.Window` with the content.
- Parameters:
- app: The application.
- Returns: The window.
The window scene's body is itself.
14 changes: 14 additions & 0 deletions Documentation/Reference/extensions/WindowSceneGroup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
**EXTENSION**

# `WindowSceneGroup`

## Methods
### `windows()`

Get the windows described by the group.
- Returns: The windows.

### `update(_:)`

Update the windows described by the group.
- Parameter storage: The window's storage.
23 changes: 22 additions & 1 deletion Documentation/Reference/protocols/WindowScene.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,25 @@

# `WindowScene`

A structure conforming to `WindowScene` can be added to an app's `scene`.
A structure representing the content for a certain window type.

## Properties
### `id`

The window type's identifier.

### `open`

The number of instances of the window at the startup.

## Methods
### `createWindow(app:)`

Get the storage for the window.
- Parameter app: The application.
- Returns: The storage.

### `update(_:)`

Update a window storage's content.
- Parameter storage: The storage to update.
10 changes: 10 additions & 0 deletions Documentation/Reference/protocols/WindowSceneGroup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
**PROTOCOL**

# `WindowSceneGroup`

A structure conforming to `WindowScene` can be added to an app's `scene`.

## Properties
### `body`

The group's content.
52 changes: 52 additions & 0 deletions Documentation/Reference/structs/Window.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
**STRUCT**

# `Window`

A structure representing a simple window type.

Note that multiple instances of a window can be opened at the same time.

## Properties
### `id`

The window's identifier.

### `content`

The window's content.

### `open`

Whether an instance of the window type should be opened when the app is starting up.

## Methods
### `init(id:open:content:)`

Create a window type with a certain identifier and user interface.
- Parameters:
- id: The identifier.
- open: The number of instances of the window type when the app is starting.
- content: The window's content.

### `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.

### `getViewStorage(window:)`

Get the storage of the content view.
- Parameter window: The window.
- Returns: The storage of the content of the window.

### `update(_:)`

Update a window storage's content.
- Parameter storage: The storage to update.
Binary file added Icons/HelloWorld.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Icons/TwoWindows.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 17 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,20 @@ brew install libadwaita

### Basics

* [Creating Views][12]
* [Hello World][12]
* [Creating Views][13]
* [Windows][14]

## Thanks

### Dependencies
- [SwiftGui][13] licensed under the [GPL-3.0 license][14]
- [SwiftGui][15] licensed under the [GPL-3.0 license][16]

### Other Thanks
- The [contributors][15]
- [SwiftLint][16] for checking whether code style conventions are violated
- The programming language [Swift][17]
- [SourceDocs][18] used for generating the [docs][19]
- The [contributors][17]
- [SwiftLint][18] for checking whether code style conventions are violated
- The programming language [Swift][19]
- [SourceDocs][20] used for generating the [docs][21]

[1]: #goals
[2]: #widgets
Expand All @@ -133,12 +135,14 @@ brew install libadwaita
[10]: https://brew.sh
[11]: user-manual/GettingStarted.md
[12]: user-manual/Basics/CreatingViews.md
[13]: https://github.com/JCWasmx86/SwiftGui
[14]: https://github.com/JCWasmx86/SwiftGui/blob/main/COPYING
[15]: Contributors.md
[16]: https://github.com/realm/SwiftLint
[17]: https://github.com/apple/swift
[18]: https://github.com/SourceDocs/SourceDocs
[19]: Documentation/Reference/README.md
[13]
[14]
[15]: https://github.com/JCWasmx86/SwiftGui
[16]: https://github.com/JCWasmx86/SwiftGui/blob/main/COPYING
[17]: Contributors.md
[18]: https://github.com/realm/SwiftLint
[19]: https://github.com/apple/swift
[20]: https://github.com/SourceDocs/SourceDocs
[21]: Documentation/Reference/README.md

[image-1]: Icons/Screenshot.png
8 changes: 6 additions & 2 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@

## Basics

* [Creating Views][3]
* [Hello World][3]
* [Creating Views][4]
* [Windows][5]

[1]: README.md
[2]: user-manual/GettingStarted.md
[3]: user-manual/Basics/CreatingViews.md
[3]: user-manual/Basics/HelloWorld.md
[4]: user-manual/Basics/CreatingViews.md
[5]: user-manual/Basics/Windows.md
10 changes: 10 additions & 0 deletions Sources/Adwaita/Model/Extensions/Array.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ extension Array where Element == View {

}

extension Array where Element == WindowSceneGroup {

/// Get the content of an array of window scene groups.
/// - Returns: The array of windows.
public func windows() -> [WindowScene] {
flatMap { $0.windows() }
}

}

extension Array {

/// Accesses the element at the specified position safely.
Expand Down
12 changes: 9 additions & 3 deletions Sources/Adwaita/Model/User Interface/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,17 @@ extension App {
var appInstance = self.init()
appInstance.app = GTUIApp(appInstance.id) { appInstance }
GTUIApp.updateHandlers.append {
for (windowIndex, window) in appInstance.scene.enumerated() {
if let stored = appInstance.app.sceneStorage[safe: windowIndex] {
window.widget().updateStorage(stored.view)
var removeIndices: [Int] = []
for (index, window) in appInstance.app.sceneStorage.enumerated() {
if window.destroy {
removeIndices.insert(index, at: 0)
} else if let scene = appInstance.scene.windows().first(where: { $0.id == window.id }) {
scene.update(window)
}
}
for index in removeIndices {
appInstance.app.sceneStorage.remove(at: index)
}
}
appInstance.app.run()
}
Expand Down
28 changes: 21 additions & 7 deletions Sources/Adwaita/Model/User Interface/GTUIApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,27 @@ public class GTUIApp: Application {
/// The entry point of the application.
override public func onActivate() {
let body = body()
for windowScene in body.scene {
let window = GTUI.Window(app: self)
let child = windowScene.storage()
let view = child.view
window.setChild(view)
sceneStorage.append(.init(window: window, view: child))
window.show()
for windowScene in body.scene.windows() {
for _ in 0..<windowScene.open {
sceneStorage.append(windowScene.createWindow(app: self))
}
}
}

/// Focus the window with a certain id. Create the window if it doesn't already exist.
/// - Parameters:
/// - id: The window's id.
public func showWindow(_ id: String) {
sceneStorage.last { $0.id == id && !$0.destroy }?.window.show() ?? addWindow(id)
}

/// Add a new window with the content of the window with a certain id.
/// - Parameters:
/// - id: The window's id.
public func addWindow(_ id: String) {
if let window = body().scene.windows().first(where: { $0.id == id }) {
sceneStorage.append(window.createWindow(app: self))
showWindow(id)
}
}
}
28 changes: 22 additions & 6 deletions Sources/Adwaita/Model/User Interface/WindowScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@

import GTUI

/// A structure conforming to `WindowScene` can be added to an app's `scene`.
public protocol WindowScene: View { }
/// A structure representing the content for a certain window type.
public protocol WindowScene: WindowSceneGroup {

/// `Scene` is an array of windows.
public typealias Scene = [WindowScene]
/// A builder for the `Scene`
public typealias SceneBuilder = ArrayBuilder<WindowScene>
/// The window type's identifier.
var id: String { get }
/// The number of instances of the window at the startup.
var `open`: Int { get }
/// Get the storage for the window.
/// - Parameter app: The application.
/// - Returns: The storage.
func createWindow(app: GTUIApp) -> WindowStorage
/// Update a window storage's content.
/// - Parameter storage: The storage to update.
func update(_ storage: WindowStorage)

}

extension WindowScene {

/// The window scene's body is itself.
@SceneBuilder public var body: Scene { self }

}
Loading

0 comments on commit f1e4537

Please sign in to comment.