toggle_buttons_theme.dart 10.2 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
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
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:ui' show lerpDouble;

import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';

import 'theme.dart';

/// Defines the color and border properties of [ToggleButtons] widgets.
///
/// Used by [ToggleButtonsTheme] to control the color and border properties
/// of toggle buttons in a widget subtree.
///
/// To obtain the current [ToggleButtonsTheme], use [ToggleButtonsTheme.of].
///
/// Values specified here are used for [ToggleButtons] properties that are not
/// given an explicit non-null value.
///
/// See also:
///
///  * [ToggleButtonsTheme], which describes the actual configuration of a
///    toggle buttons theme.
27
@immutable
28
class ToggleButtonsThemeData with Diagnosticable {
29 30 31
  /// Creates the set of color and border properties used to configure
  /// [ToggleButtons].
  const ToggleButtonsThemeData({
32
    this.textStyle,
33
    this.constraints,
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
    this.color,
    this.selectedColor,
    this.disabledColor,
    this.fillColor,
    this.focusColor,
    this.highlightColor,
    this.hoverColor,
    this.splashColor,
    this.borderColor,
    this.selectedBorderColor,
    this.disabledBorderColor,
    this.borderRadius,
    this.borderWidth,
  });

49 50 51 52 53
  /// The default text style for [ToggleButtons.children].
  ///
  /// [TextStyle.color] will be ignored and substituted by [color],
  /// [selectedColor] or [disabledColor] depending on whether the buttons
  /// are active, selected, or disabled.
54
  final TextStyle? textStyle;
55

56 57 58
  /// Defines the button's size.
  ///
  /// Typically used to constrain the button's minimum size.
59
  final BoxConstraints? constraints;
60

61 62
  /// The color for descendant [Text] and [Icon] widgets if the toggle button
  /// is enabled.
63
  final Color? color;
64 65 66

  /// The color for descendant [Text] and [Icon] widgets if the toggle button
  /// is selected.
67
  final Color? selectedColor;
68 69 70

  /// The color for descendant [Text] and [Icon] widgets if the toggle button
  /// is disabled.
71
  final Color? disabledColor;
72 73

  /// The fill color for selected toggle buttons.
74
  final Color? fillColor;
75 76

  /// The color to use for filling the button when the button has input focus.
77
  final Color? focusColor;
78 79

  /// The highlight color for the toggle button's [InkWell].
80
  final Color? highlightColor;
81 82

  /// The splash color for the toggle button's [InkWell].
83
  final Color? splashColor;
84 85 86

  /// The color to use for filling the toggle button when the button has a
  /// pointer hovering over it.
87
  final Color? hoverColor;
88 89

  /// The border color to display when the toggle button is enabled.
90
  final Color? borderColor;
91 92

  /// The border color to display when the toggle button is selected.
93
  final Color? selectedBorderColor;
94 95

  /// The border color to display when the toggle button is disabled.
96
  final Color? disabledBorderColor;
97 98 99 100 101 102 103 104

  /// The width of the border surrounding each toggle button.
  ///
  /// This applies to both the greater surrounding border, as well as the
  /// borders dividing each toggle button.
  ///
  /// To render a hairline border (one physical pixel), set borderWidth to 0.0.
  /// See [BorderSide.width] for more details on hairline borders.
105
  final double? borderWidth;
106 107

  /// The radii of the border's corners.
108
  final BorderRadius? borderRadius;
109 110 111 112

  /// Creates a copy of this object but with the given fields replaced with the
  /// new values.
  ToggleButtonsThemeData copyWith({
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
    TextStyle? textStyle,
    BoxConstraints? constraints,
    Color? color,
    Color? selectedColor,
    Color? disabledColor,
    Color? fillColor,
    Color? focusColor,
    Color? highlightColor,
    Color? hoverColor,
    Color? splashColor,
    Color? borderColor,
    Color? selectedBorderColor,
    Color? disabledBorderColor,
    BorderRadius? borderRadius,
    double? borderWidth,
128 129
  }) {
    return ToggleButtonsThemeData(
130
      textStyle: textStyle ?? this.textStyle,
131
      constraints: constraints ?? this.constraints,
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
      color: color ?? this.color,
      selectedColor: selectedColor ?? this.selectedColor,
      disabledColor: disabledColor ?? this.disabledColor,
      fillColor: fillColor ?? this.fillColor,
      focusColor: focusColor ?? this.focusColor,
      highlightColor: highlightColor ?? this.highlightColor,
      hoverColor: hoverColor ?? this.hoverColor,
      splashColor: splashColor ?? this.splashColor,
      borderColor: borderColor ?? this.borderColor,
      selectedBorderColor: selectedBorderColor ?? this.selectedBorderColor,
      disabledBorderColor: disabledBorderColor ?? this.disabledBorderColor,
      borderRadius: borderRadius ?? this.borderRadius,
      borderWidth: borderWidth ?? this.borderWidth,
    );
  }

  /// Linearly interpolate between two toggle buttons themes.
149
  static ToggleButtonsThemeData? lerp(ToggleButtonsThemeData? a, ToggleButtonsThemeData? b, double t) {
150 151 152 153
    assert (t != null);
    if (a == null && b == null)
      return null;
    return ToggleButtonsThemeData(
154
      textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
155
      constraints: BoxConstraints.lerp(a?.constraints, b?.constraints, t),
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
      color: Color.lerp(a?.color, b?.color, t),
      selectedColor: Color.lerp(a?.selectedColor, b?.selectedColor, t),
      disabledColor: Color.lerp(a?.disabledColor, b?.disabledColor, t),
      fillColor: Color.lerp(a?.fillColor, b?.fillColor, t),
      focusColor: Color.lerp(a?.focusColor, b?.focusColor, t),
      highlightColor: Color.lerp(a?.highlightColor, b?.highlightColor, t),
      hoverColor: Color.lerp(a?.hoverColor, b?.hoverColor, t),
      splashColor: Color.lerp(a?.splashColor, b?.splashColor, t),
      borderColor: Color.lerp(a?.borderColor, b?.borderColor, t),
      selectedBorderColor: Color.lerp(a?.selectedBorderColor, b?.selectedBorderColor, t),
      disabledBorderColor: Color.lerp(a?.disabledBorderColor, b?.disabledBorderColor, t),
      borderRadius: BorderRadius.lerp(a?.borderRadius, b?.borderRadius, t),
      borderWidth: lerpDouble(a?.borderWidth, b?.borderWidth, t),
    );
  }

  @override
  int get hashCode {
    return hashValues(
175
      textStyle,
176
      constraints,
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
      color,
      selectedColor,
      disabledColor,
      fillColor,
      focusColor,
      highlightColor,
      hoverColor,
      splashColor,
      borderColor,
      selectedBorderColor,
      disabledBorderColor,
      borderRadius,
      borderWidth,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other))
      return true;
    if (other.runtimeType != runtimeType)
      return false;
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    return other is ToggleButtonsThemeData
        && other.textStyle == textStyle
        && other.constraints == constraints
        && other.color == color
        && other.selectedColor == selectedColor
        && other.disabledColor == disabledColor
        && other.fillColor == fillColor
        && other.focusColor == focusColor
        && other.highlightColor == highlightColor
        && other.hoverColor == hoverColor
        && other.splashColor == splashColor
        && other.borderColor == borderColor
        && other.selectedBorderColor == selectedBorderColor
        && other.disabledBorderColor == disabledBorderColor
        && other.borderRadius == borderRadius
        && other.borderWidth == borderWidth;
215 216 217 218 219
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
220
    textStyle?.debugFillProperties(properties, prefix: 'textStyle.');
221
    properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
    properties.add(ColorProperty('color', color, defaultValue: null));
    properties.add(ColorProperty('selectedColor', selectedColor, defaultValue: null));
    properties.add(ColorProperty('disabledColor', disabledColor, defaultValue: null));
    properties.add(ColorProperty('fillColor', fillColor, defaultValue: null));
    properties.add(ColorProperty('focusColor', focusColor, defaultValue: null));
    properties.add(ColorProperty('highlightColor', highlightColor, defaultValue: null));
    properties.add(ColorProperty('hoverColor', hoverColor, defaultValue: null));
    properties.add(ColorProperty('splashColor', splashColor, defaultValue: null));
    properties.add(ColorProperty('borderColor', borderColor, defaultValue: null));
    properties.add(ColorProperty('selectedBorderColor', selectedBorderColor, defaultValue: null));
    properties.add(ColorProperty('disabledBorderColor', disabledBorderColor, defaultValue: null));
    properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius, defaultValue: null));
    properties.add(DoubleProperty('borderWidth', borderWidth, defaultValue: null));
  }
}

/// An inherited widget that defines color and border parameters for
/// [ToggleButtons] in this widget's subtree.
///
/// Values specified here are used for [ToggleButtons] properties that are not
/// given an explicit non-null value.
243
class ToggleButtonsTheme extends InheritedTheme {
244 245
  /// Creates a toggle buttons theme that controls the color and border
  /// parameters for [ToggleButtons].
246 247 248
  ///
  /// The data argument must not be null.
  const ToggleButtonsTheme({
249 250 251
    Key? key,
    required this.data,
    required Widget child,
252
  }) : assert(data != null), super(key: key, child: child);
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267

  /// Specifies the color and border values for descendant [ToggleButtons] widgets.
  final ToggleButtonsThemeData data;

  /// The closest instance of this class that encloses the given context.
  ///
  /// If there is no enclosing [ToggleButtonsTheme] widget, then
  /// [ThemeData.toggleButtonsTheme] is used.
  ///
  /// Typical usage is as follows:
  ///
  /// ```dart
  /// ToggleButtonsTheme theme = ToggleButtonsTheme.of(context);
  /// ```
  static ToggleButtonsThemeData of(BuildContext context) {
268
    final ToggleButtonsTheme? toggleButtonsTheme = context.dependOnInheritedWidgetOfExactType<ToggleButtonsTheme>();
269
    return toggleButtonsTheme?.data ?? Theme.of(context).toggleButtonsTheme;
270 271
  }

272 273
  @override
  Widget wrap(BuildContext context, Widget child) {
274
    return ToggleButtonsTheme(data: data, child: child);
275 276
  }

277 278
  @override
  bool updateShouldNotify(ToggleButtonsTheme oldWidget) => data != oldWidget.data;
279
}