From 1a5ce1e98ba35c92c93ee8617b243eced43245c7 Mon Sep 17 00:00:00 2001 From: matt-ragonese <46503192+matt-ragonese@users.noreply.github.com> Date: Mon, 13 Sep 2021 20:42:29 -0400 Subject: [PATCH 1/6] Rename InspectorTreeController to InspectorTreeControllerBase --- .../lib/src/inspector/inspector_controller.dart | 4 ++-- packages/devtools_app/lib/src/inspector/inspector_tree.dart | 4 ++-- .../lib/src/inspector/inspector_tree_flutter.dart | 6 +++--- .../devtools_app/lib/src/logging/logging_controller.dart | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/devtools_app/lib/src/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/inspector/inspector_controller.dart index fe1c8094702..80bbbd4f531 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_controller.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_controller.dart @@ -70,7 +70,7 @@ class InspectorController extends DisposableController implements InspectorServiceClient { InspectorController({ @required this.inspectorTree, - InspectorTreeController detailsTree, + InspectorTreeControllerBase detailsTree, @required this.treeType, this.parent, this.isSummaryTree = true, @@ -204,7 +204,7 @@ class InspectorController extends DisposableController InspectorController details; - InspectorTreeController inspectorTree; + InspectorTreeControllerBase inspectorTree; final FlutterTreeType treeType; bool _disposed = false; diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree.dart b/packages/devtools_app/lib/src/inspector/inspector_tree.dart index ab5239f12dc..f4b1485a9e0 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_tree.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree.dart @@ -314,7 +314,7 @@ class InspectorTreeConfig { final TreeEventCallback onHover; } -abstract class InspectorTreeController { +abstract class InspectorTreeControllerBase { // Abstract method defined to avoid a direct Flutter dependency. @protected void setState(VoidCallback fn); @@ -678,7 +678,7 @@ abstract class InspectorTreeController { } } -mixin InspectorTreeFixedRowHeightController on InspectorTreeController { +mixin InspectorTreeFixedRowHeightController on InspectorTreeControllerBase { Rect getBoundingBox(InspectorTreeRow row); void scrollToRect(Rect targetRect); diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart b/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart index a69dd86cd09..6235be69991 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart @@ -94,7 +94,7 @@ class _InspectorTreeRowState extends State<_InspectorTreeRowWidget> } class InspectorTreeControllerFlutter extends Object - with InspectorTreeController, InspectorTreeFixedRowHeightController { + with InspectorTreeControllerBase, InspectorTreeFixedRowHeightController { /// Client the controller notifies to trigger changes to the UI. final Set _clients = {}; @@ -192,7 +192,7 @@ class InspectorTree extends StatefulWidget { this.widgetErrors, }) : super(key: key); - final InspectorTreeController controller; + final InspectorTreeControllerBase controller; final DebuggerController debuggerController; final bool isSummaryTree; final LinkedHashMap widgetErrors; @@ -529,7 +529,7 @@ Paint _defaultPaint(ColorScheme colorScheme) => Paint() class _RowPainter extends CustomPainter { _RowPainter(this.row, this._controller, this.colorScheme); - final InspectorTreeController _controller; + final InspectorTreeControllerBase _controller; final InspectorTreeRow row; final ColorScheme colorScheme; diff --git a/packages/devtools_app/lib/src/logging/logging_controller.dart b/packages/devtools_app/lib/src/logging/logging_controller.dart index 98c4030ec62..e772ce39bce 100644 --- a/packages/devtools_app/lib/src/logging/logging_controller.dart +++ b/packages/devtools_app/lib/src/logging/logging_controller.dart @@ -36,10 +36,10 @@ bool _verboseDebugging = false; typedef OnShowDetails = void Function({ String text, - InspectorTreeController tree, + InspectorTreeControllerBase tree, }); -typedef CreateLoggingTree = InspectorTreeController Function({ +typedef CreateLoggingTree = InspectorTreeControllerBase Function({ VoidCallback onSelectionChange, }); @@ -79,7 +79,7 @@ class LoggingDetailsController { /// type. final CreateLoggingTree createLoggingTree; - InspectorTreeController tree; + InspectorTreeControllerBase tree; void setData(LogData data) { this.data = data; From 75edede82d913c5cf3145eb42be111f7d7901461 Mon Sep 17 00:00:00 2001 From: matt-ragonese <46503192+matt-ragonese@users.noreply.github.com> Date: Wed, 15 Sep 2021 17:44:29 -0400 Subject: [PATCH 2/6] Moved InspectorTreeControllerBase and InspectorTreeFixedRowHeightController into inspector_tree_flutter.dart --- .../src/inspector/inspector_controller.dart | 1 + .../lib/src/inspector/inspector_tree.dart | 390 ------------------ .../src/inspector/inspector_tree_flutter.dart | 390 ++++++++++++++++++ .../lib/src/logging/logging_controller.dart | 1 + 4 files changed, 392 insertions(+), 390 deletions(-) diff --git a/packages/devtools_app/lib/src/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/inspector/inspector_controller.dart index 80bbbd4f531..36160d76bc9 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_controller.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_controller.dart @@ -35,6 +35,7 @@ import 'inspector_screen.dart'; import 'inspector_service.dart'; import 'inspector_text_styles.dart' as inspector_text_styles; import 'inspector_tree.dart'; +import 'inspector_tree_flutter.dart'; const inspectorRefQueryParam = 'inspectorRef'; diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree.dart b/packages/devtools_app/lib/src/inspector/inspector_tree.dart index f4b1485a9e0..b1c770a6374 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_tree.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree.dart @@ -17,7 +17,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; -import '../config_specific/logger/logger.dart'; import '../theme.dart'; import '../utils.dart'; import 'diagnostics_node.dart'; @@ -313,392 +312,3 @@ class InspectorTreeConfig { final TreeEventCallback onExpand; final TreeEventCallback onHover; } - -abstract class InspectorTreeControllerBase { - // Abstract method defined to avoid a direct Flutter dependency. - @protected - void setState(VoidCallback fn); - - InspectorTreeNode get root => _root; - InspectorTreeNode _root; - set root(InspectorTreeNode node) { - setState(() { - _root = node; - }); - } - - RemoteDiagnosticsNode subtreeRoot; // Optional. - - InspectorTreeNode get selection => _selection; - InspectorTreeNode _selection; - - InspectorTreeConfig get config => _config; - InspectorTreeConfig _config; - - set config(InspectorTreeConfig value) { - // Only allow setting config once. - assert(_config == null); - _config = value; - } - - set selection(InspectorTreeNode node) { - if (node == _selection) return; - - setState(() { - _selection?.selected = false; - _selection = node; - _selection?.selected = true; - if (config.onSelectionChange != null) { - config.onSelectionChange(); - } - }); - } - - InspectorTreeNode get hover => _hover; - InspectorTreeNode _hover; - - double lastContentWidth; - - InspectorTreeNode createNode(); - - final List cachedRows = []; - - // TODO: we should add a listener instead that clears the cache when the - // root is marked as dirty. - void _maybeClearCache() { - if (root != null && root.isDirty) { - cachedRows.clear(); - root.isDirty = false; - lastContentWidth = null; - } - } - - InspectorTreeRow getCachedRow(int index) { - if (index < 0) return null; - - _maybeClearCache(); - while (cachedRows.length <= index) { - cachedRows.add(null); - } - cachedRows[index] ??= root?.getRow(index); - return cachedRows[index]; - } - - double getRowOffset(int index) { - return (getCachedRow(index)?.depth ?? 0) * columnWidth; - } - - set hover(InspectorTreeNode node) { - if (node == _hover) { - return; - } - setState(() { - _hover = node; - // TODO(jacobr): we could choose to repaint only a portion of the UI - }); - } - - RemoteDiagnosticsNode currentHoverDiagnostic; - - void navigateUp() { - _navigateHelper(-1); - } - - void navigateDown() { - _navigateHelper(1); - } - - void navigateLeft() { - // This logic is consistent with how IntelliJ handles tree navigation on - // on left arrow key press. - if (selection == null) { - _navigateHelper(-1); - return; - } - - if (selection.isExpanded) { - setState(() { - selection.isExpanded = false; - }); - return; - } - if (selection.parent != null) { - selection = selection.parent; - } - } - - void navigateRight() { - // This logic is consistent with how IntelliJ handles tree navigation on - // on right arrow key press. - - if (selection == null || selection.isExpanded) { - _navigateHelper(1); - return; - } - - setState(() { - selection.isExpanded = true; - }); - } - - void _navigateHelper(int indexOffset) { - if (numRows == 0) return; - - if (selection == null) { - selection = root; - return; - } - - selection = root - .getRow( - (root.getRowIndex(selection) + indexOffset).clamp(0, numRows - 1)) - ?.node; - } - - double get horizontalPadding => 10.0; - - double getDepthIndent(int depth) { - return (depth + 1) * columnWidth + horizontalPadding; - } - - double getRowY(int index) { - return rowHeight * index + verticalPadding; - } - - void nodeChanged(InspectorTreeNode node) { - if (node == null) return; - setState(() { - node.isDirty = true; - }); - } - - void removeNodeFromParent(InspectorTreeNode node) { - setState(() { - node.parent?.removeChild(node); - }); - } - - void appendChild(InspectorTreeNode node, InspectorTreeNode child) { - setState(() { - node.appendChild(child); - }); - } - - void expandPath(InspectorTreeNode node) { - setState(() { - _expandPath(node); - }); - } - - void _expandPath(InspectorTreeNode node) { - while (node != null) { - if (!node.isExpanded) { - node.isExpanded = true; - } - node = node.parent; - } - } - - void collapseToSelected() { - setState(() { - _collapseAllNodes(root); - if (selection == null) return; - _expandPath(selection); - }); - } - - void _collapseAllNodes(InspectorTreeNode root) { - root.isExpanded = false; - root.children.forEach(_collapseAllNodes); - } - - int get numRows => root != null ? root.subtreeSize : 0; - - int getRowIndex(double y) => math.max(0, (y - verticalPadding) ~/ rowHeight); - - InspectorTreeRow getRowForNode(InspectorTreeNode node) { - return getCachedRow(root.getRowIndex(node)); - } - - InspectorTreeRow getRow(Offset offset) { - if (root == null) return null; - final int row = getRowIndex(offset.dy); - return row < root.subtreeSize ? getCachedRow(row) : null; - } - - void animateToTargets(List targets); - - void onExpandRow(InspectorTreeRow row) { - setState(() { - row.node.isExpanded = true; - if (config.onExpand != null) { - config.onExpand(row.node); - } - }); - } - - void onCollapseRow(InspectorTreeRow row) { - setState(() { - row.node.isExpanded = false; - }); - } - - void onSelectRow(InspectorTreeRow row) { - selection = row.node; - expandPath(row.node); - } - - bool expandPropertiesByDefault(DiagnosticsTreeStyle style) { - // This code matches the text style defaults for which styles are - // by default and which aren't. - switch (style) { - case DiagnosticsTreeStyle.none: - case DiagnosticsTreeStyle.singleLine: - case DiagnosticsTreeStyle.errorProperty: - return false; - - case DiagnosticsTreeStyle.sparse: - case DiagnosticsTreeStyle.offstage: - case DiagnosticsTreeStyle.dense: - case DiagnosticsTreeStyle.transition: - case DiagnosticsTreeStyle.error: - case DiagnosticsTreeStyle.whitespace: - case DiagnosticsTreeStyle.flat: - case DiagnosticsTreeStyle.shallow: - case DiagnosticsTreeStyle.truncateChildren: - return true; - } - return true; - } - - InspectorTreeNode setupInspectorTreeNode( - InspectorTreeNode node, - RemoteDiagnosticsNode diagnosticsNode, { - @required bool expandChildren, - @required bool expandProperties, - }) { - assert(expandChildren != null); - assert(expandProperties != null); - node.diagnostic = diagnosticsNode; - if (config.onNodeAdded != null) { - config.onNodeAdded(node, diagnosticsNode); - } - - if (diagnosticsNode.hasChildren || - diagnosticsNode.inlineProperties.isNotEmpty) { - if (diagnosticsNode.childrenReady || !diagnosticsNode.hasChildren) { - final bool styleIsMultiline = - expandPropertiesByDefault(diagnosticsNode.style); - setupChildren( - diagnosticsNode, - node, - node.diagnostic.childrenNow, - expandChildren: expandChildren && styleIsMultiline, - expandProperties: expandProperties && styleIsMultiline, - ); - } else { - node.clearChildren(); - node.appendChild(createNode()); - } - } - return node; - } - - void setupChildren( - RemoteDiagnosticsNode parent, - InspectorTreeNode treeNode, - List children, { - @required bool expandChildren, - @required bool expandProperties, - }) { - assert(expandChildren != null); - assert(expandProperties != null); - treeNode.isExpanded = expandChildren; - if (treeNode.children.isNotEmpty) { - // Only case supported is this is the loading node. - assert(treeNode.children.length == 1); - removeNodeFromParent(treeNode.children.first); - } - final inlineProperties = parent.inlineProperties; - - if (inlineProperties != null) { - for (RemoteDiagnosticsNode property in inlineProperties) { - appendChild( - treeNode, - setupInspectorTreeNode( - createNode(), - property, - // We are inside a property so only expand children if - // expandProperties is true. - expandChildren: expandProperties, - expandProperties: expandProperties, - ), - ); - } - } - if (children != null) { - for (RemoteDiagnosticsNode child in children) { - appendChild( - treeNode, - setupInspectorTreeNode( - createNode(), - child, - expandChildren: expandChildren, - expandProperties: expandProperties, - ), - ); - } - } - } - - Future maybePopulateChildren(InspectorTreeNode treeNode) async { - final RemoteDiagnosticsNode diagnostic = treeNode.diagnostic; - if (diagnostic != null && - diagnostic.hasChildren && - (treeNode.hasPlaceholderChildren || treeNode.children.isEmpty)) { - try { - final children = await diagnostic.children; - if (treeNode.hasPlaceholderChildren || treeNode.children.isEmpty) { - setupChildren( - diagnostic, - treeNode, - children, - expandChildren: true, - expandProperties: false, - ); - nodeChanged(treeNode); - if (treeNode == selection) { - expandPath(treeNode); - } - } - } catch (e) { - log(e.toString(), LogLevel.error); - } - } - } -} - -mixin InspectorTreeFixedRowHeightController on InspectorTreeControllerBase { - Rect getBoundingBox(InspectorTreeRow row); - - void scrollToRect(Rect targetRect); - - @override - void animateToTargets(List targets) { - Rect targetRect; - - for (InspectorTreeNode target in targets) { - final row = getRowForNode(target); - if (row != null) { - final rowRect = getBoundingBox(row); - targetRect = - targetRect == null ? rowRect : targetRect.expandToInclude(rowRect); - } - } - - if (targetRect == null || targetRect.isEmpty) return; - - targetRect = targetRect.inflate(20.0); - scrollToRect(targetRect); - } -} diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart b/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart index 6235be69991..8eef26eec97 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart @@ -13,6 +13,7 @@ import 'package:pedantic/pedantic.dart'; import '../auto_dispose_mixin.dart'; import '../collapsible_mixin.dart'; import '../common_widgets.dart'; +import '../config_specific/logger/logger.dart'; import '../debugger/debugger_controller.dart'; import '../error_badge_manager.dart'; import '../theme.dart'; @@ -93,6 +94,395 @@ class _InspectorTreeRowState extends State<_InspectorTreeRowWidget> bool shouldShow() => widget.node.shouldShow; } +abstract class InspectorTreeControllerBase { + // Abstract method defined to avoid a direct Flutter dependency. + @protected + void setState(VoidCallback fn); + + InspectorTreeNode get root => _root; + InspectorTreeNode _root; + set root(InspectorTreeNode node) { + setState(() { + _root = node; + }); + } + + RemoteDiagnosticsNode subtreeRoot; // Optional. + + InspectorTreeNode get selection => _selection; + InspectorTreeNode _selection; + + InspectorTreeConfig get config => _config; + InspectorTreeConfig _config; + + set config(InspectorTreeConfig value) { + // Only allow setting config once. + assert(_config == null); + _config = value; + } + + set selection(InspectorTreeNode node) { + if (node == _selection) return; + + setState(() { + _selection?.selected = false; + _selection = node; + _selection?.selected = true; + if (config.onSelectionChange != null) { + config.onSelectionChange(); + } + }); + } + + InspectorTreeNode get hover => _hover; + InspectorTreeNode _hover; + + double lastContentWidth; + + InspectorTreeNode createNode(); + + final List cachedRows = []; + + // TODO: we should add a listener instead that clears the cache when the + // root is marked as dirty. + void _maybeClearCache() { + if (root != null && root.isDirty) { + cachedRows.clear(); + root.isDirty = false; + lastContentWidth = null; + } + } + + InspectorTreeRow getCachedRow(int index) { + if (index < 0) return null; + + _maybeClearCache(); + while (cachedRows.length <= index) { + cachedRows.add(null); + } + cachedRows[index] ??= root?.getRow(index); + return cachedRows[index]; + } + + double getRowOffset(int index) { + return (getCachedRow(index)?.depth ?? 0) * columnWidth; + } + + set hover(InspectorTreeNode node) { + if (node == _hover) { + return; + } + setState(() { + _hover = node; + // TODO(jacobr): we could choose to repaint only a portion of the UI + }); + } + + RemoteDiagnosticsNode currentHoverDiagnostic; + + void navigateUp() { + _navigateHelper(-1); + } + + void navigateDown() { + _navigateHelper(1); + } + + void navigateLeft() { + // This logic is consistent with how IntelliJ handles tree navigation on + // on left arrow key press. + if (selection == null) { + _navigateHelper(-1); + return; + } + + if (selection.isExpanded) { + setState(() { + selection.isExpanded = false; + }); + return; + } + if (selection.parent != null) { + selection = selection.parent; + } + } + + void navigateRight() { + // This logic is consistent with how IntelliJ handles tree navigation on + // on right arrow key press. + + if (selection == null || selection.isExpanded) { + _navigateHelper(1); + return; + } + + setState(() { + selection.isExpanded = true; + }); + } + + void _navigateHelper(int indexOffset) { + if (numRows == 0) return; + + if (selection == null) { + selection = root; + return; + } + + selection = root + .getRow( + (root.getRowIndex(selection) + indexOffset).clamp(0, numRows - 1)) + ?.node; + } + + double get horizontalPadding => 10.0; + + double getDepthIndent(int depth) { + return (depth + 1) * columnWidth + horizontalPadding; + } + + double getRowY(int index) { + return rowHeight * index + verticalPadding; + } + + void nodeChanged(InspectorTreeNode node) { + if (node == null) return; + setState(() { + node.isDirty = true; + }); + } + + void removeNodeFromParent(InspectorTreeNode node) { + setState(() { + node.parent?.removeChild(node); + }); + } + + void appendChild(InspectorTreeNode node, InspectorTreeNode child) { + setState(() { + node.appendChild(child); + }); + } + + void expandPath(InspectorTreeNode node) { + setState(() { + _expandPath(node); + }); + } + + void _expandPath(InspectorTreeNode node) { + while (node != null) { + if (!node.isExpanded) { + node.isExpanded = true; + } + node = node.parent; + } + } + + void collapseToSelected() { + setState(() { + _collapseAllNodes(root); + if (selection == null) return; + _expandPath(selection); + }); + } + + void _collapseAllNodes(InspectorTreeNode root) { + root.isExpanded = false; + root.children.forEach(_collapseAllNodes); + } + + int get numRows => root != null ? root.subtreeSize : 0; + + int getRowIndex(double y) => max(0, (y - verticalPadding) ~/ rowHeight); + + InspectorTreeRow getRowForNode(InspectorTreeNode node) { + return getCachedRow(root.getRowIndex(node)); + } + + InspectorTreeRow getRow(Offset offset) { + if (root == null) return null; + final int row = getRowIndex(offset.dy); + return row < root.subtreeSize ? getCachedRow(row) : null; + } + + void animateToTargets(List targets); + + void onExpandRow(InspectorTreeRow row) { + setState(() { + row.node.isExpanded = true; + if (config.onExpand != null) { + config.onExpand(row.node); + } + }); + } + + void onCollapseRow(InspectorTreeRow row) { + setState(() { + row.node.isExpanded = false; + }); + } + + void onSelectRow(InspectorTreeRow row) { + selection = row.node; + expandPath(row.node); + } + + bool expandPropertiesByDefault(DiagnosticsTreeStyle style) { + // This code matches the text style defaults for which styles are + // by default and which aren't. + switch (style) { + case DiagnosticsTreeStyle.none: + case DiagnosticsTreeStyle.singleLine: + case DiagnosticsTreeStyle.errorProperty: + return false; + + case DiagnosticsTreeStyle.sparse: + case DiagnosticsTreeStyle.offstage: + case DiagnosticsTreeStyle.dense: + case DiagnosticsTreeStyle.transition: + case DiagnosticsTreeStyle.error: + case DiagnosticsTreeStyle.whitespace: + case DiagnosticsTreeStyle.flat: + case DiagnosticsTreeStyle.shallow: + case DiagnosticsTreeStyle.truncateChildren: + return true; + } + return true; + } + + InspectorTreeNode setupInspectorTreeNode( + InspectorTreeNode node, + RemoteDiagnosticsNode diagnosticsNode, { + @required bool expandChildren, + @required bool expandProperties, + }) { + assert(expandChildren != null); + assert(expandProperties != null); + node.diagnostic = diagnosticsNode; + if (config.onNodeAdded != null) { + config.onNodeAdded(node, diagnosticsNode); + } + + if (diagnosticsNode.hasChildren || + diagnosticsNode.inlineProperties.isNotEmpty) { + if (diagnosticsNode.childrenReady || !diagnosticsNode.hasChildren) { + final bool styleIsMultiline = + expandPropertiesByDefault(diagnosticsNode.style); + setupChildren( + diagnosticsNode, + node, + node.diagnostic.childrenNow, + expandChildren: expandChildren && styleIsMultiline, + expandProperties: expandProperties && styleIsMultiline, + ); + } else { + node.clearChildren(); + node.appendChild(createNode()); + } + } + return node; + } + + void setupChildren( + RemoteDiagnosticsNode parent, + InspectorTreeNode treeNode, + List children, { + @required bool expandChildren, + @required bool expandProperties, + }) { + assert(expandChildren != null); + assert(expandProperties != null); + treeNode.isExpanded = expandChildren; + if (treeNode.children.isNotEmpty) { + // Only case supported is this is the loading node. + assert(treeNode.children.length == 1); + removeNodeFromParent(treeNode.children.first); + } + final inlineProperties = parent.inlineProperties; + + if (inlineProperties != null) { + for (RemoteDiagnosticsNode property in inlineProperties) { + appendChild( + treeNode, + setupInspectorTreeNode( + createNode(), + property, + // We are inside a property so only expand children if + // expandProperties is true. + expandChildren: expandProperties, + expandProperties: expandProperties, + ), + ); + } + } + if (children != null) { + for (RemoteDiagnosticsNode child in children) { + appendChild( + treeNode, + setupInspectorTreeNode( + createNode(), + child, + expandChildren: expandChildren, + expandProperties: expandProperties, + ), + ); + } + } + } + + Future maybePopulateChildren(InspectorTreeNode treeNode) async { + final RemoteDiagnosticsNode diagnostic = treeNode.diagnostic; + if (diagnostic != null && + diagnostic.hasChildren && + (treeNode.hasPlaceholderChildren || treeNode.children.isEmpty)) { + try { + final children = await diagnostic.children; + if (treeNode.hasPlaceholderChildren || treeNode.children.isEmpty) { + setupChildren( + diagnostic, + treeNode, + children, + expandChildren: true, + expandProperties: false, + ); + nodeChanged(treeNode); + if (treeNode == selection) { + expandPath(treeNode); + } + } + } catch (e) { + log(e.toString(), LogLevel.error); + } + } + } +} + +mixin InspectorTreeFixedRowHeightController on InspectorTreeControllerBase { + Rect getBoundingBox(InspectorTreeRow row); + + void scrollToRect(Rect targetRect); + + @override + void animateToTargets(List targets) { + Rect targetRect; + + for (InspectorTreeNode target in targets) { + final row = getRowForNode(target); + if (row != null) { + final rowRect = getBoundingBox(row); + targetRect = + targetRect == null ? rowRect : targetRect.expandToInclude(rowRect); + } + } + + if (targetRect == null || targetRect.isEmpty) return; + + targetRect = targetRect.inflate(20.0); + scrollToRect(targetRect); + } +} + class InspectorTreeControllerFlutter extends Object with InspectorTreeControllerBase, InspectorTreeFixedRowHeightController { /// Client the controller notifies to trigger changes to the UI. diff --git a/packages/devtools_app/lib/src/logging/logging_controller.dart b/packages/devtools_app/lib/src/logging/logging_controller.dart index e772ce39bce..7c6c0e9b7c5 100644 --- a/packages/devtools_app/lib/src/logging/logging_controller.dart +++ b/packages/devtools_app/lib/src/logging/logging_controller.dart @@ -20,6 +20,7 @@ import '../globals.dart'; import '../inspector/diagnostics_node.dart'; import '../inspector/inspector_service.dart'; import '../inspector/inspector_tree.dart'; +import '../inspector/inspector_tree_flutter.dart'; import '../ui/filter.dart'; import '../ui/search.dart'; import '../utils.dart'; From 2bf4607400a43f28612ca0b8f245f0b45618125e Mon Sep 17 00:00:00 2001 From: matt-ragonese <46503192+matt-ragonese@users.noreply.github.com> Date: Wed, 15 Sep 2021 17:51:32 -0400 Subject: [PATCH 3/6] Renamed inspector_tree_flutter.dart to inspector_tree_controller.dart --- .../devtools_app/lib/src/inspector/inspector_controller.dart | 2 +- packages/devtools_app/lib/src/inspector/inspector_screen.dart | 2 +- ...spector_tree_flutter.dart => inspector_tree_controller.dart} | 0 packages/devtools_app/lib/src/logging/logging_controller.dart | 2 +- packages/devtools_app/test/inspector_tree_test.dart | 2 +- packages/devtools_app/test/support/inspector_tree.dart | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename packages/devtools_app/lib/src/inspector/{inspector_tree_flutter.dart => inspector_tree_controller.dart} (100%) diff --git a/packages/devtools_app/lib/src/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/inspector/inspector_controller.dart index 36160d76bc9..6b325dd2c9a 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_controller.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_controller.dart @@ -35,7 +35,7 @@ import 'inspector_screen.dart'; import 'inspector_service.dart'; import 'inspector_text_styles.dart' as inspector_text_styles; import 'inspector_tree.dart'; -import 'inspector_tree_flutter.dart'; +import 'inspector_tree_controller.dart'; const inspectorRefQueryParam = 'inspectorRef'; diff --git a/packages/devtools_app/lib/src/inspector/inspector_screen.dart b/packages/devtools_app/lib/src/inspector/inspector_screen.dart index 31511fed78b..f0b91a7e7f6 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_screen.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_screen.dart @@ -26,7 +26,7 @@ import '../ui/service_extension_widgets.dart'; import 'inspector_controller.dart'; import 'inspector_screen_details_tab.dart'; import 'inspector_service.dart'; -import 'inspector_tree_flutter.dart'; +import 'inspector_tree_controller.dart'; class InspectorScreen extends Screen { const InspectorScreen() diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart b/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart similarity index 100% rename from packages/devtools_app/lib/src/inspector/inspector_tree_flutter.dart rename to packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart diff --git a/packages/devtools_app/lib/src/logging/logging_controller.dart b/packages/devtools_app/lib/src/logging/logging_controller.dart index 7c6c0e9b7c5..483da7a1a21 100644 --- a/packages/devtools_app/lib/src/logging/logging_controller.dart +++ b/packages/devtools_app/lib/src/logging/logging_controller.dart @@ -20,7 +20,7 @@ import '../globals.dart'; import '../inspector/diagnostics_node.dart'; import '../inspector/inspector_service.dart'; import '../inspector/inspector_tree.dart'; -import '../inspector/inspector_tree_flutter.dart'; +import '../inspector/inspector_tree_controller.dart'; import '../ui/filter.dart'; import '../ui/search.dart'; import '../utils.dart'; diff --git a/packages/devtools_app/test/inspector_tree_test.dart b/packages/devtools_app/test/inspector_tree_test.dart index 97532cb1b72..da22a21f547 100644 --- a/packages/devtools_app/test/inspector_tree_test.dart +++ b/packages/devtools_app/test/inspector_tree_test.dart @@ -6,7 +6,7 @@ import 'package:devtools_app/src/debugger/debugger_controller.dart'; import 'package:devtools_app/src/globals.dart'; import 'package:devtools_app/src/inspector/inspector_service.dart'; import 'package:devtools_app/src/inspector/inspector_tree.dart'; -import 'package:devtools_app/src/inspector/inspector_tree_flutter.dart'; +import 'package:devtools_app/src/inspector/inspector_tree_controller.dart'; import 'package:devtools_app/src/service_manager.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; diff --git a/packages/devtools_app/test/support/inspector_tree.dart b/packages/devtools_app/test/support/inspector_tree.dart index eb0e3ea79a5..3fd850501d5 100644 --- a/packages/devtools_app/test/support/inspector_tree.dart +++ b/packages/devtools_app/test/support/inspector_tree.dart @@ -5,7 +5,7 @@ import 'package:devtools_app/src/inspector/diagnostics_node.dart'; import 'package:devtools_app/src/inspector/inspector_service.dart'; import 'package:devtools_app/src/inspector/inspector_tree.dart'; -import 'package:devtools_app/src/inspector/inspector_tree_flutter.dart'; +import 'package:devtools_app/src/inspector/inspector_tree_controller.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; From 148300f9e70286732673a02a9fd8c32d660f22a0 Mon Sep 17 00:00:00 2001 From: matt-ragonese <46503192+matt-ragonese@users.noreply.github.com> Date: Wed, 15 Sep 2021 17:54:33 -0400 Subject: [PATCH 4/6] Rename InspectorTreeControllerFlutter to InspectorTreeController --- .../devtools_app/lib/src/inspector/inspector_screen.dart | 8 ++++---- .../lib/src/inspector/inspector_tree_controller.dart | 8 ++++---- packages/devtools_app/test/inspector_tree_test.dart | 2 +- packages/devtools_app/test/support/inspector_tree.dart | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/devtools_app/lib/src/inspector/inspector_screen.dart b/packages/devtools_app/lib/src/inspector/inspector_screen.dart index f0b91a7e7f6..7407579b02a 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_screen.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_screen.dart @@ -66,10 +66,10 @@ class InspectorScreenBodyState extends State InspectorController inspectorController; - InspectorTreeControllerFlutter get summaryTreeController => + InspectorTreeController get summaryTreeController => inspectorController?.inspectorTree; - InspectorTreeControllerFlutter get detailsTreeController => + InspectorTreeController get detailsTreeController => inspectorController?.details?.inspectorTree; DebuggerController _debuggerController; @@ -92,8 +92,8 @@ class InspectorScreenBodyState extends State return; } inspectorController = InspectorController( - inspectorTree: InspectorTreeControllerFlutter(), - detailsTree: InspectorTreeControllerFlutter(), + inspectorTree: InspectorTreeController(), + detailsTree: InspectorTreeController(), treeType: FlutterTreeType.widget, onExpandCollapseSupported: _onExpandCollapseSupported, onLayoutExplorerSupported: _onLayoutExplorerSupported, diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart b/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart index 8eef26eec97..81ee7155854 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart @@ -483,7 +483,7 @@ mixin InspectorTreeFixedRowHeightController on InspectorTreeControllerBase { } } -class InspectorTreeControllerFlutter extends Object +class InspectorTreeController extends Object with InspectorTreeControllerBase, InspectorTreeFixedRowHeightController { /// Client the controller notifies to trigger changes to the UI. final Set _clients = {}; @@ -598,7 +598,7 @@ class _InspectorTreeState extends State AutomaticKeepAliveClientMixin, AutoDisposeMixin implements InspectorControllerClient { - InspectorTreeControllerFlutter get controller => widget.controller; + InspectorTreeController get controller => widget.controller; bool get isSummaryTree => widget.isSummaryTree; @@ -627,7 +627,7 @@ class _InspectorTreeState extends State @override void didUpdateWidget(InspectorTree oldWidget) { if (oldWidget.controller != widget.controller) { - final InspectorTreeControllerFlutter oldController = oldWidget.controller; + final InspectorTreeController oldController = oldWidget.controller; oldController?.removeClient(this); cancel(); @@ -993,7 +993,7 @@ class InspectorRowContent extends StatelessWidget { }); final InspectorTreeRow row; - final InspectorTreeControllerFlutter controller; + final InspectorTreeController controller; final DebuggerController debuggerController; final VoidCallback onToggle; final Animation expandArrowAnimation; diff --git a/packages/devtools_app/test/inspector_tree_test.dart b/packages/devtools_app/test/inspector_tree_test.dart index da22a21f547..4172477f822 100644 --- a/packages/devtools_app/test/inspector_tree_test.dart +++ b/packages/devtools_app/test/inspector_tree_test.dart @@ -33,7 +33,7 @@ void main() { group('InspectorTreeController', () { testWidgets('Row with negative index regression test', (WidgetTester tester) async { - final controller = InspectorTreeControllerFlutter() + final controller = InspectorTreeController() ..config = InspectorTreeConfig( summaryTree: false, treeType: FlutterTreeType.widget, diff --git a/packages/devtools_app/test/support/inspector_tree.dart b/packages/devtools_app/test/support/inspector_tree.dart index 3fd850501d5..d7f44ae1f96 100644 --- a/packages/devtools_app/test/support/inspector_tree.dart +++ b/packages/devtools_app/test/support/inspector_tree.dart @@ -14,9 +14,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'wrappers.dart'; /// Create an `InspectorTreeControllerFlutter` from a single `RemoteDiagnosticsNode` -InspectorTreeControllerFlutter inspectorTreeControllerFromNode( +InspectorTreeController inspectorTreeControllerFromNode( RemoteDiagnosticsNode node) { - final controller = InspectorTreeControllerFlutter() + final controller = InspectorTreeController() ..config = InspectorTreeConfig( summaryTree: false, treeType: FlutterTreeType.widget, From ac24ae454130df5545d1d3bb1868ee1b2661f6e6 Mon Sep 17 00:00:00 2001 From: matt-ragonese <46503192+matt-ragonese@users.noreply.github.com> Date: Thu, 16 Sep 2021 12:32:17 -0400 Subject: [PATCH 5/6] Merged InspectorTreeControllerBase and InspectorTreeFixedRowHeightController into InspectorTreeController --- .../src/inspector/inspector_controller.dart | 4 +- .../inspector/inspector_tree_controller.dart | 218 ++++++++---------- .../lib/src/logging/logging_controller.dart | 6 +- 3 files changed, 104 insertions(+), 124 deletions(-) diff --git a/packages/devtools_app/lib/src/inspector/inspector_controller.dart b/packages/devtools_app/lib/src/inspector/inspector_controller.dart index 6b325dd2c9a..386deb954db 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_controller.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_controller.dart @@ -71,7 +71,7 @@ class InspectorController extends DisposableController implements InspectorServiceClient { InspectorController({ @required this.inspectorTree, - InspectorTreeControllerBase detailsTree, + InspectorTreeController detailsTree, @required this.treeType, this.parent, this.isSummaryTree = true, @@ -205,7 +205,7 @@ class InspectorController extends DisposableController InspectorController details; - InspectorTreeControllerBase inspectorTree; + InspectorTreeController inspectorTree; final FlutterTreeType treeType; bool _disposed = false; diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart b/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart index 81ee7155854..75f743585a0 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree_controller.dart @@ -2,12 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +library inspector_tree; + import 'dart:collection'; import 'dart:math'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:meta/meta.dart'; import 'package:pedantic/pedantic.dart'; import '../auto_dispose_mixin.dart'; @@ -94,10 +97,40 @@ class _InspectorTreeRowState extends State<_InspectorTreeRowWidget> bool shouldShow() => widget.node.shouldShow; } -abstract class InspectorTreeControllerBase { - // Abstract method defined to avoid a direct Flutter dependency. - @protected - void setState(VoidCallback fn); +class InspectorTreeController extends Object { + /// Clients the controller notifies to trigger changes to the UI. + final Set _clients = {}; + + InspectorTreeNode createNode() => InspectorTreeNode(); + + void addClient(InspectorControllerClient value) { + final firstClient = _clients.isEmpty; + _clients.add(value); + if (firstClient) { + config.onClientActiveChange(true); + } + } + + void removeClient(InspectorControllerClient value) { + _clients.remove(value); + if (_clients.isEmpty) { + config.onClientActiveChange(false); + } + } + + // Method defined to avoid a direct Flutter dependency. + void setState(VoidCallback fn) { + fn(); + for (var client in _clients) { + client.onChanged(); + } + } + + void requestFocus() { + for (var client in _clients) { + client.requestFocus(); + } + } InspectorTreeNode get root => _root; InspectorTreeNode _root; @@ -139,8 +172,6 @@ abstract class InspectorTreeControllerBase { double lastContentWidth; - InspectorTreeNode createNode(); - final List cachedRows = []; // TODO: we should add a listener instead that clears the cache when the @@ -178,8 +209,6 @@ abstract class InspectorTreeControllerBase { }); } - RemoteDiagnosticsNode currentHoverDiagnostic; - void navigateUp() { _navigateHelper(-1); } @@ -306,8 +335,6 @@ abstract class InspectorTreeControllerBase { return row < root.subtreeSize ? getCachedRow(row) : null; } - void animateToTargets(List targets); - void onExpandRow(InspectorTreeRow row) { setState(() { row.node.isExpanded = true; @@ -328,6 +355,66 @@ abstract class InspectorTreeControllerBase { expandPath(row.node); } + Rect getBoundingBox(InspectorTreeRow row) { + // For future reference: the bounding box likely needs to be in terms of + // positions after the current animations are complete so that computations + // to start animations to show specific widget scroll to where the target + // nodes will be displayed rather than where they are currently displayed. + return Rect.fromLTWH( + getDepthIndent(row.depth), + getRowY(row.index), + rowWidth, + rowHeight, + ); + } + + void scrollToRect(Rect targetRect) { + for (var client in _clients) { + client.scrollToRect(targetRect); + } + } + + /// Width each row in the tree should have ignoring its indent. + /// + /// Content in rows should wrap if it exceeds this width. + final double rowWidth = 1200; + + /// Maximum indent of the tree in pixels. + double _maxIndent; + + double get maxRowIndent { + if (lastContentWidth == null) { + double maxIndent = 0; + for (int i = 0; i < numRows; i++) { + final row = getCachedRow(i); + if (row != null) { + maxIndent = max(maxIndent, getDepthIndent(row.depth)); + } + } + lastContentWidth = maxIndent + maxIndent; + _maxIndent = maxIndent; + } + return _maxIndent; + } + + void animateToTargets(List targets) { + Rect targetRect; + + for (InspectorTreeNode target in targets) { + final row = getRowForNode(target); + if (row != null) { + final rowRect = getBoundingBox(row); + targetRect = + targetRect == null ? rowRect : targetRect.expandToInclude(rowRect); + } + } + + if (targetRect == null || targetRect.isEmpty) return; + + targetRect = targetRect.inflate(20.0); + scrollToRect(targetRect); + } + bool expandPropertiesByDefault(DiagnosticsTreeStyle style) { // This code matches the text style defaults for which styles are // by default and which aren't. @@ -458,113 +545,6 @@ abstract class InspectorTreeControllerBase { } } -mixin InspectorTreeFixedRowHeightController on InspectorTreeControllerBase { - Rect getBoundingBox(InspectorTreeRow row); - - void scrollToRect(Rect targetRect); - - @override - void animateToTargets(List targets) { - Rect targetRect; - - for (InspectorTreeNode target in targets) { - final row = getRowForNode(target); - if (row != null) { - final rowRect = getBoundingBox(row); - targetRect = - targetRect == null ? rowRect : targetRect.expandToInclude(rowRect); - } - } - - if (targetRect == null || targetRect.isEmpty) return; - - targetRect = targetRect.inflate(20.0); - scrollToRect(targetRect); - } -} - -class InspectorTreeController extends Object - with InspectorTreeControllerBase, InspectorTreeFixedRowHeightController { - /// Client the controller notifies to trigger changes to the UI. - final Set _clients = {}; - - void addClient(InspectorControllerClient value) { - final firstClient = _clients.isEmpty; - _clients.add(value); - if (firstClient) { - config.onClientActiveChange(true); - } - } - - void removeClient(InspectorControllerClient value) { - _clients.remove(value); - if (_clients.isEmpty) { - config.onClientActiveChange(false); - } - } - - @override - InspectorTreeNode createNode() => InspectorTreeNode(); - - @override - Rect getBoundingBox(InspectorTreeRow row) { - // For future reference: the bounding box likely needs to be in terms of - // positions after the current animations are complete so that computations - // to start animations to show specific widget scroll to where the target - // nodes will be displayed rather than where they are currently displayed. - return Rect.fromLTWH( - getDepthIndent(row.depth), - getRowY(row.index), - rowWidth, - rowHeight, - ); - } - - @override - void scrollToRect(Rect targetRect) { - for (var client in _clients) { - client.scrollToRect(targetRect); - } - } - - @override - void setState(VoidCallback fn) { - fn(); - for (var client in _clients) { - client.onChanged(); - } - } - - /// Width each row in the tree should have ignoring its indent. - /// - /// Content in rows should wrap if it exceeds this width. - final double rowWidth = 1200; - - /// Maximum indent of the tree in pixels. - double _maxIndent; - - double get maxRowIndent { - if (lastContentWidth == null) { - double maxIndent = 0; - for (int i = 0; i < numRows; i++) { - final row = getCachedRow(i); - if (row != null) { - maxIndent = max(maxIndent, getDepthIndent(row.depth)); - } - } - lastContentWidth = maxIndent + maxIndent; - _maxIndent = maxIndent; - } - return _maxIndent; - } - - void requestFocus() { - for (var client in _clients) { - client.requestFocus(); - } - } -} - abstract class InspectorControllerClient { void onChanged(); @@ -582,7 +562,7 @@ class InspectorTree extends StatefulWidget { this.widgetErrors, }) : super(key: key); - final InspectorTreeControllerBase controller; + final InspectorTreeController controller; final DebuggerController debuggerController; final bool isSummaryTree; final LinkedHashMap widgetErrors; @@ -919,7 +899,7 @@ Paint _defaultPaint(ColorScheme colorScheme) => Paint() class _RowPainter extends CustomPainter { _RowPainter(this.row, this._controller, this.colorScheme); - final InspectorTreeControllerBase _controller; + final InspectorTreeController _controller; final InspectorTreeRow row; final ColorScheme colorScheme; diff --git a/packages/devtools_app/lib/src/logging/logging_controller.dart b/packages/devtools_app/lib/src/logging/logging_controller.dart index 483da7a1a21..3293689f172 100644 --- a/packages/devtools_app/lib/src/logging/logging_controller.dart +++ b/packages/devtools_app/lib/src/logging/logging_controller.dart @@ -37,10 +37,10 @@ bool _verboseDebugging = false; typedef OnShowDetails = void Function({ String text, - InspectorTreeControllerBase tree, + InspectorTreeController tree, }); -typedef CreateLoggingTree = InspectorTreeControllerBase Function({ +typedef CreateLoggingTree = InspectorTreeController Function({ VoidCallback onSelectionChange, }); @@ -80,7 +80,7 @@ class LoggingDetailsController { /// type. final CreateLoggingTree createLoggingTree; - InspectorTreeControllerBase tree; + InspectorTreeController tree; void setData(LogData data) { this.data = data; From 4920dad66574ab3f0c11d9bb811144dfc43ea339 Mon Sep 17 00:00:00 2001 From: matt-ragonese <46503192+matt-ragonese@users.noreply.github.com> Date: Thu, 16 Sep 2021 14:20:49 -0400 Subject: [PATCH 6/6] Updated FakeInspectorTree with new InspectorTreeController --- .../devtools_app/lib/src/inspector/inspector_tree.dart | 2 -- packages/devtools_app/test/inspector_screen_test.dart | 1 + .../devtools_app/test/support/fake_inspector_tree.dart | 9 ++------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/devtools_app/lib/src/inspector/inspector_tree.dart b/packages/devtools_app/lib/src/inspector/inspector_tree.dart index b1c770a6374..e1a21db72ff 100644 --- a/packages/devtools_app/lib/src/inspector/inspector_tree.dart +++ b/packages/devtools_app/lib/src/inspector/inspector_tree.dart @@ -11,8 +11,6 @@ /// and will help simplify porting this code to work with Hummingbird. library inspector_tree; -import 'dart:math' as math; - import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; diff --git a/packages/devtools_app/test/inspector_screen_test.dart b/packages/devtools_app/test/inspector_screen_test.dart index 66ed16813d8..4d9d6b63562 100644 --- a/packages/devtools_app/test/inspector_screen_test.dart +++ b/packages/devtools_app/test/inspector_screen_test.dart @@ -10,6 +10,7 @@ import 'package:devtools_app/src/inspector/inspector_controller.dart'; import 'package:devtools_app/src/inspector/inspector_screen.dart'; import 'package:devtools_app/src/inspector/inspector_service.dart'; import 'package:devtools_app/src/inspector/inspector_tree.dart'; +import 'package:devtools_app/src/inspector/inspector_tree_controller.dart'; import 'package:devtools_app/src/inspector/layout_explorer/flex/flex.dart'; import 'package:devtools_app/src/inspector/layout_explorer/layout_explorer.dart'; import 'package:devtools_app/src/service_extensions.dart' as extensions; diff --git a/packages/devtools_app/test/support/fake_inspector_tree.dart b/packages/devtools_app/test/support/fake_inspector_tree.dart index 877c94e659f..34661ac50f2 100644 --- a/packages/devtools_app/test/support/fake_inspector_tree.dart +++ b/packages/devtools_app/test/support/fake_inspector_tree.dart @@ -8,22 +8,17 @@ import 'dart:async'; import 'dart:math'; import 'package:devtools_app/src/inspector/inspector_tree.dart'; +import 'package:devtools_app/src/inspector/inspector_tree_controller.dart'; import 'package:devtools_app/src/ui/icons.dart'; import 'package:flutter/material.dart'; const double fakeRowWidth = 200.0; -class FakeInspectorTree extends InspectorTreeController - with InspectorTreeFixedRowHeightController { +class FakeInspectorTree extends InspectorTreeController { FakeInspectorTree(); final List scrollToRequests = []; - @override - InspectorTreeNode createNode() { - return InspectorTreeNode(); - } - @override Rect getBoundingBox(InspectorTreeRow row) { return Rect.fromLTWH(