1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// 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 'basic.dart';
import 'framework.dart';
import 'inherited_theme.dart';
// Examples can assume:
// late BuildContext context;
/// The selection style to apply to descendant [EditableText] widgets which
/// don't have an explicit style.
///
/// {@macro flutter.cupertino.CupertinoApp.defaultSelectionStyle}
///
/// {@macro flutter.material.MaterialApp.defaultSelectionStyle}
///
/// See also:
/// * [TextSelectionTheme]: which also creates a [DefaultSelectionStyle] for
/// the subtree.
class DefaultSelectionStyle extends InheritedTheme {
/// Creates a default selection style widget that specifies the selection
/// properties for all widgets below it in the widget tree.
const DefaultSelectionStyle({
super.key,
this.cursorColor,
this.selectionColor,
this.mouseCursor,
required super.child,
});
/// A const-constructable default selection style that provides fallback
/// values (null).
///
/// Returned from [of] when the given [BuildContext] doesn't have an enclosing
/// default selection style.
///
/// This constructor creates a [DefaultTextStyle] with an invalid [child],
/// which means the constructed value cannot be incorporated into the tree.
const DefaultSelectionStyle.fallback({ super.key })
: cursorColor = null,
selectionColor = null,
mouseCursor = null,
super(child: const _NullWidget());
/// Creates a default selection style that overrides the selection styles in
/// scope at this point in the widget tree.
///
/// Any Arguments that are not null replace the corresponding properties on the
/// default selection style for the [BuildContext] where the widget is inserted.
static Widget merge({
Key? key,
Color? cursorColor,
Color? selectionColor,
MouseCursor? mouseCursor,
required Widget child,
}) {
return Builder(
builder: (BuildContext context) {
final DefaultSelectionStyle parent = DefaultSelectionStyle.of(context);
return DefaultSelectionStyle(
key: key,
cursorColor: cursorColor ?? parent.cursorColor,
selectionColor: selectionColor ?? parent.selectionColor,
mouseCursor: mouseCursor ?? parent.mouseCursor,
child: child,
);
},
);
}
/// The default cursor and selection color (semi-transparent grey).
///
/// This is the color that the [Text] widget uses when the specified selection
/// color is null.
static const Color defaultColor = Color(0x80808080);
/// The color of the text field's cursor.
///
/// The cursor indicates the current location of the text insertion point in
/// the field.
final Color? cursorColor;
/// The background color of selected text.
final Color? selectionColor;
/// The [MouseCursor] for mouse pointers hovering over selectable Text widgets.
///
/// If this property is null, [SystemMouseCursors.text] will be used.
final MouseCursor? mouseCursor;
/// The closest instance of this class that encloses the given context.
///
/// If no such instance exists, returns an instance created by
/// [DefaultSelectionStyle.fallback], which contains fallback values.
///
/// Typical usage is as follows:
///
/// ```dart
/// DefaultSelectionStyle style = DefaultSelectionStyle.of(context);
/// ```
static DefaultSelectionStyle of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<DefaultSelectionStyle>() ?? const DefaultSelectionStyle.fallback();
}
@override
Widget wrap(BuildContext context, Widget child) {
return DefaultSelectionStyle(
cursorColor: cursorColor,
selectionColor: selectionColor,
mouseCursor: mouseCursor,
child: child
);
}
@override
bool updateShouldNotify(DefaultSelectionStyle oldWidget) {
return cursorColor != oldWidget.cursorColor ||
selectionColor != oldWidget.selectionColor ||
mouseCursor != oldWidget.mouseCursor;
}
}
class _NullWidget extends StatelessWidget {
const _NullWidget();
@override
Widget build(BuildContext context) {
throw FlutterError(
'A DefaultSelectionStyle constructed with DefaultSelectionStyle.fallback cannot be incorporated into the widget tree, '
'it is meant only to provide a fallback value returned by DefaultSelectionStyle.of() '
'when no enclosing default selection style is present in a BuildContext.',
);
}
}