[go: nahoru, domu]

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