Skip to content

Commit

Permalink
[Inspector V2] Unify summary tree and widget details tree (#7912)
Browse files Browse the repository at this point in the history
  • Loading branch information
elliette committed Jun 18, 2024
1 parent 6831d58 commit efd04c1
Show file tree
Hide file tree
Showing 19 changed files with 721 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

// Do not delete these arguments. They are parsed by test runner.
// test-argument:appPath="test/test_infra/fixtures/memory_app"
// test-argument:experimentsOn=true

// ignore_for_file: avoid_print

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ class InspectorController extends DisposableController
final group = treeGroups.next;
final node = await (detailsSubtree
? group.getDetailsSubtree(subtreeRoot, subtreeDepth: subtreeDepth)
: group.getRoot(treeType));
: group.getRoot(treeType, isSummaryTree: true));
if (node == null || group.disposed || _disposed) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ class InspectorController extends DisposableController
final group = treeGroups.next;
final node = await (detailsSubtree
? group.getDetailsSubtree(subtreeRoot, subtreeDepth: subtreeDepth)
: group.getRoot(treeType));
: group.getRoot(treeType, isSummaryTree: false));
if (node == null || group.disposed || _disposed) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,7 @@ class InspectorRowContent extends StatelessWidget {
isSelected: row.isSelected,
searchValue: searchValue,
errorText: error?.errorMessage,
emphasizeNodesFromLocalProject: true,
nodeDescriptionHighlightStyle:
searchValue.isEmpty || !row.isSearchMatch
? DiagnosticsTextStyles.regular(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class DiagnosticsNodeDescription extends StatelessWidget {
this.multiline = false,
this.style,
this.nodeDescriptionHighlightStyle,
this.emphasizeNodesFromLocalProject = false,
});

final RemoteDiagnosticsNode? diagnostic;
Expand All @@ -51,6 +52,10 @@ class DiagnosticsNodeDescription extends StatelessWidget {
final bool multiline;
final TextStyle? style;
final TextStyle? nodeDescriptionHighlightStyle;
// TODO(https://github.com/flutter/devtools/issues/7860): Remove and default
// to true when turning on inspector V2. This is currently true for the V2
// inspector and false for the legacy inspector.
final bool emphasizeNodesFromLocalProject;

static Widget _paddedIcon(Widget icon) {
return Padding(
Expand Down Expand Up @@ -264,7 +269,6 @@ class DiagnosticsNodeDescription extends StatelessWidget {
colorScheme,
),
);
var descriptionTextStyle = textStyle;
// TODO(jacobr): use TextSpans and SelectableText instead of Text.
if (diagnosticLocal.isProperty) {
// Display of inline properties.
Expand All @@ -280,8 +284,7 @@ class DiagnosticsNodeDescription extends StatelessWidget {
);
// provide some contrast between the name and description if both are
// present.
descriptionTextStyle =
descriptionTextStyle.merge(theme.subtleTextStyle);
textStyle = textStyle.merge(theme.subtleTextStyle);
}

if (diagnosticLocal.isCreatedByLocalProject) {
Expand Down Expand Up @@ -332,7 +335,7 @@ class DiagnosticsNodeDescription extends StatelessWidget {
Flexible(
child: buildDescription(
description: description,
textStyle: descriptionTextStyle,
textStyle: textStyle,
colorScheme: colorScheme,
diagnostic: diagnostic,
searchValue: searchValue,
Expand Down Expand Up @@ -382,14 +385,25 @@ class DiagnosticsNodeDescription extends StatelessWidget {
}
}

if (!diagnosticLocal.isSummaryTree &&
// TODO(https://github.com/flutter/devtools/issues/7860): Remove this
// if-block once the widget details tree is gone. This bolding is only
// used there.
if (!emphasizeNodesFromLocalProject &&
!diagnosticLocal.isSummaryTree &&
diagnosticLocal.isCreatedByLocalProject) {
textStyle = textStyle.merge(DiagnosticsTextStyles.regularBold);
}

// Grey out nodes that were not created by the local project to emphasize
// those that were:
if (emphasizeNodesFromLocalProject &&
!diagnosticLocal.isCreatedByLocalProject) {
textStyle = textStyle.merge(theme.subtleTextStyle);
}

var diagnosticDescription = buildDescription(
description: diagnosticLocal.description ?? '',
textStyle: descriptionTextStyle,
textStyle: textStyle,
colorScheme: colorScheme,
diagnostic: diagnostic,
searchValue: searchValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -948,21 +948,29 @@ class ObjectGroup extends InspectorObjectGroupBase {
@override
bool canSetSelectionInspector = true;

Future<RemoteDiagnosticsNode?> getRoot(FlutterTreeType type) {
Future<RemoteDiagnosticsNode?> getRoot(
FlutterTreeType type, {
required bool isSummaryTree,
}) {
// There is no excuse to call this method on a disposed group.
assert(!disposed);
switch (type) {
case FlutterTreeType.widget:
return getRootWidget();
return getRootWidgetTree(isSummaryTree: isSummaryTree);
}
}

Future<RemoteDiagnosticsNode?> getRootWidget() {
Future<RemoteDiagnosticsNode?> getRootWidgetTree({
required bool isSummaryTree,
}) {
return parseDiagnosticsNodeDaemon(
invokeServiceMethodDaemonParams(
WidgetInspectorServiceExtensions
.getRootWidgetSummaryTreeWithPreviews.name,
{'groupName': groupName},
WidgetInspectorServiceExtensions.getRootWidgetTree.name,
{
'groupName': groupName,
'isSummaryTree': '$isSummaryTree',
'withPreviews': 'true',
},
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,14 @@ void main() {

group('screenshot tests', () {
testWidgetsWithWindowSize(
'navigation',
'initial load',
windowSize,
(WidgetTester tester) async {
await env.setupEnvironment();
expect(serviceConnection.serviceManager.service, equals(env.service));
expect(serviceConnection.serviceManager.isolateManager, isNotNull);

final screen = InspectorScreen();
await tester.pumpWidget(
wrapWithInspectorControllers(
Builder(builder: screen.build),
v2: true,
),
);
await tester.pump(const Duration(seconds: 1));
final InspectorScreenBodyState state =
tester.state(find.byType(InspectorScreenBody));
final controller = state.controller;
while (!controller.flutterAppFrameReady) {
await controller.maybeLoadUI();
await tester.pumpAndSettle();
}
await _loadInspectorUI(tester);

// Give time for the initial animation to complete.
await tester.pumpAndSettle(inspectorChangeSettleTime);
await expectLater(
Expand All @@ -82,6 +68,19 @@ void main() {
),
);

await env.tearDownEnvironment();
},
);

testWidgetsWithWindowSize(
'navigation',
windowSize,
(WidgetTester tester) async {
await _loadInspectorUI(tester);

// Give time for the initial animation to complete.
await tester.pumpAndSettle(inspectorChangeSettleTime);

// Click on the Center widget (row index #5)
await tester.tap(find.richText('Center'));
await tester.pumpAndSettle(inspectorChangeSettleTime);
Expand Down Expand Up @@ -152,6 +151,9 @@ void main() {

await env.tearDownEnvironment();
},
// TODO(https://github.com/flutter/devtools/issues/7911): Re-enable once
// the implementation details are collapsed.
skip: true,
);

// TODO(jacobr): convert these tests to screenshot tests like the initial
Expand Down Expand Up @@ -462,3 +464,21 @@ void main() {
);
});
}

Future<void> _loadInspectorUI(WidgetTester tester) async {
final screen = InspectorScreen();
await tester.pumpWidget(
wrapWithInspectorControllers(
Builder(builder: screen.build),
v2: true,
),
);
await tester.pump(const Duration(seconds: 1));
final InspectorScreenBodyState state =
tester.state(find.byType(InspectorScreenBody));
final controller = state.controller;
while (!controller.flutterAppFrameReady) {
await controller.maybeLoadUI();
await tester.pumpAndSettle();
}
}
Loading

0 comments on commit efd04c1

Please sign in to comment.