diff --git a/lib/src/chart/bar_chart/bar_chart_data.dart b/lib/src/chart/bar_chart/bar_chart_data.dart index 70fd27580..45c71155b 100644 --- a/lib/src/chart/bar_chart/bar_chart_data.dart +++ b/lib/src/chart/bar_chart/bar_chart_data.dart @@ -587,6 +587,9 @@ class BackgroundBarChartRodData with EquatableMixin { class BarTouchData extends FlTouchData with EquatableMixin { /// You can disable or enable the touch system using [enabled] flag, /// + /// You can disable or enable the scale detection using [detectScale] flag, + /// detecting scale gesture will disable pan gesture detection + /// /// [touchCallback] notifies you about the happened touch/pointer events. /// It gives you a [FlTouchEvent] which is the happened event such as [FlPointerHoverEvent], [FlTapUpEvent], ... /// It also gives you a [BarTouchResponse] which contains information @@ -603,6 +606,7 @@ class BarTouchData extends FlTouchData with EquatableMixin { /// on [BarChartRodData.backDrawRodData] too (by default it only works on the main rods). BarTouchData({ bool? enabled, + bool? detectScale, BaseTouchCallback? touchCallback, MouseCursorResolver? mouseCursorResolver, Duration? longPressDuration, @@ -619,6 +623,7 @@ class BarTouchData extends FlTouchData with EquatableMixin { touchCallback, mouseCursorResolver, longPressDuration, + detectScale ?? false, ); /// Configs of how touch tooltip popup. diff --git a/lib/src/chart/base/base_chart/base_chart_data.dart b/lib/src/chart/base/base_chart/base_chart_data.dart index 5bcc39d84..6d38ed6cc 100644 --- a/lib/src/chart/base/base_chart/base_chart_data.dart +++ b/lib/src/chart/base/base_chart/base_chart_data.dart @@ -90,11 +90,16 @@ abstract class FlTouchData with EquatableMixin { this.touchCallback, this.mouseCursorResolver, this.longPressDuration, + this.detectScale, ); /// You can disable or enable the touch system using [enabled] flag, final bool enabled; + /// You can disable or enable the scale detection using [detectScale] flag, + /// detecting scale gesture will disable pan gesture detection + final bool detectScale; + /// [touchCallback] notifies you about the happened touch/pointer events. /// It gives you a [FlTouchEvent] which is the happened event such as [FlPointerHoverEvent], [FlTapUpEvent], ... /// It also gives you a [BaseTouchResponse] which is the chart specific type and contains information diff --git a/lib/src/chart/base/base_chart/fl_touch_event.dart b/lib/src/chart/base/base_chart/fl_touch_event.dart index 73e235dfd..ff0df8f2d 100644 --- a/lib/src/chart/base/base_chart/fl_touch_event.dart +++ b/lib/src/chart/base/base_chart/fl_touch_event.dart @@ -38,6 +38,33 @@ abstract class FlTouchEvent { } } +class FlScaleStartEvent extends FlTouchEvent { + const FlScaleStartEvent(this.details); + + final ScaleStartDetails details; + + @override + Offset get localPosition => details.focalPoint; +} + +class FlScaleUpdateEvent extends FlTouchEvent { + const FlScaleUpdateEvent(this.details); + + final ScaleUpdateDetails details; + + @override + Offset get localPosition => details.focalPoint; +} + +class FlScaleEndEvent extends FlTouchEvent { + const FlScaleEndEvent(this.details); + + final ScaleEndDetails details; + + @override + Offset get localPosition => Offset.zero; +} + /// When a pointer has contacted the screen and might begin to move /// /// The [details] object provides the position of the touch. diff --git a/lib/src/chart/base/base_chart/render_base_chart.dart b/lib/src/chart/base/base_chart/render_base_chart.dart index 7652cc6d4..cacf04c1e 100644 --- a/lib/src/chart/base/base_chart/render_base_chart.dart +++ b/lib/src/chart/base/base_chart/render_base_chart.dart @@ -29,18 +29,24 @@ abstract class RenderBaseChart extends RenderBox _touchCallback = value?.touchCallback; _mouseCursorResolver = value?.mouseCursorResolver; _longPressDuration = value?.longPressDuration; + _detectScale = value?.detectScale ?? false; } BaseTouchCallback? _touchCallback; MouseCursorResolver? _mouseCursorResolver; Duration? _longPressDuration; + bool _detectScale = false; MouseCursor _latestMouseCursor = MouseCursor.defer; late bool _validForMouseTracker; - /// Recognizes pan gestures, such as onDown, onStart, onUpdate, onCancel, ... - late PanGestureRecognizer _panGestureRecognizer; + // late ScaleGestureRecognizer _scaleGestureRecognizer; + + // if [detectScale] is true, we use ScaleGestureRecognizer, otherwise we use PanGestureRecognizer + // Recognizes pan gestures, such as onDown, onStart, onUpdate, onCancel, ... + // or alternatively detects scale gestures, such as onStart, onUpdate, onEnd, ... + late OneSequenceGestureRecognizer _panOrScaleGestureRecognizer; /// Recognizes tap gestures, such as onTapDown, onTapCancel and onTapUp late TapGestureRecognizer _tapGestureRecognizer; @@ -50,23 +56,37 @@ abstract class RenderBaseChart extends RenderBox /// Initializes our recognizers and implement their callbacks. void initGestureRecognizers() { - _panGestureRecognizer = PanGestureRecognizer(); - _panGestureRecognizer - ..onDown = (dragDownDetails) { - _notifyTouchEvent(FlPanDownEvent(dragDownDetails)); - } - ..onStart = (dragStartDetails) { - _notifyTouchEvent(FlPanStartEvent(dragStartDetails)); - } - ..onUpdate = (dragUpdateDetails) { - _notifyTouchEvent(FlPanUpdateEvent(dragUpdateDetails)); - } - ..onCancel = () { - _notifyTouchEvent(const FlPanCancelEvent()); - } - ..onEnd = (dragEndDetails) { - _notifyTouchEvent(FlPanEndEvent(dragEndDetails)); - }; + if (_detectScale) { + final scaleGestureRecognizer = ScaleGestureRecognizer() + ..onStart = (details) { + _notifyTouchEvent(FlScaleStartEvent(details)); + } + ..onUpdate = (details) { + _notifyTouchEvent(FlScaleUpdateEvent(details)); + } + ..onEnd = (details) { + _notifyTouchEvent(FlScaleEndEvent(details)); + }; + _panOrScaleGestureRecognizer = scaleGestureRecognizer; + } else { + final panGestureRecognizer = PanGestureRecognizer() + ..onDown = (dragDownDetails) { + _notifyTouchEvent(FlPanDownEvent(dragDownDetails)); + } + ..onStart = (dragStartDetails) { + _notifyTouchEvent(FlPanStartEvent(dragStartDetails)); + } + ..onUpdate = (dragUpdateDetails) { + _notifyTouchEvent(FlPanUpdateEvent(dragUpdateDetails)); + } + ..onCancel = () { + _notifyTouchEvent(const FlPanCancelEvent()); + } + ..onEnd = (dragEndDetails) { + _notifyTouchEvent(FlPanEndEvent(dragEndDetails)); + }; + _panOrScaleGestureRecognizer = panGestureRecognizer; + } _tapGestureRecognizer = TapGestureRecognizer(); _tapGestureRecognizer @@ -88,7 +108,7 @@ abstract class RenderBaseChart extends RenderBox } ..onLongPressMoveUpdate = (longPressMoveUpdateDetails) { _notifyTouchEvent( - FlLongPressMoveUpdate(longPressMoveUpdateDetails), + FlLongPressMoveUpdate(longPreqssMoveUpdateDetails), ); } ..onLongPressEnd = (longPressEndDetails) => @@ -124,7 +144,7 @@ abstract class RenderBaseChart extends RenderBox if (event is PointerDownEvent) { _longPressGestureRecognizer.addPointer(event); _tapGestureRecognizer.addPointer(event); - _panGestureRecognizer.addPointer(event); + _panOrScaleGestureRecognizer.addPointer(event); } else if (event is PointerHoverEvent) { _notifyTouchEvent(FlPointerHoverEvent(event)); } diff --git a/lib/src/chart/line_chart/line_chart_data.dart b/lib/src/chart/line_chart/line_chart_data.dart index 02ffb9eb7..4903a333a 100644 --- a/lib/src/chart/line_chart/line_chart_data.dart +++ b/lib/src/chart/line_chart/line_chart_data.dart @@ -856,6 +856,9 @@ abstract class FlLineLabel with EquatableMixin { class LineTouchData extends FlTouchData with EquatableMixin { /// You can disable or enable the touch system using [enabled] flag, /// + /// You can disable or enable the scale detection using [detectScale] flag, + /// detecting scale gesture will disable pan gesture detection + /// /// [touchCallback] notifies you about the happened touch/pointer events. /// It gives you a [FlTouchEvent] which is the happened event such as [FlPointerHoverEvent], [FlTapUpEvent], ... /// It also gives you a [LineTouchResponse] which contains information @@ -873,6 +876,7 @@ class LineTouchData extends FlTouchData with EquatableMixin { /// If you need to have a distance threshold for handling touches, use [touchSpotThreshold]. const LineTouchData({ bool enabled = true, + bool detectScale = false, BaseTouchCallback? touchCallback, MouseCursorResolver? mouseCursorResolver, Duration? longPressDuration, @@ -888,6 +892,7 @@ class LineTouchData extends FlTouchData with EquatableMixin { touchCallback, mouseCursorResolver, longPressDuration, + detectScale, ); /// Configs of how touch tooltip popup. diff --git a/lib/src/chart/pie_chart/pie_chart_data.dart b/lib/src/chart/pie_chart/pie_chart_data.dart index 37e70e7b4..91676b7ab 100644 --- a/lib/src/chart/pie_chart/pie_chart_data.dart +++ b/lib/src/chart/pie_chart/pie_chart_data.dart @@ -296,6 +296,9 @@ class PieChartSectionData { class PieTouchData extends FlTouchData with EquatableMixin { /// You can disable or enable the touch system using [enabled] flag, /// + /// You can disable or enable the scale detection using [detectScale] flag, + /// detecting scale gesture will disable pan gesture detection + /// /// [touchCallback] notifies you about the happened touch/pointer events. /// It gives you a [FlTouchEvent] which is the happened event such as [FlPointerHoverEvent], [FlTapUpEvent], ... /// It also gives you a [PieTouchResponse] which contains information @@ -305,6 +308,7 @@ class PieTouchData extends FlTouchData with EquatableMixin { /// based on the provided [FlTouchEvent] and [PieTouchResponse] PieTouchData({ bool? enabled, + bool? detectScale, BaseTouchCallback? touchCallback, MouseCursorResolver? mouseCursorResolver, Duration? longPressDuration, @@ -313,6 +317,7 @@ class PieTouchData extends FlTouchData with EquatableMixin { touchCallback, mouseCursorResolver, longPressDuration, + detectScale ?? false, ); /// Used for equality check, see [EquatableMixin]. diff --git a/lib/src/chart/radar_chart/radar_chart_data.dart b/lib/src/chart/radar_chart/radar_chart_data.dart index 02664dd7b..370a627c8 100644 --- a/lib/src/chart/radar_chart/radar_chart_data.dart +++ b/lib/src/chart/radar_chart/radar_chart_data.dart @@ -382,6 +382,12 @@ class RadarTouchData extends FlTouchData with EquatableMixin { /// You can disable or enable the touch system using [enabled] flag, /// + /// You can disable or enable the scale detection using [detectScale] flag, + /// detecting scale gesture will disable pan gesture detection + /// + /// You can disable or enable the scale detection using [detectScale] flag, + /// detecting scale gesture will disable pan gesture detection + /// /// [touchCallback] notifies you about the happened touch/pointer events. /// It gives you a [FlTouchEvent] which is the happened event such as [FlPointerHoverEvent], [FlTapUpEvent], ... /// It also gives you a [RadarTouchResponse] which contains information @@ -391,6 +397,7 @@ class RadarTouchData extends FlTouchData /// based on the provided [FlTouchEvent] and [RadarTouchResponse] RadarTouchData({ bool? enabled, + bool? detectScale = false, BaseTouchCallback? touchCallback, MouseCursorResolver? mouseCursorResolver, Duration? longPressDuration, @@ -401,6 +408,7 @@ class RadarTouchData extends FlTouchData touchCallback, mouseCursorResolver, longPressDuration, + detectScale ?? false, ); /// we find the nearest spots on touched position based on this threshold diff --git a/lib/src/chart/scatter_chart/scatter_chart_data.dart b/lib/src/chart/scatter_chart/scatter_chart_data.dart index cd27e50ed..ca983c347 100644 --- a/lib/src/chart/scatter_chart/scatter_chart_data.dart +++ b/lib/src/chart/scatter_chart/scatter_chart_data.dart @@ -263,6 +263,9 @@ class ScatterTouchData extends FlTouchData with EquatableMixin { /// You can disable or enable the touch system using [enabled] flag, /// + /// You can disable or enable the scale detection using [detectScale] flag, + /// detecting scale gesture will disable pan gesture detection + /// /// [touchCallback] notifies you about the happened touch/pointer events. /// It gives you a [FlTouchEvent] which is the happened event such as [FlPointerHoverEvent], [FlTapUpEvent], ... /// It also gives you a [ScatterTouchResponse] which contains information @@ -278,6 +281,7 @@ class ScatterTouchData extends FlTouchData /// If you need to have a distance threshold for handling touches, use [touchSpotThreshold]. ScatterTouchData({ bool? enabled, + bool? detectScale, BaseTouchCallback? touchCallback, MouseCursorResolver? mouseCursorResolver, Duration? longPressDuration, @@ -292,6 +296,7 @@ class ScatterTouchData extends FlTouchData touchCallback, mouseCursorResolver, longPressDuration, + detectScale ?? false, ); /// show a tooltip on touched spots