• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 The Chromium 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 'dart:ui' show lerpDouble;
6
7import 'package:flutter/foundation.dart';
8import 'package:flutter/rendering.dart';
9import 'package:flutter/widgets.dart';
10
11import 'theme.dart';
12
13/// Defines the color and border properties of [ToggleButtons] widgets.
14///
15/// Used by [ToggleButtonsTheme] to control the color and border properties
16/// of toggle buttons in a widget subtree.
17///
18/// To obtain the current [ToggleButtonsTheme], use [ToggleButtonsTheme.of].
19///
20/// Values specified here are used for [ToggleButtons] properties that are not
21/// given an explicit non-null value.
22///
23/// See also:
24///
25///  * [ToggleButtonsTheme], which describes the actual configuration of a
26///    toggle buttons theme.
27class ToggleButtonsThemeData extends Diagnosticable {
28  /// Creates the set of color and border properties used to configure
29  /// [ToggleButtons].
30  const ToggleButtonsThemeData({
31    this.color,
32    this.selectedColor,
33    this.disabledColor,
34    this.fillColor,
35    this.focusColor,
36    this.highlightColor,
37    this.hoverColor,
38    this.splashColor,
39    this.borderColor,
40    this.selectedBorderColor,
41    this.disabledBorderColor,
42    this.borderRadius,
43    this.borderWidth,
44  });
45
46  /// The color for descendant [Text] and [Icon] widgets if the toggle button
47  /// is enabled.
48  final Color color;
49
50  /// The color for descendant [Text] and [Icon] widgets if the toggle button
51  /// is selected.
52  final Color selectedColor;
53
54  /// The color for descendant [Text] and [Icon] widgets if the toggle button
55  /// is disabled.
56  final Color disabledColor;
57
58  /// The fill color for selected toggle buttons.
59  final Color fillColor;
60
61  /// The color to use for filling the button when the button has input focus.
62  final Color focusColor;
63
64  /// The highlight color for the toggle button's [InkWell].
65  final Color highlightColor;
66
67  /// The splash color for the toggle button's [InkWell].
68  final Color splashColor;
69
70  /// The color to use for filling the toggle button when the button has a
71  /// pointer hovering over it.
72  final Color hoverColor;
73
74  /// The border color to display when the toggle button is enabled.
75  final Color borderColor;
76
77  /// The border color to display when the toggle button is selected.
78  final Color selectedBorderColor;
79
80  /// The border color to display when the toggle button is disabled.
81  final Color disabledBorderColor;
82
83  /// The width of the border surrounding each toggle button.
84  ///
85  /// This applies to both the greater surrounding border, as well as the
86  /// borders dividing each toggle button.
87  ///
88  /// To render a hairline border (one physical pixel), set borderWidth to 0.0.
89  /// See [BorderSide.width] for more details on hairline borders.
90  final double borderWidth;
91
92  /// The radii of the border's corners.
93  final BorderRadius borderRadius;
94
95  /// Creates a copy of this object but with the given fields replaced with the
96  /// new values.
97  ToggleButtonsThemeData copyWith({
98    Color color,
99    Color selectedColor,
100    Color disabledColor,
101    Color fillColor,
102    Color focusColor,
103    Color highlightColor,
104    Color hoverColor,
105    Color splashColor,
106    Color borderColor,
107    Color selectedBorderColor,
108    Color disabledBorderColor,
109    BorderRadius borderRadius,
110    double borderWidth,
111  }) {
112    return ToggleButtonsThemeData(
113      color: color ?? this.color,
114      selectedColor: selectedColor ?? this.selectedColor,
115      disabledColor: disabledColor ?? this.disabledColor,
116      fillColor: fillColor ?? this.fillColor,
117      focusColor: focusColor ?? this.focusColor,
118      highlightColor: highlightColor ?? this.highlightColor,
119      hoverColor: hoverColor ?? this.hoverColor,
120      splashColor: splashColor ?? this.splashColor,
121      borderColor: borderColor ?? this.borderColor,
122      selectedBorderColor: selectedBorderColor ?? this.selectedBorderColor,
123      disabledBorderColor: disabledBorderColor ?? this.disabledBorderColor,
124      borderRadius: borderRadius ?? this.borderRadius,
125      borderWidth: borderWidth ?? this.borderWidth,
126    );
127  }
128
129  /// Linearly interpolate between two toggle buttons themes.
130  static ToggleButtonsThemeData lerp(ToggleButtonsThemeData a, ToggleButtonsThemeData b, double t) {
131    assert (t != null);
132    if (a == null && b == null)
133      return null;
134    return ToggleButtonsThemeData(
135      color: Color.lerp(a?.color, b?.color, t),
136      selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
137      disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
138      fillColor: Color.lerp(a?.fillColor, b?.fillColor, t),
139      focusColor: Color.lerp(a?.focusColor, b?.focusColor, t),
140      highlightColor: Color.lerp(a?.highlightColor, b?.highlightColor, t),
141      hoverColor: Color.lerp(a?.hoverColor, b?.hoverColor, t),
142      splashColor: Color.lerp(a?.splashColor, b?.splashColor, t),
143      borderColor: Color.lerp(a?.borderColor, b?.borderColor, t),
144      selectedBorderColor: Color.lerp(a?.selectedBorderColor, b?.selectedBorderColor, t),
145      disabledBorderColor: Color.lerp(a?.disabledBorderColor, b?.disabledBorderColor, t),
146      borderRadius: BorderRadius.lerp(a?.borderRadius, b?.borderRadius, t),
147      borderWidth: lerpDouble(a?.borderWidth, b?.borderWidth, t),
148    );
149  }
150
151  @override
152  int get hashCode {
153    return hashValues(
154      color,
155      selectedColor,
156      disabledColor,
157      fillColor,
158      focusColor,
159      highlightColor,
160      hoverColor,
161      splashColor,
162      borderColor,
163      selectedBorderColor,
164      disabledBorderColor,
165      borderRadius,
166      borderWidth,
167    );
168  }
169
170  @override
171  bool operator ==(Object other) {
172    if (identical(this, other))
173      return true;
174    if (other.runtimeType != runtimeType)
175      return false;
176    final ToggleButtonsThemeData typedOther = other;
177    return typedOther.color == color
178        && typedOther.selectedColor == selectedColor
179        && typedOther.disabledColor == disabledColor
180        && typedOther.fillColor == fillColor
181        && typedOther.focusColor == focusColor
182        && typedOther.highlightColor == highlightColor
183        && typedOther.hoverColor == hoverColor
184        && typedOther.splashColor == splashColor
185        && typedOther.borderColor == borderColor
186        && typedOther.selectedBorderColor == selectedBorderColor
187        && typedOther.disabledBorderColor == disabledBorderColor
188        && typedOther.borderRadius == borderRadius
189        && typedOther.borderWidth == borderWidth;
190  }
191
192  @override
193  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
194    super.debugFillProperties(properties);
195    properties.add(ColorProperty('color', color, defaultValue: null));
196    properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null));
197    properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
198    properties.add(ColorProperty('fillColor', fillColor, defaultValue: null));
199    properties.add(ColorProperty('focusColor', focusColor, defaultValue: null));
200    properties.add(ColorProperty('highlightColor', highlightColor, defaultValue: null));
201    properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: null));
202    properties.add(ColorProperty('splashColor', splashColor, defaultValue: null));
203    properties.add(ColorProperty('borderColor', borderColor, defaultValue: null));
204    properties.add(ColorProperty('selectedBorderColor', selectedBorderColor, defaultValue: null));
205    properties.add(ColorProperty('disabledBorderColor', disabledBorderColor, defaultValue: null));
206    properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius, defaultValue: null));
207    properties.add(DoubleProperty('borderWidth', borderWidth, defaultValue: null));
208  }
209}
210
211/// An inherited widget that defines color and border parameters for
212/// [ToggleButtons] in this widget's subtree.
213///
214/// Values specified here are used for [ToggleButtons] properties that are not
215/// given an explicit non-null value.
216class ToggleButtonsTheme extends InheritedWidget {
217  /// Creates a toggle buttons theme that controls the color and border
218  /// parameters for [ToggleButtons].
219  ///
220  /// The data argument must not be null.
221  const ToggleButtonsTheme({
222    Key key,
223    @required this.data,
224    Widget child,
225  }) : assert(data != null), super(key: key, child: child);
226
227  /// Specifies the color and border values for descendant [ToggleButtons] widgets.
228  final ToggleButtonsThemeData data;
229
230  /// The closest instance of this class that encloses the given context.
231  ///
232  /// If there is no enclosing [ToggleButtonsTheme] widget, then
233  /// [ThemeData.toggleButtonsTheme] is used.
234  ///
235  /// Typical usage is as follows:
236  ///
237  /// ```dart
238  /// ToggleButtonsTheme theme = ToggleButtonsTheme.of(context);
239  /// ```
240  static ToggleButtonsThemeData of(BuildContext context) {
241    final ToggleButtonsTheme toggleButtonsTheme = context.inheritFromWidgetOfExactType(ToggleButtonsTheme);
242    return toggleButtonsTheme?.data ?? Theme.of(context).toggleButtonsTheme;
243  }
244
245  @override
246  bool updateShouldNotify(ToggleButtonsTheme oldWidget) => data != oldWidget.data;
247}
248