1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/material.dart';
6import 'package:flutter/rendering.dart';
7
8/// Flutter code sample for [SelectionContainer].
9
10void main() => runApp(const SelectionContainerExampleApp());
11
12class SelectionContainerExampleApp extends StatelessWidget {
13 const SelectionContainerExampleApp({super.key});
14
15 @override
16 Widget build(BuildContext context) {
17 return MaterialApp(
18 home: SelectionArea(
19 child: Scaffold(
20 appBar: AppBar(title: const Text('SelectionContainer Sample')),
21 body: const Center(
22 child: SelectionAllOrNoneContainer(
23 child: Column(
24 mainAxisAlignment: MainAxisAlignment.center,
25 children: <Widget>[Text('Row 1'), Text('Row 2'), Text('Row 3')],
26 ),
27 ),
28 ),
29 ),
30 ),
31 );
32 }
33}
34
35class SelectionAllOrNoneContainer extends StatefulWidget {
36 const SelectionAllOrNoneContainer({super.key, required this.child});
37
38 final Widget child;
39
40 @override
41 State<StatefulWidget> createState() => _SelectionAllOrNoneContainerState();
42}
43
44class _SelectionAllOrNoneContainerState extends State<SelectionAllOrNoneContainer> {
45 final SelectAllOrNoneContainerDelegate delegate = SelectAllOrNoneContainerDelegate();
46
47 @override
48 void dispose() {
49 delegate.dispose();
50 super.dispose();
51 }
52
53 @override
54 Widget build(BuildContext context) {
55 return SelectionContainer(delegate: delegate, child: widget.child);
56 }
57}
58
59class SelectAllOrNoneContainerDelegate extends MultiSelectableSelectionContainerDelegate {
60 Offset? _adjustedStartEdge;
61 Offset? _adjustedEndEdge;
62 bool _isSelected = false;
63
64 // This method is called when newly added selectable is in the current
65 // selected range.
66 @override
67 void ensureChildUpdated(Selectable selectable) {
68 if (_isSelected) {
69 dispatchSelectionEventToChild(selectable, const SelectAllSelectionEvent());
70 }
71 }
72
73 @override
74 SelectionResult handleSelectWord(SelectWordSelectionEvent event) {
75 // Treat select word as select all.
76 return handleSelectAll(const SelectAllSelectionEvent());
77 }
78
79 @override
80 SelectionResult handleSelectionEdgeUpdate(SelectionEdgeUpdateEvent event) {
81 final Rect containerRect = Rect.fromLTWH(0, 0, containerSize.width, containerSize.height);
82 final Matrix4 globalToLocal = getTransformTo(null)..invert();
83 final Offset localOffset = MatrixUtils.transformPoint(globalToLocal, event.globalPosition);
84 final Offset adjustOffset = SelectionUtils.adjustDragOffset(containerRect, localOffset);
85 if (event.type == SelectionEventType.startEdgeUpdate) {
86 _adjustedStartEdge = adjustOffset;
87 } else {
88 _adjustedEndEdge = adjustOffset;
89 }
90 // Select all content if the selection rect intercepts with the rect.
91 if (_adjustedStartEdge != null && _adjustedEndEdge != null) {
92 final Rect selectionRect = Rect.fromPoints(_adjustedStartEdge!, _adjustedEndEdge!);
93 if (!selectionRect.intersect(containerRect).isEmpty) {
94 handleSelectAll(const SelectAllSelectionEvent());
95 } else {
96 super.handleClearSelection(const ClearSelectionEvent());
97 }
98 } else {
99 super.handleClearSelection(const ClearSelectionEvent());
100 }
101 return SelectionUtils.getResultBasedOnRect(containerRect, localOffset);
102 }
103
104 @override
105 SelectionResult handleClearSelection(ClearSelectionEvent event) {
106 _adjustedStartEdge = null;
107 _adjustedEndEdge = null;
108 _isSelected = false;
109 return super.handleClearSelection(event);
110 }
111
112 @override
113 SelectionResult handleSelectAll(SelectAllSelectionEvent event) {
114 _isSelected = true;
115 return super.handleSelectAll(event);
116 }
117}
118

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com