Unverified Commit d72daf60 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

`CupertinoSlider`: Add clickable cursor for web (#99557)

parent 7d8a5561
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' show lerpDouble; import 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart' show clampDouble; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'colors.dart'; import 'colors.dart';
...@@ -294,6 +295,7 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget { ...@@ -294,6 +295,7 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
onChangeEnd: onChangeEnd, onChangeEnd: onChangeEnd,
vsync: vsync, vsync: vsync,
textDirection: Directionality.of(context), textDirection: Directionality.of(context),
cursor: kIsWeb ? SystemMouseCursors.click : MouseCursor.defer,
); );
} }
...@@ -322,7 +324,7 @@ const Duration _kDiscreteTransitionDuration = Duration(milliseconds: 500); ...@@ -322,7 +324,7 @@ const Duration _kDiscreteTransitionDuration = Duration(milliseconds: 500);
const double _kAdjustmentUnit = 0.1; // Matches iOS implementation of material slider. const double _kAdjustmentUnit = 0.1; // Matches iOS implementation of material slider.
class _RenderCupertinoSlider extends RenderConstrainedBox { class _RenderCupertinoSlider extends RenderConstrainedBox implements MouseTrackerAnnotation {
_RenderCupertinoSlider({ _RenderCupertinoSlider({
required double value, required double value,
int? divisions, int? divisions,
...@@ -334,8 +336,11 @@ class _RenderCupertinoSlider extends RenderConstrainedBox { ...@@ -334,8 +336,11 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
this.onChangeEnd, this.onChangeEnd,
required TickerProvider vsync, required TickerProvider vsync,
required TextDirection textDirection, required TextDirection textDirection,
MouseCursor cursor = MouseCursor.defer,
}) : assert(value != null && value >= 0.0 && value <= 1.0), }) : assert(value != null && value >= 0.0 && value <= 1.0),
assert(textDirection != null), assert(textDirection != null),
assert(cursor != null),
_cursor = cursor,
_value = value, _value = value,
_divisions = divisions, _divisions = divisions,
_activeColor = activeColor, _activeColor = activeColor,
...@@ -584,4 +589,27 @@ class _RenderCupertinoSlider extends RenderConstrainedBox { ...@@ -584,4 +589,27 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
onChanged!(clampDouble(value - _semanticActionUnit, 0.0, 1.0)); onChanged!(clampDouble(value - _semanticActionUnit, 0.0, 1.0));
} }
} }
@override
MouseCursor get cursor => _cursor;
MouseCursor _cursor;
set cursor(MouseCursor value) {
if (_cursor != value) {
_cursor = value;
// A repaint is needed in order to trigger a device update of
// [MouseTracker] so that this new value can be found.
markNeedsPaint();
}
}
@override
PointerEnterEventListener? onEnter;
PointerHoverEventListener? onHover;
@override
PointerExitEventListener? onExit;
@override
bool get validForMouseTracker => false;
} }
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
...@@ -613,4 +615,46 @@ void main() { ...@@ -613,4 +615,46 @@ void main() {
..rrect(color: CupertinoColors.activeOrange.color), ..rrect(color: CupertinoColors.activeOrange.color),
); );
}); });
testWidgets('Hovering over Cupertino slider thumb updates cursor to clickable on Web', (WidgetTester tester) async {
final Key sliderKey = UniqueKey();
double value = 0.0;
await tester.pumpWidget(
CupertinoApp(
home: Directionality(
textDirection: TextDirection.ltr,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: Center(
child: CupertinoSlider(
key: sliderKey,
value: value,
onChanged: (double newValue) {
setState(() { value = newValue; });
},
),
),
);
},
),
),
),
);
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
await gesture.addPointer(location: const Offset(10, 10));
await tester.pumpAndSettle();
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
final Offset topLeft = tester.getTopLeft(find.byKey(sliderKey));
await gesture.moveTo(topLeft + const Offset(15, 0));
addTearDown(gesture.removePointer);
await tester.pumpAndSettle();
expect(
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment