diff --git a/Sources/TokamakGTK/Modifiers/LayoutModifiers.swift b/Sources/TokamakGTK/Modifiers/LayoutModifiers.swift index 431aa67c..f9f785da 100644 --- a/Sources/TokamakGTK/Modifiers/LayoutModifiers.swift +++ b/Sources/TokamakGTK/Modifiers/LayoutModifiers.swift @@ -43,3 +43,14 @@ extension _FlexFrameLayout: WidgetModifier { gtk_widget_set_size_request(widget, Int32(idealWidth ?? -1), Int32(idealHeight ?? -1)) } } + +extension _BackgroundModifier: WidgetModifier where Background == Color { + public func modify(widget: UnsafeMutablePointer) { + let resolved = _ColorProxy(self.background).resolve(in: environment) + var color = GdkRGBA(red: resolved.red, + green: resolved.green, + blue: resolved.blue, + alpha: resolved.opacity) + gtk_widget_override_background_color(widget, GtkStateFlags(rawValue: 0), &color) + } +} diff --git a/Sources/TokamakGTK/Modifiers/WidgetModifier.swift b/Sources/TokamakGTK/Modifiers/WidgetModifier.swift index 046481d4..8743d404 100644 --- a/Sources/TokamakGTK/Modifiers/WidgetModifier.swift +++ b/Sources/TokamakGTK/Modifiers/WidgetModifier.swift @@ -24,38 +24,44 @@ protocol WidgetModifier { extension ModifiedContent: ViewDeferredToRenderer where Content: View { public var deferredBody: AnyView { - if let widgetModifier = modifier as? WidgetModifier { - if let anyView = content as? ViewDeferredToRenderer, - let anyWidget = mapAnyView( - anyView.deferredBody, - transform: { (widget: AnyWidget) in widget } - ) - { - return AnyView(WidgetView { - let contentWidget = anyWidget.new($0) - widgetModifier.modify(widget: contentWidget) - return contentWidget - } content: { - if let parentView = anyWidget as? ParentView { - ForEach(Array(parentView.children.enumerated()), id: \.offset) { _, view in - view - } - } - }) - } else if let anyWidget = content as? AnyWidget { - return AnyView(WidgetView { - let contentWidget = anyWidget.new($0) - widgetModifier.modify(widget: contentWidget) - return contentWidget - } content: { - if let parentView = anyWidget as? ParentView { - ForEach(Array(parentView.children.enumerated()), id: \.offset) { _, view in - view - } - } - }) + guard let widgetModifier = modifier as? WidgetModifier else { + return AnyView(content) + } + let anyWidget: AnyWidget + if let anyView = content as? ViewDeferredToRenderer, + let _anyWidget = mapAnyView( + anyView.deferredBody, + transform: { (widget: AnyWidget) in widget } + ) + { + anyWidget = _anyWidget + } else if let _anyWidget = content as? AnyWidget { + anyWidget = _anyWidget + } else { + return AnyView(content) + } + return AnyView(WidgetView { + let contentWidget = anyWidget.new($0) + widgetModifier.modify(widget: contentWidget) + return contentWidget + } + update: { widget in + anyWidget.update(widget: widget) + + // Is it correct to apply the modifier again after updating? + // I assume so since the modifier parameters may have changed. + if case .widget(let w) = widget.storage { + widgetModifier.modify(widget: w) } } - return AnyView(content) + content: { + if let parentView = anyWidget as? ParentView, parentView.children.count > 1 { + ForEach(Array(parentView.children.enumerated()), id: \.offset) { _, view in + view + } + } else if let parentView = anyWidget as? ParentView, parentView.children.count == 1 { + parentView.children[0] + } + }) } } diff --git a/Sources/TokamakGTK/Widget.swift b/Sources/TokamakGTK/Widget.swift index 1fa716fc..988a2374 100644 --- a/Sources/TokamakGTK/Widget.swift +++ b/Sources/TokamakGTK/Widget.swift @@ -27,16 +27,19 @@ extension AnyWidget { struct WidgetView: View, AnyWidget, ParentView { let build: (UnsafeMutablePointer) -> UnsafeMutablePointer + let update: (Widget) -> Void let content: Content let expand: Bool init(build: @escaping (UnsafeMutablePointer) -> UnsafeMutablePointer, + update: @escaping (Widget) -> Void = { _ in }, expand: Bool = false, @ViewBuilder content: () -> Content) { self.build = build self.expand = expand self.content = content() + self.update = update } func new(_ application: UnsafeMutablePointer) -> UnsafeMutablePointer { @@ -44,9 +47,8 @@ struct WidgetView: View, AnyWidget, ParentView { } func update(widget: Widget) { - // Rebuild from scratch - if case let .widget(w) = widget.storage { - widget.destroy() + if case .widget = widget.storage { + update(widget) } } diff --git a/Sources/TokamakGTKDemo/main.swift b/Sources/TokamakGTKDemo/main.swift index dc49da27..54df3a2d 100644 --- a/Sources/TokamakGTKDemo/main.swift +++ b/Sources/TokamakGTKDemo/main.swift @@ -22,7 +22,7 @@ struct Counter: View { @State private var count: Int = 0 var body: some View { VStack { - Text("\(count)") + Text("\(count)").background(Color(red: 0.5, green: 1, blue: 0.5)) HStack { Button("Decrement") { count -= 1 } Button("Increment") { count += 1 }