Allow gtk modifiers to be expressed as css attributes. (#345)

This commit is contained in:
Morten Bek Ditlevsen 2020-12-31 23:15:00 +01:00 committed by GitHub
parent c9877dcbd7
commit a97a05ffd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 14 deletions

View File

@ -19,15 +19,13 @@ import CGTK
import TokamakCore
extension _FrameLayout: WidgetModifier {
public func modify(widget: UnsafeMutablePointer<GtkWidget>) {
func modify(widget: UnsafeMutablePointer<GtkWidget>) {
gtk_widget_set_size_request(widget, Int32(width ?? -1), Int32(height ?? -1))
// gtk_widget_set_halign(widget, alignment.horizontal.gtkValue)
// gtk_widget_set_valign(widget, alignment.vertical.gtkValue)
}
}
extension _FlexFrameLayout: WidgetModifier {
public func modify(widget: UnsafeMutablePointer<GtkWidget>) {
func modify(widget: UnsafeMutablePointer<GtkWidget>) {
gtk_widget_set_halign(widget, alignment.horizontal.gtkValue)
gtk_widget_set_valign(widget, alignment.vertical.gtkValue)
if maxWidth == .infinity {
@ -44,13 +42,32 @@ extension _FlexFrameLayout: WidgetModifier {
}
}
extension _BackgroundModifier: WidgetModifier where Background == Color {
public func modify(widget: UnsafeMutablePointer<GtkWidget>) {
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)
}
extension Color {
func cssValue(_ environment: EnvironmentValues) -> String {
let rgba = _ColorProxy(self).resolve(in: environment)
return "rgba(\(rgba.red * 255), \(rgba.green * 255), \(rgba.blue * 255), \(rgba.opacity))"
}
}
// Border modifier
extension _OverlayModifier: WidgetAttributeModifier, WidgetModifier
where Overlay == _ShapeView<_StrokedShape<TokamakCore.Rectangle._Inset>, Color>
{
var attributes: [String: String] {
let style = overlay.shape.style.dashPhase == 0 ? "solid" : "dashed"
return [
"border-style": style,
"border-width": "\(overlay.shape.style.lineWidth)px",
"border-color": overlay.style.cssValue(environment),
"border-radius": "inherit"
]
}
}
extension _BackgroundModifier: WidgetAttributeModifier, WidgetModifier where Background == Color {
var attributes: [String: String] {
let cssValue = background.cssValue(environment)
return ["background": cssValue]
}
}

View File

@ -22,6 +22,30 @@ protocol WidgetModifier {
func modify(widget: UnsafeMutablePointer<GtkWidget>)
}
protocol WidgetAttributeModifier: WidgetModifier {
var attributes: [String: String] { get }
}
extension WidgetAttributeModifier {
func modify(widget: UnsafeMutablePointer<GtkWidget>) {
let context = gtk_widget_get_style_context(widget)
let provider = gtk_css_provider_new()
let renderedStyle = attributes.reduce("", { $0 + "\($1.0):\($1.1);"})
gtk_css_provider_load_from_data(provider,
"* { \(renderedStyle) }",
-1,
nil)
gtk_style_context_add_provider(context,
OpaquePointer(provider),
1 /* GTK_STYLE_PROVIDER_PRIORITY_FALLBACK */)
g_object_unref(provider)
}
}
extension ModifiedContent: ViewDeferredToRenderer where Content: View {
public var deferredBody: AnyView {
guard let widgetModifier = modifier as? WidgetModifier else {

View File

@ -22,7 +22,9 @@ struct Counter: View {
@State private var count: Int = 0
var body: some View {
VStack {
Text("\(count)").background(Color(red: 0.5, green: 1, blue: 0.5))
Text("\(count)")
.background(Color(red: 0.5, green: 1, blue: 0.5))
.border(Color.red, width: 1)
HStack {
Button("Decrement") { count -= 1 }
Button("Increment") { count += 1 }