-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Add mouseCursor property to CupertinoCheckbox
#151788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add mouseCursor property to CupertinoCheckbox
#151788
Conversation
| final Color effectiveCheckColor = widget.checkColor | ||
| ?? CupertinoColors.white; | ||
|
|
||
| final WidgetStateProperty<MouseCursor> effectiveMouseCursor = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After updating the parameter we can assign widget.mouseCursor and followed by default.
Like
final WidgetStateProperty<MouseCursor> effectiveMouseCursor = widget.mouseCursor ?? <Default>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly does this mean it should be rewritten as
final MouseCursor effectiveMouseCursor = widget.mouseCursor ??
WidgetStateProperty.resolveWith<MouseCursor>((Set<WidgetState> states) {
return states.contains(WidgetState.disabled)
? SystemMouseCursors.basic
: kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic
);
(And therefore the default cursor can be extracted as a const class?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But buildToggleable expects effectiveMouseCursor to be of type WidgetStateProperty not of type MouseCursor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Thank you for explaining.
|
@victorsanni |
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the plan to migrate Checkbox.mouseCursor to a MaterialStateProperty after this PR?
Can you add a test that creates a Checkbox.adaptive on iOS and check that it respects CheckBox.mouseCursor?
That would be a good next step. I'll open a PR for that, with data-driven fixes. |
| value: value, | ||
| tristate: tristate, | ||
| onChanged: onChanged, | ||
| mouseCursor: WidgetStateProperty.all(widget.mouseCursor ?? SystemMouseCursors.basic), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| mouseCursor: WidgetStateProperty.all(widget.mouseCursor ?? SystemMouseCursors.basic), | |
| mouseCursor: WidgetStateProperty.resolveWith((Set<MaterialState> states) { | |
| return MaterialStateProperty.resolveAs<MouseCursor?>(widget.mouseCursor, states) | |
| ?? SystemMouseCursors.basic; | |
| }), |
Reviewing this I realized some widgets still "resolve" non-state cursor. This is to support WidgetStateMouseCursor. Widgets such as buttons already support this. Check out official sample here
https://api.flutter.dev/flutter/widgets/WidgetStateMouseCursor-class.html
I created a Checkbox.adaptive for your PR to test this. Try this sample before applying the suggestion and then after it.
Code sample
expand to view the code sample
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Sample'),
),
body: const Checkbox.adaptive(
mouseCursor: CheckboxCursor(),
value: true,
// onChanged: (bool? value) {},
onChanged: null,
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
),
);
}
}
class CheckboxCursor extends WidgetStateMouseCursor {
const CheckboxCursor();
@override
MouseCursor resolve(Set<WidgetState> states) {
if (states.contains(WidgetState.disabled)) {
return SystemMouseCursors.forbidden;
}
return SystemMouseCursors.basic;
}
@override
String get debugDescription => 'CheckboxCursor()';
}This will not work with WidgetStatePropertyAll, we should use resolveWith with the Checkbox states to support WidgetStateMouseCursor. This allows allows using mouse states for Cupertino Checkbox from adaptive Checkbox.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you apply this suggestion, we will need adaptive checkbox test to cover this use case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah because WidgetStateMouseCursor is a MouseCursor. This is very tricky, though, or maybe I just need to study up on WidgetStateProperty.
- If @victorsanni migrates Checkbox.mouseCursor to be a WidgetStateProperty, then will this code need to change?
- Am I supposed to be able to pass around a WidgetStateMouseCursor as if it were a MouseCursor and it will just work? Though actually the consumer of the WidgetStateMouseCursor must use resolveAs?
It will be really easy to make this same mistake elsewhere in the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we make CupertinoCheckbox.mouseCursor simply MouseCursor? WidgetStateMouseCursor extends MouseCursor and we always resolve them at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we make
CupertinoCheckbox.mouseCursorsimplyMouseCursor?WidgetStateMouseCursorextendsMouseCursorand we always resolve them at some point.
I initially thought the same way too.
@justinmc mentioned WidgetStateMouseCursor felt like a hack to get MouseCursor and WidgetStateProperty<MouseCursor> to play well with each other. @TahaTesser also mentioned that new properties like color, mouse cursor, etc. should be introduced as WidgetStatePropertys so that they can be resolved in different WidgetStates.
An extra point is CheckboxThemeDatas mouseCursor is a WidgetStateProperty. So for later (possible) .adaptive work, passing WidgetStatePropertys would make it so that the property can be resolved with non-stale states in CupertinoCheckbox, instead of using stale states in Checkbox.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean we're deprecating WidgetStateMouseCursor? I don't think this is a hack. At least we have other classes that act like this as well, such as CupertinoDynamicColor, which extends Color and the widget will always resolve an incoming Color for possible brightness variety.
I think we should either:
- Use
MouseCursoras the type, and always resolve it by states. Or: - Use
WidgetStateProperty<MouseCursor>as the type, but clearly state thatWidgetStateMouseCursoris to be deprecated and discouraged, and add another constructor as an adaptor fromTtoWidgetStateProperty<T>for convenience, instead of having to use this "double wrapping" every time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of having to use this "double wrapping" every time.
@dkwingsmt what do you think about migrating existing properties from T to WidgetStateProperty<T>?
For example, in this case, that would entail converting Material Checkboxs mouseCursor to be of type WidgetStateProperty<MouseCursor> instead of MouseCursor to remove the need for this double wrapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my opinion, we should use MouseCursor as the type, and resolve it if a WidgetStateProperty is given, the same way mouseCursor works for the current Material checkbox. The adaptive checkbox should pass mouseCursor to the Cupertino widget with as few transformations and let the Cupertino widget handle it's default behavior if it's null.
WidgetStateMouseCursor I believe is never used as a type for constructor arguments, but it is used regularly as a default behavior with it's static const constructors like WidgetStateMouseCursor.clickable. It seems convenient for devs to make their own default behavior too. I don't see a need to deprecate it.
Ideally a property of WidgetStateProperties<T> would just automatically handle if it's passed a property of just type T, but Dart doesn't allow that currently. In several places we have parameters of type T but we check if it's a WidgetState and resolve it appropriately, then call it out in the documentation. I think that's slightly better than using WidgetStateProperty<T> in a lot of cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I think we should stick with the current convention for using MouseCursor. It might be a gimmick, but a good one (in my opinion).
Manual roll Flutter from 0975e61 to ec2e12b (54 revisions) Manual roll requested by [email protected] flutter/flutter@0975e61...ec2e12b 2024-10-03 [email protected] Roll Flutter Engine from bd44b58e3204 to 247bc68c578e (7 revisions) (flutter/flutter#156144) 2024-10-03 [email protected] Roll Flutter Engine from 70232fa124d0 to bd44b58e3204 (1 revision) (flutter/flutter#156124) 2024-10-03 [email protected] Roll Flutter Engine from 33ac1b30ab0a to 70232fa124d0 (2 revisions) (flutter/flutter#156122) 2024-10-02 [email protected] Update `ThemeData.dialogTheme` type to accept `DialogThemeData` (flutter/flutter#155129) 2024-10-02 [email protected] Roll Flutter Engine from 751ab9b3c5eb to 33ac1b30ab0a (4 revisions) (flutter/flutter#156118) 2024-10-02 [email protected] Add back main() methods to benchmark benches. (flutter/flutter#156083) 2024-10-02 [email protected] Roll pub packages (flutter/flutter#156117) 2024-10-02 [email protected] Add `mouseCursor` property to `CupertinoCheckbox` (flutter/flutter#151788) 2024-10-02 [email protected] Roll Flutter Engine from 3bdc1c0a30b6 to 751ab9b3c5eb (3 revisions) (flutter/flutter#156115) 2024-10-02 [email protected] Roll pub packages (flutter/flutter#156114) 2024-10-02 [email protected] [ Cocoon ] Wait for task results to be received by the task runner before shutting down the task process (flutter/flutter#156002) 2024-10-02 [email protected] Allow mixing route transitions in one app. (flutter/flutter#150031) 2024-10-02 [email protected] Roll Flutter Engine from f20681241753 to 3bdc1c0a30b6 (5 revisions) (flutter/flutter#156107) 2024-10-02 [email protected] Update Upgrading-Engine's-Android-API-version.md to reflect code move (flutter/flutter#156108) 2024-10-02 [email protected] Roll Packages from ebcc4f0 to 7c97c88 (5 revisions) (flutter/flutter#156106) 2024-10-02 [email protected] Roll pub packages (flutter/flutter#156105) 2024-10-02 [email protected] fix wrong test in "fixing `DropdownMenu` keyboard navigation" (flutter/flutter#156084) 2024-10-02 [email protected] fix ReorderableList not passing in item extent builder (flutter/flutter#155994) 2024-10-02 98614782+auto-submit[bot]@users.noreply.github.com Reverts "integration_test: migrate to build.gradle.kts (#154125)" (flutter/flutter#156087) 2024-10-02 [email protected] Add deprecation warning for "flutter create --ios-language" (flutter/flutter#155867) 2024-10-02 [email protected] update flutter create generated projects to use package:flutter_lints 5.0.0 (flutter/flutter#156011) 2024-10-02 [email protected] Roll Flutter Engine from d48c35d16814 to f20681241753 (1 revision) (flutter/flutter#156080) 2024-10-02 [email protected] [Docs] `CupertinoListTile` API Example (flutter/flutter#154548) 2024-10-02 [email protected] integration_test: migrate to build.gradle.kts (flutter/flutter#154125) 2024-10-02 [email protected] Marks Windows_mokey native_assets_android to be flaky (flutter/flutter#156064) 2024-10-02 [email protected] Fix DropdownMenu does not rematch initialSelection when entries have changed (flutter/flutter#155757) 2024-10-02 [email protected] Roll Flutter Engine from 9b224bd2f895 to d48c35d16814 (1 revision) (flutter/flutter#156074) 2024-10-02 [email protected] Roll Flutter Engine from 8774940b9ddc to 9b224bd2f895 (1 revision) (flutter/flutter#156065) 2024-10-02 [email protected] Roll Flutter Engine from 21ad04948457 to 8774940b9ddc (1 revision) (flutter/flutter#156055) 2024-10-02 [email protected] Roll Flutter Engine from 767bdc38cf51 to 21ad04948457 (1 revision) (flutter/flutter#156049) 2024-10-02 [email protected] Roll Flutter Engine from 055969512dc5 to 767bdc38cf51 (1 revision) (flutter/flutter#156043) 2024-10-02 [email protected] Roll Flutter Engine from e0f049d69240 to 055969512dc5 (2 revisions) (flutter/flutter#156042) 2024-10-02 [email protected] fix `DropdownMenu` keyboard navigation when entries are filtered empty (flutter/flutter#155252) 2024-10-02 [email protected] Roll Flutter Engine from a5bc2e2708c7 to e0f049d69240 (1 revision) (flutter/flutter#156039) 2024-10-02 [email protected] mark {Linux,Windows} tool_integration_tests_* non-bringup (flutter/flutter#155773) 2024-10-02 [email protected] Roll Flutter Engine from a7abf7a8163e to a5bc2e2708c7 (2 revisions) (flutter/flutter#156038) 2024-10-02 [email protected] Roll Flutter Engine from df1982dd4482 to a7abf7a8163e (1 revision) (flutter/flutter#156032) 2024-10-02 [email protected] Add `enableSplash` parameter to `CarouselView` (flutter/flutter#155214) 2024-10-02 [email protected] Roll pub packages (flutter/flutter#156030) 2024-10-01 [email protected] Roll Flutter Engine from ab48d6d8c167 to df1982dd4482 (1 revision) (flutter/flutter#156029) 2024-10-01 [email protected] Marks Mac_arm64_ios hot_mode_dev_cycle_ios__benchmark to be unflaky (flutter/flutter#147289) 2024-10-01 [email protected] Add WidgetStateMouseCursor example and tests for it. (flutter/flutter#155552) 2024-10-01 49699333+dependabot[bot]@users.noreply.github.com Bump codecov/codecov-action from 4.5.0 to 4.6.0 (flutter/flutter#156024) 2024-10-01 [email protected] Roll Flutter Engine from e7b3ce717006 to ab48d6d8c167 (1 revision) (flutter/flutter#156023) ...
Part of #58192
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.