mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
add axial alignment
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user