mirror of
https://github.com/flutter/flutter
synced 2024-10-02 22:44:13 +00:00
TabBar: add themeable mouse cursor (#96737)
This commit is contained in:
parent
36a8f0f2ae
commit
a6504ead31
|
@ -37,6 +37,7 @@ class TabBarTheme with Diagnosticable {
|
|||
this.unselectedLabelStyle,
|
||||
this.overlayColor,
|
||||
this.splashFactory,
|
||||
this.mouseCursor,
|
||||
});
|
||||
|
||||
/// Default value for [TabBar.indicator].
|
||||
|
@ -70,6 +71,11 @@ class TabBarTheme with Diagnosticable {
|
|||
/// Default value for [TabBar.splashFactory].
|
||||
final InteractiveInkFeatureFactory? splashFactory;
|
||||
|
||||
/// {@macro flutter.material.tabs.mouseCursor}
|
||||
///
|
||||
/// If specified, overrides the default value of [TabBar.mouseCursor].
|
||||
final MaterialStateProperty<MouseCursor?>? mouseCursor;
|
||||
|
||||
/// Creates a copy of this object but with the given fields replaced with the
|
||||
/// new values.
|
||||
TabBarTheme copyWith({
|
||||
|
@ -82,6 +88,7 @@ class TabBarTheme with Diagnosticable {
|
|||
TextStyle? unselectedLabelStyle,
|
||||
MaterialStateProperty<Color?>? overlayColor,
|
||||
InteractiveInkFeatureFactory? splashFactory,
|
||||
MaterialStateProperty<MouseCursor?>? mouseCursor,
|
||||
}) {
|
||||
return TabBarTheme(
|
||||
indicator: indicator ?? this.indicator,
|
||||
|
@ -93,6 +100,7 @@ class TabBarTheme with Diagnosticable {
|
|||
unselectedLabelStyle: unselectedLabelStyle ?? this.unselectedLabelStyle,
|
||||
overlayColor: overlayColor ?? this.overlayColor,
|
||||
splashFactory: splashFactory ?? this.splashFactory,
|
||||
mouseCursor: mouseCursor ?? this.mouseCursor,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -120,6 +128,7 @@ class TabBarTheme with Diagnosticable {
|
|||
unselectedLabelStyle: TextStyle.lerp(a.unselectedLabelStyle, b.unselectedLabelStyle, t),
|
||||
overlayColor: _LerpColors(a.overlayColor, b.overlayColor, t),
|
||||
splashFactory: t < 0.5 ? a.splashFactory : b.splashFactory,
|
||||
mouseCursor: t < 0.5 ? a.mouseCursor : b.mouseCursor,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -135,6 +144,7 @@ class TabBarTheme with Diagnosticable {
|
|||
unselectedLabelStyle,
|
||||
overlayColor,
|
||||
splashFactory,
|
||||
mouseCursor,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -153,7 +163,8 @@ class TabBarTheme with Diagnosticable {
|
|||
&& other.unselectedLabelColor == unselectedLabelColor
|
||||
&& other.unselectedLabelStyle == unselectedLabelStyle
|
||||
&& other.overlayColor == overlayColor
|
||||
&& other.splashFactory == splashFactory;
|
||||
&& other.splashFactory == splashFactory
|
||||
&& other.mouseCursor == mouseCursor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -803,10 +803,23 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
|
|||
/// {@macro flutter.widgets.scrollable.dragStartBehavior}
|
||||
final DragStartBehavior dragStartBehavior;
|
||||
|
||||
/// {@template flutter.material.tabs.mouseCursor}
|
||||
/// The cursor for a mouse pointer when it enters or is hovering over the
|
||||
/// individual tab widgets.
|
||||
///
|
||||
/// If this property is null, [SystemMouseCursors.click] will be used.
|
||||
/// If [mouseCursor] is a [MaterialStateProperty<MouseCursor>],
|
||||
/// [MaterialStateProperty.resolve] is used for the following [MaterialState]s:
|
||||
///
|
||||
/// * [MaterialState.selected].
|
||||
/// {@endtemplate}
|
||||
///
|
||||
/// If null, then the value of [TabBarTheme.mouseCursor] is used. If
|
||||
/// that is also null, then [MaterialStateMouseCursor.clickable] is used.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [MaterialStateMouseCursor], which can be used to create a [MouseCursor]
|
||||
/// that is also a [MaterialStateProperty<MouseCursor>].
|
||||
final MouseCursor? mouseCursor;
|
||||
|
||||
/// Whether detected gestures should provide acoustic and/or haptic feedback.
|
||||
|
@ -1222,8 +1235,16 @@ class _TabBarState extends State<TabBar> {
|
|||
// the same share of the tab bar's overall width.
|
||||
final int tabCount = widget.tabs.length;
|
||||
for (int index = 0; index < tabCount; index += 1) {
|
||||
final Set<MaterialState> states = <MaterialState>{
|
||||
if (index == _currentIndex) MaterialState.selected,
|
||||
};
|
||||
|
||||
final MouseCursor effectiveMouseCursor = MaterialStateProperty.resolveAs<MouseCursor?>(widget.mouseCursor, states)
|
||||
?? tabBarTheme.mouseCursor?.resolve(states)
|
||||
?? MaterialStateMouseCursor.clickable.resolve(states);
|
||||
|
||||
wrappedTabs[index] = InkWell(
|
||||
mouseCursor: widget.mouseCursor ?? SystemMouseCursors.click,
|
||||
mouseCursor: effectiveMouseCursor,
|
||||
onTap: () { _handleTap(index); },
|
||||
enableFeedback: widget.enableFeedback ?? true,
|
||||
overlayColor: widget.overlayColor ?? tabBarTheme.overlayColor,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
// machines.
|
||||
@Tags(<String>['reduced-test-set'])
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
@ -67,6 +68,7 @@ void main() {
|
|||
expect(const TabBarTheme().unselectedLabelStyle, null);
|
||||
expect(const TabBarTheme().overlayColor, null);
|
||||
expect(const TabBarTheme().splashFactory, null);
|
||||
expect(const TabBarTheme().mouseCursor, null);
|
||||
});
|
||||
|
||||
testWidgets('Tab bar defaults - label style and selected/unselected label colors', (WidgetTester tester) async {
|
||||
|
@ -302,6 +304,22 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
testWidgets('Tab bar theme overrides tab mouse cursor', (WidgetTester tester) async {
|
||||
const TabBarTheme tabBarTheme = TabBarTheme(mouseCursor: MaterialStateMouseCursor.textable);
|
||||
|
||||
await tester.pumpWidget(_withTheme(tabBarTheme));
|
||||
|
||||
final Offset tabBar = tester.getCenter(
|
||||
find.ancestor(of: find.text('tab 1'),matching: find.byType(TabBar)),
|
||||
);
|
||||
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||
await gesture.addPointer();
|
||||
addTearDown(gesture.removePointer);
|
||||
await gesture.moveTo(tabBar);
|
||||
await tester.pumpAndSettle();
|
||||
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
|
||||
});
|
||||
|
||||
testWidgets('Tab bar theme - custom tab indicator', (WidgetTester tester) async {
|
||||
final TabBarTheme tabBarTheme = TabBarTheme(
|
||||
indicator: BoxDecoration(
|
||||
|
|
Loading…
Reference in a new issue