Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Row & Column feature parity] LastBaseline alignment experiment #805

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.foundation.layout.LayoutScopeMarker
import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.layout.FirstBaseline
import androidx.compose.ui.layout.LastBaseline
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.core.parser.CLArray
Expand Down Expand Up @@ -83,6 +84,11 @@ class ConstrainScope internal constructor(
*/
val baseline: BaselineAnchorable = ConstraintBaselineAnchorable(containerObject)

/**
* The [LastBaseline] of the layout - can be constrained using [LastBaselineAnchorable.linkTo].
*/
val lastBaseline: LastBaselineAnchorable = ConstraintLastBaselineAnchorable(containerObject)

/**
* The width of the [ConstraintLayout] child.
*/
Expand Down Expand Up @@ -399,6 +405,7 @@ class ConstrainScope internal constructor(
containerObject.remove("top")
containerObject.remove("bottom")
containerObject.remove("baseline")
containerObject.remove("lastBaseline")
}

/**
Expand Down Expand Up @@ -523,6 +530,23 @@ private class ConstraintBaselineAnchorable constructor(
containerObject.put("baseline", constraintArray)
}

/**
* Adds a link towards a [ConstraintLayoutBaseScope.LastBaselineAnchor].
*/
override fun linkTo(
anchor: ConstraintLayoutBaseScope.LastBaselineAnchor,
margin: Dp,
goneMargin: Dp
) {
val constraintArray = CLArray(charArrayOf()).apply {
add(CLString.from(anchor.id.toString()))
add(CLString.from("lastBaseline"))
add(CLNumber(margin.value))
add(CLNumber(goneMargin.value))
}
containerObject.put("baseline", constraintArray)
}

/**
* Adds a link towards a [ConstraintLayoutBaseScope.HorizontalAnchor].
*/
Expand All @@ -540,4 +564,64 @@ private class ConstraintBaselineAnchorable constructor(
}
containerObject.put("baseline", constraintArray)
}
}

/**
* Represents the [LastBaseline] of a layout that can be anchored
* using [linkTo] in their `Modifier.constrainAs` blocks.
*/
private class ConstraintLastBaselineAnchorable constructor(
private val containerObject: CLObject
) : LastBaselineAnchorable {
/**
* Adds a link towards a [ConstraintLayoutBaseScope.BaselineAnchor].
*/
override fun linkTo(
anchor: ConstraintLayoutBaseScope.BaselineAnchor,
margin: Dp,
goneMargin: Dp
) {
val constraintArray = CLArray(charArrayOf()).apply {
add(CLString.from(anchor.id.toString()))
add(CLString.from("baseline"))
add(CLNumber(margin.value))
add(CLNumber(goneMargin.value))
}
containerObject.put("lastBaseline", constraintArray)
}

/**
* Adds a link towards a [ConstraintLayoutBaseScope.LastBaselineAnchor].
*/
override fun linkTo(
anchor: ConstraintLayoutBaseScope.LastBaselineAnchor,
margin: Dp,
goneMargin: Dp
) {
val constraintArray = CLArray(charArrayOf()).apply {
add(CLString.from(anchor.id.toString()))
add(CLString.from("lastBaseline"))
add(CLNumber(margin.value))
add(CLNumber(goneMargin.value))
}
containerObject.put("lastBaseline", constraintArray)
}

/**
* Adds a link towards a [ConstraintLayoutBaseScope.HorizontalAnchor].
*/
override fun linkTo(
anchor: ConstraintLayoutBaseScope.HorizontalAnchor,
margin: Dp,
goneMargin: Dp
) {
val targetAnchorName = AnchorFunctions.horizontalAnchorIndexToAnchorName(anchor.index)
val constraintArray = CLArray(charArrayOf()).apply {
add(CLString.from(anchor.id.toString()))
add(CLString.from(targetAnchorName))
add(CLNumber(margin.value))
add(CLNumber(goneMargin.value))
}
containerObject.put("lastBaseline", constraintArray)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.layout.AlignmentLine
import androidx.compose.ui.layout.FirstBaseline
import androidx.compose.ui.layout.LastBaseline
import androidx.compose.ui.layout.LayoutIdParentData
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
Expand Down Expand Up @@ -1210,6 +1211,8 @@ internal open class Measurer(
val baseline =
if (currentPlaceable != null && state.isBaselineNeeded(constraintWidget)) {
currentPlaceable[FirstBaseline]
} else if (currentPlaceable != null && state.isLastBaselineNeeded(constraintWidget)) {
currentPlaceable[LastBaseline]
} else {
AlignmentLine.Unspecified
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package androidx.constraintlayout.compose
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import androidx.compose.ui.layout.FirstBaseline
import androidx.compose.ui.layout.LastBaseline
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.core.parser.CLArray
Expand Down Expand Up @@ -105,6 +106,19 @@ abstract class ConstraintLayoutBaseScope internal constructor(extendFrom: CLObje
val reference: LayoutReference
)

/**
* Represents a horizontal anchor corresponding to the [LastBaseline] of a layout that other
* layouts can link to in their `Modifier.constrainAs` or `constrain` blocks.
*
* @param reference The [LayoutReference] that this anchor belongs to.
*/
// TODO(popam): investigate if this can be just a HorizontalAnchor
@Stable
data class LastBaselineAnchor internal constructor(
internal val id: Any,
val reference: LayoutReference
)

/**
* Specifies additional constraints associated to the horizontal chain identified with [ref].
*/
Expand Down Expand Up @@ -1740,6 +1754,12 @@ class ConstrainedLayoutReference(override val id: Any) : LayoutReference(id) {
*/
@Stable
val baseline = ConstraintLayoutBaseScope.BaselineAnchor(id, this)

/**
* The lastBaseline anchor of this layout.
*/
@Stable
val lastBaseline = ConstraintLayoutBaseScope.LastBaselineAnchor(id, this)
}

/**
Expand Down Expand Up @@ -1918,6 +1938,7 @@ class VerticalAlign internal constructor(
val Bottom = VerticalAlign("bottom")
val Center = VerticalAlign("center")
val Baseline = VerticalAlign("baseline")
val LastBaseline = VerticalAlign("lastBaseline")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package androidx.constraintlayout.compose

import android.util.Log
import androidx.compose.ui.layout.FirstBaseline
import androidx.compose.ui.layout.LastBaseline
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.constraintlayout.core.parser.CLArray
Expand Down Expand Up @@ -64,6 +65,15 @@ interface HorizontalAnchorable {
margin: Dp = 0.dp,
goneMargin: Dp = 0.dp
)

/**
* Adds a link towards a [ConstraintLayoutBaseScope.LastBaselineAnchor].
*/
fun linkTo(
anchor: ConstraintLayoutBaseScope.LastBaselineAnchor,
margin: Dp = 0.dp,
goneMargin: Dp = 0.dp
)
}

@JvmDefaultWithCompatibility
Expand All @@ -81,6 +91,49 @@ interface BaselineAnchorable {
goneMargin: Dp = 0.dp
)

/**
* Adds a link towards a [ConstraintLayoutBaseScope.LastBaselineAnchor].
*/
fun linkTo(
anchor: ConstraintLayoutBaseScope.LastBaselineAnchor,
margin: Dp = 0.dp,
goneMargin: Dp = 0.dp
)

/**
* Adds a link towards a [ConstraintLayoutBaseScope.HorizontalAnchor].
*/
fun linkTo(
anchor: ConstraintLayoutBaseScope.HorizontalAnchor,
margin: Dp = 0.dp,
goneMargin: Dp = 0.dp
)
}

@JvmDefaultWithCompatibility
/**
* Represents the [LastBaseline] of a layout that can be anchored
* using [linkTo] in their `Modifier.constrainAs` blocks.
*/
interface LastBaselineAnchorable {
/**
* Adds a link towards a [ConstraintLayoutBaseScope.BaselineAnchor].
*/
fun linkTo(
anchor: ConstraintLayoutBaseScope.BaselineAnchor,
margin: Dp = 0.dp,
goneMargin: Dp = 0.dp
)

/**
* Adds a link towards a [ConstraintLayoutBaseScope.LastBaselineAnchor].
*/
fun linkTo(
anchor: ConstraintLayoutBaseScope.LastBaselineAnchor,
margin: Dp = 0.dp,
goneMargin: Dp = 0.dp
)

/**
* Adds a link towards a [ConstraintLayoutBaseScope.HorizontalAnchor].
*/
Expand Down Expand Up @@ -147,6 +200,20 @@ internal abstract class BaseHorizontalAnchorable(
}
containerObject.put(anchorName, constraintArray)
}

final override fun linkTo(
anchor: ConstraintLayoutBaseScope.LastBaselineAnchor,
margin: Dp,
goneMargin: Dp
) {
val constraintArray = CLArray(charArrayOf()).apply {
add(CLString.from(anchor.id.toString()))
add(CLString.from("lastBaseline"))
add(CLNumber(margin.value))
add(CLNumber(goneMargin.value))
}
containerObject.put(anchorName, constraintArray)
}
}

internal object AnchorFunctions {
Expand Down