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()
|
||||
for windowScene in body.scene.windows() {
|
||||
for _ in 0..<windowScene.open {
|
||||
sceneStorage.append(windowScene.createWindow(app: self))
|
||||
addWindow(windowScene.id)
|
||||
}
|
||||
setParentWindows()
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,9 +49,21 @@ public class GTUIApp: Application {
|
||||
/// - 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))
|
||||
State<Any>.updateViews()
|
||||
if let window = body().scene.windows().last(where: { $0.id == id }) {
|
||||
let window = window.createWindow(app: self)
|
||||
sceneStorage.append(window)
|
||||
setParentWindows()
|
||||
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.
|
||||
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.
|
||||
var `open`: Int { get }
|
||||
/// The keyboard shortcuts on the application's level.
|
||||
|
||||
@ -12,6 +12,8 @@ public class WindowStorage {
|
||||
|
||||
/// The window's identifier.
|
||||
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.
|
||||
public var destroy = false
|
||||
/// The GTUI window.
|
||||
|
||||
@ -18,6 +18,8 @@ public struct Window: WindowScene {
|
||||
var content: (GTUIApplicationWindow) -> Body
|
||||
/// Whether an instance of the window type should be opened when the app is starting up.
|
||||
public var `open`: Int
|
||||
/// The identifier of the window's parent.
|
||||
public var parentID: String?
|
||||
/// The keyboard shortcuts.
|
||||
var shortcuts: [String: (GTUIApplicationWindow) -> Void] = [:]
|
||||
/// The keyboard shortcuts on the app level.
|
||||
@ -45,6 +47,7 @@ public struct Window: WindowScene {
|
||||
windowStorage.destroy = true
|
||||
return false
|
||||
}
|
||||
windowStorage.parentID = parentID
|
||||
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.
|
||||
/// - Parameters:
|
||||
/// - shortcut: The keyboard shortcut.
|
||||
|
||||
@ -20,6 +20,12 @@ struct Demo: App {
|
||||
Window(id: "main") { window in
|
||||
DemoContent(window: window, app: app)
|
||||
}
|
||||
.overlay {
|
||||
Window(id: "overlay", open: 0) { window in
|
||||
OverlayWindowDemo.WindowContent(window: window)
|
||||
}
|
||||
.keyboardShortcut("Escape") { $0.close() }
|
||||
}
|
||||
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 transition
|
||||
case dice
|
||||
case overlayWindow
|
||||
|
||||
var id: Self {
|
||||
self
|
||||
}
|
||||
|
||||
var label: String {
|
||||
rawValue.capitalized
|
||||
switch self {
|
||||
case .overlayWindow:
|
||||
return "Overlay Window"
|
||||
default:
|
||||
return rawValue.capitalized
|
||||
}
|
||||
}
|
||||
|
||||
var icon: GTUI.Icon? {
|
||||
@ -50,6 +56,8 @@ enum Page: String, Identifiable, CaseIterable {
|
||||
return "A slide transition between two views."
|
||||
case .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()
|
||||
case .dice:
|
||||
DiceDemo()
|
||||
case .overlayWindow:
|
||||
OverlayWindowDemo(app: app)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user