Update to latest Meta version

This commit is contained in:
david-swift 2024-08-25 16:42:55 +02:00
parent ec86bf1324
commit 376d8c724f
24 changed files with 180 additions and 56 deletions

View File

@ -25,18 +25,18 @@ public struct ButtonCollection: ButtonWidget, Wrapper {
/// - type: The type of the views.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
var buttons: [Button] = []
for element in content.storages(modifiers: modifiers, type: type) {
for element in content.storages(data: data, 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)])
return .init(buttons, content: [.mainContent: content.storages(data: data, type: type)])
}
/// Update the stored content.
@ -47,7 +47,7 @@ public struct ButtonCollection: ButtonWidget, Wrapper {
/// - type: The type of the views.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(AnyView) -> AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -14,6 +14,8 @@ public enum ButtonContext: ViewRenderData {
public typealias WidgetType = ButtonWidget
/// The wrapper type.
public typealias WrapperType = ButtonCollection
/// The either view type.
public typealias EitherViewType = NotUpdatableEitherView
}

View File

@ -0,0 +1,23 @@
//
// NotUpdatableEitherView.swift
// TermKitBackend
//
// Created by david-swift on 25.08.2024.
//
/// An either view for views which do not support updating.
public struct NotUpdatableEitherView: SimpleView, Meta.EitherView {
/// The content.
public var view: Body
/// Initialize the either view.
/// - Parameters:
/// - condition: The condition.
/// - view1: The first view.
/// - view2: The other view.
public init(_ condition: Bool, view1: () -> Body, else view2: () -> Body) {
self.view = condition ? view1() : view2()
}
}

View File

@ -30,10 +30,10 @@ public struct Menu: MenuWidget {
/// - type: The type of the views.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let children = content.storages(modifiers: modifiers, type: type)
let children = content.storages(data: data, type: type)
let menu = MenuBarItem(title: label, children: children.compactMap { $0.pointer as? MenuItem })
return .init(menu, content: [.mainContent: children])
}
@ -46,14 +46,14 @@ public struct Menu: MenuWidget {
/// - type: The type of the views.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(AnyView) -> AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
content.update(storages, data: data, updateProperties: updateProperties, type: type)
}
}

View File

@ -25,12 +25,12 @@ public struct MenuCollection: MenuWidget, Wrapper {
/// - type: The type of the views.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
var storages: [ViewStorage] = []
forEachMenu { menu in
storages.append(menu.container(modifiers: modifiers, type: type))
storages.append(menu.container(data: data, type: type))
}
return .init(storages.compactMap { $0.pointer }, content: [.mainContent: storages])
}
@ -43,7 +43,7 @@ public struct MenuCollection: MenuWidget, Wrapper {
/// - type: The type of the views.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(AnyView) -> AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -14,6 +14,8 @@ public enum MenuContext: ViewRenderData {
public typealias WidgetType = MenuWidget
/// The wrapper type.
public typealias WrapperType = MenuCollection
/// The either view type.
public typealias EitherViewType = NotUpdatableEitherView
}

View File

@ -7,6 +7,7 @@
import TermKit
/// Extend `AnyView`.
extension AnyView {
/// Set a view's width and height.

View File

@ -12,5 +12,7 @@ public enum TermKitMainView: ViewRenderData {
public typealias WidgetType = TermKitWidget
/// The wrapper type.
public typealias WrapperType = VStack
/// The either view type.
public typealias EitherViewType = EitherView
}

View File

@ -33,7 +33,11 @@ struct MenuBar: TermKitSceneElement {
/// The scene storage.
/// - Parameter app: The app storage.
func container<Storage>(app: Storage) -> SceneStorage where Storage: AppStorage {
let items = MenuCollection { content }.container(modifiers: [], type: MenuContext.self)
let storage = SceneStorage(id: id, pointer: nil) { }
let items = MenuCollection { content }.container(
data: .init(sceneStorage: storage, appStorage: app),
type: MenuContext.self
)
let menubar = TermKit.MenuBar(
menus: items.pointer as? [TermKit.MenuBarItem] ?? []
)
@ -41,9 +45,11 @@ struct MenuBar: TermKitSceneElement {
element.y = .bottom(of: menubar)
}
Application.top.addSubview(menubar)
return .init(id: id, pointer: menubar) {
storage.pointer = menubar
storage.show = {
menubar.ensureFocus()
}
return storage
}
/// Update the stored content.

View File

@ -40,13 +40,18 @@ public struct Window: TermKitSceneElement {
let win = TermKit.Window(title)
win.fill()
Application.top.addSubview(win)
let viewStorage = content.storage(modifiers: [], type: TermKitMainView.self)
let storage = SceneStorage(id: id, pointer: win) {
win.ensureFocus()
}
let viewStorage = content.storage(
data: .init(sceneStorage: storage, appStorage: app),
type: TermKitMainView.self
)
if let pointer = viewStorage.pointer as? TermKit.View {
win.addSubview(pointer)
}
return .init(id: id, pointer: win, content: [.mainContent: [viewStorage]]) {
win.ensureFocus()
}
storage.content = [.mainContent: [viewStorage]]
return storage
}
/// Update the stored content.
@ -63,7 +68,12 @@ public struct Window: TermKitSceneElement {
return
}
content
.updateStorage(viewStorage, modifiers: [], updateProperties: updateProperties, type: TermKitMainView.self)
.updateStorage(
viewStorage,
data: .init(sceneStorage: storage, appStorage: app),
updateProperties: updateProperties,
type: TermKitMainView.self
)
Application.refresh()
}

View File

@ -33,7 +33,7 @@ public struct Button: TermKitWidget, ButtonWidget, MenuWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
if type == MenuContext.self {
@ -59,7 +59,7 @@ public struct Button: TermKitWidget, ButtonWidget, MenuWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -30,7 +30,7 @@ public struct Checkbox: TermKitWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let button = TermKit.Checkbox(label, checked: isOn.wrappedValue)
@ -48,7 +48,7 @@ public struct Checkbox: TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -32,11 +32,11 @@ struct Box: TermKitWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storage = ViewStorage(nil)
let contentStorage = content.storage(modifiers: modifiers, type: type)
let contentStorage = content.storage(data: data, type: type)
storage.pointer = contentStorage.pointer
return .init(contentStorage.pointer, content: [.mainContent: [contentStorage]])
}
@ -49,16 +49,16 @@ struct Box: TermKitWidget {
/// - type: The type of the app storage.
func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let storage = storage.content[.mainContent]?.first else {
return
}
content.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
content.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
let buttons = ButtonCollection { self.buttons }
.storage(modifiers: modifiers, type: ButtonContext.self).pointer as? [Button] ?? []
.storage(data: data, type: ButtonContext.self).pointer as? [Button] ?? []
storage.fields[boxButtonsID] = buttons
if signal.update {
if buttons.isEmpty {
@ -77,6 +77,7 @@ struct Box: TermKitWidget {
}
/// Extend `AnyView`,
extension AnyView {
/// Add a query box.

View File

@ -0,0 +1,78 @@
//
// EitherView.swift
// TermKitBackend
//
// Created by david-swift on 25.08.2024.
//
import TermKit
/// A container which draws a frame around its contents.
public struct EitherView: TermKitWidget, Meta.EitherView {
/// The condition.
var condition: Bool
/// The first view.
var view1: Body
/// The second view.
var view2: Body
/// Initialize an either view.
/// - Parameters:
/// - condition: The condition.
/// - view1: The first view.
/// - view2: The second view.
public init(_ condition: Bool, @ViewBuilder view1: () -> Body, @ViewBuilder else view2: () -> Body) {
self.condition = condition
self.view1 = view1()
self.view2 = view2()
}
/// The view storage.
/// - Parameters:
/// - modifiers: Modify views before being updated.
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let view = TermKit.View()
let storage = ViewStorage(view)
update(storage, data: data, updateProperties: true, type: type)
return storage
}
/// Update the stored content.
/// - Parameters:
/// - storage: The storage to update.
/// - modifiers: Modify views before being updated
/// - updateProperties: Whether to update the view's properties.
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let parent = storage.pointer as? TermKit.View else {
return
}
let view: TermKit.View?
let body = condition ? view1 : view2
if let content = storage.content[condition.description]?.first {
body.updateStorage(content, data: data, updateProperties: updateProperties, type: type)
view = content.pointer as? TermKit.View
} else {
let content = body.storage(data: data, type: type)
storage.content[condition.description] = [content]
view = content.pointer as? TermKit.View
}
if let view, (storage.previousState as? Self)?.condition != condition {
parent.removeAllSubviews()
parent.addSubview(view)
}
storage.previousState = self
}
}

View File

@ -30,11 +30,11 @@ public struct Frame: TermKitWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let frame = TermKit.Frame(label)
let subview = view.storage(modifiers: modifiers, type: type)
let subview = view.storage(data: data, type: type)
if let pointer = subview.pointer as? TermKit.View {
frame.addSubview(pointer)
}
@ -49,12 +49,12 @@ public struct Frame: TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
if let storage = storage.content[.mainContent]?.first {
view.updateStorage(storage, modifiers: modifiers, updateProperties: updateProperties, type: type)
view.updateStorage(storage, data: data, updateProperties: updateProperties, type: type)
}
guard let pointer = storage.pointer as? TermKit.Frame,
updateProperties,

View File

@ -24,10 +24,10 @@ public struct HStack: Wrapper, TermKitWidget {
/// - modifiers: Modify views before being updated.
/// - type: The type of the app storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storages = content.storages(modifiers: modifiers, type: type)
let storages = content.storages(data: data, type: type)
if storages.count == 1 {
return .init(storages[0].pointer, content: [.mainContent: storages])
}
@ -51,14 +51,14 @@ public struct HStack: Wrapper, TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
content.update(storages, data: data, updateProperties: updateProperties, type: type)
}
}

View File

@ -25,7 +25,7 @@ public struct Label: TermKitWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let button = TermKit.Label(label)
@ -40,7 +40,7 @@ public struct Label: TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -30,7 +30,7 @@ public struct ListView<Element>: TermKitWidget where Element: CustomStringConver
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let list = TermKit.ListView(items: items.map { $0.description })
@ -46,7 +46,7 @@ public struct ListView<Element>: TermKitWidget where Element: CustomStringConver
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -35,7 +35,7 @@ public struct ProgressBar: TermKitWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let bar = TermKit.ProgressBar()
@ -51,7 +51,7 @@ public struct ProgressBar: TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -25,10 +25,10 @@ public struct ScrollView: TermKitWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storages = content.storages(modifiers: modifiers, type: type)
let storages = content.storages(data: data, type: type)
if storages.count == 1 {
return .init(storages[0].pointer, content: [.mainContent: storages])
}
@ -52,14 +52,14 @@ public struct ScrollView: TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
content.update(storages, data: data, updateProperties: updateProperties, type: type)
}
}

View File

@ -30,7 +30,7 @@ public struct TextField: TermKitWidget {
/// - type: The type of the app storage.
/// - Returns: The view storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let field = TermKit.TextField(text.wrappedValue)
@ -53,7 +53,7 @@ public struct TextField: TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {

View File

@ -24,10 +24,10 @@ public struct VStack: Wrapper, TermKitWidget {
/// - modifiers: Modify views before being updated.
/// - type: The type of the app storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storages = content.storages(modifiers: modifiers, type: type)
let storages = content.storages(data: data, type: type)
if storages.count == 1 {
return .init(storages[0].pointer, content: [.mainContent: storages])
}
@ -51,14 +51,14 @@ public struct VStack: Wrapper, TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let storages = storage.content[.mainContent] else {
return
}
content.update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
content.update(storages, data: data, updateProperties: updateProperties, type: type)
}
}

View File

@ -24,10 +24,10 @@ public struct ZStack: Wrapper, TermKitWidget {
/// - modifiers: Modify views before being updated.
/// - type: The type of the app storage.
public func container<Data>(
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let storages = content.reversed().storages(modifiers: modifiers, type: type)
let storages = content.reversed().storages(data: data, type: type)
if storages.count == 1 {
return .init(storages[0].pointer, content: [.mainContent: storages])
}
@ -48,14 +48,14 @@ public struct ZStack: Wrapper, TermKitWidget {
/// - type: The type of the app storage.
public func update<Data>(
_ storage: ViewStorage,
modifiers: [(any AnyView) -> any AnyView],
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
guard let storages = storage.content[.mainContent] else {
return
}
content.reversed().update(storages, modifiers: modifiers, updateProperties: updateProperties, type: type)
content.reversed().update(storages, data: data, updateProperties: updateProperties, type: type)
}
}

View File

@ -12,7 +12,6 @@ import TermKitBackend
struct TestApp: App {
@State private var about: Signal = .init()
@State private var state = false
let id = "io.github.AparokshaUI.TestApp"
var app: TermKitApp!