opt gesture

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-01-28 18:51:58 +08:00
parent bce73d9f16
commit d1713504a0
13 changed files with 2499 additions and 52 deletions

View File

@@ -0,0 +1,147 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:PiliPlus/common/widgets/flutter/selectable_text/selectable_region.dart';
import 'package:flutter/cupertino.dart'
hide
SelectableRegion,
SelectableRegionState,
SelectableRegionContextMenuBuilder;
import 'package:flutter/material.dart'
hide
SelectableRegion,
SelectableRegionState,
SelectableRegionContextMenuBuilder;
import 'package:flutter/rendering.dart';
/// A widget that introduces an area for user selections with adaptive selection
/// controls.
///
/// This widget creates a [SelectableRegion] with platform-adaptive selection
/// controls.
///
/// Flutter widgets are not selectable by default. To enable selection for
/// a specific screen, consider wrapping the body of the [Route] with a
/// [SelectionArea].
///
/// The [SelectionArea] widget must have a [Localizations] ancestor that
/// contains a [MaterialLocalizations] delegate; using the [MaterialApp] widget
/// ensures that such an ancestor is present.
///
/// {@tool dartpad}
/// This example shows how to make a screen selectable.
///
/// ** See code in examples/api/lib/material/selection_area/selection_area.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [SelectableRegion], which provides an overview of the selection system.
/// * [SelectableText], which enables selection on a single run of text.
/// * [SelectionListener], which enables accessing the [SelectionDetails] of
/// the selectable subtree it wraps.
class SelectionArea extends StatefulWidget {
/// Creates a [SelectionArea].
///
/// If [selectionControls] is null, a platform specific one is used.
const SelectionArea({
super.key,
this.focusNode,
this.selectionControls,
this.contextMenuBuilder = _defaultContextMenuBuilder,
this.magnifierConfiguration,
this.onSelectionChanged,
required this.child,
});
/// 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. To suppress the
/// magnifier, consider passing [TextMagnifierConfiguration.disabled].
///
/// {@macro flutter.widgets.magnifier.intro}
final TextMagnifierConfiguration? magnifierConfiguration;
/// {@macro flutter.widgets.Focus.focusNode}
final FocusNode? focusNode;
/// The delegate to build the selection handles and toolbar.
///
/// If it is null, the platform specific selection control is used.
final TextSelectionControls? selectionControls;
/// {@macro flutter.widgets.EditableText.contextMenuBuilder}
///
/// If not provided, will build a default menu based on the ambient
/// [ThemeData.platform].
///
/// {@tool dartpad}
/// This example shows how to build a custom context menu for any selected
/// content in a SelectionArea.
///
/// ** See code in examples/api/lib/material/context_menu/selectable_region_toolbar_builder.0.dart **
/// {@end-tool}
///
/// See also:
///
/// * [AdaptiveTextSelectionToolbar], which is built by default.
final SelectableRegionContextMenuBuilder? contextMenuBuilder;
/// Called when the selected content changes.
final ValueChanged<SelectedContent?>? onSelectionChanged;
/// The child widget this selection area applies to.
///
/// {@macro flutter.widgets.ProxyWidget.child}
final Widget child;
static Widget _defaultContextMenuBuilder(
BuildContext context,
SelectableRegionState selectableRegionState,
) => AdaptiveTextSelectionToolbar.buttonItems(
buttonItems: selectableRegionState.contextMenuButtonItems,
anchors: selectableRegionState.contextMenuAnchors,
);
@override
State<StatefulWidget> createState() => SelectionAreaState();
}
/// State for a [SelectionArea].
class SelectionAreaState extends State<SelectionArea> {
final GlobalKey<SelectableRegionState> _selectableRegionKey =
GlobalKey<SelectableRegionState>();
/// The [State] of the [SelectableRegion] for which this [SelectionArea] wraps.
SelectableRegionState get selectableRegion =>
_selectableRegionKey.currentState!;
@protected
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
final TextSelectionControls controls =
widget.selectionControls ??
switch (Theme.of(context).platform) {
TargetPlatform.android ||
TargetPlatform.fuchsia => materialTextSelectionHandleControls,
TargetPlatform.linux ||
TargetPlatform.windows => desktopTextSelectionHandleControls,
TargetPlatform.iOS => cupertinoTextSelectionHandleControls,
TargetPlatform.macOS => cupertinoDesktopTextSelectionHandleControls,
};
return SelectableRegion(
key: _selectableRegionKey,
selectionControls: controls,
focusNode: widget.focusNode,
contextMenuBuilder: widget.contextMenuBuilder,
magnifierConfiguration:
widget.magnifierConfiguration ??
TextMagnifier.adaptiveMagnifierConfiguration,
onSelectionChanged: widget.onSelectionChanged,
child: widget.child,
);
}
}