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

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle; import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
import 'package:PiliPlus/common/widgets/flutter/text_intro/text_selection.dart'; import 'package:PiliPlus/common/widgets/flutter/selectable_text/text_selection.dart';
import 'package:flutter/cupertino.dart' import 'package:flutter/cupertino.dart'
hide TextSelectionGestureDetectorBuilder; hide TextSelectionGestureDetectorBuilder;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';

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,
);
}
}

View File

@@ -1083,3 +1083,42 @@ class TapAndHorizontalDragGestureRecognizer
@override @override
String get debugDescription => 'tap and horizontal drag'; String get debugDescription => 'tap and horizontal drag';
} }
/// {@template flutter.gestures.selectionrecognizers.TapAndPanGestureRecognizer}
/// Recognizes taps along with both horizontal and vertical movement.
///
/// This recognizer will accept a drag on any axis, regardless if it has won the
/// arena for the primary pointer being tracked.
///
/// See also:
///
/// * [BaseTapAndDragGestureRecognizer], for the class that provides the main
/// implementation details of this recognizer.
/// * [TapAndHorizontalDragGestureRecognizer], for a similar recognizer that
/// only accepts horizontal drags before it has won the arena for the primary
/// pointer being tracked.
/// * [PanGestureRecognizer], for a similar recognizer that only recognizes
/// movement.
/// {@endtemplate}
class TapAndPanGestureRecognizer extends BaseTapAndDragGestureRecognizer {
/// Create a gesture recognizer for interactions on a plane.
TapAndPanGestureRecognizer({super.debugOwner, super.supportedDevices});
@override
bool _hasSufficientGlobalDistanceToAccept(
PointerDeviceKind pointerDeviceKind,
) {
return true;
// return _globalDistanceMoved.abs() >
// computePanSlop(pointerDeviceKind, gestureSettings);
}
// @override
// Offset _getDeltaForDetails(Offset delta) => delta;
// @override
// double? _getPrimaryValueFromOffset(Offset value) => null;
@override
String get debugDescription => 'tap and pan';
}

View File

@@ -0,0 +1,42 @@
import 'package:PiliPlus/common/widgets/flutter/selectable_text/selectable_text.dart';
import 'package:PiliPlus/common/widgets/flutter/selectable_text/selection_area.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:flutter/material.dart' hide SelectableText, SelectionArea;
Widget selectableText(
String text, {
TextStyle? style,
}) {
if (PlatformUtils.isDesktop) {
return SelectionArea(
child: Text(
style: style,
text,
),
);
}
return SelectableText(
style: style,
text,
scrollPhysics: const NeverScrollableScrollPhysics(),
);
}
Widget selectableRichText(
TextSpan textSpan, {
TextStyle? style,
}) {
if (PlatformUtils.isDesktop) {
return SelectionArea(
child: Text.rich(
style: style,
textSpan,
),
);
}
return SelectableText.rich(
style: style,
textSpan,
scrollPhysics: const NeverScrollableScrollPhysics(),
);
}

View File

@@ -4,10 +4,13 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'package:PiliPlus/common/widgets/flutter/text_intro/tap_and_drag.dart'; import 'package:PiliPlus/common/widgets/flutter/selectable_text/tap_and_drag.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart' import 'package:flutter/gestures.dart'
hide BaseTapAndDragGestureRecognizer, TapAndHorizontalDragGestureRecognizer; hide
BaseTapAndDragGestureRecognizer,
TapAndHorizontalDragGestureRecognizer,
TapAndPanGestureRecognizer;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class CustomTextSelectionGestureDetectorBuilder class CustomTextSelectionGestureDetectorBuilder

View File

@@ -1,22 +0,0 @@
import 'package:PiliPlus/common/widgets/flutter/text_intro/selectable_text.dart';
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:flutter/material.dart' hide SelectableText;
Widget selectableRichText(
TextSpan textSpan, {
TextStyle? style,
}) {
if (PlatformUtils.isDesktop) {
return SelectionArea(
child: Text.rich(
style: style,
textSpan,
),
);
}
return SelectableText.rich(
style: style,
textSpan,
scrollPhysics: const NeverScrollableScrollPhysics(),
);
}

View File

@@ -1,12 +1,13 @@
import 'dart:async'; import 'dart:async';
import 'package:PiliPlus/common/widgets/flutter/selectable_text/selection_area.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart'; import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models_new/live/live_superchat/item.dart'; import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart' hide SelectionArea;
import 'package:get/get.dart'; import 'package:get/get.dart';
class SuperChatCard extends StatefulWidget { class SuperChatCard extends StatefulWidget {

View File

@@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
import 'package:PiliPlus/common/widgets/flutter/selectable_text/selectable_text.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
@@ -17,7 +18,7 @@ import 'package:PiliPlus/utils/extension/theme_ext.dart';
import 'package:PiliPlus/utils/num_utils.dart'; import 'package:PiliPlus/utils/num_utils.dart';
import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart' hide SelectableText;
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';

View File

@@ -1,8 +1,8 @@
import 'package:PiliPlus/common/widgets/flutter/selectable_text/text.dart';
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart'; import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/models_new/video/video_ai_conclusion/model_result.dart'; import 'package:PiliPlus/models_new/video/video_ai_conclusion/model_result.dart';
import 'package:PiliPlus/pages/common/slide/common_slide_page.dart'; import 'package:PiliPlus/pages/common/slide/common_slide_page.dart';
import 'package:PiliPlus/pages/video/controller.dart'; import 'package:PiliPlus/pages/video/controller.dart';
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/selectable_text.dart';
import 'package:PiliPlus/utils/duration_utils.dart'; import 'package:PiliPlus/utils/duration_utils.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/flutter/page/tabs.dart'; import 'package:PiliPlus/common/widgets/flutter/page/tabs.dart';
import 'package:PiliPlus/common/widgets/flutter/selectable_text/text.dart';
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart'; import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart'; import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart';
@@ -8,7 +9,6 @@ import 'package:PiliPlus/models_new/video/video_tag/data.dart';
import 'package:PiliPlus/pages/common/slide/common_slide_page.dart'; import 'package:PiliPlus/pages/common/slide/common_slide_page.dart';
import 'package:PiliPlus/pages/pgc_review/view.dart'; import 'package:PiliPlus/pages/pgc_review/view.dart';
import 'package:PiliPlus/pages/search/widgets/search_text.dart'; import 'package:PiliPlus/pages/search/widgets/search_text.dart';
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/selectable_text.dart';
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart'; import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart' hide TabBarView; import 'package:flutter/material.dart' hide TabBarView;

View File

@@ -1,6 +1,7 @@
import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/common/widgets/flutter/text_intro/text.dart'; import 'package:PiliPlus/common/widgets/flutter/selectable_text/selection_area.dart';
import 'package:PiliPlus/common/widgets/flutter/selectable_text/text.dart';
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart'; import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/pendant_avatar.dart'; import 'package:PiliPlus/common/widgets/pendant_avatar.dart';
@@ -36,7 +37,7 @@ import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/request_utils.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:expandable/expandable.dart'; import 'package:expandable/expandable.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart' hide SelectionArea;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';

View File

@@ -1,21 +0,0 @@
import 'package:PiliPlus/utils/platform_utils.dart';
import 'package:flutter/material.dart';
Widget selectableText(
String text, {
TextStyle? style,
}) {
if (PlatformUtils.isDesktop) {
return SelectionArea(
child: Text(
style: style,
text,
),
);
}
return SelectableText(
style: style,
text,
scrollPhysics: const NeverScrollableScrollPhysics(),
);
}