toggle_buttons_theme.dart 10.1 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
// 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';

13 14 15
// Examples can assume:
// late BuildContext context;

16 17 18 19 20 21 22 23 24 25 26 27 28 29
/// 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.
30
@immutable
31
class ToggleButtonsThemeData with Diagnosticable {
32 33 34
  /// Creates the set of color and border properties used to configure
  /// [ToggleButtons].
  const ToggleButtonsThemeData({
35
    this.textStyle,
36
    this.constraints,
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
    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,
  });

52 53 54 55 56
  /// 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.
57
  final TextStyle? textStyle;
58

59 60 61
  /// Defines the button's size.
  ///
  /// Typically used to constrain the button's minimum size.
62
  final BoxConstraints? constraints;
63

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

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

  /// The color for descendant [Text] and [Icon] widgets if the toggle button
  /// is disabled.
74
  final Color? disabledColor;
75 76

  /// The fill color for selected toggle buttons.
77
  final Color? fillColor;
78 79

  /// The color to use for filling the button when the button has input focus.
80
  final Color? focusColor;
81 82

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

  /// The splash color for the toggle button's [InkWell].
86
  final Color? splashColor;
87 88 89

  /// The color to use for filling the toggle button when the button has a
  /// pointer hovering over it.
90
  final Color? hoverColor;
91 92

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

  /// The border color to display when the toggle button is selected.
96
  final Color? selectedBorderColor;
97 98

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

  /// 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.
108
  final double? borderWidth;
109 110

  /// The radii of the border's corners.
111
  final BorderRadius? borderRadius;
112 113 114 115

  /// Creates a copy of this object but with the given fields replaced with the
  /// new values.
  ToggleButtonsThemeData copyWith({
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    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,
131 132
  }) {
    return ToggleButtonsThemeData(
133
      textStyle: textStyle ?? this.textStyle,
134
      constraints: constraints ?? this.constraints,
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
      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.
152
  static ToggleButtonsThemeData? lerp(ToggleButtonsThemeData? a, ToggleButtonsThemeData? b, double t) {
153 154
    if (identical(a, b)) {
      return a;
155
    }
156
    return ToggleButtonsThemeData(
157
      textStyle: TextStyle.lerp(a?.textStyle, b?.textStyle, t),
158
      constraints: BoxConstraints.lerp(a?.constraints, b?.constraints, t),
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
      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
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
  int get hashCode => Object.hash(
    textStyle,
    constraints,
    color,
    selectedColor,
    disabledColor,
    fillColor,
    focusColor,
    highlightColor,
    hoverColor,
    splashColor,
    borderColor,
    selectedBorderColor,
    disabledBorderColor,
    borderRadius,
    borderWidth,
  );
193 194 195

  @override
  bool operator ==(Object other) {
196
    if (identical(this, other)) {
197
      return true;
198 199
    }
    if (other.runtimeType != runtimeType) {
200
      return false;
201
    }
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
    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;
218 219 220 221 222
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
223
    textStyle?.debugFillProperties(properties, prefix: 'textStyle.');
224
    properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
    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.
246
class ToggleButtonsTheme extends InheritedTheme {
247 248
  /// Creates a toggle buttons theme that controls the color and border
  /// parameters for [ToggleButtons].
249
  const ToggleButtonsTheme({
250
    super.key,
251
    required this.data,
252
    required super.child,
253
  });
254 255 256 257 258 259 260 261 262 263 264 265

  /// 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
266
  /// ToggleButtonsThemeData theme = ToggleButtonsTheme.of(context);
267 268
  /// ```
  static ToggleButtonsThemeData of(BuildContext context) {
269
    final ToggleButtonsTheme? toggleButtonsTheme = context.dependOnInheritedWidgetOfExactType<ToggleButtonsTheme>();
270
    return toggleButtonsTheme?.data ?? Theme.of(context).toggleButtonsTheme;
271 272
  }

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

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