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