Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
9fccb32a
Unverified
Commit
9fccb32a
authored
Feb 07, 2024
by
Ian Hickson
Committed by
GitHub
Feb 07, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Various improvements to text-editing-related documentation. (#142561)
parent
4becae25
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
126 additions
and
115 deletions
+126
-115
text_field.dart
packages/flutter/lib/src/cupertino/text_field.dart
+6
-7
selectable_text.dart
packages/flutter/lib/src/material/selectable_text.dart
+5
-7
selection_area.dart
packages/flutter/lib/src/material/selection_area.dart
+6
-7
text_field.dart
packages/flutter/lib/src/material/text_field.dart
+5
-7
editable_text.dart
packages/flutter/lib/src/widgets/editable_text.dart
+23
-9
magnifier.dart
packages/flutter/lib/src/widgets/magnifier.dart
+55
-58
selectable_region.dart
packages/flutter/lib/src/widgets/selectable_region.dart
+5
-4
text_selection.dart
packages/flutter/lib/src/widgets/text_selection.dart
+13
-13
text_selection_toolbar_layout_delegate.dart
...b/src/widgets/text_selection_toolbar_layout_delegate.dart
+8
-3
No files found.
packages/flutter/lib/src/cupertino/text_field.dart
View file @
9fccb32a
...
...
@@ -763,15 +763,14 @@ class CupertinoTextField extends StatefulWidget {
);
}
///
{@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
///
Configuration for the text field magnifier.
///
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details}
/// By default (when this property is set to null), a [CupertinoTextMagnifier]
/// is used on mobile platforms, and nothing on desktop platforms. To suppress
/// the magnifier on all platforms, consider passing
/// [TextMagnifierConfiguration.disabled] explicitly.
///
/// By default, builds a [CupertinoTextMagnifier] on iOS and Android nothing on all other
/// platforms. If it is desired to suppress the magnifier, consider passing
/// [TextMagnifierConfiguration.disabled].
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@tool dartpad}
/// This sample demonstrates how to customize the magnifier that this text field uses.
...
...
packages/flutter/lib/src/material/selectable_text.dart
View file @
9fccb32a
...
...
@@ -502,15 +502,13 @@ class SelectableText extends StatefulWidget {
);
}
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
///
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details}
/// The configuration for the magnifier used when the text is selected.
///
/// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier]
/// on Android, and builds nothing on all other platforms. If it is desired to
/// suppress the magnifier, consider passing [TextMagnifierConfiguration.disabled].
/// on Android, and builds nothing on all other platforms. To suppress the
/// magnifier, consider passing [TextMagnifierConfiguration.disabled].
///
/// {@macro flutter.widgets.magnifier.intro}
final
TextMagnifierConfiguration
?
magnifierConfiguration
;
@override
...
...
packages/flutter/lib/src/material/selection_area.dart
View file @
9fccb32a
...
...
@@ -33,6 +33,7 @@ import 'theme.dart';
/// {@end-tool}
///
/// See also:
///
/// * [SelectableRegion], which provides an overview of the selection system.
class
SelectionArea
extends
StatefulWidget
{
/// Creates a [SelectionArea].
...
...
@@ -48,15 +49,13 @@ class SelectionArea extends StatefulWidget {
required
this
.
child
,
});
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
///
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details}
/// The configuration for the magnifier in the selection region.
///
/// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier]
/// on Android, and builds nothing on all other platforms. If it is desired to
/// suppress the magnifier, consider passing [TextMagnifierConfiguration.disabled].
/// on Android, and builds nothing on all other platforms. To suppress the
/// magnifier, consider passing [TextMagnifierConfiguration.disabled].
///
/// {@macro flutter.widgets.magnifier.intro}
final
TextMagnifierConfiguration
?
magnifierConfiguration
;
/// {@macro flutter.widgets.Focus.focusNode}
...
...
packages/flutter/lib/src/material/text_field.dart
View file @
9fccb32a
...
...
@@ -349,15 +349,13 @@ class TextField extends StatefulWidget {
keyboardType
=
keyboardType
??
(
maxLines
==
1
?
TextInputType
.
text
:
TextInputType
.
multiline
),
enableInteractiveSelection
=
enableInteractiveSelection
??
(!
readOnly
||
!
obscureText
);
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
///
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details}
/// The configuration for the magnifier of this text field.
///
/// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier]
/// on Android, and builds nothing on all other platforms. If it is desired to
/// suppress the magnifier, consider passing [TextMagnifierConfiguration.disabled].
/// on Android, and builds nothing on all other platforms. To suppress the
/// magnifier, consider passing [TextMagnifierConfiguration.disabled].
///
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@tool dartpad}
/// This sample demonstrates how to customize the magnifier that this text field uses.
...
...
packages/flutter/lib/src/widgets/editable_text.dart
View file @
9fccb32a
...
...
@@ -1799,11 +1799,28 @@ class EditableText extends StatefulWidget {
/// {@template flutter.widgets.EditableText.contextMenuBuilder}
/// Builds the text selection toolbar when requested by the user.
///
/// `primaryAnchor` is the desired anchor position for the context menu, while
/// `secondaryAnchor` is the fallback location if the menu doesn't fit.
/// The context menu is built when [EditableTextState.showToolbar] is called,
/// typically by one of the callbacks installed by the widget created by
/// [TextSelectionGestureDetectorBuilder.buildGestureDetector]. The widget
/// returned by [contextMenuBuilder] is passed to a [ContextMenuController].
///
/// `buttonItems` represents the buttons that would be built by default for
/// this widget.
/// If no callback is provided, no context menu will be shown.
///
/// The [EditableTextContextMenuBuilder] signature used by the
/// [contextMenuBuilder] callback has two parameters, the [BuildContext] of
/// the [EditableText] and the [EditableTextState] of the [EditableText].
///
/// The [EditableTextState] has two properties that are especially useful when
/// building the widgets for the context menu:
///
/// * [EditableTextState.contextMenuAnchors] specifies the desired anchor
/// position for the context menu.
///
/// * [EditableTextState.contextMenuButtonItems] represents the buttons that
/// should typically be built for this widget (e.g. cut, copy, paste).
///
/// The [TextSelectionToolbarLayoutDelegate] class may be particularly useful
/// in honoring the preferred anchor positions.
///
/// For backwards compatibility, when [selectionControls] is set to an object
/// that does not mix in [TextSelectionHandleControls], [contextMenuBuilder]
...
...
@@ -1834,8 +1851,6 @@ class EditableText extends StatefulWidget {
/// * [BrowserContextMenu], which allows the browser's context menu on web
/// to be disabled and Flutter-rendered context menus to appear.
/// {@endtemplate}
///
/// If not provided, no context menu will be shown.
final
EditableTextContextMenuBuilder
?
contextMenuBuilder
;
/// {@template flutter.widgets.EditableText.spellCheckConfiguration}
...
...
@@ -1852,11 +1867,10 @@ class EditableText extends StatefulWidget {
/// {@endtemplate}
final
SpellCheckConfiguration
?
spellCheckConfiguration
;
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
/// The configuration for the magnifier to use with selections in this text
/// field.
///
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.details}
final
TextMagnifierConfiguration
magnifierConfiguration
;
bool
get
_userSelectionEnabled
=>
enableInteractiveSelection
&&
(!
readOnly
||
!
obscureText
);
...
...
packages/flutter/lib/src/widgets/magnifier.dart
View file @
9fccb32a
...
...
@@ -15,19 +15,17 @@ import 'inherited_theme.dart';
import
'navigator.dart'
;
import
'overlay.dart'
;
/// {@template flutter.widgets.magnifier.MagnifierBuilder}
/// Signature for a builder that builds a [Widget] with a [MagnifierController].
///
/// Consuming [MagnifierController] or [ValueNotifier]<[MagnifierInfo]> is not
/// required, although if a Widget intends to have entry or exit animations, it should take
/// [MagnifierController] and provide it an [AnimationController], so that [MagnifierController]
/// can wait before removing it from the overlay.
/// {@endtemplate}
/// The builder is called exactly once per magnifier.
///
/// See also:
/// If the `controller` parameter's [MagnifierController.animationController]
/// field is set (by the builder) to an [AnimationController], the
/// [MagnifierController] will drive the animation during entry and exit.
///
/// - [MagnifierInfo], the data class that updates the
/// magnifier.
/// The `magnifierInfo` parameter is updated with new [MagnifierInfo] instances
/// during the lifetime of the built magnifier, e.g. as the user moves their
/// finger around the text field.
typedef
MagnifierBuilder
=
Widget
?
Function
(
BuildContext
context
,
MagnifierController
controller
,
...
...
@@ -57,9 +55,9 @@ class MagnifierInfo {
/// The offset of the gesture position that the magnifier should be shown at.
final
Offset
globalGesturePosition
;
/// The rect of the current line the magnifier should be shown at,
///
without taking into account any padding of the field; only the position
///
of the
first and last character.
/// The rect of the current line the magnifier should be shown at,
without
///
taking into account any padding of the field; only the position of the
/// first and last character.
final
Rect
currentLineBoundaries
;
/// The rect of the handle that the magnifier should follow.
...
...
@@ -89,48 +87,45 @@ class MagnifierInfo {
);
}
/// {@template flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
/// A configuration object for a magnifier.
/// {@endtemplate}
/// A configuration object for a magnifier (e.g. in a text field).
///
/// {@macro flutter.widgets.magnifier.intro}
///
/// {@template flutter.widgets.magnifier.TextMagnifierConfiguration.details}
/// In general, most features of the magnifier can be configured through
/// [MagnifierBuilder]. [TextMagnifierConfiguration] is used to configure
/// the magnifier's behavior through the [SelectionOverlay].
/// {@endtemplate}
/// In general, most features of the magnifier can be configured by controlling
/// the widgets built by the [magnifierBuilder].
class
TextMagnifierConfiguration
{
/// Constructs a [TextMagnifierConfiguration] from parts.
///
/// If [magnifierBuilder] is null, a default [MagnifierBuilder] will be used
/// that
never builds
a magnifier.
/// that
does not build
a magnifier.
const
TextMagnifierConfiguration
({
MagnifierBuilder
?
magnifierBuilder
,
this
.
shouldDisplayHandlesInMagnifier
=
true
this
.
shouldDisplayHandlesInMagnifier
=
true
,
})
:
_magnifierBuilder
=
magnifierBuilder
;
/// The passed in [MagnifierBuilder].
///
/// This is nullable because [disabled] needs to be static const,
/// so that it can be used as a default parameter. If left null,
/// the [magnifierBuilder] getter will be a function that always returns
/// null.
/// The builder callback that creates the widget that renders the magnifier.
MagnifierBuilder
get
magnifierBuilder
=>
_magnifierBuilder
??
_none
;
final
MagnifierBuilder
?
_magnifierBuilder
;
/// {@macro flutter.widgets.magnifier.MagnifierBuilder}
MagnifierBuilder
get
magnifierBuilder
=>
_magnifierBuilder
??
(
_
,
__
,
___
)
=>
null
;
static
Widget
?
_none
(
BuildContext
context
,
MagnifierController
controller
,
ValueNotifier
<
MagnifierInfo
>
magnifierInfo
,
)
=>
null
;
/// Determines whether a magnifier should show the text editing handles or not.
/// Whether a magnifier should show the text editing handles or not.
///
/// This flag is used by [SelectionOverlay.showMagnifier] to control the order
/// of layers in the rendering; specifically, whether to place the layer
/// containing the handles above or below the layer containing the magnifier
/// in the [Overlay].
final
bool
shouldDisplayHandlesInMagnifier
;
/// A constant for a [TextMagnifierConfiguration] that is disabled.
///
/// In particular, this [TextMagnifierConfiguration] is considered disabled
/// because it never builds anything, regardless of platform.
/// A constant for a [TextMagnifierConfiguration] that is disabled, meaning it
/// never builds anything, regardless of platform.
static
const
TextMagnifierConfiguration
disabled
=
TextMagnifierConfiguration
();
}
/// A controller for a magnifier.
///
/// [MagnifierController]'s main benefit over holding a raw [OverlayEntry] is that
/// [MagnifierController] will handle logic around waiting for a magnifier to animate in or out.
///
...
...
@@ -156,11 +151,11 @@ class MagnifierController {
/// The magnifier's [OverlayEntry], if currently in the overlay.
///
/// This is
public in case other overlay entries need to be positioned
///
above or below this [overlayEntry]. Anything in the paint order after
///
the [RawMagnifier] will not be displayed in the magnifier; this means that if it
///
is desired for an overlay entry to be displayed in the magnifier,
/// it _must_ be positioned below the magnifier.
/// This is
exposed so that other overlay entries can be positioned above or
///
below this [overlayEntry]. Anything in the paint order after the
///
[RawMagnifier] in this [OverlayEntry] will not be displayed in the
///
magnifier; if it is desired for an overlay entry to be displayed in the
///
magnifier,
it _must_ be positioned below the magnifier.
///
/// {@tool snippet}
/// ```dart
...
...
@@ -198,20 +193,22 @@ class MagnifierController {
/// ```
/// {@end-tool}
///
/// A null check on [overlayEntry] will not suffice to check if a magnifier is in the
/// overlay or not; instead, you should check [shown]. This is because it is possible,
/// such as in cases where [hide] was called with `removeFromOverlay` false, that the magnifier
/// is not shown, but the entry is not null.
/// To check if a magnifier is in the overlay, use [shown]. The [overlayEntry]
/// field may be non-null even when the magnifier is not visible.
OverlayEntry
?
get
overlayEntry
=>
_overlayEntry
;
OverlayEntry
?
_overlayEntry
;
/// If the magnifier is shown or not.
/// Whether the magnifier is currently being shown.
///
/// This is false when nothing is in the overlay, when the
/// [animationController] is in the [AnimationStatus.dismissed] state, or when
/// the [animationController] is animating out (i.e. in the
/// [AnimationStatus.reverse] state).
///
/// [shown] is:
/// - false when nothing is in the overlay.
/// - false when [animationController] is [AnimationStatus.dismissed].
/// - false when [animationController] is animating out.
/// and true in all other circumstances.
/// It is true in the opposite cases, i.e. when the overlay is not empty, and
/// either the [animationController] is null, in the
/// [AnimationStatus.completed] state, or in the [AnimationStatus.forward]
/// state.
bool
get
shown
{
if
(
overlayEntry
==
null
)
{
return
false
;
...
...
@@ -225,17 +222,17 @@ class MagnifierController {
return
true
;
}
///
Shows the [RawMagnifier] that this controller controls
.
///
Displays the magnifier
.
///
/// Returns a future that completes when the magnifier is fully shown, i.e. done
/// with its entry animation.
///
/// To control what overlays are shown in the magnifier, u
tilize [below]
. See
/// [overlayEntry] for more details on how to utilize
[below]
.
/// To control what overlays are shown in the magnifier, u
se `below`
. See
/// [overlayEntry] for more details on how to utilize
`below`
.
///
/// If the magnifier already exists (i.e. [overlayEntry] != null), then [show]
will
///
override the old overlay and not play an exit animation. Consider awaiting [hide]
///
first, to guarantee
/// If the magnifier already exists (i.e. [overlayEntry] != null), then [show]
///
will replace the old overlay without playing an exit animation. Consider
///
awaiting [hide] first, to animate from the old magnifier to the new one.
Future
<
void
>
show
({
required
BuildContext
context
,
required
WidgetBuilder
builder
,
...
...
packages/flutter/lib/src/widgets/selectable_region.dart
View file @
9fccb32a
...
...
@@ -192,6 +192,7 @@ const double _kSelectableVerticalComparingThreshold = 3.0;
/// ```
///
/// See also:
///
/// * [SelectionArea], which creates a [SelectableRegion] with
/// platform-adaptive selection controls.
/// * [SelectionHandler], which contains APIs to handle selection events from the
...
...
@@ -216,13 +217,13 @@ class SelectableRegion extends StatefulWidget {
this
.
onSelectionChanged
,
});
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
///
/// {@macro flutter.widgets.magnifier.intro}
/// The configuration for the magnifier used with selections in this region.
///
/// By default, [SelectableRegion]'s [TextMagnifierConfiguration] is disabled.
/// For a version of [SelectableRegion] that adapts automatically to the
/// current platform, consider [SelectionArea].
///
/// {@macro flutter.widgets.magnifier.
TextMagnifierConfiguration.details
}
/// {@macro flutter.widgets.magnifier.
intro
}
final
TextMagnifierConfiguration
magnifierConfiguration
;
/// {@macro flutter.widgets.Focus.focusNode}
...
...
packages/flutter/lib/src/widgets/text_selection.dart
View file @
9fccb32a
...
...
@@ -989,19 +989,18 @@ class SelectionOverlay {
final
ValueNotifier
<
MagnifierInfo
>
_magnifierInfo
=
ValueNotifier
<
MagnifierInfo
>(
MagnifierInfo
.
empty
);
/// [MagnifierController.show] and [MagnifierController.hide] should not be called directly, except
/// from inside [showMagnifier] and [hideMagnifier]. If it is desired to show or hide the magnifier,
/// call [showMagnifier] or [hideMagnifier]. This is because the magnifier needs to orchestrate
/// with other properties in [SelectionOverlay].
// [MagnifierController.show] and [MagnifierController.hide] should not be
// called directly, except from inside [showMagnifier] and [hideMagnifier]. If
// it is desired to show or hide the magnifier, call [showMagnifier] or
// [hideMagnifier]. This is because the magnifier needs to orchestrate with
// other properties in [SelectionOverlay].
final
MagnifierController
_magnifierController
=
MagnifierController
();
/// {@macro flutter.widgets.magnifier.TextMagnifierConfiguration.intro}
///
/// {@macro flutter.widgets.magnifier.intro}
/// The configuration for the magnifier.
///
/// By default, [SelectionOverlay]'s [TextMagnifierConfiguration] is disabled.
///
/// {@macro flutter.widgets.magnifier.
TextMagnifierConfiguration.details
}
/// {@macro flutter.widgets.magnifier.
intro
}
final
TextMagnifierConfiguration
magnifierConfiguration
;
/// {@template flutter.widgets.SelectionOverlay.toolbarIsVisible}
...
...
@@ -1047,11 +1046,12 @@ class SelectionOverlay {
}
_magnifierController
.
show
(
context:
context
,
below:
magnifierConfiguration
.
shouldDisplayHandlesInMagnifier
?
null
:
_handles
?.
start
,
builder:
(
_
)
=>
builtMagnifier
);
context:
context
,
below:
magnifierConfiguration
.
shouldDisplayHandlesInMagnifier
?
null
:
_handles
?.
start
,
builder:
(
_
)
=>
builtMagnifier
,
);
}
/// {@template flutter.widgets.SelectionOverlay.hideMagnifier}
...
...
packages/flutter/lib/src/widgets/text_selection_toolbar_layout_delegate.dart
View file @
9fccb32a
...
...
@@ -6,9 +6,12 @@ import 'dart:math' as math;
import
'package:flutter/rendering.dart'
;
/// Positions the toolbar above [anchorAbove] if it fits, or otherwise below
/// A [SingleChildLayoutDelegate] for use with [CustomSingleChildLayout] that
/// positions its child above [anchorAbove] if it fits, or otherwise below
/// [anchorBelow].
///
/// Primarily intended for use with toolbars or context menus.
///
/// See also:
///
/// * [TextSelectionToolbar], which uses this to position itself.
...
...
@@ -16,6 +19,8 @@ import 'package:flutter/rendering.dart';
/// itself.
class
TextSelectionToolbarLayoutDelegate
extends
SingleChildLayoutDelegate
{
/// Creates an instance of TextSelectionToolbarLayoutDelegate.
///
/// The [fitsAbove] parameter is optional; if omitted, it will be calculated.
TextSelectionToolbarLayoutDelegate
({
required
this
.
anchorAbove
,
required
this
.
anchorBelow
,
...
...
@@ -41,8 +46,8 @@ class TextSelectionToolbarLayoutDelegate extends SingleChildLayoutDelegate {
/// If not provided, it will be calculated.
final
bool
?
fitsAbove
;
/// Return the
value that centers width as closely as possible to position
///
while fitting inside of min and max
.
/// Return the
distance from zero that centers `width` as closely as possible
///
to `position` from zero while fitting between zero and `max`
.
static
double
centerOn
(
double
position
,
double
width
,
double
max
)
{
// If it overflows on the left, put it as far left as possible.
if
(
position
-
width
/
2.0
<
0.0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment