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
154
155
156
157
158
159
160
// 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/foundation.dart';
import 'package:flutter/widgets.dart';
import 'action_buttons.dart';
import 'theme.dart';
// Examples can assume:
// late BuildContext context;
/// A [ActionIconThemeData] that overrides the default icons of
/// [BackButton], [CloseButton], [DrawerButton], and [EndDrawerButton] with
/// [ActionIconTheme.of] or the overall [Theme]'s [ThemeData.actionIconTheme].
@immutable
class ActionIconThemeData with Diagnosticable {
/// Creates an [ActionIconThemeData].
///
/// The builders [backButtonIconBuilder], [closeButtonIconBuilder],
/// [drawerButtonIconBuilder], [endDrawerButtonIconBuilder] may be null.
const ActionIconThemeData({ this.backButtonIconBuilder, this.closeButtonIconBuilder, this.drawerButtonIconBuilder, this.endDrawerButtonIconBuilder });
/// Overrides [BackButtonIcon]'s icon.
///
/// If [backButtonIconBuilder] is null, then [BackButtonIcon]
/// fallbacks to the platform's default back button icon.
final WidgetBuilder? backButtonIconBuilder;
/// Overrides [CloseButtonIcon]'s icon.
///
/// If [closeButtonIconBuilder] is null, then [CloseButtonIcon]
/// fallbacks to the platform's default close button icon.
final WidgetBuilder? closeButtonIconBuilder;
/// Overrides [DrawerButtonIcon]'s icon.
///
/// If [drawerButtonIconBuilder] is null, then [DrawerButtonIcon]
/// fallbacks to the platform's default drawer button icon.
final WidgetBuilder? drawerButtonIconBuilder;
/// Overrides [EndDrawerButtonIcon]'s icon.
///
/// If [endDrawerButtonIconBuilder] is null, then [EndDrawerButtonIcon]
/// fallbacks to the platform's default end drawer button icon.
final WidgetBuilder? endDrawerButtonIconBuilder;
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
ActionIconThemeData copyWith({
WidgetBuilder? backButtonIconBuilder,
WidgetBuilder? closeButtonIconBuilder,
WidgetBuilder? drawerButtonIconBuilder,
WidgetBuilder? endDrawerButtonIconBuilder,
}) {
return ActionIconThemeData(
backButtonIconBuilder: backButtonIconBuilder ?? this.backButtonIconBuilder,
closeButtonIconBuilder: closeButtonIconBuilder ?? this.closeButtonIconBuilder,
drawerButtonIconBuilder: drawerButtonIconBuilder ?? this.drawerButtonIconBuilder,
endDrawerButtonIconBuilder: endDrawerButtonIconBuilder ?? this.endDrawerButtonIconBuilder,
);
}
/// Linearly interpolate between two action icon themes.
static ActionIconThemeData? lerp(ActionIconThemeData? a, ActionIconThemeData? b, double t) {
if (a == null && b == null) {
return null;
}
return ActionIconThemeData(
backButtonIconBuilder: t < 0.5 ? a?.backButtonIconBuilder : b?.backButtonIconBuilder,
closeButtonIconBuilder: t < 0.5 ? a?.closeButtonIconBuilder : b?.closeButtonIconBuilder,
drawerButtonIconBuilder: t < 0.5 ? a?.drawerButtonIconBuilder : b?.drawerButtonIconBuilder,
endDrawerButtonIconBuilder: t < 0.5 ? a?.endDrawerButtonIconBuilder : b?.endDrawerButtonIconBuilder,
);
}
@override
int get hashCode {
final List<Object?> values = <Object?>[
backButtonIconBuilder,
closeButtonIconBuilder,
drawerButtonIconBuilder,
endDrawerButtonIconBuilder,
];
return Object.hashAll(values);
}
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
}
if (other.runtimeType != runtimeType) {
return false;
}
return other is ActionIconThemeData
&& other.backButtonIconBuilder == backButtonIconBuilder
&& other.closeButtonIconBuilder == closeButtonIconBuilder
&& other.drawerButtonIconBuilder == drawerButtonIconBuilder
&& other.endDrawerButtonIconBuilder == endDrawerButtonIconBuilder;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<WidgetBuilder>('backButtonIconBuilder', backButtonIconBuilder, defaultValue: null));
properties.add(DiagnosticsProperty<WidgetBuilder>('closeButtonIconBuilder', closeButtonIconBuilder, defaultValue: null));
properties.add(DiagnosticsProperty<WidgetBuilder>('drawerButtonIconBuilder', drawerButtonIconBuilder, defaultValue: null));
properties.add(DiagnosticsProperty<WidgetBuilder>('endDrawerButtonIconBuilder', endDrawerButtonIconBuilder, defaultValue: null));
}
}
/// An inherited widget that overrides the default icon of [BackButtonIcon],
/// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] in this
/// widget's subtree.
///
/// {@tool dartpad}
/// This example shows how to define custom builders for drawer and back
/// buttons.
///
/// ** See code in examples/api/lib/material/action_buttons/action_icon_theme.0.dart **
/// {@end-tool}
class ActionIconTheme extends InheritedTheme {
/// Creates a theme that overrides the default icon of [BackButtonIcon],
/// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] in this
/// widget's subtree.
const ActionIconTheme({
super.key,
required this.data,
required super.child,
});
/// Specifies the default icon overrides for descendant [BackButtonIcon],
/// [CloseButtonIcon], [DrawerButtonIcon], and [EndDrawerButtonIcon] widgets.
final ActionIconThemeData data;
/// The closest instance of this class that encloses the given context.
///
/// If there is no enclosing [ActionIconTheme] widget, then
/// [ThemeData.actionIconTheme] is used.
///
/// Typical usage is as follows:
///
/// ```dart
/// ActionIconThemeData? theme = ActionIconTheme.of(context);
/// ```
static ActionIconThemeData? of(BuildContext context) {
final ActionIconTheme? actionIconTheme = context.dependOnInheritedWidgetOfExactType<ActionIconTheme>();
return actionIconTheme?.data ?? Theme.of(context).actionIconTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
return ActionIconTheme(data: data, child: child);
}
@override
bool updateShouldNotify(ActionIconTheme oldWidget) => data != oldWidget.data;
}