Pickup inspector parameters for the layout inspector
Bug: 158130075
Test: Added test for modifiers
Relnote: N/A
Change-Id: I5647bc5715ae89bc2b8ebaf3de22cdf29a825fe1
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/inspector/ParameterFactoryTest.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/inspector/ParameterFactoryTest.kt
index 6e197dc..4b9beab 100644
--- a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/inspector/ParameterFactoryTest.kt
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/inspector/ParameterFactoryTest.kt
@@ -16,27 +16,30 @@
package androidx.ui.tooling.inspector
-import androidx.test.filters.SmallTest
-import androidx.ui.core.AbsoluteAlignment
-import androidx.ui.core.Alignment
import androidx.compose.foundation.Border
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.CrossAxisAlignment
+import androidx.compose.foundation.layout.InnerPadding
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.preferredWidth
+import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.shape.ZeroCornerSize
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.LinearGradient
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.colorspace.ColorModel
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.toArgb
-import androidx.compose.ui.text.intl.Locale
-import androidx.compose.ui.text.intl.LocaleList
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.CrossAxisAlignment
-import androidx.compose.foundation.layout.InnerPadding
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
@@ -44,16 +47,24 @@
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.font.ResourceFont
+import androidx.compose.ui.text.intl.Locale
+import androidx.compose.ui.text.intl.LocaleList
import androidx.compose.ui.text.style.BaselineShift
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextGeometricTransform
import androidx.compose.ui.text.style.TextIndent
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
+import androidx.test.filters.SmallTest
+import androidx.ui.core.AbsoluteAlignment
+import androidx.ui.core.Alignment
+import androidx.ui.core.Modifier
+import androidx.ui.core.paint
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
@@ -331,6 +342,59 @@
}
@Test
+ fun testModifier() {
+ validate(factory.create(node, "modifier",
+ Modifier
+ .background(Color.Blue)
+ .padding(2.0.dp)
+ .fillMaxWidth()
+ .wrapContentHeight(Alignment.Bottom)
+ .preferredWidth(30.0.dp)
+ .paint(TestPainter(10f, 20f)))!!) {
+ parameter("modifier", ParameterType.String, "") {
+ parameter("background", ParameterType.Color, Color.Blue.toArgb()) {
+ parameter("color", ParameterType.Color, Color.Blue.toArgb())
+ parameter("alpha", ParameterType.Float, 1.0f)
+ parameter("shape", ParameterType.String, "Shape")
+ }
+ parameter("padding", ParameterType.DimensionDp, 2.0f) {
+ parameter("start", ParameterType.DimensionDp, 2.0f)
+ parameter("top", ParameterType.DimensionDp, 2.0f)
+ parameter("end", ParameterType.DimensionDp, 2.0f)
+ parameter("bottom", ParameterType.DimensionDp, 2.0f)
+ }
+ parameter("fillMaxWidth", ParameterType.String, "")
+ parameter("wrapContentHeight", ParameterType.String, "") {
+ parameter("alignment", ParameterType.String, "Bottom")
+ }
+ parameter("preferredWidth", ParameterType.DimensionDp, 30.0f) {
+ parameter("width", ParameterType.DimensionDp, 30.0f)
+ }
+ // TODO: Map Painter, ContentScale, ColorFilter
+ parameter("paint", ParameterType.String, "") {
+ parameter("sizeToIntrinsics", ParameterType.Boolean, true)
+ parameter("alignment", ParameterType.String, "Center")
+ parameter("alpha", ParameterType.Float, 1.0f)
+ }
+ }
+ }
+ }
+
+ @Test
+ fun testSingleModifier() {
+ validate(factory.create(node, "modifier", Modifier.padding(2.0.dp))!!) {
+ parameter("modifier", ParameterType.String, "") {
+ parameter("padding", ParameterType.DimensionDp, 2.0f) {
+ parameter("start", ParameterType.DimensionDp, 2.0f)
+ parameter("top", ParameterType.DimensionDp, 2.0f)
+ parameter("end", ParameterType.DimensionDp, 2.0f)
+ parameter("bottom", ParameterType.DimensionDp, 2.0f)
+ }
+ }
+ }
+ }
+
+ @Test
fun testOffset() {
validate(factory.create(node, "offset", Offset(1.0f, 5.0f))!!) {
parameter("offset", ParameterType.String, Offset::class.java.simpleName) {
@@ -462,6 +526,26 @@
}
}
+private class TestPainter(
+ val width: Float,
+ val height: Float
+) : Painter() {
+
+ var color = Color.Red
+
+ override val intrinsicSize: Size
+ get() = Size(width, height)
+
+ override fun applyLayoutDirection(layoutDirection: LayoutDirection): Boolean {
+ color = if (layoutDirection == LayoutDirection.Rtl) Color.Blue else Color.Red
+ return true
+ }
+
+ override fun DrawScope.onDraw() {
+ drawRect(color = color)
+ }
+}
+
class ParameterValidationReceiver(val parameterIterator: Iterator<NodeParameter>) {
fun parameter(
name: String,
@@ -469,14 +553,17 @@
value: Any?,
children: ParameterValidationReceiver.() -> Unit = {}
) {
- assertWithMessage(name).that(parameterIterator.hasNext()).isTrue()
+ assertWithMessage("No such element found: $name").that(parameterIterator.hasNext()).isTrue()
val parameter = parameterIterator.next()
assertThat(parameter.name).isEqualTo(name)
assertWithMessage(name).that(parameter.type).isEqualTo(type)
assertWithMessage(name).that(parameter.value).isEqualTo(value)
val elements = ParameterValidationReceiver(parameter.elements.listIterator())
elements.children()
- assertWithMessage("$name: has more elements")
- .that(elements.parameterIterator.hasNext()).isFalse()
+ if (elements.parameterIterator.hasNext()) {
+ val elementNames = mutableListOf<String>()
+ elements.parameterIterator.forEachRemaining { elementNames.add(it.name) }
+ error("$name: has more elements like: ${elementNames.joinToString()}")
+ }
}
}
diff --git a/ui/ui-tooling/src/main/java/androidx/ui/tooling/inspector/ParameterFactory.kt b/ui/ui-tooling/src/main/java/androidx/ui/tooling/inspector/ParameterFactory.kt
index a4101b8..4ef68a6 100644
--- a/ui/ui-tooling/src/main/java/androidx/ui/tooling/inspector/ParameterFactory.kt
+++ b/ui/ui-tooling/src/main/java/androidx/ui/tooling/inspector/ParameterFactory.kt
@@ -16,9 +16,10 @@
package androidx.ui.tooling.inspector
-import androidx.ui.core.AbsoluteAlignment
-import androidx.ui.core.Alignment
import androidx.compose.foundation.Border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.CrossAxisAlignment
+import androidx.compose.foundation.layout.InnerPadding
import androidx.compose.foundation.shape.CornerBasedShape
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.ui.geometry.Offset
@@ -29,11 +30,6 @@
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.toArgb
-import androidx.compose.ui.text.intl.Locale
-import androidx.compose.ui.text.intl.LocaleList
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.CrossAxisAlignment
-import androidx.compose.foundation.layout.InnerPadding
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
@@ -41,16 +37,21 @@
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.font.ResourceFont
+import androidx.compose.ui.text.intl.Locale
+import androidx.compose.ui.text.intl.LocaleList
import androidx.compose.ui.text.style.BaselineShift
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextGeometricTransform
import androidx.compose.ui.text.style.TextIndent
-import androidx.ui.tooling.inspector.ParameterType.DimensionDp
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
-import java.lang.reflect.Modifier
+import androidx.ui.core.AbsoluteAlignment
+import androidx.ui.core.Alignment
+import androidx.ui.core.InspectableParameter
+import androidx.ui.core.Modifier
+import androidx.ui.tooling.inspector.ParameterType.DimensionDp
import kotlin.math.abs
/**
@@ -109,6 +110,8 @@
is FontListFontFamily -> createFromFontListFamily(name, value)
is FontWeight -> NodeParameter(name, ParameterType.Int32, value.weight)
is InnerPadding -> createFromInnerPadding(node, name, value)
+ is Modifier -> createFromModifier(node, name, value)
+ is InspectableParameter -> createFromInspectableParameter(node, name, value)
is Int -> NodeParameter(name, ParameterType.Int32, value)
is Locale -> NodeParameter(name, ParameterType.String, value.toString())
is LocaleList -> NodeParameter(name, ParameterType.String,
@@ -199,6 +202,39 @@
return parameter
}
+ private fun createFromInspectableParameter(
+ node: MutableInspectorNode,
+ name: String,
+ value: InspectableParameter
+ ): NodeParameter {
+ val tempValue = value.valueOverride ?: ""
+ val parameterName = name.ifEmpty { value.nameFallback } ?: "element"
+ val parameterValue = if (tempValue is InspectableParameter) "" else tempValue
+ val parameter = create(node, parameterName, parameterValue)
+ ?: NodeParameter(parameterName, ParameterType.String, "")
+ val elements = parameter.elements
+ value.inspectableElements.mapNotNullTo(elements) { create(node, it.name, it.value) }
+ return parameter
+ }
+
+ private fun createFromModifier(
+ node: MutableInspectorNode,
+ name: String,
+ value: Modifier
+ ): NodeParameter? =
+ when {
+ name.isNotEmpty() -> {
+ val parameter = NodeParameter(name, ParameterType.String, "")
+ val elements = parameter.elements
+ value.foldIn(elements) { acc, m ->
+ create(node, "", m)?.let { param -> acc.apply { add(param) } } ?: acc
+ }
+ parameter
+ }
+ value is InspectableParameter -> createFromInspectableParameter(node, name, value)
+ else -> null
+ }
+
private fun createFromOffset(name: String, value: Offset): NodeParameter {
val parameter = NodeParameter(name, ParameterType.String, Offset::class.java.simpleName)
val elements = parameter.elements
@@ -307,7 +343,7 @@
// REDO: If we decide to add a kotlin reflection dependency
companionInstance::class.java.declaredMethods.asSequence()
.filter {
- Modifier.isPublic(it.modifiers) &&
+ java.lang.reflect.Modifier.isPublic(it.modifiers) &&
it.returnType != Void.TYPE &&
it.parameterTypes.isEmpty() &&
it.name.startsWith("get") &&