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 }
}
/// 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.
@Property(
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 {
g_object_unref(adw_breakpoint_get_condition(breakpoint)?.cast())
adw_breakpoint_set_condition(breakpoint, condition)
adw_breakpoint_set_condition(breakpoint, string)
} else {
let breakpoint = adw_breakpoint_new(condition)
adw_breakpoint_bin_add_breakpoint(bin.cast(), breakpoint)
let breakpoint = adw_breakpoint_new(string); adw_breakpoint_bin_add_breakpoint(bin.cast(), breakpoint)
storage.fields["breakpoint"] = breakpoint
if let bin = storage.content["_content"]?.first?.content["append"]?.first {
adw_breakpoint_add_setter(
@ -97,9 +110,13 @@ public enum BreakpointCondition: Equatable {
case minWidth(_ width: Int)
/// Define a minimum height.
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.
var condition: String {
var condition: String? {
switch self {
case let .maxWidth(width):
"max-width: \(width)sp"
@ -109,6 +126,8 @@ public enum BreakpointCondition: Equatable {
"min-width: \(width)sp"
case let .minHeight(height):
"min-height: \(height)sp"
default:
nil
}
}

View File

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