Add support for natural sizes for breakpoints
All checks were successful
Deploy Docs / publish (push) Successful in 21m0s
SwiftLint / SwiftLint (push) Successful in 5s

This commit is contained in:
david-swift 2024-10-25 14:02:45 +02:00
parent e7c81dba1d
commit ced07e4293
3 changed files with 37 additions and 6 deletions

View File

@ -299,4 +299,16 @@ extension AnyView {
BreakpointBin(condition: .minHeight(minHeight), matches: matches) { self } BreakpointBin(condition: .minHeight(minHeight), matches: matches) { self }
} }
/// Whether the view has a width higher or equal to its natural width.
/// - Parameter matches: Whether the content view matches the breakpoint.
public func naturalWidth(matches: Binding<Bool>) -> AnyView {
BreakpointBin(condition: .naturalWidth, matches: matches) { self }
}
/// Whether the view has a height higher or equal to its natural height.
/// - Parameter matches: Whether the content view matches the breakpoint.
public func naturalHeight(matches: Binding<Bool>) -> AnyView {
BreakpointBin(condition: .naturalHeight, matches: matches) { self }
}
} }

View File

@ -30,13 +30,26 @@ public struct BreakpointBin: AdwaitaWidget {
/// The condition. /// The condition.
@Property( @Property(
set: { bin, condition, storage in set: { bin, condition, storage in
let condition = adw_breakpoint_condition_parse(condition.condition) let string: OpaquePointer
switch condition {
case .naturalWidth:
let child = adw_breakpoint_bin_get_child(bin.cast())
var size: Int32 = 0
gtk_widget_measure(child, GTK_ORIENTATION_HORIZONTAL, -1, nil, &size, nil, nil)
string = adw_breakpoint_condition_parse(BreakpointCondition.minWidth(.init(size)).condition)
case .naturalHeight:
let child = adw_breakpoint_bin_get_child(bin.cast())
var size: Int32 = 0
gtk_widget_measure(child, GTK_ORIENTATION_VERTICAL, -1, nil, &size, nil, nil)
string = adw_breakpoint_condition_parse(BreakpointCondition.minHeight(.init(size)).condition)
default:
string = adw_breakpoint_condition_parse(condition.condition)
}
if let breakpoint = storage.fields["breakpoint"] as? OpaquePointer { if let breakpoint = storage.fields["breakpoint"] as? OpaquePointer {
g_object_unref(adw_breakpoint_get_condition(breakpoint)?.cast()) g_object_unref(adw_breakpoint_get_condition(breakpoint)?.cast())
adw_breakpoint_set_condition(breakpoint, condition) adw_breakpoint_set_condition(breakpoint, string)
} else { } else {
let breakpoint = adw_breakpoint_new(condition) let breakpoint = adw_breakpoint_new(string); adw_breakpoint_bin_add_breakpoint(bin.cast(), breakpoint)
adw_breakpoint_bin_add_breakpoint(bin.cast(), breakpoint)
storage.fields["breakpoint"] = breakpoint storage.fields["breakpoint"] = breakpoint
if let bin = storage.content["_content"]?.first?.content["append"]?.first { if let bin = storage.content["_content"]?.first?.content["append"]?.first {
adw_breakpoint_add_setter( adw_breakpoint_add_setter(
@ -97,9 +110,13 @@ public enum BreakpointCondition: Equatable {
case minWidth(_ width: Int) case minWidth(_ width: Int)
/// Define a minimum height. /// Define a minimum height.
case minHeight(_ height: Int) case minHeight(_ height: Int)
/// The minimum width is the content's natural width.
case naturalWidth
/// The minimum height is the content's natural height.
case naturalHeight
/// The condition to parse. /// The condition to parse.
var condition: String { var condition: String? {
switch self { switch self {
case let .maxWidth(width): case let .maxWidth(width):
"max-width: \(width)sp" "max-width: \(width)sp"
@ -109,6 +126,8 @@ public enum BreakpointCondition: Equatable {
"min-width: \(width)sp" "min-width: \(width)sp"
case let .minHeight(height): case let .minHeight(height):
"min-height: \(height)sp" "min-height: \(height)sp"
default:
nil
} }
} }

View File

@ -47,7 +47,7 @@ struct ViewSwitcherDemo: View {
.bottomToolbar(visible: bottom) { .bottomToolbar(visible: bottom) {
toolbar(bottom: true) toolbar(bottom: true)
} }
.breakpoint(maxWidth: 600, matches: $bottom) .naturalWidth(matches: .init { !bottom } set: { bottom = !$0 })
} }
func toolbar(bottom: Bool) -> AnyView { func toolbar(bottom: Bool) -> AnyView {