add axial alignment

This commit is contained in:
bugperson
2023-06-04 14:54:45 +03:00
parent 49464f93b1
commit e294aefc3e
10 changed files with 143 additions and 105 deletions
@@ -13,9 +13,6 @@ public enum Alignment {
case center
/// Child items are laid out at the right/bottom of the container
case trailing
case spaceBetween
case spaceAround
case spaceEvenly
}
extension Alignment {
@@ -30,10 +27,6 @@ extension Alignment {
return ((availableSpace - contentSize) * 0.5).roundedToScreenScale
case .trailing:
return availableSpace - contentSize
// TODO: @bugperson should be implemented here DIVKIT-2378
default:
assertionFailure("Others alignments not supported yet")
return 0
}
}
}
@@ -47,12 +40,6 @@ extension Alignment: CustomDebugStringConvertible {
return "Center"
case .trailing:
return "Trailing"
case .spaceBetween:
return "space-between"
case .spaceAround:
return "space-around"
case .spaceEvenly:
return "space-evenly"
}
}
}
@@ -150,16 +150,21 @@ extension DivContainer: DivBlockModeling {
) throws -> Block {
let expressionResolver = context.expressionResolver
let layoutDirection = orientation.layoutDirection
let axialAlignment: Alignment
let crossAlignment: ContainerBlock.CrossAlignment
switch layoutDirection {
case .horizontal:
axialAlignment = resolveContentAlignmentHorizontal(expressionResolver).alignment
crossAlignment = resolveContentAlignmentVertical(expressionResolver).crossAlignment
case .vertical:
axialAlignment = resolveContentAlignmentVertical(expressionResolver).alignment
crossAlignment = resolveContentAlignmentHorizontal(expressionResolver).crossAlignment
}
let divContentAlignmentVertical = resolveContentAlignmentVertical(expressionResolver)
let divContentAlignmentHorizontal = resolveContentAlignmentHorizontal(expressionResolver)
let axialAlignment = makeAxialAlignment(
layoutDirection,
verticalAlignment: divContentAlignmentVertical,
horizontalAlignment: divContentAlignmentHorizontal
)
let crossAlignment = makeCrossAlignment(
layoutDirection,
verticalAlignment: divContentAlignmentVertical,
horizontalAlignment: divContentAlignmentHorizontal
)
let fallbackWidth = getFallbackWidth(
orientation: orientation,
@@ -393,7 +398,7 @@ extension DivAlignmentVertical {
}
extension DivContentAlignmentHorizontal {
var alignment: Alignment {
fileprivate var alignment: Alignment {
switch self {
case .left:
return .leading
@@ -401,35 +406,15 @@ extension DivContentAlignmentHorizontal {
return .center
case .right:
return .trailing
case .spaceBetween:
return .spaceBetween
case .spaceAround:
return .spaceAround
case .spaceEvenly:
return .spaceEvenly
}
}
var crossAlignment: ContainerBlock.CrossAlignment {
switch self {
case .left:
case .spaceEvenly, .spaceAround, .spaceBetween:
DivKitLogger.warning("Alignment \(rawValue) is not supported")
return .leading
case .center:
return .center
case .right:
return .trailing
case .spaceBetween:
return .spaceBetween
case .spaceAround:
return .spaceAround
case .spaceEvenly:
return .spaceEvenly
}
}
}
extension DivContentAlignmentVertical {
var alignment: Alignment {
fileprivate var alignment: Alignment {
switch self {
case .top:
return .leading
@@ -437,34 +422,9 @@ extension DivContentAlignmentVertical {
return .center
case .bottom:
return .trailing
case .baseline:
DivKitLogger.warning("Baseline alignment not supported.")
case .spaceEvenly, .spaceAround, .spaceBetween, .baseline:
DivKitLogger.warning("Alignment \(rawValue) is not supported")
return .leading
case .spaceBetween:
return .spaceBetween
case .spaceAround:
return .spaceAround
case .spaceEvenly:
return .spaceEvenly
}
}
var crossAlignment: ContainerBlock.CrossAlignment {
switch self {
case .top:
return .leading
case .center:
return .center
case .bottom:
return .trailing
case .baseline:
return .baseline
case .spaceBetween:
return .spaceBetween
case .spaceAround:
return .spaceAround
case .spaceEvenly:
return .spaceEvenly
}
}
}
@@ -517,3 +477,81 @@ private let defaultFallbackSize = DivOverridenSize(
original: .divMatchParentSize(DivMatchParentSize()),
overriden: .divWrapContentSize(DivWrapContentSize(constrained: .value(true)))
)
fileprivate func makeCrossAlignment(
_ direction: ContainerBlock.LayoutDirection,
verticalAlignment: DivContentAlignmentVertical,
horizontalAlignment: DivContentAlignmentHorizontal
) -> ContainerBlock.CrossAlignment {
switch direction {
case .horizontal:
switch verticalAlignment {
case .top:
return .leading
case .center:
return .center
case .bottom:
return .trailing
case .baseline:
return .baseline
case .spaceBetween, .spaceEvenly, .spaceAround:
return .leading
}
case .vertical:
switch horizontalAlignment {
case .left:
return .leading
case .center:
return .center
case .right:
return .trailing
case .spaceBetween, .spaceEvenly, .spaceAround:
return .center
}
}
}
fileprivate func makeAxialAlignment(
_ direction: ContainerBlock.LayoutDirection,
verticalAlignment: DivContentAlignmentVertical,
horizontalAlignment: DivContentAlignmentHorizontal
) -> ContainerBlock.AxialAlignment {
switch direction {
case .horizontal:
switch horizontalAlignment {
case .left:
return .leading
case .center:
return .center
case .right:
return .trailing
case .spaceBetween:
return .spaceBetween
case .spaceAround:
return .spaceAround
case .spaceEvenly:
return .spaceEvenly
}
case .vertical:
switch verticalAlignment {
case .top:
return .leading
case .center:
return .center
case .bottom:
return .trailing
case .baseline:
DivKitLogger.warning("Baseline alignment not supported.")
return .leading
case .spaceBetween:
return .spaceBetween
case .spaceAround:
return .spaceAround
case .spaceEvenly:
return .spaceEvenly
}
}
}
@@ -46,6 +46,12 @@ public final class ContainerBlock: BlockWithLayout {
case center
case trailing
case baseline
}
public enum AxialAlignment {
case leading
case center
case trailing
case spaceBetween
case spaceAround
case spaceEvenly
@@ -86,7 +92,7 @@ public final class ContainerBlock: BlockWithLayout {
public let layoutMode: LayoutMode
public let widthTrait: LayoutTrait
public let heightTrait: LayoutTrait
public let axialAlignment: Alignment
public let axialAlignment: AxialAlignment
public let crossAlignment: CrossAlignment
public let gaps: [CGFloat]
public let children: [Child]
@@ -105,7 +111,7 @@ public final class ContainerBlock: BlockWithLayout {
layoutMode: LayoutMode = .noWrap,
widthTrait: LayoutTrait = .resizable,
heightTrait: LayoutTrait = .intrinsic,
axialAlignment: Alignment = .leading,
axialAlignment: AxialAlignment = .leading,
crossAlignment: CrossAlignment = .leading,
gaps: [CGFloat]? = nil,
children: [Child],
@@ -554,9 +560,23 @@ extension ContainerBlock.CrossAlignment {
return ((availableSpace - contentSize) * 0.5).roundedToScreenScale
case .trailing:
return availableSpace - contentSize
// TODO: @bugperson should be implemented here DIVKIT-2378
default:
assertionFailure("Others alignments not supported yet")
}
}
}
extension ContainerBlock.AxialAlignment {
public func offset(
forAvailableSpace availableSpace: CGFloat,
contentSize: CGFloat = 0
) -> CGFloat {
switch self {
case .leading:
return 0
case .center:
return ((availableSpace - contentSize) * 0.5).roundedToScreenScale
case .trailing:
return availableSpace - contentSize
case .spaceEvenly, .spaceBetween, .spaceAround:
return 0
}
}
@@ -9,7 +9,7 @@ extension ContainerBlock {
layoutMode: LayoutMode? = nil,
widthTrait: LayoutTrait? = nil,
heightTrait: LayoutTrait? = nil,
axialAlignment: Alignment? = nil,
axialAlignment: AxialAlignment? = nil,
crossAlignment: CrossAlignment? = nil,
gaps: [CGFloat]? = nil,
children: [Child]? = nil,
@@ -51,15 +51,15 @@ extension ContainerBlock {
clipContent: Bool = true,
accessibilityElement: AccessibilityElement? = nil
) throws {
let axialAlignment: Alignment
let axialAlignment: AxialAlignment
let crossAlignment: CrossAlignment
switch layoutDirection {
case .horizontal:
axialAlignment = horizontalChildrenAlignment
axialAlignment = horizontalChildrenAlignment.axialAlignment
crossAlignment = verticalChildrenAlignment.crossAlignment
case .vertical:
axialAlignment = verticalChildrenAlignment
axialAlignment = verticalChildrenAlignment.axialAlignment
crossAlignment = horizontalChildrenAlignment.crossAlignment
}
@@ -94,12 +94,17 @@ extension Alignment {
return .center
case .trailing:
return .trailing
case .spaceBetween:
return .spaceBetween
case .spaceAround:
return .spaceAround
case .spaceEvenly:
return .spaceEvenly
}
}
fileprivate var axialAlignment: ContainerBlock.AxialAlignment {
switch self {
case .leading:
return .leading
case .center:
return .center
case .trailing:
return .trailing
}
}
}
@@ -33,7 +33,7 @@ struct ContainerBlockLayout {
let gaps: [CGFloat]
let layoutDirection: ContainerBlock.LayoutDirection
let layoutMode: ContainerBlock.LayoutMode
let axialAlignment: Alignment
let axialAlignment: ContainerBlock.AxialAlignment
let crossAlignment: ContainerBlock.CrossAlignment
let size: CGSize
@@ -44,7 +44,7 @@ struct ContainerBlockLayout {
gaps: [CGFloat],
layoutDirection: ContainerBlock.LayoutDirection,
layoutMode: ContainerBlock.LayoutMode,
axialAlignment: Alignment,
axialAlignment: ContainerBlock.AxialAlignment,
crossAlignment: ContainerBlock.CrossAlignment,
size: CGSize
) {
@@ -56,7 +56,7 @@ private final class ContainerBlockView: UIView, BlockViewProtocol, VisibleBounds
let gaps: [CGFloat]
let layoutDirection: ContainerBlock.LayoutDirection
let layoutMode: ContainerBlock.LayoutMode
let axialAlignment: Alignment
let axialAlignment: ContainerBlock.AxialAlignment
let crossAlignment: ContainerBlock.CrossAlignment
let contentAnimation: BlockAnimation?
let anchorPoint: AnchorPoint
@@ -458,10 +458,6 @@ extension Alignment {
case .leading: return .top
case .center: return .center
case .trailing: return .bottom
// TODO: @bugperson should be implemented here DIVKIT-2378
default:
assertionFailure("Others alignments not supported yet")
return .top
}
}
}
@@ -271,10 +271,6 @@ extension Alignment {
return floor((minimum + maximum - dimension) / 2)
case .trailing:
return maximum - dimension
// TODO: @bugperson should be implemented here DIVKIT-2378
default:
assertionFailure("Others alignments not supported yet")
return minimum
}
}
}
@@ -258,10 +258,6 @@ extension Alignment {
return floor((minimum + maximum - dimension) / 2)
case .trailing:
return maximum - dimension
// TODO: @bugperson should be implemented here DIVKIT-2378
default:
assertionFailure("Others alignments not supported yet")
return minimum
}
}
}
@@ -12,7 +12,7 @@ extension ContainerBlockLayout {
layoutDirection: ContainerBlock.LayoutDirection,
layoutMode: ContainerBlock.LayoutMode = .noWrap,
crossAlignment: ContainerBlock.CrossAlignment = .leading,
axialAlignment: Alignment = .leading,
axialAlignment: ContainerBlock.AxialAlignment = .leading,
size: CGSize
) {
self.init(