forked from aparoksha/adwaita-swift
Add support for modal windows
This commit is contained in:
parent
ac0c775985
commit
da08bc435c
@ -32,8 +32,9 @@ public class GTUIApp: Application {
|
|||||||
let body = body()
|
let body = body()
|
||||||
for windowScene in body.scene.windows() {
|
for windowScene in body.scene.windows() {
|
||||||
for _ in 0..<windowScene.open {
|
for _ in 0..<windowScene.open {
|
||||||
sceneStorage.append(windowScene.createWindow(app: self))
|
addWindow(windowScene.id)
|
||||||
}
|
}
|
||||||
|
setParentWindows()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,9 +49,21 @@ public class GTUIApp: Application {
|
|||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - id: The window's id.
|
/// - id: The window's id.
|
||||||
public func addWindow(_ id: String) {
|
public func addWindow(_ id: String) {
|
||||||
if let window = body().scene.windows().first(where: { $0.id == id }) {
|
State<Any>.updateViews()
|
||||||
sceneStorage.append(window.createWindow(app: self))
|
if let window = body().scene.windows().last(where: { $0.id == id }) {
|
||||||
|
let window = window.createWindow(app: self)
|
||||||
|
sceneStorage.append(window)
|
||||||
|
setParentWindows()
|
||||||
showWindow(id)
|
showWindow(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the parents of every window having a parent window.
|
||||||
|
func setParentWindows() {
|
||||||
|
for window in sceneStorage {
|
||||||
|
if let parent = sceneStorage.first { $0.id == window.parentID } {
|
||||||
|
window.window.setParent(parent.window)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,8 @@ public protocol WindowScene: WindowSceneGroup {
|
|||||||
|
|
||||||
/// The window type's identifier.
|
/// The window type's identifier.
|
||||||
var id: String { get }
|
var id: String { get }
|
||||||
|
/// The identifier of the window's parent window.
|
||||||
|
var parentID: String? { get set }
|
||||||
/// The number of instances of the window at the startup.
|
/// The number of instances of the window at the startup.
|
||||||
var `open`: Int { get }
|
var `open`: Int { get }
|
||||||
/// The keyboard shortcuts on the application's level.
|
/// The keyboard shortcuts on the application's level.
|
||||||
|
|||||||
@ -12,6 +12,8 @@ public class WindowStorage {
|
|||||||
|
|
||||||
/// The window's identifier.
|
/// The window's identifier.
|
||||||
public var id: String
|
public var id: String
|
||||||
|
/// The identifier of the window's parent window.
|
||||||
|
public var parentID: String?
|
||||||
/// 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.
|
||||||
|
|||||||
@ -18,6 +18,8 @@ public struct Window: WindowScene {
|
|||||||
var content: (GTUIApplicationWindow) -> Body
|
var content: (GTUIApplicationWindow) -> 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
|
||||||
|
/// The identifier of the window's parent.
|
||||||
|
public var parentID: String?
|
||||||
/// The keyboard shortcuts.
|
/// The keyboard shortcuts.
|
||||||
var shortcuts: [String: (GTUIApplicationWindow) -> Void] = [:]
|
var shortcuts: [String: (GTUIApplicationWindow) -> Void] = [:]
|
||||||
/// The keyboard shortcuts on the app level.
|
/// The keyboard shortcuts on the app level.
|
||||||
@ -45,6 +47,7 @@ public struct Window: WindowScene {
|
|||||||
windowStorage.destroy = true
|
windowStorage.destroy = true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
windowStorage.parentID = parentID
|
||||||
return windowStorage
|
return windowStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +83,17 @@ public struct Window: WindowScene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add windows that overlay the last instance of this window if presented.
|
||||||
|
/// - Parameter windows: The windows.
|
||||||
|
/// - Returns: The new windows and this window.
|
||||||
|
public func overlay(@SceneBuilder windows: () -> [WindowSceneGroup]) -> [WindowScene] {
|
||||||
|
windows().windows().map { window in
|
||||||
|
var newWindow = window
|
||||||
|
newWindow.parentID = id
|
||||||
|
return newWindow
|
||||||
|
} + [self]
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a keyboard shortcut.
|
/// Add a keyboard shortcut.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - shortcut: The keyboard shortcut.
|
/// - shortcut: The keyboard shortcut.
|
||||||
|
|||||||
@ -20,6 +20,12 @@ struct Demo: App {
|
|||||||
Window(id: "main") { window in
|
Window(id: "main") { window in
|
||||||
DemoContent(window: window, app: app)
|
DemoContent(window: window, app: app)
|
||||||
}
|
}
|
||||||
|
.overlay {
|
||||||
|
Window(id: "overlay", open: 0) { window in
|
||||||
|
OverlayWindowDemo.WindowContent(window: window)
|
||||||
|
}
|
||||||
|
.keyboardShortcut("Escape") { $0.close() }
|
||||||
|
}
|
||||||
HelperWindows()
|
HelperWindows()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
53
Tests/OverlayWindowDemo.swift
Normal file
53
Tests/OverlayWindowDemo.swift
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// OverlayWindowDemo.swift
|
||||||
|
// Adwaita
|
||||||
|
//
|
||||||
|
// Created by david-swift on 09.11.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
// swiftlint:disable missing_docs implicitly_unwrapped_optional no_magic_numbers
|
||||||
|
|
||||||
|
import Adwaita
|
||||||
|
|
||||||
|
struct OverlayWindowDemo: View {
|
||||||
|
|
||||||
|
var app: GTUIApp!
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
VStack {
|
||||||
|
Button("Show Window") {
|
||||||
|
app.showWindow("overlay")
|
||||||
|
}
|
||||||
|
.style("pill")
|
||||||
|
.frame(maxSize: 100)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WindowContent: View {
|
||||||
|
|
||||||
|
var window: GTUIWindow
|
||||||
|
|
||||||
|
var view: Body {
|
||||||
|
VStack {
|
||||||
|
Button("Close Window") {
|
||||||
|
window.close()
|
||||||
|
}
|
||||||
|
.style("pill")
|
||||||
|
.padding()
|
||||||
|
.frame(maxSize: 100)
|
||||||
|
}
|
||||||
|
.valign(.center)
|
||||||
|
.topToolbar {
|
||||||
|
HeaderBar.empty()
|
||||||
|
}
|
||||||
|
.onAppear {
|
||||||
|
window.setDefaultSize(width: 300, height: 200)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// swiftlint:enable missing_docs implicitly_unwrapped_optional no_magic_numbers
|
||||||
@ -18,13 +18,19 @@ enum Page: String, Identifiable, CaseIterable {
|
|||||||
case toolbar
|
case toolbar
|
||||||
case transition
|
case transition
|
||||||
case dice
|
case dice
|
||||||
|
case overlayWindow
|
||||||
|
|
||||||
var id: Self {
|
var id: Self {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
var label: String {
|
var label: String {
|
||||||
rawValue.capitalized
|
switch self {
|
||||||
|
case .overlayWindow:
|
||||||
|
return "Overlay Window"
|
||||||
|
default:
|
||||||
|
return rawValue.capitalized
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var icon: GTUI.Icon? {
|
var icon: GTUI.Icon? {
|
||||||
@ -50,6 +56,8 @@ enum Page: String, Identifiable, CaseIterable {
|
|||||||
return "A slide transition between two views."
|
return "A slide transition between two views."
|
||||||
case .dice:
|
case .dice:
|
||||||
return "Roll the dice."
|
return "Roll the dice."
|
||||||
|
case .overlayWindow:
|
||||||
|
return "A window on top of another window."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +76,8 @@ enum Page: String, Identifiable, CaseIterable {
|
|||||||
TransitionDemo()
|
TransitionDemo()
|
||||||
case .dice:
|
case .dice:
|
||||||
DiceDemo()
|
DiceDemo()
|
||||||
|
case .overlayWindow:
|
||||||
|
OverlayWindowDemo(app: app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user