mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
FloatingActionButton: add themeable mouse cursor (#103473)
This commit is contained in:
parent
2756f868b6
commit
fbb3036b73
@ -11,6 +11,7 @@ import 'package:flutter/widgets.dart';
|
||||
import 'button.dart';
|
||||
import 'color_scheme.dart';
|
||||
import 'floating_action_button_theme.dart';
|
||||
import 'material_state.dart';
|
||||
import 'scaffold.dart';
|
||||
import 'text_theme.dart';
|
||||
import 'theme.dart';
|
||||
@ -603,7 +604,7 @@ class FloatingActionButton extends StatelessWidget {
|
||||
|
||||
Widget result = RawMaterialButton(
|
||||
onPressed: onPressed,
|
||||
mouseCursor: mouseCursor,
|
||||
mouseCursor: _EffectiveMouseCursor(mouseCursor, floatingActionButtonTheme.mouseCursor),
|
||||
elevation: elevation,
|
||||
focusElevation: focusElevation,
|
||||
hoverElevation: hoverElevation,
|
||||
@ -664,6 +665,26 @@ class FloatingActionButton extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// This MaterialStateProperty is passed along to RawMaterialButton which
|
||||
// resolves the property against MaterialState.pressed, MaterialState.hovered,
|
||||
// MaterialState.focused, MaterialState.disabled.
|
||||
class _EffectiveMouseCursor extends MaterialStateMouseCursor {
|
||||
const _EffectiveMouseCursor(this.widgetCursor, this.themeCursor);
|
||||
|
||||
final MouseCursor? widgetCursor;
|
||||
final MaterialStateProperty<MouseCursor?>? themeCursor;
|
||||
|
||||
@override
|
||||
MouseCursor resolve(Set<MaterialState> states) {
|
||||
return MaterialStateProperty.resolveAs<MouseCursor?>(widgetCursor, states)
|
||||
?? themeCursor?.resolve(states)
|
||||
?? MaterialStateMouseCursor.clickable.resolve(states);
|
||||
}
|
||||
|
||||
@override
|
||||
String get debugDescription => 'MaterialStateMouseCursor(FloatActionButton)';
|
||||
}
|
||||
|
||||
// This widget's size matches its child's size unless its constraints
|
||||
// force it to be larger or smaller. The child is centered.
|
||||
//
|
||||
|
||||
@ -7,6 +7,8 @@ import 'dart:ui' show lerpDouble;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
import 'material_state.dart';
|
||||
|
||||
/// Defines default property values for descendant [FloatingActionButton]
|
||||
/// widgets.
|
||||
///
|
||||
@ -51,6 +53,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
this.extendedIconLabelSpacing,
|
||||
this.extendedPadding,
|
||||
this.extendedTextStyle,
|
||||
this.mouseCursor,
|
||||
});
|
||||
|
||||
/// Color to be used for the unselected, enabled [FloatingActionButton]'s
|
||||
@ -129,6 +132,11 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
/// The text style for an extended [FloatingActionButton]'s label.
|
||||
final TextStyle? extendedTextStyle;
|
||||
|
||||
/// {@macro flutter.material.RawMaterialButton.mouseCursor}
|
||||
///
|
||||
/// If specified, overrides the default value of [FloatingActionButton.mouseCursor].
|
||||
final MaterialStateProperty<MouseCursor?>? mouseCursor;
|
||||
|
||||
/// Creates a copy of this object with the given fields replaced with the
|
||||
/// new values.
|
||||
FloatingActionButtonThemeData copyWith({
|
||||
@ -152,6 +160,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
double? extendedIconLabelSpacing,
|
||||
EdgeInsetsGeometry? extendedPadding,
|
||||
TextStyle? extendedTextStyle,
|
||||
MaterialStateProperty<MouseCursor?>? mouseCursor,
|
||||
}) {
|
||||
return FloatingActionButtonThemeData(
|
||||
foregroundColor: foregroundColor ?? this.foregroundColor,
|
||||
@ -174,6 +183,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
extendedIconLabelSpacing: extendedIconLabelSpacing ?? this.extendedIconLabelSpacing,
|
||||
extendedPadding: extendedPadding ?? this.extendedPadding,
|
||||
extendedTextStyle: extendedTextStyle ?? this.extendedTextStyle,
|
||||
mouseCursor: mouseCursor ?? this.mouseCursor,
|
||||
);
|
||||
}
|
||||
|
||||
@ -208,6 +218,7 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
extendedIconLabelSpacing: lerpDouble(a?.extendedIconLabelSpacing, b?.extendedIconLabelSpacing, t),
|
||||
extendedPadding: EdgeInsetsGeometry.lerp(a?.extendedPadding, b?.extendedPadding, t),
|
||||
extendedTextStyle: TextStyle.lerp(a?.extendedTextStyle, b?.extendedTextStyle, t),
|
||||
mouseCursor: t < 0.5 ? a?.mouseCursor : b?.mouseCursor,
|
||||
);
|
||||
}
|
||||
|
||||
@ -232,7 +243,10 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
extendedSizeConstraints,
|
||||
extendedIconLabelSpacing,
|
||||
extendedPadding,
|
||||
extendedTextStyle,
|
||||
Object.hash(
|
||||
extendedTextStyle,
|
||||
mouseCursor,
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
@ -263,7 +277,8 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
&& other.extendedSizeConstraints == extendedSizeConstraints
|
||||
&& other.extendedIconLabelSpacing == extendedIconLabelSpacing
|
||||
&& other.extendedPadding == extendedPadding
|
||||
&& other.extendedTextStyle == extendedTextStyle;
|
||||
&& other.extendedTextStyle == extendedTextStyle
|
||||
&& other.mouseCursor == mouseCursor;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -290,5 +305,6 @@ class FloatingActionButtonThemeData with Diagnosticable {
|
||||
properties.add(DoubleProperty('extendedIconLabelSpacing', extendedIconLabelSpacing, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('extendedPadding', extendedPadding, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<TextStyle>('extendedTextStyle', extendedTextStyle, defaultValue: null));
|
||||
properties.add(DiagnosticsProperty<MaterialStateProperty<MouseCursor?>>('mouseCursor', mouseCursor, defaultValue: null));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -287,6 +288,7 @@ void main() {
|
||||
extendedIconLabelSpacing: 12,
|
||||
extendedPadding: EdgeInsetsDirectional.only(start: 7.0, end: 8.0),
|
||||
extendedTextStyle: TextStyle(letterSpacing: 2.0),
|
||||
mouseCursor: MaterialStateMouseCursor.clickable,
|
||||
).debugFillProperties(builder);
|
||||
|
||||
final List<String> description = builder.properties
|
||||
@ -315,8 +317,33 @@ void main() {
|
||||
'extendedIconLabelSpacing: 12.0',
|
||||
'extendedPadding: EdgeInsetsDirectional(7.0, 0.0, 8.0, 0.0)',
|
||||
'extendedTextStyle: TextStyle(inherit: true, letterSpacing: 2.0)',
|
||||
'mouseCursor: MaterialStateMouseCursor(clickable)',
|
||||
]);
|
||||
});
|
||||
|
||||
testWidgets('FloatingActionButton.mouseCursor uses FloatingActionButtonThemeData.mouseCursor when specified.', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData().copyWith(
|
||||
floatingActionButtonTheme: FloatingActionButtonThemeData(
|
||||
mouseCursor: MaterialStateProperty.all(SystemMouseCursors.text),
|
||||
),
|
||||
),
|
||||
home: Scaffold(
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () { },
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||
await gesture.addPointer();
|
||||
addTearDown(gesture.removePointer);
|
||||
await gesture.moveTo(tester.getCenter(find.byType(FloatingActionButton)));
|
||||
await tester.pumpAndSettle();
|
||||
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
|
||||
});
|
||||
}
|
||||
|
||||
RawMaterialButton _getRawMaterialButton(WidgetTester tester) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user