portico/Sources/Portico/State/Condition.swift

82 lines
3.1 KiB
Swift

import Adw
/// A type-safe builder for libadwaita breakpoint conditions.
///
/// Use a condition with ``WidgetView/breakpoint(_:isActive:)`` or one of the
/// typed setter breakpoint modifiers. String literals are parsed by libadwaita.
public enum Condition: ExpressibleByStringLiteral {
/// Matches when the width is at most the supplied value.
case maxWidth(Double, LengthUnit = .px)
/// Matches when the width is at least the supplied value.
case minWidth(Double, LengthUnit = .px)
/// Matches when the height is at most the supplied value.
case maxHeight(Double, LengthUnit = .px)
/// Matches when the height is at least the supplied value.
case minHeight(Double, LengthUnit = .px)
/// Matches when the aspect ratio is at most `width / height`.
case maxAspectRatio(width: Int, height: Int = 1)
/// Matches when the aspect ratio is at least `width / height`.
case minAspectRatio(width: Int, height: Int = 1)
/// Matches when both nested conditions match.
indirect case and(Condition, Condition)
/// Matches when either nested condition matches.
indirect case or(Condition, Condition)
/// Wraps an already constructed libadwaita condition.
case raw(BreakpointCondition)
/// Creates a condition from a libadwaita condition string.
public init(stringLiteral value: String) {
self = .raw(BreakpointCondition.parse(str: value))
}
/// The libadwaita condition represented by this value.
public var condition: BreakpointCondition {
switch self {
case let .maxWidth(value, unit):
return BreakpointCondition(
type: .maxWidth,
value: value,
unit: unit
)
case let .minWidth(value, unit):
return BreakpointCondition(
type: .minWidth,
value: value,
unit: unit
)
case let .maxHeight(value, unit):
return BreakpointCondition(
type: .maxHeight,
value: value,
unit: unit
)
case let .minHeight(value, unit):
return BreakpointCondition(
type: .minHeight,
value: value,
unit: unit
)
case let .maxAspectRatio(width, height):
return BreakpointCondition(
type: .maxAspectRatio,
width: Int32(width),
height: Int32(height)
)
case let .minAspectRatio(width, height):
return BreakpointCondition(
type: .minAspectRatio,
width: Int32(width),
height: Int32(height)
)
case let .and(first, second):
return BreakpointCondition(condition1: first.condition, condition2: second.condition)
case let .or(first, second):
return BreakpointCondition(
orCondition1: first.condition,
orCondition2: second.condition
)
case let .raw(condition):
return condition
}
}
}