Add layout direction to DrawScope
Fixes: 152750722
Test: new tests, old tests passed
Relnote: "Rtl support for draw modifiers."
Change-Id: I0aaf9072582e51e967d403cfec1d39f89680fc71
diff --git a/ui/ui-core/api/0.1.0-dev09.txt b/ui/ui-core/api/0.1.0-dev09.txt
index 00d1aae..8ff5c46 100644
--- a/ui/ui-core/api/0.1.0-dev09.txt
+++ b/ui/ui-core/api/0.1.0-dev09.txt
@@ -164,7 +164,9 @@
}
public interface DrawScope extends androidx.ui.graphics.Canvas androidx.ui.unit.Density {
+ method public androidx.ui.core.LayoutDirection getLayoutDirection();
method public androidx.ui.unit.PxSize getSize();
+ property public abstract androidx.ui.core.LayoutDirection layoutDirection;
property public abstract androidx.ui.unit.PxSize size;
}
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index 00d1aae..8ff5c46 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -164,7 +164,9 @@
}
public interface DrawScope extends androidx.ui.graphics.Canvas androidx.ui.unit.Density {
+ method public androidx.ui.core.LayoutDirection getLayoutDirection();
method public androidx.ui.unit.PxSize getSize();
+ property public abstract androidx.ui.core.LayoutDirection layoutDirection;
property public abstract androidx.ui.unit.PxSize size;
}
diff --git a/ui/ui-core/api/public_plus_experimental_0.1.0-dev09.txt b/ui/ui-core/api/public_plus_experimental_0.1.0-dev09.txt
index 00d1aae..8ff5c46 100644
--- a/ui/ui-core/api/public_plus_experimental_0.1.0-dev09.txt
+++ b/ui/ui-core/api/public_plus_experimental_0.1.0-dev09.txt
@@ -164,7 +164,9 @@
}
public interface DrawScope extends androidx.ui.graphics.Canvas androidx.ui.unit.Density {
+ method public androidx.ui.core.LayoutDirection getLayoutDirection();
method public androidx.ui.unit.PxSize getSize();
+ property public abstract androidx.ui.core.LayoutDirection layoutDirection;
property public abstract androidx.ui.unit.PxSize size;
}
diff --git a/ui/ui-core/api/public_plus_experimental_current.txt b/ui/ui-core/api/public_plus_experimental_current.txt
index 00d1aae..8ff5c46 100644
--- a/ui/ui-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-core/api/public_plus_experimental_current.txt
@@ -164,7 +164,9 @@
}
public interface DrawScope extends androidx.ui.graphics.Canvas androidx.ui.unit.Density {
+ method public androidx.ui.core.LayoutDirection getLayoutDirection();
method public androidx.ui.unit.PxSize getSize();
+ property public abstract androidx.ui.core.LayoutDirection layoutDirection;
property public abstract androidx.ui.unit.PxSize size;
}
diff --git a/ui/ui-core/api/restricted_0.1.0-dev09.txt b/ui/ui-core/api/restricted_0.1.0-dev09.txt
index 00d1aae..8ff5c46 100644
--- a/ui/ui-core/api/restricted_0.1.0-dev09.txt
+++ b/ui/ui-core/api/restricted_0.1.0-dev09.txt
@@ -164,7 +164,9 @@
}
public interface DrawScope extends androidx.ui.graphics.Canvas androidx.ui.unit.Density {
+ method public androidx.ui.core.LayoutDirection getLayoutDirection();
method public androidx.ui.unit.PxSize getSize();
+ property public abstract androidx.ui.core.LayoutDirection layoutDirection;
property public abstract androidx.ui.unit.PxSize size;
}
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index 00d1aae..8ff5c46 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -164,7 +164,9 @@
}
public interface DrawScope extends androidx.ui.graphics.Canvas androidx.ui.unit.Density {
+ method public androidx.ui.core.LayoutDirection getLayoutDirection();
method public androidx.ui.unit.PxSize getSize();
+ property public abstract androidx.ui.core.LayoutDirection layoutDirection;
property public abstract androidx.ui.unit.PxSize size;
}
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/ContentDrawScope.kt b/ui/ui-core/src/main/java/androidx/ui/core/ContentDrawScope.kt
index 73b1c69..7443440 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/ContentDrawScope.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/ContentDrawScope.kt
@@ -29,6 +29,11 @@
* The size of layout being drawn in.
*/
val size: PxSize
+
+ /**
+ * The layout direction of the layout being drawn in.
+ */
+ val layoutDirection: LayoutDirection
}
/**
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
index ca0559a..910a739 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
@@ -39,9 +39,7 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
-import androidx.ui.core.Alignment
import androidx.ui.core.Constraints
-import androidx.ui.core.DensityAmbient
import androidx.ui.core.DrawLayerModifier
import androidx.ui.core.DrawModifier
import androidx.ui.core.ContentDrawScope
@@ -73,14 +71,14 @@
import androidx.ui.graphics.PaintingStyle
import androidx.ui.graphics.Path
import androidx.ui.graphics.Shape
+import androidx.ui.layout.ltr
+import androidx.ui.layout.rtl
import androidx.ui.layout.size
-import androidx.ui.layout.wrapContentSize
import androidx.ui.unit.Density
import androidx.ui.unit.IntPx
import androidx.ui.unit.IntPxPosition
import androidx.ui.unit.IntPxSize
import androidx.ui.unit.PxSize
-import androidx.ui.unit.dp
import androidx.ui.unit.ipx
import androidx.ui.unit.max
import androidx.ui.unit.min
@@ -1697,6 +1695,68 @@
validateSquareColors(outerColor = outerColor, innerColor = innerColor, size = 10)
}
+ @Test
+ fun drawModifier_afterRtlModifier_testLayoutDirection() {
+ val drawLatch = CountDownLatch(1)
+ var layoutDirection = Ref<LayoutDirection>()
+ activityTestRule.runOnUiThreadIR {
+ activity.setContentInFrameLayout {
+ FixedSize(
+ 50.ipx,
+ Modifier.rtl.drawBehind {
+ layoutDirection.value = this.layoutDirection
+ drawLatch.countDown()
+ }
+ )
+ }
+ }
+
+ assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+ assertEquals(LayoutDirection.Rtl, layoutDirection.value)
+ }
+
+ @Test
+ fun drawModifier_beforeRtlModifiers_testLayoutDirection() {
+ val drawLatch = CountDownLatch(1)
+ var layoutDirection = Ref<LayoutDirection>()
+
+ activityTestRule.runOnUiThreadIR {
+ activity.setContentInFrameLayout {
+ FixedSize(
+ 50.ipx,
+ Modifier.drawBehind {
+ layoutDirection.value = this.layoutDirection
+ drawLatch.countDown()
+ }.ltr.rtl
+ )
+ }
+ }
+
+ assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+ assertEquals(LayoutDirection.Ltr, layoutDirection.value)
+ }
+
+ @Test
+ fun drawModifier_betweenRtlModifiers_testLayoutDirection() {
+ val drawLatch = CountDownLatch(1)
+ var layoutDirection = Ref<LayoutDirection>()
+
+ activityTestRule.runOnUiThreadIR {
+ activity.setContentInFrameLayout {
+ FixedSize(
+ 50.ipx,
+ Modifier.rtl.drawBehind {
+ layoutDirection.value = this.layoutDirection
+ drawLatch.countDown()
+ }.ltr
+ )
+ }
+ }
+
+ assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+ assertEquals(LayoutDirection.Ltr, layoutDirection.value)
+ }
+
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
@Test
fun drawModifier_modelChangesOnRoot() {
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
index 546b225..bf6bd08 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
@@ -703,6 +703,9 @@
var currentDensity: Density
) : Canvas by canvas, Density by currentDensity, ContentDrawScope {
internal var childDrawn = false
+ // Draw composable does not support Rtl and will be removed soon anyway.
+ // The only place where Draw is in use is Table which will be updated anyway b/150276337.
+ override val layoutDirection: LayoutDirection = LayoutDirection.Ltr
override fun drawContent() {
if (childDrawn) {
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt b/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt
index 085b9d2..4851272 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt
@@ -38,6 +38,9 @@
override val isAttached: Boolean
get() = _isAttached && layoutNode.isAttached()
+ override val layoutDirection: LayoutDirection
+ get() = wrapped.layoutDirection
+
init {
wrapped.wrappedBy = this
}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt b/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt
index 30179e0..23d6677 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt
@@ -60,6 +60,9 @@
.firstOrNull { it.layoutNodeWrapper.parentData != null }?.parentData
}
+ override val layoutDirection: LayoutDirection
+ get() = layoutNode.layoutDirection!!
+
override fun findLayer(): OwnedLayer? {
return wrappedBy?.findLayer()
}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt b/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
index 0d7e892..2c38036 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
@@ -51,6 +51,8 @@
final override var measurementConstraints = Constraints()
+ abstract val layoutDirection: LayoutDirection
+
private var _measureResult: MeasureScope.MeasureResult? = null
var measureResult: MeasureScope.MeasureResult
get() = _measureResult ?: error(UnmeasuredError)
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedDrawNode.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedDrawNode.kt
index 32a34b1..4c70c74 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedDrawNode.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedDrawNode.kt
@@ -77,6 +77,9 @@
override val nativeCanvas: NativeCanvas
get() = canvas!!.nativeCanvas
+ override val layoutDirection: LayoutDirection
+ get() = this@ModifiedDrawNode.layoutDirection
+
override fun save() = canvas!!.save()
override fun restore() = canvas!!.restore()
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedLayoutNode.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedLayoutNode.kt
index 771f436..2b581d4 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedLayoutNode.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ModifiedLayoutNode.kt
@@ -88,18 +88,18 @@
override fun performMeasure(constraints: Constraints): Placeable = with(layoutModifier) {
updateLayoutDirection()
val placeable = wrapped.measure(
- layoutNode.measureScope.modifyConstraints(constraints, layoutNode.layoutDirection!!)
+ layoutNode.measureScope.modifyConstraints(constraints, layoutDirection)
)
val size = layoutNode.measureScope.modifySize(
constraints,
- layoutNode.layoutDirection!!,
+ layoutDirection,
IntPxSize(placeable.width, placeable.height)
)
val wrappedPosition = with(layoutModifier) {
layoutNode.measureScope.modifyPosition(
IntPxSize(placeable.width, placeable.height),
size,
- layoutNode.layoutDirection!!
+ layoutDirection
)
}
measureResult = object : MeasureScope.MeasureResult {
@@ -115,29 +115,29 @@
override fun minIntrinsicWidth(height: IntPx): IntPx = with(layoutModifier) {
updateLayoutDirection()
- layoutNode.measureScope.minIntrinsicWidthOf(wrapped, height, layoutNode.layoutDirection!!)
+ layoutNode.measureScope.minIntrinsicWidthOf(wrapped, height, layoutDirection)
}
override fun maxIntrinsicWidth(height: IntPx): IntPx = with(layoutModifier) {
updateLayoutDirection()
- layoutNode.measureScope.maxIntrinsicWidthOf(wrapped, height, layoutNode.layoutDirection!!)
+ layoutNode.measureScope.maxIntrinsicWidthOf(wrapped, height, layoutDirection)
}
override fun minIntrinsicHeight(width: IntPx): IntPx = with(layoutModifier) {
updateLayoutDirection()
- layoutNode.measureScope.minIntrinsicHeightOf(wrapped, width, layoutNode.layoutDirection!!)
+ layoutNode.measureScope.minIntrinsicHeightOf(wrapped, width, layoutDirection)
}
override fun maxIntrinsicHeight(width: IntPx): IntPx = with(layoutModifier) {
updateLayoutDirection()
- layoutNode.measureScope.maxIntrinsicHeightOf(wrapped, width, layoutNode.layoutDirection!!)
+ layoutNode.measureScope.maxIntrinsicHeightOf(wrapped, width, layoutDirection)
}
override operator fun get(line: AlignmentLine): IntPx? = with(layoutModifier) {
return layoutNode.measureScope.modifyAlignmentLine(
line,
super.get(line),
- layoutNode.layoutDirection!!
+ layoutDirection
)
}
@@ -158,9 +158,12 @@
}
}
+ override lateinit var layoutDirection: LayoutDirection
+
private fun updateLayoutDirection() = with(layoutModifier) {
val modifiedLayoutDirection =
layoutNode.measureScope.modifyLayoutDirection(layoutNode.layoutDirection!!)
layoutNode.layoutDirection = modifiedLayoutDirection
+ layoutDirection = modifiedLayoutDirection
}
}
\ No newline at end of file