Skip to content

Stop using SelectionChangedCause internally to show the text selection toolbar - #27534

Merged
xster merged 4 commits into
flutter:masterfrom
xster:deprecate-selection-change-cause
Feb 6, 2019
Merged

xster merged 4 commits into
flutter:masterfrom
xster:deprecate-selection-change-cause

Conversation

@xster

@xster xster commented Feb 5, 2019

Copy link
Copy Markdown
Member

Stop passing the SelectionChangedCause from (Cupertino)TextField all the way down through EditableText into RenderEditable, then bubble back up to EditableTextState to decide whether to show a toolbar (since it depends on more than just the SelectionChangedCause).

Let (Cupertino)TextField just invoke it directly when factors are satisfied.

#26026

It's a soft API break. (Cupertino)TextField will continue to work as is. Various listeners using SelectionChangedHandler will also continue to work as is.

Users using EditableText directly with rendererIgnoresPointer = false or who calls the descendent RenderEditable's select* will also need to call EditableTextState.showToolbar() directly.

@xster xster added the c: API break Backwards-incompatible API changes label Feb 5, 2019
@goderbauer goderbauer added framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages p: cupertino_ui cupertino_ui package in flutter/packages labels Feb 5, 2019
@xster
xster requested review from HansMuller and jslavitz February 5, 2019 18:59
@xster xster added the a: text input Entering text in a text field or keyboard related problems label Feb 5, 2019
@xster
xster force-pushed the deprecate-selection-change-cause branch from 0b4791e to f489feb Compare February 5, 2019 21:25

@HansMuller HansMuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks like a fine improvement over the way things were.

Only non-trivial feedback I have is: shouldn't the RenderEditable methods that have a cause parameter allow cause: null (or another enum value) for changes that were not triggered by an input event?

Comment thread packages/flutter/lib/src/widgets/editable_text.dart Outdated
Comment thread packages/flutter/test/widgets/editable_text_test.dart
tester.state<EditableTextState>(find.byType(EditableText));

expect(state.showToolbar(), false);
await tester.pump();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be pumpAndSettle()? What if the toolbar animates into view?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Visual behavior changes should be test-breaking changes.

// Select something. Doesn't really matter what.
state.renderEditable.selectWordsInRange(
from: const Offset(0, 0),
cause: SelectionChangedCause.tap,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If this parameter needed? Since we're now being honest with the cause parameter, it seems like there should a special value (or just cause == null) that indicates a programmatic change.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm not deprecating SelectionChangedCause (my branch name is a misnomer I guess :D). We're still trying to be honest™️ with the real cause to supply it to users of the existing APIs via the various onSelectionChanged and whatnot. We're just not using it internally anymore, but we're not breaking external users.

In this test, I'm intending for it to mean a single tap.

I'm not making the select*'s cause optional because they still aren't (to keep supporting onSelectionChanged users who might care).

So far, there are no 'fake' selection causes yet to have a new enum value.

@HansMuller HansMuller Feb 6, 2019 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So far, there are no 'fake' selection causes yet to have a new enum value.

What about programmatic changes to the selection that are not triggered by an input event?

@xster xster Feb 6, 2019 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Programmatic changes actually circumvents the whole thing it appears. i.e. nothing is triggered through the RenderEditable directly, no on*Changed is bubbled back through EditableText, there are no SelectionChangedCause involved, no toolbars are ever triggered and no on*Changed is called.

This is in the various @template flutter.widgets.editableText.onChanged docs. This callback does run not when the TextField's text is changed, via the TextField's [controller].

Adding some additional docs to RenderEditable.select* to indicate that it's used for translating UI manipulations to logical selections and if you own the TextEditingController, it's a lot easier to go manipulate that directly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for clarifying that. So the rough summary would be: the RenderEditable selection changing methods are only called in response to user input. That makes sense.

@xster xster Feb 6, 2019 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's a good question though. I only thought about it after you asked. But the new docs should address the apparent redundancy now.

expect(find.text('PASTE'), findsNothing);

controller.text = 'blah';
expect(state.showToolbar(), false);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe pump a frame first, so that 'blah' actually ends up in the textfield?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah, good point, done.

@xster

xster commented Feb 6, 2019

Copy link
Copy Markdown
Member Author

PTAL

@xster

xster commented Feb 6, 2019

Copy link
Copy Markdown
Member Author

I added some more docs to RenderEditable. Take a look to see if it's any helpful.

@HansMuller HansMuller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

// Select something. Doesn't really matter what.
state.renderEditable.selectWordsInRange(
from: const Offset(0, 0),
cause: SelectionChangedCause.tap,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for clarifying that. So the rough summary would be: the RenderEditable selection changing methods are only called in response to user input. That makes sense.

@xster
xster merged commit ee30499 into flutter:master Feb 6, 2019
@xster
xster deleted the deprecate-selection-change-cause branch February 6, 2019 22:39
kangwang1988 pushed a commit to XianyuTech/flutter that referenced this pull request Feb 12, 2019
@legalcodes legalcodes mentioned this pull request Apr 2, 2019
1 of 2 tasks
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

a: text input Entering text in a text field or keyboard related problems c: API break Backwards-incompatible API changes framework flutter/packages/flutter repository. See also f: labels. p: cupertino_ui cupertino_ui package in flutter/packages p: material_ui material_ui package in flutter/packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants