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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// 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:flutter/widgets.dart';
import 'colors.dart';
/// A button in a _ContextMenuSheet.
///
/// A typical use case is to pass a [Text] as the [child] here, but be sure to
/// use [TextOverflow.ellipsis] for the [Text.overflow] field if the text may be
/// long, as without it the text will wrap to the next line.
class CupertinoContextMenuAction extends StatefulWidget {
/// Construct a CupertinoContextMenuAction.
const CupertinoContextMenuAction({
Key? key,
required this.child,
this.isDefaultAction = false,
this.isDestructiveAction = false,
this.onPressed,
this.trailingIcon,
}) : assert(child != null),
assert(isDefaultAction != null),
assert(isDestructiveAction != null),
super(key: key);
/// The widget that will be placed inside the action.
final Widget child;
/// Indicates whether this action should receive the style of an emphasized,
/// default action.
final bool isDefaultAction;
/// Indicates whether this action should receive the style of a destructive
/// action.
final bool isDestructiveAction;
/// Called when the action is pressed.
final VoidCallback? onPressed;
/// An optional icon to display to the right of the child.
///
/// Will be colored in the same way as the [TextStyle] used for [child] (for
/// example, if using [isDestructiveAction]).
final IconData? trailingIcon;
@override
State<CupertinoContextMenuAction> createState() => _CupertinoContextMenuActionState();
}
class _CupertinoContextMenuActionState extends State<CupertinoContextMenuAction> {
static const Color _kBackgroundColor = CupertinoDynamicColor.withBrightness(
color: Color(0xFFEEEEEE),
darkColor: Color(0xFF212122),
);
static const Color _kBackgroundColorPressed = CupertinoDynamicColor.withBrightness(
color: Color(0xFFDDDDDD),
darkColor: Color(0xFF3F3F40),
);
static const double _kButtonHeight = 56.0;
static const TextStyle _kActionSheetActionStyle = TextStyle(
fontFamily: '.SF UI Text',
inherit: false,
fontSize: 20.0,
fontWeight: FontWeight.w400,
color: CupertinoColors.black,
textBaseline: TextBaseline.alphabetic,
);
final GlobalKey _globalKey = GlobalKey();
bool _isPressed = false;
void onTapDown(TapDownDetails details) {
setState(() {
_isPressed = true;
});
}
void onTapUp(TapUpDetails details) {
setState(() {
_isPressed = false;
});
}
void onTapCancel() {
setState(() {
_isPressed = false;
});
}
TextStyle get _textStyle {
if (widget.isDefaultAction) {
return _kActionSheetActionStyle.copyWith(
fontWeight: FontWeight.w600,
);
}
if (widget.isDestructiveAction) {
return _kActionSheetActionStyle.copyWith(
color: CupertinoColors.destructiveRed,
);
}
return _kActionSheetActionStyle.copyWith(
color: CupertinoDynamicColor.resolve(CupertinoColors.label, context)
);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
key: _globalKey,
onTapDown: onTapDown,
onTapUp: onTapUp,
onTapCancel: onTapCancel,
onTap: widget.onPressed,
behavior: HitTestBehavior.opaque,
child: ConstrainedBox(
constraints: const BoxConstraints(
minHeight: _kButtonHeight,
),
child: Semantics(
button: true,
child: Container(
decoration: BoxDecoration(
color: _isPressed
? CupertinoDynamicColor.resolve(_kBackgroundColorPressed, context)
: CupertinoDynamicColor.resolve(_kBackgroundColor, context),
),
padding: const EdgeInsets.symmetric(
vertical: 16.0,
horizontal: 10.0,
),
child: DefaultTextStyle(
style: _textStyle,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: widget.child,
),
if (widget.trailingIcon != null)
Icon(
widget.trailingIcon,
color: _textStyle.color,
),
],
),
),
),
),
),
);
}
}