debug this
diff --git a/packages/devtools_app/.flutter-plugins-dependencies b/packages/devtools_app/.flutter-plugins-dependencies new file mode 100644 index 0000000..a015c88 --- /dev/null +++ b/packages/devtools_app/.flutter-plugins-dependencies
@@ -0,0 +1 @@ +{"dependencyGraph":[{"name":"image_gallery_saver","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"devtools_app","dependencies":[]}]} \ No newline at end of file
diff --git a/packages/devtools_app/lib/src/inspector/diagnostics_node.dart b/packages/devtools_app/lib/src/inspector/diagnostics_node.dart index 8f4b1ad..b80ff9d 100644 --- a/packages/devtools_app/lib/src/inspector/diagnostics_node.dart +++ b/packages/devtools_app/lib/src/inspector/diagnostics_node.dart
@@ -674,19 +674,6 @@ await (await inspectorService) ?.setSelectionInspector(valueRef, uiAlreadyUpdated); } - - Future<void> getRenderObject() async { - if (_renderObject != null) return; - final service = await inspectorService; - _renderObject = await service.renderObject(valueRef); - if (isFlex && _children != null) - for (var i = 0; i < _children.length; ++i) { - final List<dynamic> children = - _renderObject.json['children']; - _children[i]._renderObject = RemoteDiagnosticsNode( - children[i], inspectorService, true, _children[i]); - } - } } class InspectorSourceLocation {
diff --git a/packages/devtools_app/lib/src/inspector/flutter/inspector_screen_details_tab.dart b/packages/devtools_app/lib/src/inspector/flutter/inspector_screen_details_tab.dart index ff4a438..dc9660d 100644 --- a/packages/devtools_app/lib/src/inspector/flutter/inspector_screen_details_tab.dart +++ b/packages/devtools_app/lib/src/inspector/flutter/inspector_screen_details_tab.dart
@@ -106,13 +106,18 @@ RemoteDiagnosticsNode root; void onSelectionChanged() async { + if (!selected.isFlex && selected.parent != null && !selected.parent.isFlex) + return; objectGroupManager.cancelNext(); + + // TODO(albertusangga) show loading animation when root is null? setState(() { root = null; }); + final nextObjectGroup = objectGroupManager.next; - if (selected ?? false) { - final root = await nextObjectGroup.getDetailsSubtree( + if (selected != null) { + root = await nextObjectGroup.getDetailsSubtreeWithRenderObject( selected, subtreeDepth: 1, ); @@ -139,6 +144,7 @@ 'flex-layout', ); } + onSelectionChanged(); } @override @@ -157,12 +163,8 @@ Widget build(BuildContext context) { super.build(context); // TODO(albertusangga): Visualize non-flex widget constraint model - if (selected == null || - (!selected.isFlex && !(selected.parent?.isFlex ?? false))) - return const SizedBox(); - final flexLayoutProperties = FlexLayoutProperties.fromDiagnostics( - selected.isFlex ? selected : selected.parent, - ); + if (root == null) return const SizedBox(); + final flexLayoutProperties = FlexLayoutProperties.fromDiagnostics(root); final highlightChild = selected.isFlex ? null : selected.parent.childrenNow.indexOf(selected); return StoryOfYourFlexWidget(
diff --git a/packages/devtools_app/lib/src/inspector/inspector_service.dart b/packages/devtools_app/lib/src/inspector/inspector_service.dart index b43ef94..3829636 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_service.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_service.dart
@@ -955,29 +955,79 @@ )); } - Future<RemoteDiagnosticsNode> renderObject(InspectorInstanceRef ref) async { - // TODO(albertusangga): Make this new Service Extension in flutter/flutter - String command = ''' - final id = '${ref.id}'; - final instance = WidgetInspectorService.instance; - final Element object = WidgetInspectorService.instance.toObject(id); - final RenderObject renderObject = object.renderObject; - return instance._safeJsonEncode( - instance._nodeToJson( - renderObject.toDiagnosticsNode(), - _SerializationDelegate( - groupName: '', - service: instance, - includeProperties: true, - ), - )); - '''; - command = '((){${command.split('\n').join()})()'; - final val = await inspectorLibrary.eval( - command, - isAlive: this, - ); - return parseDiagnosticsNodeObservatory(val); + static const getDetailsSubtreeWithRenderObjectServiceExtensionName = 'getDetailsSubtreeWithRenderObject'; + + Future<RemoteDiagnosticsNode> getDetailsSubtreeWithRenderObject(RemoteDiagnosticsNode node, { int subtreeDepth = 1 }) async { + if (node == null) return null; + if (!serviceManager.serviceExtensionManager.isServiceExtensionAvailable(getDetailsSubtreeWithRenderObjectServiceExtensionName)) { + String command = ''' + print('start registering...'); + WidgetInspectorService.instance.registerServiceExtension( + name: 'getDetailsSubtreeWithRenderObject', + callback: (Map<String, String> parameters) async { + print('inside callback...'); + Map<String, Object> _getDetailsSubtreeWithRenderObject( + String id, + String groupName, + int subtreeDepth, + ) { + final DiagnosticsNode root = WidgetInspectorService.instance.toObject(id); + if (root == null) { + return null; + } + return WidgetInspectorService.instance._nodeToJson( + root, + _SerializationDelegate( + groupName: groupName, + summaryTree: false, + subtreeDepth: subtreeDepth, + includeProperties: true, + service: WidgetInspectorService.instance, + addAdditionalPropertiesCallback: (node, delegate) { + final Map<String, Object> additionalJson = <String, Object>{}; + final Object value = node.value; + if (value is Element) { + additionalJson['renderObject'] = value.renderObject.toDiagnosticsNode()?.toJsonMap( + delegate.copyWith( + subtreeDepth: 0, + includeProperties: true, + ), + ); + } + return additionalJson; + } + ), + ); + } + assert(parameters.containsKey('objectGroup')); + final String subtreeDepth = parameters['subtreeDepth']; + return <String, Object>{ + 'result': _getDetailsSubtreeWithRenderObject( + parameters['arg'], + parameters['objectGroup'], + subtreeDepth != null ? int.parse(subtreeDepth) : 2, + ), + }; + }, + ); + print('finish registering...'); + '''; + command = '((){${command.split('\n').join()}})()'; + await inspectorLibrary.eval( + command, + isAlive: this, + ); + } + final args = { + 'objectGroup': groupName, + 'arg': node.dartDiagnosticRef.id, + 'subtreeDepth': '$subtreeDepth', + }; + + return parseDiagnosticsNodeDaemon(invokeServiceMethodDaemonParams( + getDetailsSubtreeWithRenderObjectServiceExtensionName, + args, + )); } }