Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/two_dimensional_scrollables/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 0.5.3

* Fixes hit testing for `TreeView` row content and gestures after horizontal scrolling.
* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10.

## 0.5.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,12 @@ class RenderTreeViewport extends RenderTwoDimensionalViewport {
row = childAfter(row);
continue;
}
final Rect rowRect = parentData.paintOffset! & Size(viewportDimension.width, row.size.height);
final rowRect = Rect.fromLTRB(
math.min(0.0, parentData.paintOffset!.dx),
parentData.paintOffset!.dy,
math.max(viewportDimension.width, parentData.paintOffset!.dx + row.size.width),
parentData.paintOffset!.dy + row.size.height,
);
Comment thread
Piinks marked this conversation as resolved.
if (rowRect.contains(position)) {
result.addWithPaintOffset(
offset: parentData.paintOffset,
Expand Down
2 changes: 1 addition & 1 deletion packages/two_dimensional_scrollables/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: two_dimensional_scrollables
description: Widgets that scroll using the two dimensional scrolling foundation.
version: 0.5.2
version: 0.5.3
repository: https://github.com/flutter/packages/tree/main/packages/two_dimensional_scrollables
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+two_dimensional_scrollables%22+

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,109 @@ void main() {
expect(log, <String>['First', 'Second', 'Third']);
});

testWidgets('TreeRow gesture hit testing spans the viewport when scrolled', (
WidgetTester tester,
) async {
final horizontalController = ScrollController();
addTearDown(horizontalController.dispose);
var tapped = false;

await tester.pumpWidget(
MaterialApp(
home: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 200,
height: 80,
child: TreeView<int>(
tree: <TreeViewNode<int>>[TreeViewNode<int>(0), TreeViewNode<int>(1)],
horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
indentation: TreeViewIndentationType.none,
treeNodeBuilder: (_, TreeViewNode<int> node, _) {
return SizedBox(width: node.content == 0 ? 100 : 250, height: 40);
},
treeRowBuilder: (TreeViewNode<int> node) {
return TreeRow(
extent: const FixedTreeRowExtent(40),
recognizerFactories: node.content == 0
? <Type, GestureRecognizerFactory>{
TapGestureRecognizer:
GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
TapGestureRecognizer.new,
(TapGestureRecognizer recognizer) {
recognizer.onTap = () => tapped = true;
},
),
}
: <Type, GestureRecognizerFactory>{},
);
},
),
),
),
),
);
await tester.pump();

horizontalController.jumpTo(50);
await tester.pump();
await tester.tapAt(const Offset(175, 20));
await tester.pump();

expect(tapped, isTrue);
});

testWidgets('row children remain hittable after horizontal scrolling', (
WidgetTester tester,
) async {
final horizontalController = ScrollController();
addTearDown(horizontalController.dispose);
final tappedSegments = <String>[];

await tester.pumpWidget(
MaterialApp(
home: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 200,
height: 40,
child: TreeView<int>(
tree: <TreeViewNode<int>>[TreeViewNode<int>(0)],
horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
indentation: TreeViewIndentationType.none,
treeNodeBuilder: (_, _, _) {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => tappedSegments.add('leading'),
child: const SizedBox(width: 200, height: 40),
),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => tappedSegments.add('trailing'),
child: const SizedBox(width: 50, height: 40),
),
],
);
},
treeRowBuilder: (_) => const TreeRow(extent: FixedTreeRowExtent(40)),
),
),
),
),
);
await tester.pump();

horizontalController.jumpTo(50);
await tester.pump();
await tester.tapAt(const Offset(175, 20));
await tester.pump();

expect(tappedSegments, <String>['trailing']);
});

testWidgets('mouse handling', (WidgetTester tester) async {
var enterCounter = 0;
var exitCounter = 0;
Expand Down