Skip to content

Commit

Permalink
Reduce frequent onTextSelectionChange calls
Browse files Browse the repository at this point in the history
  • Loading branch information
espresso3389 committed Aug 30, 2024
1 parent f45e4ac commit c5a4038
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/src/pdf_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ class PdfTextRanges {
bool get isEmpty => ranges.isEmpty;

/// Determine whether the text ranges are *NOT* empty.
bool get isNotEmpty => !isEmpty;
bool get isNotEmpty => ranges.isNotEmpty;

/// Page number of the text ranges.
int get pageNumber => pageText.pageNumber;
Expand Down
13 changes: 11 additions & 2 deletions lib/src/widgets/pdf_page_text_overlay.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
Expand Down Expand Up @@ -28,7 +30,7 @@ class PdfPageTextOverlay extends StatefulWidget {
super.key,
});

final Map<int, Selectable> selectables;
final SplayTreeMap<int, PdfPageTextSelectable> selectables;
final bool enabled;
final PdfPage page;
final Rect pageRect;
Expand Down Expand Up @@ -197,8 +199,12 @@ class _PdfTextWidget extends LeafRenderObjectWidget {
}
}

mixin PdfPageTextSelectable implements Selectable {
PdfTextRanges get selectedRanges;
}

/// The code is based on the code on [Making a widget selectable](https://api.flutter.dev/flutter/widgets/SelectableRegion-class.html#widgets).SelectableRegion.2]
class _PdfTextRenderBox extends RenderBox with Selectable, SelectionRegistrant {
class _PdfTextRenderBox extends RenderBox with PdfPageTextSelectable, Selectable, SelectionRegistrant {
_PdfTextRenderBox(
this._selectionColor,
this._textWidget,
Expand Down Expand Up @@ -277,6 +283,9 @@ class _PdfTextRenderBox extends RenderBox with Selectable, SelectionRegistrant {
late PdfTextRanges _selectedRanges =
PdfTextRanges.createEmpty(_textWidget._state._pageText!);

@override
PdfTextRanges get selectedRanges => _selectedRanges;

void _notifySelectionChange() {
_textWidget._state._notifySelectionChange(_selectedRanges);
}
Expand Down
29 changes: 13 additions & 16 deletions lib/src/widgets/pdf_viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,11 @@ class _PdfViewerState extends State<PdfViewer>
// Changes to the stream rebuilds the viewer
final _updateStream = BehaviorSubject<Matrix4>();

final _selectionHandlers = <int, Selectable>{};
final _selectionHandlers = SplayTreeMap<int, PdfPageTextSelectable>();
Timer? _selectionChangedThrottleTimer;

final _textSelections = SplayTreeSet<PdfTextRanges>(
(a, b) => a.pageNumber.compareTo(b.pageNumber));
Timer? _interactionEndedTimer;
bool _isInteractionGoingOn = false;

@override
void initState() {
Expand Down Expand Up @@ -306,6 +307,7 @@ class _PdfViewerState extends State<PdfViewer>
void _onDocumentChanged() async {
_layout = null;

_selectionChangedThrottleTimer?.cancel();
_stopInteraction();
_releaseAllImages();
_canvasLinkPainter.resetAll();
Expand Down Expand Up @@ -347,6 +349,7 @@ class _PdfViewerState extends State<PdfViewer>

@override
void dispose() {
_selectionChangedThrottleTimer?.cancel();
_stopInteraction();
_cancelAllPendingRenderings();
_animController.dispose();
Expand Down Expand Up @@ -484,9 +487,6 @@ class _PdfViewerState extends State<PdfViewer>
});
}

Timer? _interactionEndedTimer;
bool _isInteractionGoingOn = false;

void _startInteraction() {
_interactionEndedTimer?.cancel();
_interactionEndedTimer = null;
Expand Down Expand Up @@ -866,16 +866,13 @@ class _PdfViewerState extends State<PdfViewer>
}

void _onSelectionChange(PdfTextRanges selection) {
if (selection.isEmpty) {
if (!_textSelections.contains(selection)) return;
_textSelections.remove(selection);
} else {
if (_textSelections.contains(selection)) {
_textSelections.remove(selection);
}
_textSelections.add(selection);
}
widget.params.onTextSelectionChange?.call(_textSelections.toList());
_selectionChangedThrottleTimer?.cancel();
_selectionChangedThrottleTimer = Timer(const Duration(milliseconds: 300), () {
if (!mounted || !_selectionHandlers.containsKey(selection.pageNumber)) return;
widget.params.onTextSelectionChange?.call(
_selectionHandlers.values.map((s) => s.selectedRanges).where((s) => s.isNotEmpty).toList()
);
});
}

Rect _getCacheExtentRect() {
Expand Down

0 comments on commit c5a4038

Please sign in to comment.