CupertinoSlider
: Add clickable cursor for web (#99557)
This commit is contained in:
parent
7d8a55619a
commit
d72daf602d
@ -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 {
|
|||||||
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);
|
|||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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 @@
|
|||||||
// 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() {
|
|||||||
..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,
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user