Skip to content

Conversation

justinmc
Copy link
Contributor

@justinmc justinmc commented Jul 6, 2022

Design doc

This PR makes it easy to work with context menus, the menu that shows up on right click, longpress, or when working with text selection.

Screenshot from 2022-07-26 16-45-11

tl;dr

  • Widgets that have context menus, like TextField, now have a contextMenuBuilder parameter that allows any widget to be built as the context menu.
  • The context menu can be controlled, and even displayed in new places, using the new global ContextMenuController.
  • Several new widgets have been added to make it easy to compose context menus, like AdaptiveTextSelectionToolbar.
  • The old way to build context menus in TextSelectionControls has been deprecated.

More details below.

Deprecations

The old way of building a toolbar still works exactly as before, but it's deprecated. That's toolbarOptions and the toolbar-related parts of TextSelectionControls.

  • toolbarOptions (in EditableText et. al.)
  • TextSelectionControls.buildToolbar
  • TextSelectionControls.canCopy (and other toolbar operations)
  • TextSelectionDelegate.canCopy (and other toolbar operations)
  • TextSelectionControls.handleCopy etc.

All of these have been replace by contextMenuBuilder and a suite of widgets that allow customizing the default text selection toolbar. Direct equivalents of canCopy etc. are now at TextSelectionToolbarButtonItemsBuilder.canCopy etc.

New stuff immediately deprecated

  • TextSelectionHandleControls
    • Since I have deprecated the parts of TextSelectionControls related to the toolbar, I needed a way to distinguish old TextSelectionControls that still desire to customize the toolbar. To do that, I created a new mixin TextSelectionHandleControls on TextSelectionControls for new usages that don't care about the toolbar. I immediately deprecated TextSelectionHandleControls. When the deprecation is removed, we can remove that class and all TextSelectionControls will only relate to handles and not toolbars.
  • buttonItemsForToolbarOptions
    • For the same reason as the previous point, this method was created and immediately deprecated. It translates between the old toolbarOptions system and the new buttonItems.

User-side changes

  • Mac no longer shows a "Select all" button. I think we missed this before and native Mac shouldn't show one. I don't ever see one natively, except in the browser.
  • The text selection menu is now clamped to within the field.

API changes

  • The desktop text selection toolbar and buttons classes that were previously private have been made public.
    • DesktopTextSelectionToolbar, CupertinoDesktopTextSelectionToolbar, CupertinoDesktopTextSelectionToolbarButton, CupertinoDesktopTextSelectionToolbarButton
    • This is so that we can give users a way to build the default toolbar for the platform, via AdaptiveTextSelectionToolbar and CupertinoAdaptiveTextSelectionToolbar.
  • EditableTextState.clipboardStatus was made public.
    • This was done to allow EditableTextContextMenuButtonItemsBuilder to build the context menu buttons based on the same clipboard status that the EditableText has.

Open questions

  • ContextMenuButtonItem
    • I'm not using @gspencergoog's MenuItem class as it doesn't seem relevant here. Am I wrong or is there anything else to do to make this easier to mesh with cascading menus?
    • Also, @Renzo-Olivares had the idea to include a child parameter to pass a Widget to the button instead of just a text label hardcoded to a Text. A good use case would be for an icon button.
  • ContextMenuController.isShown only knows if any menu is shown, not a specific one.
    • Because ContextMenuController is global, show/hide can be called at any time from anywhere. If I call show, I have no guarantee that my menu is visible or not in the future. Will that be important? I could add an "onHidden" callback or something.

Related

This PR was reopened from #104647 due to incorrectly failing customer tests, losing ~91 commits of history.

Fixes #98272
Fixes #73574
Fixes #90563
Fixes #79796
Fixes #22210
Fixes #49996
Partial fix for #74255
After deprecations are removed, will fix: #111213

@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 Jul 6, 2022
@justinmc justinmc mentioned this pull request Jul 8, 2022
@justinmc justinmc force-pushed the context-menu-anywhere-2 branch from 232f2fa to 92abf41 Compare July 8, 2022 18:20
@justinmc justinmc force-pushed the context-menu-anywhere-2 branch from 92abf41 to 6d44ca1 Compare July 8, 2022 18:30
@justinmc justinmc mentioned this pull request Jul 8, 2022
@justinmc justinmc force-pushed the context-menu-anywhere-2 branch from 82750ca to dc85106 Compare July 11, 2022 18:46
@justinmc justinmc changed the title ContextMenu Context Menus Oct 28, 2022
@justinmc justinmc merged commit 0b451b6 into flutter:master Oct 28, 2022
@justinmc justinmc deleted the context-menu-anywhere-2 branch October 28, 2022 19:40
@justinmc justinmc self-assigned this Oct 28, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 29, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Oct 29, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Oct 29, 2022
@BernardinD
Copy link

Hi, thx for introducing this feature. It's been very helpful.

I'm wondering if the "undo" will become available for android. I had assumed all the default menu options for the platform always show up for each text field type but "undo" isn't showing up for TextFormField so I'm in need of some guidance.

@justinmc
Copy link
Contributor Author

@BernardinD I'm glad this has been useful for you!

I think this is the relevant issue: #107578

Would you be able to leave a comment over there with details about when the "undo" button should show up? Looking at that issue, it seems that I missed it when I investigated which buttons are missing for Android. Currently, only Cut, Copy, Paste, and Select all are built-in, but now that this PR has been merged, it should be much easier to add the missing buttons.

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 c: contributor-productivity Team-specific productivity, code health, technical debt. d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. will affect goldens Changes to golden files
Projects
None yet
10 participants