streamline the hit test logic a bit ( maybe ) + add option to register adhoc pointer event listeners
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:infinite_lazy_grid/core/background.dart';
|
||||
import '../../utils/measure_size.dart';
|
||||
import '../spatial_hashing.dart';
|
||||
@@ -41,6 +42,11 @@ class LazyCanvasController with ChangeNotifier {
|
||||
OnWidgetEnteredRender? onWidgetEnteredRender;
|
||||
OnWidgetExitedRender? onWidgetExitedRender;
|
||||
Set<CanvasChildId> _renderedWidgets = {}; // to track which widgets are currently rendered
|
||||
PointerDownEventListener? rawPointerDownListener;
|
||||
PointerMoveEventListener? rawPointerMoveListener;
|
||||
PointerUpEventListener? rawPointerUpListener;
|
||||
PointerCancelEventListener? rawPointerCancelListener;
|
||||
PointerSignalEventListener? rawPointerSignalListener;
|
||||
|
||||
bool debug;
|
||||
final Duration defaultAnimationDuration;
|
||||
@@ -54,6 +60,11 @@ class LazyCanvasController with ChangeNotifier {
|
||||
this.useIdsFromArgs = false,
|
||||
this.onWidgetEnteredRender,
|
||||
this.onWidgetExitedRender,
|
||||
this.rawPointerSignalListener,
|
||||
this.rawPointerDownListener,
|
||||
this.rawPointerMoveListener,
|
||||
this.rawPointerUpListener,
|
||||
this.rawPointerCancelListener,
|
||||
}) : _hashCellSize = hashCellSize,
|
||||
_buildCacheExtent = buildCacheExtent != null ? buildCacheExtent + _kBuildCacheBuffer : null
|
||||
// only top left is considered so if a widget has long width, it'll not be rendered
|
||||
|
||||
+35
-6
@@ -56,7 +56,13 @@ class _LazyCanvasState extends State<LazyCanvas> with TickerProviderStateMixin<L
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle any other registered signal events
|
||||
widget.controller.rawPointerSignalListener?.call(event);
|
||||
},
|
||||
onPointerDown: widget.controller.rawPointerDownListener,
|
||||
onPointerMove: widget.controller.rawPointerMoveListener,
|
||||
onPointerUp: widget.controller.rawPointerUpListener,
|
||||
onPointerCancel: widget.controller.rawPointerCancelListener,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onScaleUpdate: widget.controller.onScaleUpdate,
|
||||
@@ -298,14 +304,37 @@ class _CanvasRenderBox extends RenderBox
|
||||
bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
|
||||
RenderBox? child = lastChild;
|
||||
while (child != null) {
|
||||
// need to get a coordinate in child space
|
||||
final childParentData = child.parentData as _CanvasWidgetParentData;
|
||||
final Offset childSpacePosition =
|
||||
(position - childParentData.offset /* <- distance in screen space */ ) / childParentData.scale;
|
||||
// divide by scale so if screen space is 2x, it's only x in child space
|
||||
if (child.hitTest(result, position: childSpacePosition)) {
|
||||
final _CanvasWidgetParentData childParentData = child.parentData! as _CanvasWidgetParentData;
|
||||
|
||||
bool isHit;
|
||||
if (childParentData.scale == 1.0) {
|
||||
// Fast path: only translated, no scale
|
||||
isHit = result.addWithPaintOffset(
|
||||
offset: childParentData.offset,
|
||||
position: position,
|
||||
hitTest: (BoxHitTestResult result, Offset transformed) {
|
||||
return child!.hitTest(result, position: transformed);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
// same paint transform for hit testing when scaled
|
||||
final Matrix4 transform = Matrix4.identity()
|
||||
..translate(childParentData.offset.dx, childParentData.offset.dy)
|
||||
..scale(childParentData.scale, childParentData.scale);
|
||||
|
||||
isHit = result.addWithPaintTransform(
|
||||
transform: transform,
|
||||
position: position,
|
||||
hitTest: (BoxHitTestResult result, Offset transformed) {
|
||||
return child!.hitTest(result, position: transformed);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (isHit) {
|
||||
return true;
|
||||
}
|
||||
|
||||
child = childParentData.previousSibling;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user