Move from renderable elements to views
This commit is contained in:
parent
1b4621c03a
commit
21e28344c1
59
Sources/TermKitBackend/Button/ButtonCollection.swift
Normal file
59
Sources/TermKitBackend/Button/ButtonCollection.swift
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// ButtonCollection.swift
|
||||
// TermKitBackend
|
||||
//
|
||||
// Created by david-swift on 18.07.2024.
|
||||
//
|
||||
|
||||
import TermKit
|
||||
|
||||
/// A menu is an item of a ``MenuBar``.
|
||||
public struct ButtonCollection: ButtonContext.Widget, Wrapper {
|
||||
|
||||
/// The content of the menu.
|
||||
var content: Body
|
||||
|
||||
/// Initialize a menu.
|
||||
/// - Parameters:
|
||||
/// - label: The menu's label, displayed in the menu bar.
|
||||
/// - content: The content of the menu.
|
||||
public init(@ViewBuilder content: @escaping () -> Body) {
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - type: The type of the views.
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
var buttons: [Button] = []
|
||||
for element in content.storages(modifiers: modifiers, type: type) {
|
||||
if let button = element.pointer as? Button {
|
||||
buttons.append(button)
|
||||
} else if let collection = element.pointer as? [Button] {
|
||||
buttons += collection
|
||||
}
|
||||
}
|
||||
return .init(buttons, content: [.mainContent: content.storages(modifiers: modifiers, type: type)])
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the views.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(AnyView) -> AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
// Buttons in dialogs cannot be updated
|
||||
}
|
||||
|
||||
}
|
21
Sources/TermKitBackend/Button/ButtonContext.swift
Normal file
21
Sources/TermKitBackend/Button/ButtonContext.swift
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// ButtonContext.swift
|
||||
// TermKitBackend
|
||||
//
|
||||
// Created by david-swift on 18.07.2024.
|
||||
//
|
||||
|
||||
import TermKit
|
||||
|
||||
/// The menu items view context.
|
||||
public enum ButtonContext: ViewRenderData {
|
||||
|
||||
/// The type of the widgets.
|
||||
public typealias WidgetType = Widget
|
||||
/// The wrapper type.
|
||||
public typealias WrapperType = ButtonCollection
|
||||
|
||||
/// The type of the widgets.
|
||||
public protocol Widget: Meta.Widget { }
|
||||
|
||||
}
|
@ -8,48 +8,52 @@
|
||||
import TermKit
|
||||
|
||||
/// A menu is an item of a ``MenuBar``.
|
||||
public struct Menu: Renderable {
|
||||
public struct Menu: MenuContext.Widget {
|
||||
|
||||
/// The menu's label, displayed in the menu bar.
|
||||
var label: String
|
||||
/// The content of the menu.
|
||||
var content: [Button]
|
||||
var content: Body
|
||||
|
||||
/// Initialize a menu.
|
||||
/// - Parameters:
|
||||
/// - label: The menu's label, displayed in the menu bar.
|
||||
/// - content: The content of the menu.
|
||||
public init(_ label: String, @Builder<Button> content: () -> [Button]) {
|
||||
public init(_ label: String, @ViewBuilder content: () -> Body) {
|
||||
self.label = label
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - type: The type of the renderable elements.
|
||||
/// - fields: More information.
|
||||
public func container<RenderableType>(type: RenderableType.Type, fields: [String: Any]) -> RenderableStorage {
|
||||
let children = (content as [Renderable]).storages(type: Button.self, fields: [:])
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - type: The type of the views.
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let children = content.storages(modifiers: modifiers, type: type)
|
||||
let menu = MenuBarItem(title: label, children: children.compactMap { $0.pointer as? MenuItem })
|
||||
return .init(menu, content: [.mainContent: children])
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// Update the view storage.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the renderable elements.
|
||||
/// - fields: More information.
|
||||
public func update<RenderableType>(
|
||||
_ storage: RenderableStorage,
|
||||
/// - type: The type of the views.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(AnyView) -> AnyView],
|
||||
updateProperties: Bool,
|
||||
type: RenderableType.Type,
|
||||
fields: [String: Any]
|
||||
) {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storages = storage.content[.mainContent] else {
|
||||
return
|
||||
}
|
||||
(content as [Renderable]).update(storages, updateProperties: updateProperties, type: type, fields: [:])
|
||||
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
||||
}
|
||||
|
72
Sources/TermKitBackend/Menu/MenuCollection.swift
Normal file
72
Sources/TermKitBackend/Menu/MenuCollection.swift
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// MenuCollection.swift
|
||||
// TermKitBackend
|
||||
//
|
||||
// Created by david-swift on 13.07.2024.
|
||||
//
|
||||
|
||||
import TermKit
|
||||
|
||||
/// A menu is an item of a ``MenuBar``.
|
||||
public struct MenuCollection: MenuContext.Widget, Wrapper {
|
||||
|
||||
/// The content of the menu.
|
||||
var content: Body
|
||||
|
||||
/// Initialize a menu.
|
||||
/// - Parameters:
|
||||
/// - label: The menu's label, displayed in the menu bar.
|
||||
/// - content: The content of the menu.
|
||||
public init(@ViewBuilder content: @escaping () -> Body) {
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - type: The type of the views.
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
var storages: [ViewStorage] = []
|
||||
forEachMenu { menu in
|
||||
storages.append(menu.container(modifiers: modifiers, type: type))
|
||||
}
|
||||
return .init(storages.compactMap { $0.pointer }, content: [.mainContent: storages])
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - modifiers: Modify the views before updating.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the views.
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(AnyView) -> AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
// Menus cannot be updated
|
||||
}
|
||||
|
||||
/// Run a function for each menu.
|
||||
/// - Parameter closure: The function.
|
||||
func forEachMenu(closure: @escaping (Menu) -> Void) {
|
||||
var index = 0
|
||||
for element in content {
|
||||
if let menu = element as? Menu {
|
||||
closure(menu)
|
||||
index += 1
|
||||
} else if let collection = element as? [Menu] {
|
||||
for menu in collection {
|
||||
closure(menu)
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
21
Sources/TermKitBackend/Menu/MenuContext.swift
Normal file
21
Sources/TermKitBackend/Menu/MenuContext.swift
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// MenuContext.swift
|
||||
// TermKitBackend
|
||||
//
|
||||
// Created by david-swift on 13.07.2024.
|
||||
//
|
||||
|
||||
import TermKit
|
||||
|
||||
/// The menu items view context.
|
||||
public enum MenuContext: ViewRenderData {
|
||||
|
||||
/// The type of the widgets.
|
||||
public typealias WidgetType = Widget
|
||||
/// The wrapper type.
|
||||
public typealias WrapperType = MenuCollection
|
||||
|
||||
/// The type of the widgets.
|
||||
public protocol Widget: Meta.Widget { }
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
//
|
||||
// Button.swift
|
||||
// TermKitBackend
|
||||
//
|
||||
// Created by david-swift on 07.07.2024.
|
||||
//
|
||||
|
||||
import TermKit
|
||||
|
||||
extension Button: Renderable {
|
||||
|
||||
/// An identifier for the button's action.
|
||||
var actionID: String { "action" }
|
||||
|
||||
/// The view storage.
|
||||
/// - Parameters:
|
||||
/// - type: The type of the renderable elements.
|
||||
/// - fields: More information.
|
||||
public func container<RenderableType>(type: RenderableType.Type, fields: [String: Any]) -> RenderableStorage {
|
||||
let storage = RenderableStorage(nil)
|
||||
let menuItem = MenuItem(title: label) {
|
||||
(storage.fields[actionID] as? () -> Void)?()
|
||||
}
|
||||
storage.pointer = menuItem
|
||||
storage.fields[actionID] = action
|
||||
return storage
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
/// - Parameters:
|
||||
/// - storage: The storage to update.
|
||||
/// - updateProperties: Whether to update the properties.
|
||||
/// - type: The type of the renderable elements.
|
||||
/// - fields: More information.
|
||||
public func update<RenderableType>(
|
||||
_ storage: RenderableStorage,
|
||||
updateProperties: Bool,
|
||||
type: RenderableType.Type,
|
||||
fields: [String: Any]
|
||||
) {
|
||||
guard updateProperties else {
|
||||
return
|
||||
}
|
||||
storage.fields[actionID] = action
|
||||
}
|
||||
|
||||
}
|
@ -18,8 +18,6 @@ public class TermKitApp: AppStorage {
|
||||
/// The wrapper type of the TermKit backend.
|
||||
public typealias WrapperType = VStack
|
||||
|
||||
/// The application.
|
||||
public var app: () -> any App
|
||||
/// The app storage.
|
||||
public var storage: StandardAppStorage = .init()
|
||||
|
||||
@ -27,9 +25,7 @@ public class TermKitApp: AppStorage {
|
||||
/// - Parameters:
|
||||
/// - id: The identifier.
|
||||
/// - app: The application.
|
||||
public required init(id: String, app: @escaping () -> any App) {
|
||||
self.app = app
|
||||
}
|
||||
public required init(id: String) { }
|
||||
|
||||
/// Execute the app.
|
||||
/// - Parameter setup: Set the scene elements up.
|
||||
|
16
Sources/TermKitBackend/Model/TermKitMainView.swift
Normal file
16
Sources/TermKitBackend/Model/TermKitMainView.swift
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// TermKitMainView.swift
|
||||
// TermKitBackend
|
||||
//
|
||||
// Created by david-swift on 13.07.2024.
|
||||
//
|
||||
|
||||
/// The type of widgets of the TermKit backend.
|
||||
public enum TermKitMainView: ViewRenderData {
|
||||
|
||||
/// The type of the widgets.
|
||||
public typealias WidgetType = TermKitWidget
|
||||
/// The wrapper type.
|
||||
public typealias WrapperType = VStack
|
||||
|
||||
}
|
@ -13,13 +13,13 @@ public struct MenuBar: TermKitSceneElement {
|
||||
/// The identifier of the menu bar.
|
||||
public var id: String
|
||||
/// The menu bar's content.
|
||||
var content: [Menu]
|
||||
var content: Body
|
||||
|
||||
/// Initialize the menu bar.
|
||||
/// - Parameters:
|
||||
/// - id: The identifier of the menu bar.
|
||||
/// - content: The menu bar's content.
|
||||
public init(id: String = "main-menu", @Builder<Menu> content: () -> [Menu]) {
|
||||
public init(id: String = "main-menu", @ViewBuilder content: () -> Body) {
|
||||
self.id = id
|
||||
self.content = content()
|
||||
}
|
||||
@ -33,8 +33,9 @@ public struct MenuBar: TermKitSceneElement {
|
||||
/// The scene storage.
|
||||
/// - Parameter app: The app storage.
|
||||
public func container<Storage>(app: Storage) -> SceneStorage where Storage: AppStorage {
|
||||
let items = MenuCollection { content }.container(modifiers: [], type: MenuContext.self)
|
||||
let menubar = TermKit.MenuBar(
|
||||
menus: content.compactMap { $0.container(type: Menu.self, fields: [:]).pointer as? MenuBarItem }
|
||||
menus: items.pointer as? [TermKit.MenuBarItem] ?? []
|
||||
)
|
||||
Task {
|
||||
try await Task.sleep(nanoseconds: 1)
|
||||
|
@ -40,7 +40,7 @@ public struct Window: TermKitSceneElement {
|
||||
let win = TermKit.Window(title)
|
||||
win.fill()
|
||||
Application.top.addSubview(win)
|
||||
let viewStorage = content.storage(modifiers: [], type: Storage.self)
|
||||
let viewStorage = content.storage(modifiers: [], type: TermKitMainView.self)
|
||||
if let pointer = viewStorage.pointer as? TermKit.View {
|
||||
win.addSubview(pointer)
|
||||
}
|
||||
@ -62,7 +62,8 @@ public struct Window: TermKitSceneElement {
|
||||
guard let viewStorage = storage.content[.mainContent]?.first else {
|
||||
return
|
||||
}
|
||||
content.updateStorage(viewStorage, modifiers: [], updateProperties: updateProperties, type: Storage.self)
|
||||
content
|
||||
.updateStorage(viewStorage, modifiers: [], updateProperties: updateProperties, type: TermKitMainView.self)
|
||||
Application.refresh()
|
||||
}
|
||||
|
||||
|
@ -8,13 +8,16 @@
|
||||
import TermKit
|
||||
|
||||
/// A simple button widget.
|
||||
public struct Button: TermKitWidget {
|
||||
public struct Button: TermKitWidget, ButtonContext.Widget, MenuContext.Widget {
|
||||
|
||||
/// The button's label.
|
||||
var label: String
|
||||
/// The action.
|
||||
var action: () -> Void
|
||||
|
||||
/// The identifier for the action closure.
|
||||
let actionID = "action"
|
||||
|
||||
/// Initialize a button.
|
||||
/// - Parameters:
|
||||
/// - The button's label.
|
||||
@ -28,10 +31,22 @@ public struct Button: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
if type == MenuContext.self {
|
||||
let storage = ViewStorage(nil)
|
||||
let menuItem = MenuItem(title: label) {
|
||||
(storage.fields[actionID] as? () -> Void)?()
|
||||
}
|
||||
storage.pointer = menuItem
|
||||
storage.fields[actionID] = action
|
||||
return storage
|
||||
} else if type == ButtonContext.self {
|
||||
return ViewStorage(self)
|
||||
}
|
||||
let button = TermKit.Button(label, clicked: action)
|
||||
return .init(button)
|
||||
}
|
||||
@ -42,12 +57,15 @@ public struct Button: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
if type == MenuContext.self {
|
||||
storage.fields[actionID] = action
|
||||
}
|
||||
guard let storage = storage.pointer as? TermKit.Button else {
|
||||
return
|
||||
}
|
||||
|
@ -28,10 +28,11 @@ public struct Checkbox: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let button = TermKit.Checkbox(label, checked: isOn.wrappedValue)
|
||||
button.toggled = { _ in
|
||||
isOn.wrappedValue = button.checked
|
||||
@ -45,12 +46,12 @@ public struct Checkbox: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storage = storage.pointer as? TermKit.Checkbox, updateProperties else {
|
||||
return
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ struct Box: TermKitWidget {
|
||||
/// The signal.
|
||||
var signal: Signal
|
||||
/// The buttons (info box if none).
|
||||
var buttons: [Button]
|
||||
var buttons: Body
|
||||
/// The content behind the box.
|
||||
var content: AnyView
|
||||
/// Whether it is an error box.
|
||||
@ -30,16 +30,15 @@ struct Box: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storage = ViewStorage(nil)
|
||||
let contentStorage = content.storage(modifiers: modifiers, type: type)
|
||||
storage.pointer = contentStorage.pointer
|
||||
storage.content = [.mainContent: [contentStorage]]
|
||||
storage.fields[boxButtonsID] = buttons
|
||||
return storage
|
||||
return .init(contentStorage.pointer, content: [.mainContent: [contentStorage]])
|
||||
}
|
||||
|
||||
/// Update the stored content.
|
||||
@ -48,16 +47,18 @@ struct Box: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
func update<Storage>(
|
||||
func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storage = storage.content[.mainContent]?.first else {
|
||||
return
|
||||
}
|
||||
content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
|
||||
let buttons = ButtonCollection { self.buttons }
|
||||
.storage(modifiers: modifiers, type: ButtonContext.self).pointer as? [Button] ?? []
|
||||
storage.fields[boxButtonsID] = buttons
|
||||
if signal.update {
|
||||
if buttons.isEmpty {
|
||||
@ -89,7 +90,7 @@ extension AnyView {
|
||||
_ title: String,
|
||||
message: String,
|
||||
signal: Signal,
|
||||
@Builder<Button> buttons: @escaping () -> [Button]
|
||||
@ViewBuilder buttons: @escaping () -> Body
|
||||
) -> AnyView {
|
||||
Box(title: title, message: message, signal: signal, buttons: buttons(), content: self)
|
||||
}
|
||||
@ -105,7 +106,7 @@ extension AnyView {
|
||||
_ title: String,
|
||||
message: String,
|
||||
signal: Signal,
|
||||
@Builder<Button> buttons: @escaping () -> [Button]
|
||||
@ViewBuilder buttons: @escaping () -> Body
|
||||
) -> AnyView {
|
||||
Box(title: title, message: message, signal: signal, buttons: buttons(), content: self, error: true)
|
||||
}
|
||||
|
@ -28,10 +28,11 @@ public struct Frame: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let frame = TermKit.Frame(label)
|
||||
let subview = view.storage(modifiers: modifiers, type: type)
|
||||
if let pointer = subview.pointer as? TermKit.View {
|
||||
@ -46,12 +47,12 @@ public struct Frame: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
if let storage = storage.content[.mainContent]?.first {
|
||||
view.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
|
||||
}
|
||||
|
@ -23,10 +23,10 @@ public struct HStack: Wrapper, TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storages = content.storages(modifiers: modifiers, type: type)
|
||||
if storages.count == 1 {
|
||||
return .init(storages[0].pointer, content: [.mainContent: storages])
|
||||
@ -49,12 +49,12 @@ public struct HStack: Wrapper, TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storages = storage.content[.mainContent] else {
|
||||
return
|
||||
}
|
||||
|
@ -23,10 +23,11 @@ public struct Label: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let button = TermKit.Label(label)
|
||||
return .init(button)
|
||||
}
|
||||
@ -37,12 +38,12 @@ public struct Label: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storage = storage.pointer as? TermKit.Label, updateProperties else {
|
||||
return
|
||||
}
|
||||
|
@ -28,10 +28,11 @@ public struct ListView<Element>: TermKitWidget where Element: CustomStringConver
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let list = TermKit.ListView(items: items.map { $0.description })
|
||||
setClosure(list: list)
|
||||
return .init(list)
|
||||
@ -43,12 +44,12 @@ public struct ListView<Element>: TermKitWidget where Element: CustomStringConver
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let list = storage.pointer as? TermKit.ListView else {
|
||||
return
|
||||
}
|
||||
|
@ -28,10 +28,11 @@ public struct ProgressBar: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let bar = TermKit.ProgressBar()
|
||||
bar.fraction = .init(value / max)
|
||||
return .init(bar)
|
||||
@ -43,12 +44,12 @@ public struct ProgressBar: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storage = storage.pointer as? TermKit.ProgressBar, updateProperties else {
|
||||
return
|
||||
}
|
||||
|
@ -23,10 +23,11 @@ public struct ScrollView: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storages = content.storages(modifiers: modifiers, type: type)
|
||||
if storages.count == 1 {
|
||||
return .init(storages[0].pointer, content: [.mainContent: storages])
|
||||
@ -49,12 +50,12 @@ public struct ScrollView: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storages = storage.content[.mainContent] else {
|
||||
return
|
||||
}
|
||||
|
@ -28,10 +28,11 @@ public struct TextField: TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
/// - Returns: The view storage.
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let field = TermKit.TextField(text.wrappedValue)
|
||||
let storage = ViewStorage(field)
|
||||
field.secret = secret
|
||||
@ -52,12 +53,12 @@ public struct TextField: TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let field = storage.pointer as? TermKit.TextField else {
|
||||
return
|
||||
}
|
||||
|
@ -23,10 +23,10 @@ public struct VStack: Wrapper, TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storages = content.storages(modifiers: modifiers, type: type)
|
||||
if storages.count == 1 {
|
||||
return .init(storages[0].pointer, content: [.mainContent: storages])
|
||||
@ -49,12 +49,12 @@ public struct VStack: Wrapper, TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storages = storage.content[.mainContent] else {
|
||||
return
|
||||
}
|
||||
|
@ -23,10 +23,10 @@ public struct ZStack: Wrapper, TermKitWidget {
|
||||
/// - Parameters:
|
||||
/// - modifiers: Modify views before being updated.
|
||||
/// - type: The type of the app storage.
|
||||
public func container<Storage>(
|
||||
public func container<Data>(
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
type: Storage.Type
|
||||
) -> ViewStorage where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) -> ViewStorage where Data: ViewRenderData {
|
||||
let storages = content.reversed().storages(modifiers: modifiers, type: type)
|
||||
if storages.count == 1 {
|
||||
return .init(storages[0].pointer, content: [.mainContent: storages])
|
||||
@ -46,12 +46,12 @@ public struct ZStack: Wrapper, TermKitWidget {
|
||||
/// - modifiers: Modify views before being updated
|
||||
/// - updateProperties: Whether to update the view's properties.
|
||||
/// - type: The type of the app storage.
|
||||
public func update<Storage>(
|
||||
public func update<Data>(
|
||||
_ storage: ViewStorage,
|
||||
modifiers: [(any AnyView) -> any AnyView],
|
||||
updateProperties: Bool,
|
||||
type: Storage.Type
|
||||
) where Storage: AppStorage {
|
||||
type: Data.Type
|
||||
) where Data: ViewRenderData {
|
||||
guard let storages = storage.content[.mainContent] else {
|
||||
return
|
||||
}
|
||||
|
@ -33,20 +33,25 @@ struct TestApp: App {
|
||||
|
||||
var menuBar: MenuBar {
|
||||
.init {
|
||||
Menu("File") {
|
||||
Button("_About TermKitBackend") {
|
||||
about.signal()
|
||||
}
|
||||
Button("_Quit") {
|
||||
app.quit()
|
||||
}
|
||||
}
|
||||
fileMenu
|
||||
Menu("_Actions") {
|
||||
Button("_Hello, world!") { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
var fileMenu: Body {
|
||||
Menu("File") {
|
||||
Button("_About TermKitBackend") {
|
||||
about.signal()
|
||||
}
|
||||
Button("_Quit") {
|
||||
app.quit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var aboutInfo: String {
|
||||
"""
|
||||
This is a sample backend for the Meta package of the Aparoksha project.
|
||||
|
Loading…
Reference in New Issue
Block a user