sync flutter widgets

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-02-12 11:01:35 +08:00
parent fbf7116edf
commit 483953cf56
31 changed files with 804 additions and 646 deletions

View File

@@ -12,7 +12,7 @@ import 'package:flutter/gestures.dart'
BaseTapAndDragGestureRecognizer,
TapAndHorizontalDragGestureRecognizer,
TapAndPanGestureRecognizer;
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' hide SelectableRegion;
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
@@ -277,26 +277,28 @@ class SelectableRegion extends StatefulWidget {
required final VoidCallback onSelectAll,
required final VoidCallback? onShare,
}) {
final bool canCopy =
selectionGeometry.status == SelectionStatus.uncollapsed;
final canCopy = selectionGeometry.status == SelectionStatus.uncollapsed;
final bool canSelectAll = selectionGeometry.hasContent;
final bool platformCanShare = switch (defaultTargetPlatform) {
TargetPlatform.android =>
selectionGeometry.status == SelectionStatus.uncollapsed,
TargetPlatform.macOS ||
TargetPlatform.fuchsia ||
TargetPlatform.linux ||
TargetPlatform.windows => false,
// TODO(bleroux): the share button should be shown on iOS but the share
// functionality requires some changes on the engine side because, on iPad,
// it needs an anchor for the popup.
// See: https://github.com/flutter/flutter/issues/141775.
TargetPlatform.iOS => false,
};
// The share button is not supported on the web.
final bool platformCanShare =
!kIsWeb &&
switch (defaultTargetPlatform) {
TargetPlatform.android =>
selectionGeometry.status == SelectionStatus.uncollapsed,
TargetPlatform.macOS ||
TargetPlatform.fuchsia ||
TargetPlatform.linux ||
TargetPlatform.windows => false,
// TODO(bleroux): the share button should be shown on iOS but the share
// functionality requires some changes on the engine side because, on iPad,
// it needs an anchor for the popup.
// See: https://github.com/flutter/flutter/issues/141775.
TargetPlatform.iOS => false,
};
final bool canShare = onShare != null && platformCanShare;
// On Android, the share button is before the select all button.
final bool showShareBeforeSelectAll =
final showShareBeforeSelectAll =
defaultTargetPlatform == TargetPlatform.android;
// Determine which buttons will appear so that the order and total number is
@@ -410,6 +412,16 @@ class SelectableRegionState extends State<SelectableRegion>
Orientation? _lastOrientation;
SelectedContent? _lastSelectedContent;
/// Whether the native browser context menu is enabled.
// TODO(Renzo-Olivares): Re-enable web context menu for Android
// and iOS when https://github.com/flutter/flutter/issues/177123
// is resolved.
bool get _webContextMenuEnabled =>
kIsWeb &&
BrowserContextMenu.enabled &&
defaultTargetPlatform != TargetPlatform.android &&
defaultTargetPlatform != TargetPlatform.iOS;
/// The [SelectionOverlay] that is currently visible on the screen.
///
/// Can be null if there is no visible [SelectionOverlay].
@@ -513,7 +525,7 @@ class SelectableRegionState extends State<SelectableRegion>
void _handleFocusChanged() {
if (!_focusNode.hasFocus) {
if (kIsWeb) {
if (_webContextMenuEnabled) {
PlatformSelectableRegionContextMenu.detach(_selectionDelegate);
}
if (SchedulerBinding.instance.lifecycleState ==
@@ -531,7 +543,7 @@ class SelectableRegionState extends State<SelectableRegion>
_finalizeSelectableRegionStatus();
}
}
if (kIsWeb) {
if (_webContextMenuEnabled) {
PlatformSelectableRegionContextMenu.attach(_selectionDelegate);
}
}
@@ -596,7 +608,7 @@ class SelectableRegionState extends State<SelectableRegion>
// This method should be used in all instances when details.consecutiveTapCount
// would be used.
int _getEffectiveConsecutiveTapCount(int rawCount) {
int maxConsecutiveTap = 3;
var maxConsecutiveTap = 3;
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
@@ -1177,21 +1189,9 @@ class SelectableRegionState extends State<SelectableRegion>
_selectionOverlay != null &&
(_selectionOverlay!.isDraggingStartHandle ||
_selectionOverlay!.isDraggingEndHandle);
if (widget.selectionControls is! TextSelectionHandleControls) {
if (!draggingHandles) {
_selectionOverlay!.hideMagnifier();
_selectionOverlay!.showToolbar();
}
} else {
if (!draggingHandles) {
_selectionOverlay!.hideMagnifier();
_selectionOverlay!.showToolbar(
context: context,
contextMenuBuilder: (BuildContext context) {
return widget.contextMenuBuilder!(context, this);
},
);
}
if (!draggingHandles) {
_selectionOverlay!.hideMagnifier();
_showToolbar();
}
_finalizeSelection();
_updateSelectedContentIfNeeded();
@@ -1335,13 +1335,13 @@ class SelectableRegionState extends State<SelectableRegion>
final Vector3 globalTransform = _selectable!
.getTransformTo(null)
.getTranslation();
final Offset globalTransformAsOffset = Offset(
final globalTransformAsOffset = Offset(
globalTransform.x,
globalTransform.y,
);
final Offset globalSelectionPointPosition =
selectionPoint.localPosition + globalTransformAsOffset;
final Rect caretRect = Rect.fromLTWH(
final caretRect = Rect.fromLTWH(
globalSelectionPointPosition.dx,
globalSelectionPointPosition.dy - selectionPoint.lineHeight,
0,
@@ -1439,7 +1439,7 @@ class SelectableRegionState extends State<SelectableRegion>
// functionality depending on the browser (such as translate). Due to this,
// we should not show a Flutter toolbar for the editable text elements
// unless the browser's context menu is explicitly disabled.
if (kIsWeb && BrowserContextMenu.enabled) {
if (_webContextMenuEnabled) {
return false;
}
@@ -1448,6 +1448,9 @@ class SelectableRegionState extends State<SelectableRegion>
}
_selectionOverlay!.toolbarLocation = location;
// TODO(Renzo-Olivares): Remove the logic below that does a runtimeType
// check for TextSelectionHandleControls when TextSelectionHandleControls
// is fully removed, see: https://github.com/flutter/flutter/pull/124262.
if (widget.selectionControls is! TextSelectionHandleControls) {
_selectionOverlay!.showToolbar();
return true;
@@ -1683,7 +1686,7 @@ class SelectableRegionState extends State<SelectableRegion>
/// for the default context menu buttons.
TextSelectionToolbarAnchors get contextMenuAnchors {
if (_lastSecondaryTapDownPosition != null) {
final TextSelectionToolbarAnchors anchors = TextSelectionToolbarAnchors(
final anchors = TextSelectionToolbarAnchors(
primaryAnchor: _lastSecondaryTapDownPosition!,
);
// Clear the state of _lastSecondaryTapDownPosition after use since a user may
@@ -1691,7 +1694,7 @@ class SelectableRegionState extends State<SelectableRegion>
_lastSecondaryTapDownPosition = null;
return anchors;
}
final RenderBox renderBox = context.findRenderObject()! as RenderBox;
final renderBox = context.findRenderObject()! as RenderBox;
return TextSelectionToolbarAnchors.fromSelection(
renderBox: renderBox,
startGlyphHeight: startGlyphHeight,
@@ -1843,7 +1846,7 @@ class SelectableRegionState extends State<SelectableRegion>
}
List<ContextMenuButtonItem> get _textProcessingActionButtonItems {
final List<ContextMenuButtonItem> buttonItems = <ContextMenuButtonItem>[];
final buttonItems = <ContextMenuButtonItem>[];
final SelectedContent? data = _selectable?.getSelectedContent();
if (data == null) {
return buttonItems;
@@ -2048,7 +2051,7 @@ class SelectableRegionState extends State<SelectableRegion>
child: widget.child,
),
);
if (kIsWeb) {
if (_webContextMenuEnabled) {
result = PlatformSelectableRegionContextMenu(child: result);
}
return CompositedTransformTarget(