Add additional inspectables
Summary: This change adds support for more inspectables and also introduces more complex types to be used as a value. This become specially useful for more complex yet primitive types like coordinate, size, bounds, etc. Reviewed By: LukeDefeo Differential Revision: D40307885 fbshipit-source-id: 125e832f06d6b31f56eb5405182d1c0d61388930
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f7a624a143
commit
0572808f1a
@@ -8,13 +8,13 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags
|
import com.facebook.flipper.plugins.uidebugger.descriptors.BaseTags
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister
|
import com.facebook.flipper.plugins.uidebugger.descriptors.DescriptorRegister
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor
|
import com.facebook.flipper.plugins.uidebugger.descriptors.NodeDescriptor
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.OffsetChild
|
import com.facebook.flipper.plugins.uidebugger.descriptors.OffsetChild
|
||||||
import com.facebook.flipper.plugins.uidebugger.litho.LithoTag
|
import com.facebook.flipper.plugins.uidebugger.litho.LithoTag
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
import com.facebook.litho.DebugComponent
|
import com.facebook.litho.DebugComponent
|
||||||
|
|
||||||
class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescriptor<DebugComponent> {
|
class DebugComponentDescriptor(val register: DescriptorRegister) : NodeDescriptor<DebugComponent> {
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
||||||
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.Inspectable
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.ChainedDescriptor
|
import com.facebook.flipper.plugins.uidebugger.descriptors.ChainedDescriptor
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.SectionName
|
import com.facebook.flipper.plugins.uidebugger.descriptors.SectionName
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
import com.facebook.litho.DebugComponent
|
import com.facebook.litho.DebugComponent
|
||||||
import com.facebook.litho.LithoView
|
import com.facebook.litho.LithoView
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ object LithoViewDescriptor : ChainedDescriptor<LithoView>() {
|
|||||||
|
|
||||||
override fun onGetName(node: LithoView): String = node.javaClass.simpleName
|
override fun onGetName(node: LithoView): String = node.javaClass.simpleName
|
||||||
|
|
||||||
override fun onGetChildren(node: LithoView): List<Any>? {
|
override fun onGetChildren(node: LithoView): List<Any> {
|
||||||
val result = mutableListOf<Any>()
|
val result = mutableListOf<Any>()
|
||||||
val debugComponent = DebugComponent.getRootInstance(node)
|
val debugComponent = DebugComponent.getRootInstance(node)
|
||||||
if (debugComponent != null) {
|
if (debugComponent != null) {
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.*
|
import com.facebook.flipper.plugins.uidebugger.descriptors.*
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
|
||||||
/** a drawable or view that is mounted, along with the correct descriptor */
|
/** a drawable or view that is mounted, along with the correct descriptor */
|
||||||
class MountedObject(val obj: Any, val descriptor: NodeDescriptor<Any>)
|
class MountedObject(val obj: Any, val descriptor: NodeDescriptor<Any>)
|
||||||
@@ -19,14 +19,16 @@ object MountedObjectDescriptor : NodeDescriptor<MountedObject> {
|
|||||||
|
|
||||||
override fun getBounds(node: MountedObject): Bounds? {
|
override fun getBounds(node: MountedObject): Bounds? {
|
||||||
val bounds = node.descriptor.getBounds(node.obj)
|
val bounds = node.descriptor.getBounds(node.obj)
|
||||||
|
bounds?.let { b ->
|
||||||
/**
|
/**
|
||||||
* When we ask android for the bounds the x,y offset is w.r.t to the nearest android parent view
|
* When we ask android for the bounds the x,y offset is w.r.t to the nearest android parent
|
||||||
* group. From UI debuggers perspective using the raw android offset will double the total
|
* view group. From UI debuggers perspective using the raw android offset will double the
|
||||||
* offset of this native view as the offset is included by the litho components between the
|
* total offset of this native view as the offset is included by the litho components between
|
||||||
* mounted view and its native parent
|
* the mounted view and its native parent
|
||||||
*/
|
*/
|
||||||
return bounds?.copy(x = 0, y = 0)
|
return Bounds(0, 0, b.width, b.height)
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(node: MountedObject): String = node.descriptor.getName(node.obj)
|
override fun getName(node: MountedObject): String = node.descriptor.getName(node.obj)
|
||||||
|
|||||||
@@ -7,11 +7,11 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
package com.facebook.flipper.plugins.uidebugger.litho.descriptors
|
||||||
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.Inspectable
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.ChainedDescriptor
|
import com.facebook.flipper.plugins.uidebugger.descriptors.ChainedDescriptor
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.SectionName
|
import com.facebook.flipper.plugins.uidebugger.descriptors.SectionName
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
import com.facebook.litho.widget.TextDrawable
|
import com.facebook.litho.widget.TextDrawable
|
||||||
|
|
||||||
object TextDrawableDescriptor : ChainedDescriptor<TextDrawable>() {
|
object TextDrawableDescriptor : ChainedDescriptor<TextDrawable>() {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ package com.facebook.flipper.plugins.uidebugger.common
|
|||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.facebook.flipper.plugins.uidebugger.LogTag
|
import com.facebook.flipper.plugins.uidebugger.LogTag
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.Enumeration
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
|
|
||||||
// Maintains 2 way mapping between some enum value and a readable string representation
|
// Maintains 2 way mapping between some enum value and a readable string representation
|
||||||
open class EnumMapping<T>(private val mapping: Map<String, T>) {
|
open class EnumMapping<T>(private val mapping: Map<String, T>) {
|
||||||
@@ -32,7 +34,7 @@ open class EnumMapping<T>(private val mapping: Map<String, T>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun toInspectable(value: T, mutable: Boolean): InspectableValue.Enum {
|
fun toInspectable(value: T, mutable: Boolean): InspectableValue.Enum {
|
||||||
return InspectableValue.Enum(EnumData(mapping.keys, getStringRepresentation(value)), mutable)
|
return InspectableValue.Enum(Enumeration(mapping.keys, getStringRepresentation(value)), mutable)
|
||||||
}
|
}
|
||||||
companion object {
|
companion object {
|
||||||
const val NoMapping = "__UNKNOWN_ENUM_VALUE__"
|
const val NoMapping = "__UNKNOWN_ENUM_VALUE__"
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.core.FragmentTracker
|
import com.facebook.flipper.plugins.uidebugger.core.FragmentTracker
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
|
||||||
object ActivityDescriptor : ChainedDescriptor<Activity>() {
|
object ActivityDescriptor : ChainedDescriptor<Activity>() {
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ object ApplicationRefDescriptor : ChainedDescriptor<ApplicationRef>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onGetBounds(node: ApplicationRef): Bounds {
|
override fun onGetBounds(node: ApplicationRef): Bounds {
|
||||||
val displayMetrics = Resources.getSystem().getDisplayMetrics()
|
val displayMetrics = Resources.getSystem().displayMetrics
|
||||||
return Bounds(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
|
return Bounds(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A chained descriptor is a special type of descriptor that models the inheritance hierarchy in
|
* A chained descriptor is a special type of descriptor that models the inheritance hierarchy in
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
|
|||||||
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.Inspectable
|
import com.facebook.flipper.plugins.uidebugger.model.Color
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
|
|
||||||
object ColorDrawableDescriptor : ChainedDescriptor<ColorDrawable>() {
|
object ColorDrawableDescriptor : ChainedDescriptor<ColorDrawable>() {
|
||||||
|
|
||||||
@@ -22,9 +23,8 @@ object ColorDrawableDescriptor : ChainedDescriptor<ColorDrawable>() {
|
|||||||
attributeSections: MutableMap<SectionName, InspectableObject>
|
attributeSections: MutableMap<SectionName, InspectableObject>
|
||||||
) {
|
) {
|
||||||
val props = mutableMapOf<String, Inspectable>()
|
val props = mutableMapOf<String, Inspectable>()
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||||
props.put("color", InspectableValue.Color(node.color, mutable = true))
|
props["color"] = InspectableValue.Color(Color.fromColor(node.color), mutable = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeSections["ColorDrawable"] = InspectableObject(props.toMap())
|
attributeSections["ColorDrawable"] = InspectableObject(props.toMap())
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import android.graphics.drawable.Drawable
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.UIDebuggerException
|
import com.facebook.flipper.plugins.uidebugger.common.UIDebuggerException
|
||||||
@@ -32,6 +33,7 @@ class DescriptorRegister {
|
|||||||
mapping.register(ViewGroup::class.java, ViewGroupDescriptor)
|
mapping.register(ViewGroup::class.java, ViewGroupDescriptor)
|
||||||
mapping.register(View::class.java, ViewDescriptor)
|
mapping.register(View::class.java, ViewDescriptor)
|
||||||
mapping.register(TextView::class.java, TextViewDescriptor)
|
mapping.register(TextView::class.java, TextViewDescriptor)
|
||||||
|
mapping.register(ImageView::class.java, ImageViewDescriptor)
|
||||||
mapping.register(ViewPager::class.java, ViewPagerDescriptor)
|
mapping.register(ViewPager::class.java, ViewPagerDescriptor)
|
||||||
mapping.register(Drawable::class.java, DrawableDescriptor)
|
mapping.register(Drawable::class.java, DrawableDescriptor)
|
||||||
mapping.register(ColorDrawable::class.java, ColorDrawableDescriptor)
|
mapping.register(ColorDrawable::class.java, ColorDrawableDescriptor)
|
||||||
|
|||||||
@@ -9,10 +9,7 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
|
|||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.Inspectable
|
import com.facebook.flipper.plugins.uidebugger.model.*
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
|
||||||
|
|
||||||
object DrawableDescriptor : ChainedDescriptor<Drawable>() {
|
object DrawableDescriptor : ChainedDescriptor<Drawable>() {
|
||||||
override fun onGetName(node: Drawable): String = node.javaClass.simpleName
|
override fun onGetName(node: Drawable): String = node.javaClass.simpleName
|
||||||
@@ -24,13 +21,15 @@ object DrawableDescriptor : ChainedDescriptor<Drawable>() {
|
|||||||
node: Drawable,
|
node: Drawable,
|
||||||
attributeSections: MutableMap<SectionName, InspectableObject>
|
attributeSections: MutableMap<SectionName, InspectableObject>
|
||||||
) {
|
) {
|
||||||
val props = mutableMapOf<String, Inspectable>()
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
props.put("alpha", InspectableValue.Number(node.getAlpha(), true))
|
val props = mutableMapOf<String, Inspectable>()
|
||||||
}
|
props["alpha"] = InspectableValue.Number(node.alpha, true)
|
||||||
|
|
||||||
attributeSections["Drawable"] = InspectableObject(props.toMap())
|
val bounds = node.bounds
|
||||||
|
props["bounds"] = InspectableValue.SpaceBox(SpaceBox.fromRect(bounds))
|
||||||
|
|
||||||
|
attributeSections["Drawable"] = InspectableObject(props.toMap())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onGetTags(node: Drawable): Set<String> = BaseTags.NativeAndroid
|
override fun onGetTags(node: Drawable): Set<String> = BaseTags.NativeAndroid
|
||||||
|
|||||||
@@ -7,7 +7,11 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
|
|
||||||
object FragmentFrameworkDescriptor : ChainedDescriptor<android.app.Fragment>() {
|
object FragmentFrameworkDescriptor : ChainedDescriptor<android.app.Fragment>() {
|
||||||
|
|
||||||
@@ -21,5 +25,20 @@ object FragmentFrameworkDescriptor : ChainedDescriptor<android.app.Fragment>() {
|
|||||||
override fun onGetData(
|
override fun onGetData(
|
||||||
node: android.app.Fragment,
|
node: android.app.Fragment,
|
||||||
attributeSections: MutableMap<String, InspectableObject>
|
attributeSections: MutableMap<String, InspectableObject>
|
||||||
) {}
|
) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||||
|
val args: Bundle = node.arguments
|
||||||
|
|
||||||
|
val props = mutableMapOf<String, Inspectable>()
|
||||||
|
for (key in args.keySet()) {
|
||||||
|
when (val value = args[key]) {
|
||||||
|
is Number -> props[key] = InspectableValue.Number(value)
|
||||||
|
is Boolean -> props[key] = InspectableValue.Boolean(value)
|
||||||
|
is String -> props[key] = InspectableValue.Text(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeSections["Fragment"] = InspectableObject(props.toMap())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
|
|
||||||
object FragmentSupportDescriptor : ChainedDescriptor<androidx.fragment.app.Fragment>() {
|
object FragmentSupportDescriptor : ChainedDescriptor<androidx.fragment.app.Fragment>() {
|
||||||
|
|
||||||
@@ -21,5 +23,18 @@ object FragmentSupportDescriptor : ChainedDescriptor<androidx.fragment.app.Fragm
|
|||||||
override fun onGetData(
|
override fun onGetData(
|
||||||
node: androidx.fragment.app.Fragment,
|
node: androidx.fragment.app.Fragment,
|
||||||
attributeSections: MutableMap<String, InspectableObject>
|
attributeSections: MutableMap<String, InspectableObject>
|
||||||
) {}
|
) {
|
||||||
|
val args = node.arguments
|
||||||
|
args?.let { bundle ->
|
||||||
|
val props = mutableMapOf<String, Inspectable>()
|
||||||
|
for (key in bundle.keySet()) {
|
||||||
|
when (val value = bundle[key]) {
|
||||||
|
is Number -> props[key] = InspectableValue.Number(value)
|
||||||
|
is Boolean -> props[key] = InspectableValue.Boolean(value)
|
||||||
|
is String -> props[key] = InspectableValue.Text(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attributeSections["Fragment"] = InspectableObject(props.toMap())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.ImageView.ScaleType
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.common.EnumMapping
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
|
||||||
|
object ImageViewDescriptor : ChainedDescriptor<ImageView>() {
|
||||||
|
override fun onGetName(node: ImageView): String = node.javaClass.simpleName
|
||||||
|
|
||||||
|
override fun onGetData(
|
||||||
|
node: ImageView,
|
||||||
|
attributeSections: MutableMap<SectionName, InspectableObject>
|
||||||
|
) {
|
||||||
|
val props = mutableMapOf<String, Inspectable>()
|
||||||
|
props["scaleType"] = scaleTypeMapping.toInspectable(node.scaleType, true)
|
||||||
|
|
||||||
|
attributeSections["ImageView"] = InspectableObject(props)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val scaleTypeMapping: EnumMapping<ScaleType> =
|
||||||
|
object :
|
||||||
|
EnumMapping<ScaleType>(
|
||||||
|
mapOf(
|
||||||
|
"CENTER" to ScaleType.CENTER,
|
||||||
|
"CENTER_CROP" to ScaleType.CENTER_CROP,
|
||||||
|
"CENTER_INSIDE" to ScaleType.CENTER_INSIDE,
|
||||||
|
"FIT_CENTER" to ScaleType.FIT_CENTER,
|
||||||
|
"FIT_END" to ScaleType.FIT_END,
|
||||||
|
"FIT_START" to ScaleType.FIT_START,
|
||||||
|
"FIT_XY" to ScaleType.FIT_XY,
|
||||||
|
"MATRIX" to ScaleType.MATRIX,
|
||||||
|
)) {}
|
||||||
|
}
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Descriptors are an extension point used during traversal to extract data out of arbitrary
|
Descriptors are an extension point used during traversal to extract data out of arbitrary
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
|
||||||
object ObjectDescriptor : NodeDescriptor<Any> {
|
object ObjectDescriptor : NodeDescriptor<Any> {
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
|
||||||
/** a drawable or view that is mounted, along with the correct descriptor */
|
/** a drawable or view that is mounted, along with the correct descriptor */
|
||||||
class OffsetChild(val child: Any, val descriptor: NodeDescriptor<Any>, val x: Int, val y: Int) {
|
class OffsetChild(val child: Any, val descriptor: NodeDescriptor<Any>, val x: Int, val y: Int) {
|
||||||
@@ -22,7 +22,10 @@ object OffsetChildDescriptor : NodeDescriptor<OffsetChild> {
|
|||||||
|
|
||||||
override fun getBounds(node: OffsetChild): Bounds? {
|
override fun getBounds(node: OffsetChild): Bounds? {
|
||||||
val bounds = node.descriptor.getBounds(node.child)
|
val bounds = node.descriptor.getBounds(node.child)
|
||||||
return bounds?.copy(x = node.x, y = node.y)
|
bounds?.let { b ->
|
||||||
|
return Bounds(node.x, node.y, b.width, b.height)
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(node: OffsetChild): String = node.descriptor.getName(node.child)
|
override fun getName(node: OffsetChild): String = node.descriptor.getName(node.child)
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ package com.facebook.flipper.plugins.uidebugger.descriptors
|
|||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.Inspectable
|
import com.facebook.flipper.plugins.uidebugger.model.Color
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
|
|
||||||
object TextViewDescriptor : ChainedDescriptor<TextView>() {
|
object TextViewDescriptor : ChainedDescriptor<TextView>() {
|
||||||
|
|
||||||
@@ -26,7 +27,8 @@ object TextViewDescriptor : ChainedDescriptor<TextView>() {
|
|||||||
mutableMapOf<String, Inspectable>(
|
mutableMapOf<String, Inspectable>(
|
||||||
"text" to InspectableValue.Text(node.text.toString(), false),
|
"text" to InspectableValue.Text(node.text.toString(), false),
|
||||||
"textSize" to InspectableValue.Number(node.textSize, false),
|
"textSize" to InspectableValue.Number(node.textSize, false),
|
||||||
"textColor" to InspectableValue.Color(node.getTextColors().getDefaultColor(), false))
|
"textColor" to
|
||||||
|
InspectableValue.Color(Color.fromColor(node.textColors.defaultColor), false))
|
||||||
|
|
||||||
val typeface = node.typeface
|
val typeface = node.typeface
|
||||||
if (typeface != null) {
|
if (typeface != null) {
|
||||||
@@ -50,6 +52,6 @@ object TextViewDescriptor : ChainedDescriptor<TextView>() {
|
|||||||
props["maxWidth"] = InspectableValue.Number(node.maxWidth, false)
|
props["maxWidth"] = InspectableValue.Number(node.maxWidth, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
attributeSections.put("TextView", InspectableObject(props))
|
attributeSections["TextView"] = InspectableObject(props)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.*
|
import com.facebook.flipper.plugins.uidebugger.common.BitmapPool
|
||||||
import com.facebook.flipper.plugins.uidebugger.model.Bounds
|
import com.facebook.flipper.plugins.uidebugger.common.EnumMapping
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.*
|
||||||
import com.facebook.flipper.plugins.uidebugger.util.ResourcesUtil
|
import com.facebook.flipper.plugins.uidebugger.util.ResourcesUtil
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
@@ -47,14 +48,16 @@ object ViewDescriptor : ChainedDescriptor<View>() {
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
val props = mutableMapOf<String, Inspectable>()
|
val props = mutableMapOf<String, Inspectable>()
|
||||||
props["height"] = InspectableValue.Number(node.height, mutable = true)
|
props["size"] = InspectableValue.Size(Size(node.width, node.height), mutable = true)
|
||||||
props["width"] = InspectableValue.Number(node.width, mutable = true)
|
|
||||||
props["alpha"] = InspectableValue.Number(node.alpha, mutable = true)
|
props["alpha"] = InspectableValue.Number(node.alpha, mutable = true)
|
||||||
props["visibility"] = VisibilityMapping.toInspectable(node.visibility, mutable = false)
|
props["visibility"] = VisibilityMapping.toInspectable(node.visibility, mutable = false)
|
||||||
|
|
||||||
fromDrawable(node.background)?.let { props["background"] = it }
|
fromDrawable(node.background)?.let { background -> props["background"] = background }
|
||||||
|
|
||||||
|
node.tag
|
||||||
|
?.let { InspectableValue.fromAny(it, mutable = false) }
|
||||||
|
?.let { tag -> props.put("tag", tag) }
|
||||||
|
|
||||||
node.tag?.let { InspectableValue.fromAny(it, mutable = false) }?.let { props.put("tag", it) }
|
|
||||||
props["keyedTags"] = InspectableObject(getViewTags(node))
|
props["keyedTags"] = InspectableObject(getViewTags(node))
|
||||||
props["layoutParams"] = getLayoutParams(node)
|
props["layoutParams"] = getLayoutParams(node)
|
||||||
props["state"] =
|
props["state"] =
|
||||||
@@ -66,46 +69,20 @@ object ViewDescriptor : ChainedDescriptor<View>() {
|
|||||||
"selected" to InspectableValue.Boolean(node.isSelected, mutable = false)))
|
"selected" to InspectableValue.Boolean(node.isSelected, mutable = false)))
|
||||||
|
|
||||||
props["bounds"] =
|
props["bounds"] =
|
||||||
InspectableObject(
|
InspectableValue.SpaceBox(SpaceBox(node.top, node.right, node.bottom, node.left))
|
||||||
mapOf<String, Inspectable>(
|
|
||||||
"left" to InspectableValue.Number(node.left, mutable = true),
|
|
||||||
"right" to InspectableValue.Number(node.right, mutable = true),
|
|
||||||
"top" to InspectableValue.Number(node.top, mutable = true),
|
|
||||||
"bottom" to InspectableValue.Number(node.bottom, mutable = true)))
|
|
||||||
props["padding"] =
|
props["padding"] =
|
||||||
InspectableObject(
|
InspectableValue.SpaceBox(
|
||||||
mapOf<String, Inspectable>(
|
SpaceBox(node.paddingTop, node.paddingRight, node.paddingBottom, node.paddingLeft))
|
||||||
"left" to InspectableValue.Number(node.paddingLeft, mutable = true),
|
|
||||||
"right" to InspectableValue.Number(node.paddingRight, mutable = true),
|
|
||||||
"top" to InspectableValue.Number(node.paddingTop, mutable = true),
|
|
||||||
"bottom" to InspectableValue.Number(node.paddingBottom, mutable = true)))
|
|
||||||
|
|
||||||
props["rotation"] =
|
props["rotation"] =
|
||||||
InspectableObject(
|
InspectableValue.Coordinate3D(Coordinate3D(node.rotationX, node.rotationY, node.rotation))
|
||||||
mapOf<String, Inspectable>(
|
props["scale"] = InspectableValue.Coordinate(Coordinate(node.scaleX, node.scaleY))
|
||||||
"x" to InspectableValue.Number(node.rotationX, mutable = true),
|
props["pivot"] = InspectableValue.Coordinate(Coordinate(node.pivotX, node.pivotY))
|
||||||
"y" to InspectableValue.Number(node.rotationY, mutable = true),
|
|
||||||
"z" to InspectableValue.Number(node.rotation, mutable = true)))
|
|
||||||
|
|
||||||
props["scale"] =
|
|
||||||
InspectableObject(
|
|
||||||
mapOf(
|
|
||||||
"x" to InspectableValue.Number(node.scaleX, mutable = true),
|
|
||||||
"y" to InspectableValue.Number(node.scaleY, mutable = true)))
|
|
||||||
props["pivot"] =
|
|
||||||
InspectableObject(
|
|
||||||
mapOf(
|
|
||||||
"x" to InspectableValue.Number(node.pivotX, mutable = true),
|
|
||||||
"y" to InspectableValue.Number(node.pivotY, mutable = true)))
|
|
||||||
|
|
||||||
val positionOnScreen = IntArray(2)
|
val positionOnScreen = IntArray(2)
|
||||||
node.getLocationOnScreen(positionOnScreen)
|
node.getLocationOnScreen(positionOnScreen)
|
||||||
|
|
||||||
props["globalPosition"] =
|
props["globalPosition"] =
|
||||||
InspectableObject(
|
InspectableValue.Coordinate(Coordinate(positionOnScreen[0], positionOnScreen[1]))
|
||||||
mapOf(
|
|
||||||
"x" to InspectableValue.Number(positionOnScreen[0], mutable = false),
|
|
||||||
"y" to InspectableValue.Number(positionOnScreen[1], mutable = false)))
|
|
||||||
|
|
||||||
val localVisible = Rect()
|
val localVisible = Rect()
|
||||||
node.getLocalVisibleRect(localVisible)
|
node.getLocalVisibleRect(localVisible)
|
||||||
@@ -113,12 +90,39 @@ object ViewDescriptor : ChainedDescriptor<View>() {
|
|||||||
props["localVisible"] =
|
props["localVisible"] =
|
||||||
InspectableObject(
|
InspectableObject(
|
||||||
mapOf(
|
mapOf(
|
||||||
"x" to InspectableValue.Number(localVisible.left, mutable = true),
|
"position" to InspectableValue.Coordinate(Coordinate(localVisible.left, node.top)),
|
||||||
"y" to InspectableValue.Number(node.top, mutable = true),
|
"size" to InspectableValue.Size(Size(node.width, node.height))),
|
||||||
"width" to InspectableValue.Number(node.width, mutable = true),
|
|
||||||
"height" to InspectableValue.Number(node.height, mutable = true)),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
props["layoutDirection"] = LayoutDirectionMapping.toInspectable(node.layoutDirection, false)
|
||||||
|
props["textDirection"] = TextDirectionMapping.toInspectable(node.textDirection, false)
|
||||||
|
props["textAlignment"] = TextAlignmentMapping.toInspectable(node.textAlignment, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
props["elevation"] = InspectableValue.Number(node.elevation)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
props["translation"] =
|
||||||
|
InspectableValue.Coordinate3D(
|
||||||
|
Coordinate3D(node.translationX, node.translationY, node.translationZ))
|
||||||
|
} else {
|
||||||
|
props["translation"] =
|
||||||
|
InspectableValue.Coordinate(Coordinate(node.translationX, node.translationY))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||||
|
props["position"] = InspectableValue.Coordinate3D(Coordinate3D(node.x, node.y, node.z))
|
||||||
|
} else {
|
||||||
|
props["position"] = InspectableValue.Coordinate(Coordinate(node.x, node.y))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
fromDrawable(node.foreground)?.let { foreground -> props["foreground"] = foreground }
|
||||||
|
}
|
||||||
|
|
||||||
attributeSections["View"] = InspectableObject(props.toMap())
|
attributeSections["View"] = InspectableObject(props.toMap())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +152,7 @@ object ViewDescriptor : ChainedDescriptor<View>() {
|
|||||||
|
|
||||||
private fun fromDrawable(d: Drawable?): Inspectable? {
|
private fun fromDrawable(d: Drawable?): Inspectable? {
|
||||||
return if (d is ColorDrawable) {
|
return if (d is ColorDrawable) {
|
||||||
InspectableValue.Color(d.color, mutable = false)
|
InspectableValue.Color(Color.fromColor(d.color), mutable = false)
|
||||||
} else null
|
} else null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,15 +164,13 @@ object ViewDescriptor : ChainedDescriptor<View>() {
|
|||||||
params["height"] = LayoutParamsMapping.toInspectable(layoutParams.height, mutable = true)
|
params["height"] = LayoutParamsMapping.toInspectable(layoutParams.height, mutable = true)
|
||||||
|
|
||||||
if (layoutParams is ViewGroup.MarginLayoutParams) {
|
if (layoutParams is ViewGroup.MarginLayoutParams) {
|
||||||
val margin =
|
params["margin"] =
|
||||||
InspectableObject(
|
InspectableValue.SpaceBox(
|
||||||
mapOf<String, Inspectable>(
|
SpaceBox(
|
||||||
"left" to InspectableValue.Number(layoutParams.leftMargin, mutable = true),
|
layoutParams.topMargin,
|
||||||
"top" to InspectableValue.Number(layoutParams.topMargin, mutable = true),
|
layoutParams.rightMargin,
|
||||||
"right" to InspectableValue.Number(layoutParams.rightMargin, mutable = true),
|
layoutParams.bottomMargin,
|
||||||
"bottom" to InspectableValue.Number(layoutParams.bottomMargin, mutable = true)))
|
layoutParams.leftMargin))
|
||||||
|
|
||||||
params["margin"] = margin
|
|
||||||
}
|
}
|
||||||
if (layoutParams is FrameLayout.LayoutParams) {
|
if (layoutParams is FrameLayout.LayoutParams) {
|
||||||
params["gravity"] = GravityMapping.toInspectable(layoutParams.gravity, mutable = true)
|
params["gravity"] = GravityMapping.toInspectable(layoutParams.gravity, mutable = true)
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ import android.os.Build
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.ViewGroupCompat
|
import androidx.core.view.ViewGroupCompat
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.*
|
import com.facebook.flipper.plugins.uidebugger.common.EnumMapping
|
||||||
import com.facebook.flipper.plugins.uidebugger.core.FragmentTracker
|
import com.facebook.flipper.plugins.uidebugger.core.FragmentTracker
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.*
|
||||||
|
|
||||||
object ViewGroupDescriptor : ChainedDescriptor<ViewGroup>() {
|
object ViewGroupDescriptor : ChainedDescriptor<ViewGroup>() {
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
import androidx.viewpager.widget.ViewPager
|
import androidx.viewpager.widget.ViewPager
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
|
|
||||||
object ViewPagerDescriptor : ChainedDescriptor<ViewPager>() {
|
object ViewPagerDescriptor : ChainedDescriptor<ViewPager>() {
|
||||||
|
|
||||||
@@ -25,6 +25,6 @@ object ViewPagerDescriptor : ChainedDescriptor<ViewPager>() {
|
|||||||
InspectableObject(
|
InspectableObject(
|
||||||
mapOf("currentItemIndex" to InspectableValue.Number(node.currentItem, false)))
|
mapOf("currentItemIndex" to InspectableValue.Number(node.currentItem, false)))
|
||||||
|
|
||||||
attributeSections.put("ViewPager", props)
|
attributeSections["ViewPager"] = props
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,99 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.descriptors
|
package com.facebook.flipper.plugins.uidebugger.descriptors
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.util.TypedValue
|
||||||
import android.view.Window
|
import android.view.Window
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.Color
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.Inspectable
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableObject
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
object WindowDescriptor : ChainedDescriptor<Window>() {
|
object WindowDescriptor : ChainedDescriptor<Window>() {
|
||||||
|
|
||||||
|
private var internalRStyleableClass: Class<*>? = null
|
||||||
|
private var internalRStyleableFields: Array<Field>? = null
|
||||||
|
private var internalRStyleableWindowField: Field? = null
|
||||||
|
private var internalRStyleable: Any? = null
|
||||||
|
|
||||||
override fun onGetName(node: Window): String {
|
override fun onGetName(node: Window): String {
|
||||||
return node.javaClass.simpleName
|
return node.javaClass.simpleName
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onGetChildren(node: Window): List<Any> = listOf(node.decorView)
|
override fun onGetChildren(node: Window): List<Any> = listOf(node.decorView)
|
||||||
|
|
||||||
|
@SuppressLint("PrivateApi")
|
||||||
|
override fun onGetData(
|
||||||
|
node: Window,
|
||||||
|
attributeSections: MutableMap<SectionName, InspectableObject>
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
if (internalRStyleableClass == null) {
|
||||||
|
internalRStyleableClass = Class.forName("com.android.internal.R\$styleable")
|
||||||
|
internalRStyleableClass?.let { clazz ->
|
||||||
|
internalRStyleable = clazz.newInstance()
|
||||||
|
internalRStyleableFields = clazz.declaredFields
|
||||||
|
internalRStyleableWindowField = clazz.getDeclaredField("Window")
|
||||||
|
internalRStyleableWindowField?.isAccessible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
internalRStyleableWindowField?.let { field ->
|
||||||
|
val windowStyleable = field[internalRStyleable] as IntArray? ?: return
|
||||||
|
|
||||||
|
val indexToName: MutableMap<Int, String> = mutableMapOf()
|
||||||
|
internalRStyleableFields?.forEach { f ->
|
||||||
|
if (f.name.startsWith("Window_") && f.type == Int::class.javaPrimitiveType) {
|
||||||
|
indexToName[f.getInt(internalRStyleable)] = f.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val props = mutableMapOf<String, Inspectable>()
|
||||||
|
|
||||||
|
val typedValue = TypedValue()
|
||||||
|
for ((index, attr) in windowStyleable.withIndex()) {
|
||||||
|
val fieldName = indexToName[index] ?: continue
|
||||||
|
|
||||||
|
if (node.context.theme.resolveAttribute(attr, typedValue, true)) {
|
||||||
|
// Strip 'Windows_' (length: 7) from the name.
|
||||||
|
val name = fieldName.substring(7)
|
||||||
|
|
||||||
|
when (typedValue.type) {
|
||||||
|
TypedValue.TYPE_STRING ->
|
||||||
|
props[name] = InspectableValue.Text(typedValue.string.toString())
|
||||||
|
TypedValue.TYPE_INT_BOOLEAN ->
|
||||||
|
props[name] = InspectableValue.Boolean(typedValue.data != 0)
|
||||||
|
TypedValue.TYPE_INT_HEX ->
|
||||||
|
props[name] = InspectableValue.Text("0x" + Integer.toHexString(typedValue.data))
|
||||||
|
TypedValue.TYPE_FLOAT ->
|
||||||
|
props[name] =
|
||||||
|
InspectableValue.Number(java.lang.Float.intBitsToFloat(typedValue.data))
|
||||||
|
TypedValue.TYPE_REFERENCE -> {
|
||||||
|
val resId = typedValue.data
|
||||||
|
if (resId != 0) {
|
||||||
|
props[name] = InspectableValue.Text(node.context.resources.getResourceName(resId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
|
||||||
|
typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) {
|
||||||
|
val hexColor = "#" + Integer.toHexString(typedValue.data)
|
||||||
|
val color = android.graphics.Color.parseColor(hexColor)
|
||||||
|
props[name] = InspectableValue.Color(Color.fromColor(color))
|
||||||
|
} else if (typedValue.type >= TypedValue.TYPE_FIRST_INT &&
|
||||||
|
typedValue.type <= TypedValue.TYPE_LAST_INT) {
|
||||||
|
props[name] = InspectableValue.Number(typedValue.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attributeSections["Window"] = InspectableObject(props.toMap())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.common
|
package com.facebook.flipper.plugins.uidebugger.model
|
||||||
|
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
@@ -21,13 +21,15 @@ sealed class Inspectable {
|
|||||||
abstract val mutable: kotlin.Boolean
|
abstract val mutable: kotlin.Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// mutable here means you can add/remove items, for native android this should probably be false
|
// In this context, mutable means you can add/remove items,
|
||||||
|
// for native android this should probably be false.
|
||||||
@SerialName("array")
|
@SerialName("array")
|
||||||
@Serializable
|
@Serializable
|
||||||
data class InspectableArray(val items: List<Inspectable>, override val mutable: Boolean = false) :
|
data class InspectableArray(val items: List<Inspectable>, override val mutable: Boolean = false) :
|
||||||
Inspectable()
|
Inspectable()
|
||||||
|
|
||||||
// mutable here means you can add / remove keys, for native android this should probably be false
|
// In this context, mutable means you can add / remove keys,
|
||||||
|
// for native android this should probably be false.
|
||||||
@SerialName("object")
|
@SerialName("object")
|
||||||
@Serializable
|
@Serializable
|
||||||
data class InspectableObject(
|
data class InspectableObject(
|
||||||
@@ -40,34 +42,75 @@ sealed class InspectableValue : Inspectable() {
|
|||||||
|
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
@SerialName("text")
|
@SerialName("text")
|
||||||
class Text(val value: String, override val mutable: kotlin.Boolean) : InspectableValue()
|
class Text(val value: String, override val mutable: kotlin.Boolean = false) : InspectableValue()
|
||||||
|
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
@SerialName("boolean")
|
@SerialName("boolean")
|
||||||
class Boolean(val value: kotlin.Boolean, override val mutable: kotlin.Boolean) :
|
class Boolean(val value: kotlin.Boolean, override val mutable: kotlin.Boolean = false) :
|
||||||
InspectableValue()
|
InspectableValue()
|
||||||
|
|
||||||
@SerialName("number")
|
@SerialName("number")
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
data class Number(
|
data class Number(
|
||||||
@Serializable(with = NumberSerializer::class) val value: kotlin.Number,
|
@Serializable(with = NumberSerializer::class) val value: kotlin.Number,
|
||||||
override val mutable: kotlin.Boolean
|
override val mutable: kotlin.Boolean = false
|
||||||
) : InspectableValue()
|
) : InspectableValue()
|
||||||
|
|
||||||
@SerialName("color")
|
@SerialName("color")
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
data class Color(val value: Int, override val mutable: kotlin.Boolean) : InspectableValue()
|
data class Color(
|
||||||
|
val value: com.facebook.flipper.plugins.uidebugger.model.Color,
|
||||||
|
override val mutable: kotlin.Boolean = false
|
||||||
|
) : InspectableValue()
|
||||||
|
|
||||||
|
@SerialName("coordinate")
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Coordinate(
|
||||||
|
val value: com.facebook.flipper.plugins.uidebugger.model.Coordinate,
|
||||||
|
override val mutable: kotlin.Boolean = false
|
||||||
|
) : InspectableValue()
|
||||||
|
|
||||||
|
@SerialName("coordinate3d")
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Coordinate3D(
|
||||||
|
val value: com.facebook.flipper.plugins.uidebugger.model.Coordinate3D,
|
||||||
|
override val mutable: kotlin.Boolean = false
|
||||||
|
) : InspectableValue()
|
||||||
|
|
||||||
|
@SerialName("size")
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Size(
|
||||||
|
val value: com.facebook.flipper.plugins.uidebugger.model.Size,
|
||||||
|
override val mutable: kotlin.Boolean = false
|
||||||
|
) : InspectableValue()
|
||||||
|
|
||||||
|
@SerialName("bounds")
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Bounds(
|
||||||
|
val value: com.facebook.flipper.plugins.uidebugger.model.Bounds,
|
||||||
|
override val mutable: kotlin.Boolean = false
|
||||||
|
) : InspectableValue()
|
||||||
|
|
||||||
|
@SerialName("space")
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class SpaceBox(
|
||||||
|
val value: com.facebook.flipper.plugins.uidebugger.model.SpaceBox,
|
||||||
|
override val mutable: kotlin.Boolean = false
|
||||||
|
) : InspectableValue()
|
||||||
|
|
||||||
@SerialName("enum")
|
@SerialName("enum")
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
data class Enum(val value: EnumData, override val mutable: kotlin.Boolean) : InspectableValue()
|
data class Enum(
|
||||||
|
val value: com.facebook.flipper.plugins.uidebugger.model.Enumeration,
|
||||||
|
override val mutable: kotlin.Boolean = false
|
||||||
|
) : InspectableValue()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Will attempt to convert Any ref to a suitable primitive inspectable value. Only use if you
|
* Will attempt to convert Any ref to a suitable primitive inspectable value. Only use if you
|
||||||
* are dealing with an Any / object type. Prefer the specific contructors
|
* are dealing with an Any / object type. Prefer the specific constructors
|
||||||
*/
|
*/
|
||||||
fun fromAny(any: Any, mutable: kotlin.Boolean): Inspectable? {
|
fun fromAny(any: Any, mutable: kotlin.Boolean = false): Inspectable? {
|
||||||
return when (any) {
|
return when (any) {
|
||||||
is kotlin.Number -> InspectableValue.Number(any, mutable)
|
is kotlin.Number -> InspectableValue.Number(any, mutable)
|
||||||
is kotlin.Boolean -> InspectableValue.Boolean(any, mutable)
|
is kotlin.Boolean -> InspectableValue.Boolean(any, mutable)
|
||||||
@@ -78,8 +121,6 @@ sealed class InspectableValue : Inspectable() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlinx.serialization.Serializable data class EnumData(val values: Set<String>, val value: String)
|
|
||||||
|
|
||||||
object NumberSerializer : KSerializer<Number> {
|
object NumberSerializer : KSerializer<Number> {
|
||||||
override val descriptor: SerialDescriptor =
|
override val descriptor: SerialDescriptor =
|
||||||
PrimitiveSerialDescriptor("com.meta.NumberSerializer", PrimitiveKind.DOUBLE)
|
PrimitiveSerialDescriptor("com.meta.NumberSerializer", PrimitiveKind.DOUBLE)
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
package com.facebook.flipper.plugins.uidebugger.model
|
package com.facebook.flipper.plugins.uidebugger.model
|
||||||
|
|
||||||
import android.graphics.Rect
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableObject
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.descriptors.Id
|
import com.facebook.flipper.plugins.uidebugger.descriptors.Id
|
||||||
|
|
||||||
@kotlinx.serialization.Serializable
|
@kotlinx.serialization.Serializable
|
||||||
@@ -21,12 +19,3 @@ data class Node(
|
|||||||
val children: List<Id>,
|
val children: List<Id>,
|
||||||
val activeChild: Id?,
|
val activeChild: Id?,
|
||||||
)
|
)
|
||||||
|
|
||||||
@kotlinx.serialization.Serializable
|
|
||||||
data class Bounds(val x: Int, val y: Int, val width: Int, val height: Int) {
|
|
||||||
companion object {
|
|
||||||
fun fromRect(rect: Rect): Bounds {
|
|
||||||
return Bounds(rect.left, rect.top, rect.width(), rect.height())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.facebook.flipper.plugins.uidebugger.model
|
||||||
|
|
||||||
|
import android.graphics.Rect
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Bounds(val x: Int, val y: Int, val width: Int, val height: Int) {
|
||||||
|
companion object {
|
||||||
|
fun fromRect(rect: Rect): Bounds {
|
||||||
|
return Bounds(rect.left, rect.top, rect.width(), rect.height())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class SpaceBox(val top: Int, val right: Int, val bottom: Int, val left: Int) {
|
||||||
|
companion object {
|
||||||
|
fun fromRect(rect: Rect): SpaceBox {
|
||||||
|
return SpaceBox(rect.top, rect.right, rect.bottom, rect.left)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Color(val r: Int, val g: Int, val b: Int, val alpha: Int) {
|
||||||
|
companion object {
|
||||||
|
fun fromColor(color: Int): Color {
|
||||||
|
val alpha: Int = (color shr 24) and 0xFF / 255
|
||||||
|
val red: Int = (color shr 16) and 0xFF
|
||||||
|
val green: Int = (color shr 8) and 0xFF
|
||||||
|
val blue: Int = (color shr 0) and 0xFF
|
||||||
|
return Color(red, green, blue, alpha)
|
||||||
|
}
|
||||||
|
fun fromColor(color: android.graphics.Color): Color {
|
||||||
|
return fromColor(color.toArgb())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Coordinate(
|
||||||
|
@Serializable(with = NumberSerializer::class) val x: Number,
|
||||||
|
@Serializable(with = NumberSerializer::class) val y: Number
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Coordinate3D(
|
||||||
|
@Serializable(with = NumberSerializer::class) val x: Number,
|
||||||
|
@Serializable(with = NumberSerializer::class) val y: Number,
|
||||||
|
@Serializable(with = NumberSerializer::class) val z: Number
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Size(
|
||||||
|
@Serializable(with = NumberSerializer::class) val width: Number,
|
||||||
|
@Serializable(with = NumberSerializer::class) val height: Number
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@kotlinx.serialization.Serializable
|
||||||
|
data class Enumeration(val values: Set<String>, val value: String)
|
||||||
@@ -8,9 +8,9 @@
|
|||||||
package com.facebook.flipper.plugins.uidebugger
|
package com.facebook.flipper.plugins.uidebugger
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.EnumData
|
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.EnumMapping
|
import com.facebook.flipper.plugins.uidebugger.common.EnumMapping
|
||||||
import com.facebook.flipper.plugins.uidebugger.common.InspectableValue
|
import com.facebook.flipper.plugins.uidebugger.model.Enumeration
|
||||||
|
import com.facebook.flipper.plugins.uidebugger.model.InspectableValue
|
||||||
import org.hamcrest.CoreMatchers.*
|
import org.hamcrest.CoreMatchers.*
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.hamcrest.MatcherAssert.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -42,6 +42,6 @@ class EnumMappingTest {
|
|||||||
visibility.toInspectable(View.GONE, true),
|
visibility.toInspectable(View.GONE, true),
|
||||||
equalTo(
|
equalTo(
|
||||||
InspectableValue.Enum(
|
InspectableValue.Enum(
|
||||||
EnumData(setOf("VISIBLE", "INVISIBLE", "GONE"), "GONE"), mutable = true)))
|
Enumeration(setOf("VISIBLE", "INVISIBLE", "GONE"), "GONE"), mutable = true)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,13 @@ export type Bounds = {
|
|||||||
height: number;
|
height: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Color = {
|
||||||
|
r: number;
|
||||||
|
g: number;
|
||||||
|
b: number;
|
||||||
|
alpha: number;
|
||||||
|
};
|
||||||
|
|
||||||
export type Snapshot = string;
|
export type Snapshot = string;
|
||||||
export type Id = number;
|
export type Id = number;
|
||||||
|
|
||||||
@@ -76,7 +83,13 @@ export type InspectableNumber = {
|
|||||||
|
|
||||||
export type InspectableColor = {
|
export type InspectableColor = {
|
||||||
type: 'number';
|
type: 'number';
|
||||||
value: number;
|
value: Color;
|
||||||
|
mutable: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type InspectableBounds = {
|
||||||
|
type: 'bounds';
|
||||||
|
value: Bounds;
|
||||||
mutable: boolean;
|
mutable: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user