From a59085cdb3b0150812e691ee1273489ce87f4e5c Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 10 Jul 2026 15:38:47 -0700 Subject: [PATCH 1/2] Impl --- .../context_menu_controller.0.dart | 184 --------- .../editable_text_toolbar_builder.0.dart | 98 ----- .../editable_text_toolbar_builder.1.dart | 115 ------ .../platform_menu_bar.0.dart | 140 ------- .../selectable_region.0.dart | 377 ------------------ .../selection_container.0.dart | 137 ------- .../selection_container_disabled.0.dart | 34 -- .../context_menu_controller.0_test.dart | 66 --- .../editable_text_toolbar_builder.0_test.dart | 61 --- .../editable_text_toolbar_builder.1_test.dart | 98 ----- .../platform_menu_bar.0_test.dart | 130 ------ .../selectable_region.0_test.dart | 59 --- .../selection_container.0_test.dart | 67 ---- .../selection_container_disabled.0_test.dart | 88 ---- 14 files changed, 1654 deletions(-) delete mode 100644 packages/material_ui/example/lib/context_menu/context_menu_controller.0.dart delete mode 100644 packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.0.dart delete mode 100644 packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.1.dart delete mode 100644 packages/material_ui/example/lib/platform_menu_bar/platform_menu_bar.0.dart delete mode 100644 packages/material_ui/example/lib/selectable_region/selectable_region.0.dart delete mode 100644 packages/material_ui/example/lib/selection_container/selection_container.0.dart delete mode 100644 packages/material_ui/example/lib/selection_container/selection_container_disabled.0.dart delete mode 100644 packages/material_ui/example/test/context_menu/context_menu_controller.0_test.dart delete mode 100644 packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.0_test.dart delete mode 100644 packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.1_test.dart delete mode 100644 packages/material_ui/example/test/platform_menu_bar/platform_menu_bar.0_test.dart delete mode 100644 packages/material_ui/example/test/selectable_region/selectable_region.0_test.dart delete mode 100644 packages/material_ui/example/test/selection_container/selection_container.0_test.dart delete mode 100644 packages/material_ui/example/test/selection_container/selection_container_disabled.0_test.dart diff --git a/packages/material_ui/example/lib/context_menu/context_menu_controller.0.dart b/packages/material_ui/example/lib/context_menu/context_menu_controller.0.dart deleted file mode 100644 index 99257c851d7a..000000000000 --- a/packages/material_ui/example/lib/context_menu/context_menu_controller.0.dart +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This sample demonstrates allowing a context menu to be shown in a widget -// subtree in response to user gestures. - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:material_ui/material_ui.dart'; - -void main() => runApp(const ContextMenuControllerExampleApp()); - -/// A builder that includes an Offset to draw the context menu at. -typedef ContextMenuBuilder = - Widget Function(BuildContext context, Offset offset); - -class ContextMenuControllerExampleApp extends StatefulWidget { - const ContextMenuControllerExampleApp({super.key}); - - @override - State createState() => - _ContextMenuControllerExampleAppState(); -} - -class _ContextMenuControllerExampleAppState - extends State { - void _showDialog(BuildContext context) { - Navigator.of(context).push( - DialogRoute( - context: context, - builder: (BuildContext context) => - const AlertDialog(title: Text('You clicked print!')), - ), - ); - } - - @override - void initState() { - super.initState(); - // On web, disable the browser's context menu since this example uses a custom - // Flutter-rendered context menu. - if (kIsWeb) { - BrowserContextMenu.disableContextMenu(); - } - } - - @override - void dispose() { - if (kIsWeb) { - BrowserContextMenu.enableContextMenu(); - } - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar(title: const Text('Context menu outside of text')), - body: _ContextMenuRegion( - contextMenuBuilder: (BuildContext context, Offset offset) { - // The custom context menu will look like the default context menu - // on the current platform with a single 'Print' button. - return AdaptiveTextSelectionToolbar.buttonItems( - anchors: TextSelectionToolbarAnchors(primaryAnchor: offset), - buttonItems: [ - ContextMenuButtonItem( - onPressed: () { - ContextMenuController.removeAny(); - _showDialog(context); - }, - label: 'Print', - ), - ], - ); - }, - // In this case this wraps a big open space in a GestureDetector in - // order to show the context menu, but it could also wrap a single - // widget like an Image to give it a context menu. - child: ListView( - children: [ - Container(height: 20.0), - const Text( - 'Right click (desktop) or long press (mobile) anywhere, not just on this text, to show the custom menu.', - ), - ], - ), - ), - ), - ); - } -} - -/// Shows and hides the context menu based on user gestures. -/// -/// By default, shows the menu on right clicks and long presses. -class _ContextMenuRegion extends StatefulWidget { - /// Creates an instance of [_ContextMenuRegion]. - const _ContextMenuRegion({ - required this.child, - required this.contextMenuBuilder, - }); - - /// Builds the context menu. - final ContextMenuBuilder contextMenuBuilder; - - /// The child widget that will be listened to for gestures. - final Widget child; - - @override - State<_ContextMenuRegion> createState() => _ContextMenuRegionState(); -} - -class _ContextMenuRegionState extends State<_ContextMenuRegion> { - Offset? _longPressOffset; - - final ContextMenuController _contextMenuController = ContextMenuController(); - - static bool get _longPressEnabled { - switch (defaultTargetPlatform) { - case .android: - case .iOS: - return true; - case .macOS: - case .fuchsia: - case .linux: - case .windows: - return false; - } - } - - void _onSecondaryTapUp(TapUpDetails details) { - _show(details.globalPosition); - } - - void _onTap() { - if (!_contextMenuController.isShown) { - return; - } - _hide(); - } - - void _onLongPressStart(LongPressStartDetails details) { - _longPressOffset = details.globalPosition; - } - - void _onLongPress() { - assert(_longPressOffset != null); - _show(_longPressOffset!); - _longPressOffset = null; - } - - void _show(Offset position) { - _contextMenuController.show( - context: context, - contextMenuBuilder: (BuildContext context) { - return widget.contextMenuBuilder(context, position); - }, - ); - } - - void _hide() { - _contextMenuController.remove(); - } - - @override - void dispose() { - _hide(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onSecondaryTapUp: _onSecondaryTapUp, - onTap: _onTap, - onLongPress: _longPressEnabled ? _onLongPress : null, - onLongPressStart: _longPressEnabled ? _onLongPressStart : null, - child: widget.child, - ); - } -} diff --git a/packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.0.dart b/packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.0.dart deleted file mode 100644 index a62ccb9303c9..000000000000 --- a/packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.0.dart +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This example demonstrates showing the default buttons, but customizing their -// appearance. - -import 'package:cupertino_ui/cupertino_ui.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:material_ui/material_ui.dart'; - -void main() => runApp(const EditableTextToolbarBuilderExampleApp()); - -class EditableTextToolbarBuilderExampleApp extends StatefulWidget { - const EditableTextToolbarBuilderExampleApp({super.key}); - - @override - State createState() => - _EditableTextToolbarBuilderExampleAppState(); -} - -class _EditableTextToolbarBuilderExampleAppState - extends State { - final TextEditingController _controller = TextEditingController( - text: - 'Right click (desktop) or long press (mobile) to see the menu with custom buttons.', - ); - - @override - void initState() { - super.initState(); - // On web, disable the browser's context menu since this example uses a custom - // Flutter-rendered context menu. - if (kIsWeb) { - BrowserContextMenu.disableContextMenu(); - } - } - - @override - void dispose() { - if (kIsWeb) { - BrowserContextMenu.enableContextMenu(); - } - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar(title: const Text('Custom button appearance')), - body: Center( - child: Column( - children: [ - const SizedBox(height: 20.0), - TextField( - controller: _controller, - contextMenuBuilder: - ( - BuildContext context, - EditableTextState editableTextState, - ) { - return AdaptiveTextSelectionToolbar( - anchors: editableTextState.contextMenuAnchors, - // Build the default buttons, but make them look custom. - // In a real project you may want to build different - // buttons depending on the platform. - children: editableTextState.contextMenuButtonItems.map(( - ContextMenuButtonItem buttonItem, - ) { - return CupertinoButton( - color: const Color(0xffaaaa00), - disabledColor: const Color(0xffaaaaff), - onPressed: buttonItem.onPressed, - padding: const .all(10.0), - pressedOpacity: 0.7, - child: SizedBox( - width: 200.0, - child: Text( - CupertinoTextSelectionToolbarButton.getButtonLabel( - context, - buttonItem, - ), - ), - ), - ); - }).toList(), - ); - }, - ), - ], - ), - ), - ), - ); - } -} diff --git a/packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.1.dart b/packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.1.dart deleted file mode 100644 index 395bddfdf137..000000000000 --- a/packages/material_ui/example/lib/context_menu/editable_text_toolbar_builder.1.dart +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This example demonstrates showing a custom context menu only when some -// narrowly defined text is selected. - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:material_ui/material_ui.dart'; - -void main() => runApp(const EditableTextToolbarBuilderExampleApp()); - -const String emailAddress = 'me@example.com'; -const String text = 'Select the email address and open the menu: $emailAddress'; - -class EditableTextToolbarBuilderExampleApp extends StatefulWidget { - const EditableTextToolbarBuilderExampleApp({super.key}); - - @override - State createState() => - _EditableTextToolbarBuilderExampleAppState(); -} - -class _EditableTextToolbarBuilderExampleAppState - extends State { - final TextEditingController _controller = TextEditingController(text: text); - - void _showDialog(BuildContext context) { - Navigator.of(context).push( - DialogRoute( - context: context, - builder: (BuildContext context) => - const AlertDialog(title: Text('You clicked send email!')), - ), - ); - } - - @override - void initState() { - super.initState(); - // On web, disable the browser's context menu since this example uses a custom - // Flutter-rendered context menu. - if (kIsWeb) { - BrowserContextMenu.disableContextMenu(); - } - } - - @override - void dispose() { - if (kIsWeb) { - BrowserContextMenu.enableContextMenu(); - } - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar(title: const Text('Custom button for emails')), - body: Center( - child: Column( - children: [ - Container(height: 20.0), - TextField( - controller: _controller, - contextMenuBuilder: - ( - BuildContext context, - EditableTextState editableTextState, - ) { - final List buttonItems = - editableTextState.contextMenuButtonItems; - // Here we add an "Email" button to the default TextField - // context menu for the current platform, but only if an email - // address is currently selected. - final TextEditingValue value = _controller.value; - if (_isValidEmail( - value.selection.textInside(value.text), - )) { - buttonItems.insert( - 0, - ContextMenuButtonItem( - label: 'Send email', - onPressed: () { - ContextMenuController.removeAny(); - _showDialog(context); - }, - ), - ); - } - return AdaptiveTextSelectionToolbar.buttonItems( - anchors: editableTextState.contextMenuAnchors, - buttonItems: buttonItems, - ); - }, - ), - ], - ), - ), - ), - ); - } -} - -bool _isValidEmail(String text) { - return RegExp( - r'(?[a-zA-Z0-9]+)' - r'@' - r'(?[a-zA-Z0-9]+)' - r'\.' - r'(?[a-zA-Z0-9]+)', - ).hasMatch(text); -} diff --git a/packages/material_ui/example/lib/platform_menu_bar/platform_menu_bar.0.dart b/packages/material_ui/example/lib/platform_menu_bar/platform_menu_bar.0.dart deleted file mode 100644 index 913f15c3a2ab..000000000000 --- a/packages/material_ui/example/lib/platform_menu_bar/platform_menu_bar.0.dart +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// THIS SAMPLE ONLY WORKS ON MACOS. - -import 'package:flutter/services.dart'; -import 'package:material_ui/material_ui.dart'; - -/// Flutter code sample for [PlatformMenuBar]. - -void main() => runApp(const ExampleApp()); - -enum MenuSelection { about, showMessage } - -class ExampleApp extends StatelessWidget { - const ExampleApp({super.key}); - - @override - Widget build(BuildContext context) { - return const MaterialApp(home: Scaffold(body: PlatformMenuBarExample())); - } -} - -class PlatformMenuBarExample extends StatefulWidget { - const PlatformMenuBarExample({super.key}); - - @override - State createState() => _PlatformMenuBarExampleState(); -} - -class _PlatformMenuBarExampleState extends State { - String _message = 'Hello'; - bool _showMessage = false; - - void _handleMenuSelection(MenuSelection value) { - switch (value) { - case MenuSelection.about: - showAboutDialog( - context: context, - applicationName: 'MenuBar Sample', - applicationVersion: '1.0.0', - ); - case MenuSelection.showMessage: - setState(() { - _showMessage = !_showMessage; - }); - } - } - - @override - Widget build(BuildContext context) { - //////////////////////////////////// - // THIS SAMPLE ONLY WORKS ON MACOS. - //////////////////////////////////// - - // This builds a menu hierarchy that looks like this: - // Flutter API Sample - // ├ About - // ├ ──────── (group divider) - // ├ Hide/Show Message - // ├ Messages - // │ ├ I am not throwing away my shot. - // │ └ There's a million things I haven't done, but just you wait. - // └ Quit - return PlatformMenuBar( - menus: [ - PlatformMenu( - label: 'Flutter API Sample', - menus: [ - PlatformMenuItemGroup( - members: [ - PlatformMenuItem( - label: 'About', - onSelected: () { - _handleMenuSelection(MenuSelection.about); - }, - ), - ], - ), - PlatformMenuItemGroup( - members: [ - PlatformMenuItem( - onSelected: () { - _handleMenuSelection(MenuSelection.showMessage); - }, - shortcut: const CharacterActivator('m'), - label: _showMessage ? 'Hide Message' : 'Show Message', - ), - PlatformMenu( - label: 'Messages', - menus: [ - PlatformMenuItem( - label: 'I am not throwing away my shot.', - shortcut: const SingleActivator( - LogicalKeyboardKey.digit1, - meta: true, - ), - onSelected: () { - setState(() { - _message = 'I am not throwing away my shot.'; - }); - }, - ), - PlatformMenuItem( - label: - "There's a million things I haven't done, but just you wait.", - shortcut: const SingleActivator( - LogicalKeyboardKey.digit2, - meta: true, - ), - onSelected: () { - setState(() { - _message = - "There's a million things I haven't done, but just you wait."; - }); - }, - ), - ], - ), - ], - ), - if (PlatformProvidedMenuItem.hasMenu( - PlatformProvidedMenuItemType.quit, - )) - const PlatformProvidedMenuItem(type: .quit), - ], - ), - ], - child: Center( - child: Text( - _showMessage - ? _message - : 'This space intentionally left blank.\n' - 'Show a message here using the menu.', - ), - ), - ); - } -} diff --git a/packages/material_ui/example/lib/selectable_region/selectable_region.0.dart b/packages/material_ui/example/lib/selectable_region/selectable_region.0.dart deleted file mode 100644 index e644a59facca..000000000000 --- a/packages/material_ui/example/lib/selectable_region/selectable_region.0.dart +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/rendering.dart'; -import 'package:material_ui/material_ui.dart'; - -/// Flutter code sample for [SelectableRegion]. - -void main() => runApp(const SelectableRegionExampleApp()); - -class SelectableRegionExampleApp extends StatelessWidget { - const SelectableRegionExampleApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: SelectableRegion( - selectionControls: materialTextSelectionControls, - child: Scaffold( - appBar: AppBar(title: const Text('SelectableRegion Sample')), - body: const Center( - child: Column( - mainAxisAlignment: .center, - children: [ - Text('Select this icon', style: TextStyle(fontSize: 30)), - SizedBox(height: 10), - MySelectableAdapter(child: Icon(Icons.key, size: 30)), - ], - ), - ), - ), - ), - ); - } -} - -class MySelectableAdapter extends StatelessWidget { - const MySelectableAdapter({super.key, required this.child}); - - final Widget child; - - @override - Widget build(BuildContext context) { - final SelectionRegistrar? registrar = SelectionContainer.maybeOf(context); - if (registrar == null) { - return child; - } - return MouseRegion( - cursor: SystemMouseCursors.text, - child: _SelectableAdapter(registrar: registrar, child: child), - ); - } -} - -class _SelectableAdapter extends SingleChildRenderObjectWidget { - const _SelectableAdapter({required this.registrar, required Widget child}) - : super(child: child); - - final SelectionRegistrar registrar; - - @override - _RenderSelectableAdapter createRenderObject(BuildContext context) { - return _RenderSelectableAdapter( - DefaultSelectionStyle.of(context).selectionColor!, - registrar, - ); - } - - @override - void updateRenderObject( - BuildContext context, - _RenderSelectableAdapter renderObject, - ) { - renderObject - ..selectionColor = DefaultSelectionStyle.of(context).selectionColor! - ..registrar = registrar; - } -} - -class _RenderSelectableAdapter extends RenderProxyBox - with Selectable, SelectionRegistrant { - _RenderSelectableAdapter(Color selectionColor, SelectionRegistrar registrar) - : _selectionColor = selectionColor, - _geometry = ValueNotifier(_noSelection) { - this.registrar = registrar; - _geometry.addListener(markNeedsPaint); - } - - static const SelectionGeometry _noSelection = SelectionGeometry( - status: SelectionStatus.none, - hasContent: true, - ); - final ValueNotifier _geometry; - - Color get selectionColor => _selectionColor; - Color _selectionColor; - set selectionColor(Color value) { - if (_selectionColor == value) { - return; - } - _selectionColor = value; - markNeedsPaint(); - } - - // ValueListenable APIs - - @override - void addListener(VoidCallback listener) => _geometry.addListener(listener); - - @override - void removeListener(VoidCallback listener) => - _geometry.removeListener(listener); - - @override - SelectionGeometry get value => _geometry.value; - - // Selectable APIs. - - @override - List get boundingBoxes => [paintBounds]; - - // Adjust this value to enlarge or shrink the selection highlight. - static const double _padding = 10.0; - Rect _getSelectionHighlightRect() { - return Rect.fromLTWH( - 0 - _padding, - 0 - _padding, - size.width + _padding * 2, - size.height + _padding * 2, - ); - } - - Offset? _start; - Offset? _end; - void _updateGeometry() { - if (_start == null || _end == null) { - _geometry.value = _noSelection; - return; - } - final Rect renderObjectRect = Rect.fromLTWH(0, 0, size.width, size.height); - final Rect selectionRect = Rect.fromPoints(_start!, _end!); - if (renderObjectRect.intersect(selectionRect).isEmpty) { - _geometry.value = _noSelection; - } else { - final Rect selectionRect = _getSelectionHighlightRect(); - final SelectionPoint firstSelectionPoint = SelectionPoint( - localPosition: selectionRect.bottomLeft, - lineHeight: selectionRect.size.height, - handleType: TextSelectionHandleType.left, - ); - final SelectionPoint secondSelectionPoint = SelectionPoint( - localPosition: selectionRect.bottomRight, - lineHeight: selectionRect.size.height, - handleType: TextSelectionHandleType.right, - ); - final bool isReversed; - if (_start!.dy > _end!.dy) { - isReversed = true; - } else if (_start!.dy < _end!.dy) { - isReversed = false; - } else { - isReversed = _start!.dx > _end!.dx; - } - _geometry.value = SelectionGeometry( - status: SelectionStatus.uncollapsed, - hasContent: true, - startSelectionPoint: isReversed - ? secondSelectionPoint - : firstSelectionPoint, - endSelectionPoint: isReversed - ? firstSelectionPoint - : secondSelectionPoint, - selectionRects: [selectionRect], - ); - } - } - - @override - SelectionResult dispatchSelectionEvent(SelectionEvent event) { - SelectionResult result = .none; - switch (event.type) { - case SelectionEventType.startEdgeUpdate: - case SelectionEventType.endEdgeUpdate: - final Rect renderObjectRect = Rect.fromLTWH( - 0, - 0, - size.width, - size.height, - ); - // Normalize offset in case it is out side of the rect. - final Offset point = globalToLocal( - (event as SelectionEdgeUpdateEvent).globalPosition, - ); - final Offset adjustedPoint = SelectionUtils.adjustDragOffset( - renderObjectRect, - point, - ); - if (event.type == SelectionEventType.startEdgeUpdate) { - _start = adjustedPoint; - } else { - _end = adjustedPoint; - } - result = SelectionUtils.getResultBasedOnRect(renderObjectRect, point); - case SelectionEventType.clear: - _start = _end = null; - case SelectionEventType.selectAll: - case SelectionEventType.selectWord: - case SelectionEventType.selectParagraph: - _start = Offset.zero; - _end = Offset.infinite; - case SelectionEventType.granularlyExtendSelection: - result = SelectionResult.end; - final GranularlyExtendSelectionEvent extendSelectionEvent = - event as GranularlyExtendSelectionEvent; - // Initialize the offset it there is no ongoing selection. - if (_start == null || _end == null) { - if (extendSelectionEvent.forward) { - _start = _end = Offset.zero; - } else { - _start = _end = Offset.infinite; - } - } - // Move the corresponding selection edge. - final Offset newOffset = extendSelectionEvent.forward - ? Offset.infinite - : Offset.zero; - if (extendSelectionEvent.isEnd) { - if (newOffset == _end) { - result = extendSelectionEvent.forward - ? SelectionResult.next - : SelectionResult.previous; - } - _end = newOffset; - } else { - if (newOffset == _start) { - result = extendSelectionEvent.forward - ? SelectionResult.next - : SelectionResult.previous; - } - _start = newOffset; - } - case SelectionEventType.directionallyExtendSelection: - result = SelectionResult.end; - final DirectionallyExtendSelectionEvent extendSelectionEvent = - event as DirectionallyExtendSelectionEvent; - // Convert to local coordinates. - final double horizontalBaseLine = globalToLocal(Offset(event.dx, 0)).dx; - final Offset newOffset; - final bool forward; - switch (extendSelectionEvent.direction) { - case SelectionExtendDirection.backward: - case SelectionExtendDirection.previousLine: - forward = false; - // Initialize the offset it there is no ongoing selection. - if (_start == null || _end == null) { - _start = _end = Offset.infinite; - } - // Move the corresponding selection edge. - if (extendSelectionEvent.direction == - SelectionExtendDirection.previousLine || - horizontalBaseLine < 0) { - newOffset = Offset.zero; - } else { - newOffset = Offset.infinite; - } - case SelectionExtendDirection.nextLine: - case SelectionExtendDirection.forward: - forward = true; - // Initialize the offset it there is no ongoing selection. - if (_start == null || _end == null) { - _start = _end = Offset.zero; - } - // Move the corresponding selection edge. - if (extendSelectionEvent.direction == - SelectionExtendDirection.nextLine || - horizontalBaseLine > size.width) { - newOffset = Offset.infinite; - } else { - newOffset = Offset.zero; - } - } - if (extendSelectionEvent.isEnd) { - if (newOffset == _end) { - result = forward ? SelectionResult.next : SelectionResult.previous; - } - _end = newOffset; - } else { - if (newOffset == _start) { - result = forward ? SelectionResult.next : SelectionResult.previous; - } - _start = newOffset; - } - } - _updateGeometry(); - return result; - } - - // This method is called when users want to copy selected content in this - // widget into clipboard. - @override - SelectedContent? getSelectedContent() { - return value.hasSelection - ? const SelectedContent(plainText: 'Custom Text') - : null; - } - - @override - SelectedContentRange? getSelection() { - if (!value.hasSelection) { - return null; - } - return const SelectedContentRange(startOffset: 0, endOffset: 1); - } - - @override - int get contentLength => 1; - - LayerLink? _startHandle; - LayerLink? _endHandle; - - @override - void pushHandleLayers(LayerLink? startHandle, LayerLink? endHandle) { - if (_startHandle == startHandle && _endHandle == endHandle) { - return; - } - _startHandle = startHandle; - _endHandle = endHandle; - markNeedsPaint(); - } - - @override - void paint(PaintingContext context, Offset offset) { - super.paint(context, offset); - if (!_geometry.value.hasSelection) { - return; - } - // Draw the selection highlight. - final Paint selectionPaint = Paint() - ..style = PaintingStyle.fill - ..color = _selectionColor; - context.canvas.drawRect( - _getSelectionHighlightRect().shift(offset), - selectionPaint, - ); - - // Push the layer links if any. - if (_startHandle != null) { - context.pushLayer( - LeaderLayer( - link: _startHandle!, - offset: offset + value.startSelectionPoint!.localPosition, - ), - (PaintingContext context, Offset offset) {}, - Offset.zero, - ); - } - if (_endHandle != null) { - context.pushLayer( - LeaderLayer( - link: _endHandle!, - offset: offset + value.endSelectionPoint!.localPosition, - ), - (PaintingContext context, Offset offset) {}, - Offset.zero, - ); - } - } - - @override - void dispose() { - _geometry.dispose(); - _startHandle = null; - _endHandle = null; - super.dispose(); - } -} diff --git a/packages/material_ui/example/lib/selection_container/selection_container.0.dart b/packages/material_ui/example/lib/selection_container/selection_container.0.dart deleted file mode 100644 index 4477f160da41..000000000000 --- a/packages/material_ui/example/lib/selection_container/selection_container.0.dart +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/rendering.dart'; -import 'package:material_ui/material_ui.dart'; - -/// Flutter code sample for [SelectionContainer]. - -void main() => runApp(const SelectionContainerExampleApp()); - -class SelectionContainerExampleApp extends StatelessWidget { - const SelectionContainerExampleApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: SelectionArea( - child: Scaffold( - appBar: AppBar(title: const Text('SelectionContainer Sample')), - body: const Center( - child: SelectionAllOrNoneContainer( - child: Column( - mainAxisAlignment: .center, - children: [Text('Row 1'), Text('Row 2'), Text('Row 3')], - ), - ), - ), - ), - ), - ); - } -} - -class SelectionAllOrNoneContainer extends StatefulWidget { - const SelectionAllOrNoneContainer({super.key, required this.child}); - - final Widget child; - - @override - State createState() => _SelectionAllOrNoneContainerState(); -} - -class _SelectionAllOrNoneContainerState - extends State { - final SelectAllOrNoneContainerDelegate delegate = - SelectAllOrNoneContainerDelegate(); - - @override - void dispose() { - delegate.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return SelectionContainer(delegate: delegate, child: widget.child); - } -} - -class SelectAllOrNoneContainerDelegate - extends MultiSelectableSelectionContainerDelegate { - Offset? _adjustedStartEdge; - Offset? _adjustedEndEdge; - bool _isSelected = false; - - // This method is called when newly added selectable is in the current - // selected range. - @override - void ensureChildUpdated(Selectable selectable) { - if (_isSelected) { - dispatchSelectionEventToChild( - selectable, - const SelectAllSelectionEvent(), - ); - } - } - - @override - SelectionResult handleSelectWord(SelectWordSelectionEvent event) { - // Treat select word as select all. - return handleSelectAll(const SelectAllSelectionEvent()); - } - - @override - SelectionResult handleSelectionEdgeUpdate(SelectionEdgeUpdateEvent event) { - final Rect containerRect = Rect.fromLTWH( - 0, - 0, - containerSize.width, - containerSize.height, - ); - final Matrix4 globalToLocal = getTransformTo(null)..invert(); - final Offset localOffset = MatrixUtils.transformPoint( - globalToLocal, - event.globalPosition, - ); - final Offset adjustOffset = SelectionUtils.adjustDragOffset( - containerRect, - localOffset, - ); - if (event.type == SelectionEventType.startEdgeUpdate) { - _adjustedStartEdge = adjustOffset; - } else { - _adjustedEndEdge = adjustOffset; - } - // Select all content if the selection rect intercepts with the rect. - if (_adjustedStartEdge != null && _adjustedEndEdge != null) { - final Rect selectionRect = Rect.fromPoints( - _adjustedStartEdge!, - _adjustedEndEdge!, - ); - if (!selectionRect.intersect(containerRect).isEmpty) { - handleSelectAll(const SelectAllSelectionEvent()); - } else { - super.handleClearSelection(const ClearSelectionEvent()); - } - } else { - super.handleClearSelection(const ClearSelectionEvent()); - } - return SelectionUtils.getResultBasedOnRect(containerRect, localOffset); - } - - @override - SelectionResult handleClearSelection(ClearSelectionEvent event) { - _adjustedStartEdge = null; - _adjustedEndEdge = null; - _isSelected = false; - return super.handleClearSelection(event); - } - - @override - SelectionResult handleSelectAll(SelectAllSelectionEvent event) { - _isSelected = true; - return super.handleSelectAll(event); - } -} diff --git a/packages/material_ui/example/lib/selection_container/selection_container_disabled.0.dart b/packages/material_ui/example/lib/selection_container/selection_container_disabled.0.dart deleted file mode 100644 index 0a2dcbba6de9..000000000000 --- a/packages/material_ui/example/lib/selection_container/selection_container_disabled.0.dart +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flutter example for [SelectionContainer.disabled]. - -import 'package:material_ui/material_ui.dart'; - -void main() => runApp(const SelectionContainerDisabledExampleApp()); - -class SelectionContainerDisabledExampleApp extends StatelessWidget { - const SelectionContainerDisabledExampleApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar(title: const Text('SelectionContainer.disabled Sample')), - body: const Center( - child: SelectionArea( - child: Column( - mainAxisAlignment: .center, - children: [ - Text('Selectable text'), - SelectionContainer.disabled(child: Text('Non-selectable text')), - Text('Selectable text'), - ], - ), - ), - ), - ), - ); - } -} diff --git a/packages/material_ui/example/test/context_menu/context_menu_controller.0_test.dart b/packages/material_ui/example/test/context_menu/context_menu_controller.0_test.dart deleted file mode 100644 index fa99ab73ffe4..000000000000 --- a/packages/material_ui/example/test/context_menu/context_menu_controller.0_test.dart +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/foundation.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui/material_ui.dart'; -import 'package:material_ui_examples/context_menu/context_menu_controller.0.dart' - as example; - -void main() { - testWidgets('showing and hiding the custom context menu in the whole app', ( - WidgetTester tester, - ) async { - bool disabledWasCalled = false; - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(SystemChannels.contextMenu, ( - MethodCall methodCall, - ) { - if (methodCall.method == 'disableContextMenu') { - expect(methodCall.arguments, isNull); - disabledWasCalled = true; - } - return; - }); - addTearDown(() { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(SystemChannels.contextMenu, null); - }); - - await tester.pumpWidget(const example.ContextMenuControllerExampleApp()); - - expect(BrowserContextMenu.enabled, !kIsWeb); - expect(disabledWasCalled, kIsWeb); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - - // Right clicking the middle of the app shows the custom context menu. - final Offset center = tester.getCenter(find.byType(Scaffold)); - final TestGesture gesture = await tester.startGesture( - center, - kind: PointerDeviceKind.mouse, - buttons: kSecondaryMouseButton, - ); - await tester.pump(); - await gesture.up(); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget); - expect(find.text('Print'), findsOneWidget); - - // Tap to dismiss. - await tester.tapAt(center); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - - // Long pressing also shows the custom context menu. - await tester.longPressAt(center); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget); - expect(find.text('Print'), findsOneWidget); - }); -} diff --git a/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.0_test.dart b/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.0_test.dart deleted file mode 100644 index 75f203798db3..000000000000 --- a/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.0_test.dart +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:cupertino_ui/cupertino_ui.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui/material_ui.dart'; -import 'package:material_ui_examples/context_menu/editable_text_toolbar_builder.0.dart' - as example; - -void main() { - testWidgets( - 'showing and hiding the context menu in TextField with custom buttons', - (WidgetTester tester) async { - bool disabledWasCalled = false; - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(SystemChannels.contextMenu, ( - MethodCall methodCall, - ) { - if (methodCall.method == 'disableContextMenu') { - expect(methodCall.arguments, isNull); - disabledWasCalled = true; - } - return; - }); - - addTearDown(() { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(SystemChannels.contextMenu, null); - }); - await tester.pumpWidget( - const example.EditableTextToolbarBuilderExampleApp(), - ); - - expect(BrowserContextMenu.enabled, !kIsWeb); - expect(disabledWasCalled, kIsWeb); - - await tester.tap(find.byType(EditableText)); - await tester.pump(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - - // Long pressing the field shows the default context menu but with custom - // buttons. - await tester.longPress(find.byType(EditableText)); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget); - expect(find.byType(CupertinoButton), findsAtLeastNWidgets(1)); - - // Tap to dismiss. - await tester.tapAt(tester.getTopLeft(find.byType(EditableText))); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - expect(find.byType(CupertinoButton), findsNothing); - }, - ); -} diff --git a/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.1_test.dart b/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.1_test.dart deleted file mode 100644 index 9ea0290f8e1f..000000000000 --- a/packages/material_ui/example/test/context_menu/editable_text_toolbar_builder.1_test.dart +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/foundation.dart'; -import 'package:flutter/gestures.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui/material_ui.dart'; -import 'package:material_ui_examples/context_menu/editable_text_toolbar_builder.1.dart' - as example; - -void main() { - testWidgets( - 'showing and hiding the custom context menu in TextField with a specific selection', - (WidgetTester tester) async { - bool disabledWasCalled = false; - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(SystemChannels.contextMenu, ( - MethodCall methodCall, - ) { - if (methodCall.method == 'disableContextMenu') { - expect(methodCall.arguments, isNull); - disabledWasCalled = true; - } - return; - }); - - addTearDown(() { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(SystemChannels.contextMenu, null); - }); - - await tester.pumpWidget( - const example.EditableTextToolbarBuilderExampleApp(), - ); - - expect(BrowserContextMenu.enabled, !kIsWeb); - expect(disabledWasCalled, kIsWeb); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - - // Right clicking the Text in the TextField shows the custom context menu, - // but no email button since no email address is selected. - TestGesture gesture = await tester.startGesture( - tester.getTopLeft(find.text(example.text)), - kind: PointerDeviceKind.mouse, - buttons: kSecondaryMouseButton, - ); - await tester.pump(); - await gesture.up(); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget); - expect(find.text('Send email'), findsNothing); - - // Tap to dismiss. - await tester.tapAt(tester.getTopLeft(find.byType(EditableText))); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - - // Select the email address. - final EditableTextState state = tester.state( - find.byType(EditableText), - ); - state.updateEditingValue( - state.textEditingValue.copyWith( - selection: TextSelection( - baseOffset: example.text.indexOf(example.emailAddress), - extentOffset: example.text.length, - ), - ), - ); - await tester.pump(); - - // Right clicking the Text in the TextField shows the custom context menu - // with the email button. - gesture = await tester.startGesture( - tester.getCenter(find.text(example.text)), - kind: PointerDeviceKind.mouse, - buttons: kSecondaryMouseButton, - ); - await tester.pump(); - await gesture.up(); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget); - expect(find.text('Send email'), findsOneWidget); - - // Tap to dismiss. - await tester.tapAt(tester.getTopLeft(find.byType(EditableText))); - await tester.pumpAndSettle(); - - expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing); - }, - ); -} diff --git a/packages/material_ui/example/test/platform_menu_bar/platform_menu_bar.0_test.dart b/packages/material_ui/example/test/platform_menu_bar/platform_menu_bar.0_test.dart deleted file mode 100644 index 36ff87bf58a7..000000000000 --- a/packages/material_ui/example/test/platform_menu_bar/platform_menu_bar.0_test.dart +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui/material_ui.dart'; -import 'package:material_ui_examples/platform_menu_bar/platform_menu_bar.0.dart' - as example; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - late _FakeMenuChannel fakeMenuChannel; - late PlatformMenuDelegate originalDelegate; - late DefaultPlatformMenuDelegate delegate; - - setUp(() { - fakeMenuChannel = _FakeMenuChannel((MethodCall call) async {}); - delegate = DefaultPlatformMenuDelegate(channel: fakeMenuChannel); - originalDelegate = WidgetsBinding.instance.platformMenuDelegate; - WidgetsBinding.instance.platformMenuDelegate = delegate; - }); - - tearDown(() { - WidgetsBinding.instance.platformMenuDelegate = originalDelegate; - }); - - testWidgets('PlatformMenuBar creates a menu', (WidgetTester tester) async { - await tester.pumpWidget(const example.ExampleApp()); - - expect( - find.text( - 'This space intentionally left blank.\nShow a message here using the menu.', - ), - findsOne, - ); - expect(find.byType(PlatformMenuBar), findsOne); - - expect(fakeMenuChannel.outgoingCalls.last.method, 'Menu.setMenus'); - expect( - fakeMenuChannel.outgoingCalls.last.arguments, - equals(const { - '0': >[ - { - 'id': 11, - 'label': 'Flutter API Sample', - 'enabled': true, - 'children': >[ - {'id': 2, 'label': 'About', 'enabled': true}, - {'id': 3, 'isDivider': true}, - { - 'id': 5, - 'label': 'Show Message', - 'enabled': true, - 'shortcutCharacter': 'm', - 'shortcutModifiers': 0, - }, - { - 'id': 8, - 'label': 'Messages', - 'enabled': true, - 'children': >[ - { - 'id': 6, - 'label': 'I am not throwing away my shot.', - 'enabled': true, - 'shortcutTrigger': 49, - 'shortcutModifiers': 1, - }, - { - 'id': 7, - 'label': - "There's a million things I haven't done, but just you wait.", - 'enabled': true, - 'shortcutTrigger': 50, - 'shortcutModifiers': 1, - }, - ], - }, - {'id': 9, 'isDivider': true}, - { - 'id': 10, - 'enabled': true, - 'platformProvidedMenu': 1, - }, - ], - }, - ], - }), - ); - }, variant: const TargetPlatformVariant({.macOS})); -} - -class _FakeMenuChannel implements MethodChannel { - _FakeMenuChannel(this.outgoing); - - Future Function(MethodCall) outgoing; - Future Function(MethodCall)? incoming; - - List outgoingCalls = []; - - @override - BinaryMessenger get binaryMessenger => throw UnimplementedError(); - - @override - MethodCodec get codec => const StandardMethodCodec(); - - @override - Future> invokeListMethod(String method, [dynamic arguments]) => - throw UnimplementedError(); - - @override - Future> invokeMapMethod(String method, [dynamic arguments]) => - throw UnimplementedError(); - - @override - Future invokeMethod(String method, [dynamic arguments]) async { - final MethodCall call = MethodCall(method, arguments); - outgoingCalls.add(call); - return await outgoing(call) as T; - } - - @override - String get name => 'flutter/menu'; - - @override - void setMethodCallHandler(Future Function(MethodCall call)? handler) => - incoming = handler; -} diff --git a/packages/material_ui/example/test/selectable_region/selectable_region.0_test.dart b/packages/material_ui/example/test/selectable_region/selectable_region.0_test.dart deleted file mode 100644 index 1201957d3464..000000000000 --- a/packages/material_ui/example/test/selectable_region/selectable_region.0_test.dart +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui/material_ui.dart'; -import 'package:material_ui_examples/selectable_region/selectable_region.0.dart' - as example; - -void main() { - Future sendKeyCombination( - WidgetTester tester, - LogicalKeyboardKey key, - ) async { - final LogicalKeyboardKey modifier = switch (defaultTargetPlatform) { - .iOS || .macOS => LogicalKeyboardKey.meta, - _ => LogicalKeyboardKey.control, - }; - await tester.sendKeyDownEvent(modifier); - await tester.sendKeyDownEvent(key); - await tester.sendKeyUpEvent(key); - await tester.sendKeyUpEvent(modifier); - await tester.pump(); - } - - testWidgets('The icon can be selected with the text', ( - WidgetTester tester, - ) async { - String? clipboard; - tester.binding.defaultBinaryMessenger.setMockMethodCallHandler( - SystemChannels.platform, - (MethodCall methodCall) async { - if (methodCall.method == 'Clipboard.setData') { - clipboard = - (methodCall.arguments as Map)['text'] as String; - } - return null; - }, - ); - addTearDown(() { - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - .setMockMethodCallHandler(SystemChannels.platform, null); - }); - - await tester.pumpWidget(const example.SelectableRegionExampleApp()); - - await tester.tap(find.byIcon(Icons.key)); // Focus the application. - await tester.pump(); - - // Keyboard select all. - await sendKeyCombination(tester, LogicalKeyboardKey.keyA); - // Keyboard copy. - await sendKeyCombination(tester, LogicalKeyboardKey.keyC); - - expect(clipboard, 'SelectableRegion SampleSelect this iconCustom Text'); - }, variant: TargetPlatformVariant.all()); -} diff --git a/packages/material_ui/example/test/selection_container/selection_container.0_test.dart b/packages/material_ui/example/test/selection_container/selection_container.0_test.dart deleted file mode 100644 index 7672fbcc9dea..000000000000 --- a/packages/material_ui/example/test/selection_container/selection_container.0_test.dart +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/gestures.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui/material_ui.dart'; -import 'package:material_ui_examples/selection_container/selection_container.0.dart' - as example; - -void main() { - testWidgets( - 'The SelectionContainer should transform the partial selection into an all selection', - (WidgetTester tester) async { - await tester.pumpWidget(const example.SelectionContainerExampleApp()); - - expect( - find.widgetWithText(AppBar, 'SelectionContainer Sample'), - findsOne, - ); - - final RenderParagraph paragraph1 = tester.renderObject( - find.descendant( - of: find.text('Row 1'), - matching: find.byType(RichText), - ), - ); - final RenderParagraph paragraph2 = tester.renderObject( - find.descendant( - of: find.text('Row 2'), - matching: find.byType(RichText), - ), - ); - final RenderParagraph paragraph3 = tester.renderObject( - find.descendant( - of: find.text('Row 3'), - matching: find.byType(RichText), - ), - ); - final Rect paragraph1Rect = tester.getRect(find.text('Row 1')); - final TestGesture gesture = await tester.startGesture( - paragraph1Rect.topLeft, - kind: PointerDeviceKind.mouse, - ); - addTearDown(gesture.removePointer); - await tester.pump(); - - await gesture.moveTo(paragraph1Rect.center); - await tester.pump(); - expect( - paragraph1.selections.first, - const TextSelection(baseOffset: 0, extentOffset: 5), - ); - expect( - paragraph2.selections.first, - const TextSelection(baseOffset: 0, extentOffset: 5), - ); - expect( - paragraph3.selections.first, - const TextSelection(baseOffset: 0, extentOffset: 5), - ); - - await gesture.up(); - }, - ); -} diff --git a/packages/material_ui/example/test/selection_container/selection_container_disabled.0_test.dart b/packages/material_ui/example/test/selection_container/selection_container_disabled.0_test.dart deleted file mode 100644 index 9ab2da3d3085..000000000000 --- a/packages/material_ui/example/test/selection_container/selection_container_disabled.0_test.dart +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/gestures.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui/material_ui.dart'; -import 'package:material_ui_examples/selection_container/selection_container_disabled.0.dart' - as example; - -void main() { - testWidgets('A SelectionContainer.disabled should disable selections', ( - WidgetTester tester, - ) async { - await tester.pumpWidget( - const example.SelectionContainerDisabledExampleApp(), - ); - - expect( - find.widgetWithText(AppBar, 'SelectionContainer.disabled Sample'), - findsOne, - ); - - final RenderParagraph paragraph1 = tester.renderObject( - find.descendant( - of: find.text('Selectable text').first, - matching: find.byType(RichText), - ), - ); - final Rect paragraph1Rect = tester.getRect( - find.text('Selectable text').first, - ); - final TestGesture gesture = await tester.startGesture( - paragraph1Rect.centerLeft, - kind: PointerDeviceKind.mouse, - ); - addTearDown(gesture.removePointer); - await tester.pump(); - - await gesture.moveTo(paragraph1Rect.center); - await tester.pump(); - expect( - paragraph1.selections.first, - const TextSelection(baseOffset: 0, extentOffset: 7), - ); - - final RenderParagraph paragraph2 = tester.renderObject( - find.descendant( - of: find.text('Non-selectable text'), - matching: find.byType(RichText), - ), - ); - final Rect paragraph2Rect = tester.getRect( - find.text('Non-selectable text'), - ); - await gesture.moveTo(paragraph2Rect.center); - // Should select the rest of paragraph 1. - expect( - paragraph1.selections.first, - const TextSelection(baseOffset: 0, extentOffset: 15), - ); - // paragraph2 is in a disabled container. - expect(paragraph2.selections, isEmpty); - - final RenderParagraph paragraph3 = tester.renderObject( - find.descendant( - of: find.text('Selectable text').last, - matching: find.byType(RichText), - ), - ); - final Rect paragraph3Rect = tester.getRect( - find.text('Selectable text').last, - ); - await gesture.moveTo(paragraph3Rect.center); - expect( - paragraph1.selections.first, - const TextSelection(baseOffset: 0, extentOffset: 15), - ); - expect(paragraph2.selections, isEmpty); - expect( - paragraph3.selections.first, - const TextSelection(baseOffset: 0, extentOffset: 7), - ); - - await gesture.up(); - }); -} From c2aa60e79ec085bcdbf955583bec94491c07ab04 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 12 Jul 2026 22:08:05 -0700 Subject: [PATCH 2/2] Impl --- .../example/lib/expansible/expansible.0.dart | 75 ------------------- .../test/expansible/expansible.0_test.dart | 22 ------ 2 files changed, 97 deletions(-) delete mode 100644 packages/material_ui/example/lib/expansible/expansible.0.dart delete mode 100644 packages/material_ui/example/test/expansible/expansible.0_test.dart diff --git a/packages/material_ui/example/lib/expansible/expansible.0.dart b/packages/material_ui/example/lib/expansible/expansible.0.dart deleted file mode 100644 index bbcc92fe5eb2..000000000000 --- a/packages/material_ui/example/lib/expansible/expansible.0.dart +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:material_ui/material_ui.dart'; - -/// Flutter code sample for [Expansible]. - -void main() => runApp(const ExpansibleApp()); - -/// An application that shows an example of how to use [Expansible]. -class ExpansibleApp extends StatelessWidget { - const ExpansibleApp({super.key}); - - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar(title: const Text('Expansible Widget Example')), - body: const Center(child: ExpansibleWidgetExample()), - ), - ); - } -} - -class ExpansibleWidgetExample extends StatefulWidget { - const ExpansibleWidgetExample({super.key}); - - @override - State createState() => - _ExpansibleWidgetExampleState(); -} - -class _ExpansibleWidgetExampleState extends State { - final _controller = ExpansibleController(); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const .all(16.0), - child: Expansible( - controller: _controller, - headerBuilder: (context, animation) => ListTile( - title: const Text('Tap to Expand'), - onTap: () { - if (_controller.isExpanded) { - _controller.collapse(); - } else { - _controller.expand(); - } - }, - trailing: RotationTransition( - turns: Tween(begin: 0.0, end: 0.5).animate(animation), - child: const Icon(Icons.arrow_drop_down), - ), - ), - bodyBuilder: (context, animation) => SizeTransition( - sizeFactor: animation, - child: const Text('Hidden content revealed!'), - ), - expansibleBuilder: (context, header, body, animation) => Column( - mainAxisSize: .min, - crossAxisAlignment: .stretch, - children: [header, body], - ), - ), - ); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } -} diff --git a/packages/material_ui/example/test/expansible/expansible.0_test.dart b/packages/material_ui/example/test/expansible/expansible.0_test.dart deleted file mode 100644 index e583f9919022..000000000000 --- a/packages/material_ui/example/test/expansible/expansible.0_test.dart +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2013 The Flutter Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter_test/flutter_test.dart'; -import 'package:material_ui_examples/expansible/expansible.0.dart' as example; - -void main() { - testWidgets('Expansible can be expanded', (WidgetTester tester) async { - await tester.pumpWidget(const example.ExpansibleApp()); - - // Verify that the expanded content is not visible initially. - expect(find.text('Hidden content revealed!'), findsNothing); - - // Tap the header to expand. - await tester.tap(find.text('Tap to Expand')); - await tester.pumpAndSettle(); - - // Verify that the expanded content is now visible. - expect(find.text('Hidden content revealed!'), findsOneWidget); - }); -}