Skip to content

Commit

Permalink
[SuperEditor][SuperReader] - Lock scrolling when content fits within …
Browse files Browse the repository at this point in the history
…available space (Resolves #1409) (#1421)
  • Loading branch information
rutvik110 committed Oct 2, 2023
1 parent cc06fd7 commit 79201cb
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 4 deletions.
9 changes: 8 additions & 1 deletion super_editor/lib/src/default_editor/document_scrollable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,11 @@ class AutoScrollController with ChangeNotifier {
}

final scrollPosition = _getScrollPosition!();

if (scrollPosition.maxScrollExtent == 0) {
return;
}

scrollPosition.jumpTo(
(scrollPosition.pixels + delta).clamp(0.0, scrollPosition.maxScrollExtent),
);
Expand All @@ -388,7 +393,9 @@ class AutoScrollController with ChangeNotifier {
}

if (pos is ScrollPositionWithSingleContext) {
pos.goBallistic(pixelsPerSecond);
if (pos.maxScrollExtent > 0) {
pos.goBallistic(pixelsPerSecond);
}
pos.context.setIgnorePointer(false);
}
}
Expand Down
107 changes: 104 additions & 3 deletions super_editor/test/super_editor/supereditor_scrolling_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:super_editor/super_editor.dart';
import 'package:super_editor/super_editor_test.dart';

import 'supereditor_test_tools.dart';
import 'test_documents.dart';

void main() {
group("SuperEditor scrolling", () {
Expand Down Expand Up @@ -682,11 +683,101 @@ void main() {

// Ensure SuperEditor has scrolled
expect(editorScrollController.offset, greaterThan(0));

// Ensure that scrolling didn't scroll the ListView
expect(listScrollController.position.pixels, equals(0));
});
});

group("when all content fits in the viewport", () {
testWidgetsOnDesktop(
"trackpad doesn't scroll content",
(tester) async {
tester.view.physicalSize = const Size(800, 600);

final isScrollingUp = _scrollDirectionVariant.currentValue == _ScrollDirection.up;

await tester //
.createDocument()
.withCustomContent(
paragraphThenHrThenParagraphDoc()
..insertNodeAt(
0,
ParagraphNode(
id: Editor.createNodeId(),
text: AttributedText('Document #1'),
metadata: {
'blockType': header1Attribution,
},
),
),
)
.pump();

final scrollState = tester.state<ScrollableState>(find.byType(Scrollable));

// Perform a fling on the editor to attemp scrolling.
await tester.trackpadFling(
find.byType(SuperEditor),
Offset(0.0, isScrollingUp ? 100 : -100),
300,
);

await tester.pump();

// Ensure SuperEditor is not scrolling.
expect(scrollState.position.activity?.isScrolling, false);
},
variant: _scrollDirectionVariant,
);

testWidgetsOnDesktop(
"mouse scroll wheel doesn't scroll content",
(tester) async {
tester.view.physicalSize = const Size(800, 600);

final isScrollUp = _scrollDirectionVariant.currentValue == _ScrollDirection.up;

await tester //
.createDocument()
.withCustomContent(
paragraphThenHrThenParagraphDoc()
..insertNodeAt(
0,
ParagraphNode(
id: Editor.createNodeId(),
text: AttributedText('Document #1'),
metadata: {
'blockType': header1Attribution,
},
),
),
)
.pump();

final scrollState = tester.state<ScrollableState>(find.byType(Scrollable));

final Offset scrollEventLocation = tester.getCenter(find.byType(SuperEditor));
final TestPointer testPointer = TestPointer(1, PointerDeviceKind.mouse);

// Send initial pointer event to set the location for subsequent pointer scroll events.
await tester.sendEventToBinding(testPointer.hover(scrollEventLocation));

// Send pointer scroll event to start scrolling.
await tester.sendEventToBinding(
testPointer.scroll(
Offset(
0.0,
isScrollUp ? 100 : -100.0,
),
),
);

await tester.pump();

// Ensure SuperReader is not scrolling.
expect(scrollState.position.activity!.isScrolling, false);
},
variant: _scrollDirectionVariant,
);
});
});
});
}
Expand Down Expand Up @@ -850,3 +941,13 @@ MutableDocument _createExampleDocumentForScrolling() {
],
);
}

final _scrollDirectionVariant = ValueVariant<_ScrollDirection>({
_ScrollDirection.up,
_ScrollDirection.down,
});

enum _ScrollDirection {
up,
down;
}
104 changes: 104 additions & 0 deletions super_editor/test/super_reader/super_reader_scrolling_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:super_editor/super_editor.dart';
import 'package:super_editor/super_reader_test.dart';

import 'reader_test_tools.dart';
import 'test_documents.dart';

void main() {
group("SuperReader scrolling", () {
Expand Down Expand Up @@ -218,5 +219,108 @@ void main() {
isTrue,
);
});

group("when all content fits in the viewport", () {
testWidgetsOnDesktop(
"trackpad doesn't scroll content",
(tester) async {
tester.view.physicalSize = const Size(800, 600);

final isScrollUp = _scrollDirectionVariant.currentValue == _ScrollDirection.up;

await tester //
.createDocument()
.withCustomContent(
paragraphThenHrThenParagraphDoc()
..insertNodeAt(
0,
ParagraphNode(
id: Editor.createNodeId(),
text: AttributedText('Document #1'),
metadata: {
'blockType': header1Attribution,
},
),
),
)
.pump();

final scrollState = tester.state<ScrollableState>(find.byType(Scrollable));

// Perform a fling on the reader to attemp scrolling.
await tester.trackpadFling(
find.byType(SuperReader),
Offset(0.0, isScrollUp ? 100 : -100),
300,
);

await tester.pump();

// Ensure SuperReader is not scrolling.
expect(scrollState.position.activity?.isScrolling, false);
},
variant: _scrollDirectionVariant,
);

testWidgetsOnDesktop(
"mouse scroll wheel doesn't scroll content",
(tester) async {
tester.view.physicalSize = const Size(800, 600);

final isScrollUp = _scrollDirectionVariant.currentValue == _ScrollDirection.up;

await tester //
.createDocument()
.withCustomContent(
paragraphThenHrThenParagraphDoc()
..insertNodeAt(
0,
ParagraphNode(
id: Editor.createNodeId(),
text: AttributedText('Document #1'),
metadata: {
'blockType': header1Attribution,
},
),
),
)
.pump();

final scrollState = tester.state<ScrollableState>(find.byType(Scrollable));

final Offset scrollEventLocation = tester.getCenter(find.byType(SuperReader));
final TestPointer testPointer = TestPointer(1, PointerDeviceKind.mouse);

// Send initial pointer event to set the location for subsequent pointer scroll events.
await tester.sendEventToBinding(testPointer.hover(scrollEventLocation));

// Send pointer scroll event to start scrolling.
await tester.sendEventToBinding(
testPointer.scroll(
Offset(
0.0,
isScrollUp ? 100 : -100.0,
),
),
);

await tester.pump();

// Ensure SuperReader is not scrolling.
expect(scrollState.position.activity!.isScrolling, false);
},
variant: _scrollDirectionVariant,
);
});
});
}

final _scrollDirectionVariant = ValueVariant<_ScrollDirection>({
_ScrollDirection.up,
_ScrollDirection.down,
});

enum _ScrollDirection {
up,
down;
}

0 comments on commit 79201cb

Please sign in to comment.