Files
babaevmm 956c055cd8 update swiftformat, add organize rule
commit_hash:0f7ba811b37db6d2a9fc05efe5f94502feda4856
2025-08-04 16:24:48 +03:00

101 lines
3.1 KiB
Swift

import Foundation
import LayoutKit
/// ``DivViewSize`` represents the sizing information for a division card.
///
/// The structure offers flexibility in specifying sizes, ranging from
/// matching the parent's size, having a fixed desired size, to a dynamic size
/// dependent on another dimension.
public struct DivViewSize: Equatable {
/// Represents the different ways to specify a dimension for the `DivViewSize`.
///
/// - ``matchParent``: This dimension should match the parent's size.
/// - ``desired(_:)``: This dimension has a fixed size.
/// - ``dependsOnOtherDimensionSize(_:)``: The size depends on the size of another dimension.
public enum DivDimension: Equatable {
case matchParent
case desired(CGFloat)
case dependsOnOtherDimensionSize((CGFloat) -> CGFloat)
public static func ==(lhs: DivDimension, rhs: DivDimension) -> Bool {
switch (lhs, rhs) {
case let (.desired(lhs), .desired(rhs)):
lhs == rhs
case (.matchParent, .matchParent),
(.dependsOnOtherDimensionSize, dependsOnOtherDimensionSize):
true
default:
false
}
}
}
public let width: DivDimension
public let height: DivDimension
private let constrainedWidth: Bool
private let constrainedHeight: Bool
public init(block: Block) {
let width: DivDimension = block
.isHorizontallyResizable ? .matchParent : .desired(block.widthOfHorizontallyNonResizableBlock)
let height = makeHeightDimensionSize(block: block, width: width)
self.width = width
self.height = height
self.constrainedWidth = block.isHorizontallyConstrained
self.constrainedHeight = block.isVerticallyConstrained
}
/// Computes the actual size for a ``DivView`` given its parent's size.
///
/// - Parameters:
/// - parentViewSize: The size of the parent view.
///
/// - Returns:
/// A `CGSize` that represents the actual size for the ``DivView``.
public func sizeFor(parentViewSize: CGSize) -> CGSize {
let width: CGFloat
switch self.width {
case .matchParent:
width = parentViewSize.width
case let .desired(value):
if constrainedWidth {
width = min(value, parentViewSize.width)
} else {
width = value
}
case .dependsOnOtherDimensionSize:
assertionFailure("Unexpected width")
width = -1
}
let height: CGFloat = switch self.height {
case .matchParent:
parentViewSize.height
case let .desired(value):
value
case let .dependsOnOtherDimensionSize(heightForWidth):
if constrainedHeight {
min(heightForWidth(width), parentViewSize.height)
} else {
heightForWidth(width)
}
}
return CGSize(width: width, height: height)
}
}
private func makeHeightDimensionSize(block: Block, width: DivViewSize.DivDimension) -> DivViewSize
.DivDimension {
guard !block.isVerticallyResizable else {
return .matchParent
}
switch width {
case .matchParent, .desired:
return .dependsOnOtherDimensionSize { block.heightOfVerticallyNonResizableBlock(forWidth: $0) }
case .dependsOnOtherDimensionSize:
assertionFailure("Unexpected width")
return .desired(.zero)
}
}