Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Move text selection theme to widget libraries #99576

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

Closed
wants to merge 2 commits into from

Conversation

chunhtai
Copy link
Contributor

@chunhtai chunhtai commented Mar 5, 2022

Moves the text selection theme to widget layer to be reused by Global selection

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard bot added a: text input Entering text in a text field or keyboard related problems f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels Mar 5, 2022
Copy link
Contributor

@darrenaustin darrenaustin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general I understand why you want to do this, but I think it is going to cause more problems than it solves. Perhaps if we had started with a base theme system in widgets and then had Material and Cupertino subclasses this would work better. But as it stands this breaks the current pattern that we use for all the other themes, which would be confusing to learn and would require very careful documentation.

I will think about this some more and see if there is way we could make this work. Or perhaps @HansMuller has some idea about how to handle this better.

(Also it looks like there are some test failures due to the introduction of TextSelectionTheme widgets in the tree where they didn't use to exist).

Comment on lines 541 to 545
textSelectionTheme ??= TextSelectionThemeData(
selectionColor: colorScheme.primary.withOpacity(0.40),
selectionHandleColor: colorScheme.primary,
cursorColor: colorScheme.primary,
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is totally different from the pattern that is currently used for ThemeData objects. They always default to completely empty data object and are only used to override defaults, not provide them here.

Not saying we can't do this, but it would be confusing as it is not consistent with all the other ThemeData classes. We would have to document this special case which would make it harder to learn the theme APIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think i should be able to avoid this by deriving the text selection them in MaterialApp build method instead. will do that

@@ -154,7 +158,7 @@ class TextSelectionTheme extends InheritedTheme {
/// ```
static TextSelectionThemeData of(BuildContext context) {
final TextSelectionTheme? selectionTheme = context.dependOnInheritedWidgetOfExactType<TextSelectionTheme>();
return selectionTheme?.data ?? Theme.of(context).textSelectionTheme;
return selectionTheme?.data ?? const TextSelectionThemeData();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This again breaks the existing model, where the fallback values come from the surrounding ThemeData. If an app configured their ThemeData.textSelectionTheme it would not be used for defaults here, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is following the same pattern of DefaultTextStyle

@chunhtai
Copy link
Contributor Author

chunhtai commented Mar 7, 2022

Hi @darrenaustin, thanks for reviewing!

The problem I am facing is that RichText needs the selection color to draw the selection highlight. If we don't create some kind of the inherited widget, developers then have to provide selection color for every text widgets, which will be a real pain. If we do create inherited widget, the API will be the same as TextSelectionTheme. That's why i decided to move TextSelectionTheme.

I am trying to follow the pattern of DefaultTextStyle, although I think we should probably call it DefaultTextSelectionStyle instead of TextSelectionTheme to avoid confusing. but I am not sure whether it is worth it to rename to class and be a breaking change.

@skia-gold

This comment was marked as outdated.

@chunhtai chunhtai force-pushed the move-text-selection-theme branch from 1b22619 to ffa21d4 Compare March 7, 2022 22:57
@chunhtai chunhtai requested a review from darrenaustin March 7, 2022 22:59
@chunhtai chunhtai force-pushed the move-text-selection-theme branch from ffa21d4 to a325cd4 Compare March 8, 2022 18:21
@chunhtai
Copy link
Contributor Author

a friendly bump

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to suggest an alternative design, one that's a much closer analog to DefaultTextStyle.

// Defined in the widgets library
class DefaultTextSelectionStyle extends InheritedTheme {
  ...
  final Color? focusedSelectionColor
  final Color? selectionColor
  final Color? cursorColor
  final Color? focusedCursorColor
  final Color? focusedSelectionHandleColor
  final Color? selectionHandleColor
}

The focused variants enable apps to define the selection color that implies that the highlighted text will react to copy/paste/delete clipboard operations.

Widgets that depend on DefaultTextSelectionStyle.of(context) will have to provide defaults for null colors. WidgetsApp will create a fully specified DefaultTextSelectionStyle based on the underlying platform.

It's not possible to use MaterialStateProperty types here because any widget (not just Material widgets) needs to be able to lookup these colors.

TextSelectionThemeData will need to add focused variants of the existing three color properties, all of which will default to the unqualified property (for the sake of backwards compatibility). For example focusedSelectionColor will default to selectionColor. Although supporting MaterialStateColor values for the existing properties would cover this, it seems marginally worthwhile to keep this class's API the same as DefaultTextSelectionStyle.

  final Color? focusedSelectionColor
  final Color? focusedCursorColor
  final Color? focusedSelectionHandleColor

MaterialApp should create a fully-specified DefaultTextStyle based on the theme's textSelectionTheme with defaults drawn from the inherited (WidgetsApp) DefaultTextSelectionStyle.

TextSelectionTheme should create a DefaultTextStyle. Note also: TextSelectionTheme (the inherited widget) seems to be rarely used (in other words it seems unlikely that this particular change will cause any backwards compatibility problems).

@chunhtai chunhtai mentioned this pull request Mar 24, 2022
8 tasks
@chunhtai
Copy link
Contributor Author

closed in the favor of #100719

@chunhtai chunhtai closed this Mar 24, 2022
@cedvdb
Copy link
Contributor

cedvdb commented Mar 26, 2022

FWIW I prefer the implementation here, theming via the widget tree instead of the theme is odd.

This is totally different from the pattern that is currently used for ThemeData objects. They always default to completely empty data object and are only used to override defaults, not provide them here.

What's the reason behind that ? If it was swapped where every theme data object provided defaults, it might be easier to find default values

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: text input Entering text in a text field or keyboard related problems f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants