From ce8e2bb7cf15bf42bf0bb9dfabada2c9483aa354 Mon Sep 17 00:00:00 2001 From: Todd Volkert Date: Wed, 20 Nov 2019 10:42:23 -0800 Subject: [PATCH] Revert "[Material] Update the Slider and RangeSlider to the latest Material spec (#44351)" (#45268) This reverts commit 421bf64703b5c0fae7196923da0561f6a4c6ec79. Was causing severe breakages in Google. --- .../lib/demo/material/slider_demo.dart | 6 +- .../flutter_gallery/lib/gallery/themes.dart | 1 - examples/flutter_gallery/pubspec.yaml | 42 +- .../lib/src/material/range_slider.dart | 81 +-- packages/flutter/lib/src/material/slider.dart | 82 +-- .../lib/src/material/slider_theme.dart | 653 +++--------------- .../test/material/inherited_theme_test.dart | 4 +- .../test/material/range_slider_test.dart | 78 +-- .../flutter/test/material/slider_test.dart | 181 ++--- .../test/material/slider_theme_test.dart | 353 +--------- 10 files changed, 286 insertions(+), 1195 deletions(-) diff --git a/examples/flutter_gallery/lib/demo/material/slider_demo.dart b/examples/flutter_gallery/lib/demo/material/slider_demo.dart index aae6417ccff..3ba93ecc0e6 100644 --- a/examples/flutter_gallery/lib/demo/material/slider_demo.dart +++ b/examples/flutter_gallery/lib/demo/material/slider_demo.dart @@ -69,7 +69,6 @@ class _CustomRangeThumbShape extends RangeSliderThumbShape { @required SliderThemeData sliderTheme, TextDirection textDirection, Thumb thumb, - bool isPressed, }) { final Canvas canvas = context.canvas; final ColorTween colorTween = ColorTween( @@ -131,8 +130,6 @@ class _CustomThumbShape extends SliderComponentShape { SliderThemeData sliderTheme, TextDirection textDirection, double value, - double textScaleFactor, - Size sizeWithOverflow, }) { final Canvas canvas = context.canvas; final ColorTween colorTween = ColorTween( @@ -172,8 +169,6 @@ class _CustomValueIndicatorShape extends SliderComponentShape { SliderThemeData sliderTheme, TextDirection textDirection, double value, - double textScaleFactor, - Size sizeWithOverflow, }) { final Canvas canvas = context.canvas; final ColorTween enableColor = ColorTween( @@ -443,3 +438,4 @@ class _RangeSlidersState extends State<_RangeSliders> { ); } } + diff --git a/examples/flutter_gallery/lib/gallery/themes.dart b/examples/flutter_gallery/lib/gallery/themes.dart index 3e66950c97d..78430128b27 100644 --- a/examples/flutter_gallery/lib/gallery/themes.dart +++ b/examples/flutter_gallery/lib/gallery/themes.dart @@ -25,7 +25,6 @@ ThemeData _buildDarkTheme() { final ThemeData base = ThemeData( brightness: Brightness.dark, accentColorBrightness: Brightness.dark, - colorScheme: colorScheme, primaryColor: primaryColor, primaryColorDark: const Color(0xFF0050a0), primaryColorLight: secondaryColor, diff --git a/examples/flutter_gallery/pubspec.yaml b/examples/flutter_gallery/pubspec.yaml index 94a38013153..a16a27273bc 100644 --- a/examples/flutter_gallery/pubspec.yaml +++ b/examples/flutter_gallery/pubspec.yaml @@ -257,31 +257,31 @@ flutter: weight: 400 - family: LibreFranklin fonts: - - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Bold.ttf - - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Light.ttf - - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Medium.ttf - - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Regular.ttf + - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Bold.ttf + - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Light.ttf + - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Medium.ttf + - asset: packages/flutter_gallery_assets/fonts/librefranklin/LibreFranklin-Regular.ttf - family: Merriweather fonts: - - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-BlackItalic.ttf - - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Italic.ttf - - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf - - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf + - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-BlackItalic.ttf + - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Italic.ttf + - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Regular.ttf + - asset: packages/flutter_gallery_assets/fonts/merriweather/Merriweather-Light.ttf - family: Roboto Condensed fonts: - - asset: packages/rally_assets/RobotoCondensed-Light.ttf - weight: 400 - - asset: packages/rally_assets/RobotoCondensed-Regular.ttf - weight: 500 - - asset: packages/rally_assets/RobotoCondensed-Bold.ttf - weight: 700 + - asset: packages/rally_assets/RobotoCondensed-Light.ttf + weight: 400 + - asset: packages/rally_assets/RobotoCondensed-Regular.ttf + weight: 500 + - asset: packages/rally_assets/RobotoCondensed-Bold.ttf + weight: 700 - family: Eczar fonts: - - asset: packages/rally_assets/Eczar-Regular.ttf - weight: 400 - - asset: packages/rally_assets/Eczar-SemiBold.ttf - weight: 600 - - asset: packages/rally_assets/Eczar-Bold.ttf - weight: 700 + - asset: packages/rally_assets/Eczar-Regular.ttf + weight: 400 + - asset: packages/rally_assets/Eczar-SemiBold.ttf + weight: 600 + - asset: packages/rally_assets/Eczar-Bold.ttf + weight: 700 -# PUBSPEC CHECKSUM: de7e \ No newline at end of file +# PUBSPEC CHECKSUM: de7e diff --git a/packages/flutter/lib/src/material/range_slider.dart b/packages/flutter/lib/src/material/range_slider.dart index 9905277e575..565a108aff2 100644 --- a/packages/flutter/lib/src/material/range_slider.dart +++ b/packages/flutter/lib/src/material/range_slider.dart @@ -519,12 +519,12 @@ class _RangeSliderState extends State with TickerProviderStateMixin return null; }; - static const double _defaultTrackHeight = 4; + static const double _defaultTrackHeight = 2; static const RangeSliderTrackShape _defaultTrackShape = RoundedRectRangeSliderTrackShape(); static const RangeSliderTickMarkShape _defaultTickMarkShape = RoundRangeSliderTickMarkShape(); static const SliderComponentShape _defaultOverlayShape = RoundSliderOverlayShape(); static const RangeSliderThumbShape _defaultThumbShape = RoundRangeSliderThumbShape(); - static const RangeSliderValueIndicatorShape _defaultValueIndicatorShape = RectangularRangeSliderValueIndicatorShape(); + static const RangeSliderValueIndicatorShape _defaultValueIndicatorShape = PaddleRangeSliderValueIndicatorShape(); static const ShowValueIndicator _defaultShowValueIndicator = ShowValueIndicator.onlyForDiscrete; static const double _defaultMinThumbSeparation = 8; @@ -542,19 +542,6 @@ class _RangeSliderState extends State with TickerProviderStateMixin // colors come from the ThemeData.colorScheme. These colors, along with // the default shapes and text styles are aligned to the Material // Guidelines. - - // The value indicator color is not the same as the thumb and active track - // (which can be defined by activeColor) if the - // RectangularSliderValueIndicatorShape is used. In all other cases, the - // value indicator is assumed to be the same as the active color. - final RangeSliderValueIndicatorShape valueIndicatorShape = sliderTheme.rangeValueIndicatorShape ?? _defaultValueIndicatorShape; - Color valueIndicatorColor; - if (valueIndicatorShape is RectangularRangeSliderValueIndicatorShape) { - valueIndicatorColor = sliderTheme.valueIndicatorColor ?? Color.alphaBlend(theme.colorScheme.onSurface.withOpacity(0.60), theme.colorScheme.surface.withOpacity(0.90)); - } else { - valueIndicatorColor = widget.activeColor ?? sliderTheme.valueIndicatorColor ?? theme.colorScheme.primary; - } - sliderTheme = sliderTheme.copyWith( trackHeight: sliderTheme.trackHeight ?? _defaultTrackHeight, activeTrackColor: widget.activeColor ?? sliderTheme.activeTrackColor ?? theme.colorScheme.primary, @@ -569,13 +556,12 @@ class _RangeSliderState extends State with TickerProviderStateMixin overlappingShapeStrokeColor: sliderTheme.overlappingShapeStrokeColor ?? theme.colorScheme.surface, disabledThumbColor: sliderTheme.disabledThumbColor ?? theme.colorScheme.onSurface.withOpacity(0.38), overlayColor: widget.activeColor?.withOpacity(0.12) ?? sliderTheme.overlayColor ?? theme.colorScheme.primary.withOpacity(0.12), - valueIndicatorColor: valueIndicatorColor, - surfaceColor: sliderTheme.surfaceColor ?? theme.colorScheme.surface, + valueIndicatorColor: widget.activeColor ?? sliderTheme.valueIndicatorColor ?? theme.colorScheme.primary, rangeTrackShape: sliderTheme.rangeTrackShape ?? _defaultTrackShape, rangeTickMarkShape: sliderTheme.rangeTickMarkShape ?? _defaultTickMarkShape, rangeThumbShape: sliderTheme.rangeThumbShape ?? _defaultThumbShape, overlayShape: sliderTheme.overlayShape ?? _defaultOverlayShape, - rangeValueIndicatorShape: valueIndicatorShape, + rangeValueIndicatorShape: sliderTheme.rangeValueIndicatorShape ?? _defaultValueIndicatorShape, showValueIndicator: sliderTheme.showValueIndicator ?? _defaultShowValueIndicator, valueIndicatorTextStyle: sliderTheme.valueIndicatorTextStyle ?? theme.textTheme.body2.copyWith( color: theme.colorScheme.onPrimary, @@ -584,18 +570,12 @@ class _RangeSliderState extends State with TickerProviderStateMixin thumbSelector: sliderTheme.thumbSelector ?? _defaultRangeThumbSelector, ); - // This size is used as the max bounds for the painting of the value - // indicators It must be kept in sync with the function with the same name - // in slider.dart. - Size _sizeWithOverflow() => MediaQuery.of(context).size; - return _RangeSliderRenderObjectWidget( values: _unlerpRangeValues(widget.values), divisions: widget.divisions, labels: widget.labels, sliderTheme: sliderTheme, textScaleFactor: MediaQuery.of(context).textScaleFactor, - sizeWithOverflow: _sizeWithOverflow(), onChanged: (widget.onChanged != null) && (widget.max > widget.min) ? _handleChanged : null, onChangeStart: widget.onChangeStart != null ? _handleDragStart : null, onChangeEnd: widget.onChangeEnd != null ? _handleDragEnd : null, @@ -613,7 +593,6 @@ class _RangeSliderRenderObjectWidget extends LeafRenderObjectWidget { this.labels, this.sliderTheme, this.textScaleFactor, - this.sizeWithOverflow, this.onChanged, this.onChangeStart, this.onChangeEnd, @@ -626,7 +605,6 @@ class _RangeSliderRenderObjectWidget extends LeafRenderObjectWidget { final RangeLabels labels; final SliderThemeData sliderTheme; final double textScaleFactor; - final Size sizeWithOverflow; final ValueChanged onChanged; final ValueChanged onChangeStart; final ValueChanged onChangeEnd; @@ -642,7 +620,6 @@ class _RangeSliderRenderObjectWidget extends LeafRenderObjectWidget { sliderTheme: sliderTheme, theme: Theme.of(context), textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow, onChanged: onChanged, onChangeStart: onChangeStart, onChangeEnd: onChangeEnd, @@ -662,7 +639,6 @@ class _RangeSliderRenderObjectWidget extends LeafRenderObjectWidget { ..sliderTheme = sliderTheme ..theme = Theme.of(context) ..textScaleFactor = textScaleFactor - ..sizeWithOverflow = sizeWithOverflow ..onChanged = onChanged ..onChangeStart = onChangeStart ..onChangeEnd = onChangeEnd @@ -680,7 +656,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix SliderThemeData sliderTheme, ThemeData theme, double textScaleFactor, - Size sizeWithOverflow, TargetPlatform platform, ValueChanged onChanged, RangeSemanticFormatterCallback semanticFormatterCallback, @@ -701,7 +676,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix _sliderTheme = sliderTheme, _theme = theme, _textScaleFactor = textScaleFactor, - _sizeWithOverflow = sizeWithOverflow, _onChanged = onChanged, _state = state, _textDirection = textDirection { @@ -874,15 +848,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix _updateLabelPainters(); } - Size get sizeWithOverflow => _sizeWithOverflow; - Size _sizeWithOverflow; - set sizeWithOverflow(Size value) { - if (value == sizeWithOverflow) - return; - _sizeWithOverflow = value; - markNeedsPaint(); - } - ValueChanged get onChanged => _onChanged; ValueChanged _onChanged; set onChanged(ValueChanged value) { @@ -1230,11 +1195,8 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix isEnabled: isEnabled, ); - final bool startThumbSelected = _lastThumbSelection == Thumb.start; - final bool endThumbSelected = _lastThumbSelection == Thumb.end; - if (!_overlayAnimation.isDismissed) { - if (startThumbSelected) { + if (_lastThumbSelection == Thumb.start) { _sliderTheme.overlayShape.paint( context, startThumbCenter, @@ -1248,7 +1210,7 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix value: startValue, ); } - if (endThumbSelected) { + if (_lastThumbSelection == Thumb.end) { _sliderTheme.overlayShape.paint( context, endThumbCenter, @@ -1269,7 +1231,7 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix isEnabled: isEnabled, sliderTheme: _sliderTheme, ).width; - final double adjustedTrackWidth = trackRect.width - trackRect.height; + final double adjustedTrackWidth = trackRect.width - tickMarkWidth; // If the tick marks would be too dense, don't bother painting them. if (adjustedTrackWidth / divisions >= 3.0 * tickMarkWidth) { final double dy = trackRect.center.dy; @@ -1277,7 +1239,7 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix final double value = i / divisions; // The ticks are mapped to be within the track, so the tick mark width // must be subtracted from the track width. - final double dx = trackRect.left + value * adjustedTrackWidth + trackRect.height / 2; + final double dx = trackRect.left + value * adjustedTrackWidth + tickMarkWidth / 2; final Offset tickMarkOffset = Offset(dx, dy); _sliderTheme.rangeTickMarkShape.paint( context, @@ -1306,7 +1268,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix final double bottomValue = isLastThumbStart ? endValue : startValue; final double topValue = isLastThumbStart ? startValue : endValue; final bool shouldPaintValueIndicators = isEnabled && labels != null && !_valueIndicatorAnimation.isDismissed && showValueIndicator; - final Size resolvedSizeWithOverflow = sizeWithOverflow.isEmpty ? size : sizeWithOverflow; if (shouldPaintValueIndicators) { _sliderTheme.rangeValueIndicatorShape.paint( @@ -1322,8 +1283,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix textDirection: _textDirection, thumb: bottomThumb, value: bottomValue, - textScaleFactor: textScaleFactor, - sizeWithOverflow: resolvedSizeWithOverflow, ); } @@ -1337,7 +1296,6 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix textDirection: textDirection, sliderTheme: _sliderTheme, thumb: bottomThumb, - isPressed: bottomThumb == Thumb.start ? startThumbSelected : endThumbSelected, ); if (shouldPaintValueIndicators) { @@ -1346,29 +1304,15 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix center: startThumbCenter, labelPainter: _startLabelPainter, activationAnimation: _valueIndicatorAnimation, - textScaleFactor: textScaleFactor, - sizeWithOverflow: resolvedSizeWithOverflow, ); final double endOffset = sliderTheme.rangeValueIndicatorShape.getHorizontalShift( parentBox: this, center: endThumbCenter, labelPainter: _endLabelPainter, activationAnimation: _valueIndicatorAnimation, - textScaleFactor: textScaleFactor, - sizeWithOverflow: resolvedSizeWithOverflow, ); - final double startHalfWidth = sliderTheme.rangeValueIndicatorShape.getPreferredSize( - isEnabled, - isDiscrete, - labelPainter: _startLabelPainter, - textScaleFactor: textScaleFactor, - ).width / 2; - final double endHalfWidth = sliderTheme.rangeValueIndicatorShape.getPreferredSize( - isEnabled, - isDiscrete, - labelPainter: _endLabelPainter, - textScaleFactor: textScaleFactor, - ).width / 2; + final double startHalfWidth = sliderTheme.rangeValueIndicatorShape.getPreferredSize(isEnabled, isDiscrete, labelPainter: _startLabelPainter).width / 2; + final double endHalfWidth = sliderTheme.rangeValueIndicatorShape.getPreferredSize(isEnabled, isDiscrete, labelPainter: _endLabelPainter).width / 2; double innerOverflow = startHalfWidth + endHalfWidth; switch (textDirection) { case TextDirection.ltr: @@ -1394,22 +1338,19 @@ class _RenderRangeSlider extends RenderBox with RelayoutWhenSystemFontsChangeMix textDirection: _textDirection, thumb: topThumb, value: topValue, - textScaleFactor: textScaleFactor, - sizeWithOverflow: resolvedSizeWithOverflow, ); } _sliderTheme.rangeThumbShape.paint( context, topThumbCenter, - activationAnimation: _overlayAnimation, + activationAnimation: _valueIndicatorAnimation, enableAnimation: _enableAnimation, isDiscrete: isDiscrete, isOnTop: thumbDelta < sliderTheme.rangeThumbShape.getPreferredSize(isEnabled, isDiscrete).width, textDirection: textDirection, sliderTheme: _sliderTheme, thumb: topThumb, - isPressed: topThumb == Thumb.start ? startThumbSelected : endThumbSelected, ); } diff --git a/packages/flutter/lib/src/material/slider.dart b/packages/flutter/lib/src/material/slider.dart index 25db8471b10..025b68833db 100644 --- a/packages/flutter/lib/src/material/slider.dart +++ b/packages/flutter/lib/src/material/slider.dart @@ -477,12 +477,12 @@ class _SliderState extends State with TickerProviderStateMixin { return widget.max > widget.min ? (value - widget.min) / (widget.max - widget.min) : 0.0; } - static const double _defaultTrackHeight = 4; + static const double _defaultTrackHeight = 2; static const SliderTrackShape _defaultTrackShape = RoundedRectSliderTrackShape(); static const SliderTickMarkShape _defaultTickMarkShape = RoundSliderTickMarkShape(); static const SliderComponentShape _defaultOverlayShape = RoundSliderOverlayShape(); static const SliderComponentShape _defaultThumbShape = RoundSliderThumbShape(); - static const SliderComponentShape _defaultValueIndicatorShape = RectangularSliderValueIndicatorShape(); + static const SliderComponentShape _defaultValueIndicatorShape = PaddleSliderValueIndicatorShape(); static const ShowValueIndicator _defaultShowValueIndicator = ShowValueIndicator.onlyForDiscrete; @override @@ -520,19 +520,6 @@ class _SliderState extends State with TickerProviderStateMixin { // colors come from the ThemeData.colorScheme. These colors, along with // the default shapes and text styles are aligned to the Material // Guidelines. - - // The value indicator color is not the same as the thumb and active track - // (which can be defined by activeColor) if the - // RectangularSliderValueIndicatorShape is used. In all other cases, the - // value indicator is assumed to be the same as the active color. - final SliderComponentShape valueIndicatorShape = sliderTheme.valueIndicatorShape ?? _defaultValueIndicatorShape; - Color valueIndicatorColor; - if (valueIndicatorShape is RectangularSliderValueIndicatorShape) { - valueIndicatorColor = sliderTheme.valueIndicatorColor ?? Color.alphaBlend(theme.colorScheme.onSurface.withOpacity(0.60), theme.colorScheme.surface.withOpacity(0.90)); - } else { - valueIndicatorColor = widget.activeColor ?? sliderTheme.valueIndicatorColor ?? theme.colorScheme.primary; - } - sliderTheme = sliderTheme.copyWith( trackHeight: sliderTheme.trackHeight ?? _defaultTrackHeight, activeTrackColor: widget.activeColor ?? sliderTheme.activeTrackColor ?? theme.colorScheme.primary, @@ -546,31 +533,24 @@ class _SliderState extends State with TickerProviderStateMixin { thumbColor: widget.activeColor ?? sliderTheme.thumbColor ?? theme.colorScheme.primary, disabledThumbColor: sliderTheme.disabledThumbColor ?? theme.colorScheme.onSurface.withOpacity(0.38), overlayColor: widget.activeColor?.withOpacity(0.12) ?? sliderTheme.overlayColor ?? theme.colorScheme.primary.withOpacity(0.12), - valueIndicatorColor: valueIndicatorColor, - surfaceColor: sliderTheme.surfaceColor ?? theme.colorScheme.surface, + valueIndicatorColor: widget.activeColor ?? sliderTheme.valueIndicatorColor ?? theme.colorScheme.primary, trackShape: sliderTheme.trackShape ?? _defaultTrackShape, tickMarkShape: sliderTheme.tickMarkShape ?? _defaultTickMarkShape, thumbShape: sliderTheme.thumbShape ?? _defaultThumbShape, overlayShape: sliderTheme.overlayShape ?? _defaultOverlayShape, - valueIndicatorShape: valueIndicatorShape, + valueIndicatorShape: sliderTheme.valueIndicatorShape ?? _defaultValueIndicatorShape, showValueIndicator: sliderTheme.showValueIndicator ?? _defaultShowValueIndicator, valueIndicatorTextStyle: sliderTheme.valueIndicatorTextStyle ?? theme.textTheme.body2.copyWith( color: theme.colorScheme.onPrimary, ), ); - // This size is used as the max bounds for the painting of the value - // indicators It must be kept in sync with the function with the same name - // in range_slider.dart. - Size _sizeWithOverflow() => MediaQuery.of(context).size; - return _SliderRenderObjectWidget( value: _unlerp(widget.value), divisions: widget.divisions, label: widget.label, sliderTheme: sliderTheme, - textScaleFactor: MediaQuery.of(context).textScaleFactor, - sizeWithOverflow: _sizeWithOverflow(), + mediaQueryData: MediaQuery.of(context), onChanged: (widget.onChanged != null) && (widget.max > widget.min) ? _handleChanged : null, onChangeStart: widget.onChangeStart != null ? _handleDragStart : null, onChangeEnd: widget.onChangeEnd != null ? _handleDragEnd : null, @@ -606,8 +586,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { this.divisions, this.label, this.sliderTheme, - this.textScaleFactor, - this.sizeWithOverflow, + this.mediaQueryData, this.onChanged, this.onChangeStart, this.onChangeEnd, @@ -619,8 +598,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { final int divisions; final String label; final SliderThemeData sliderTheme; - final double textScaleFactor; - final Size sizeWithOverflow; + final MediaQueryData mediaQueryData; final ValueChanged onChanged; final ValueChanged onChangeStart; final ValueChanged onChangeEnd; @@ -634,8 +612,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { divisions: divisions, label: label, sliderTheme: sliderTheme, - textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow, + mediaQueryData: mediaQueryData, onChanged: onChanged, onChangeStart: onChangeStart, onChangeEnd: onChangeEnd, @@ -654,8 +631,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget { ..label = label ..sliderTheme = sliderTheme ..theme = Theme.of(context) - ..textScaleFactor = textScaleFactor - ..sizeWithOverflow = sizeWithOverflow + ..mediaQueryData = mediaQueryData ..onChanged = onChanged ..onChangeStart = onChangeStart ..onChangeEnd = onChangeEnd @@ -673,8 +649,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { int divisions, String label, SliderThemeData sliderTheme, - double textScaleFactor, - Size sizeWithOverflow, + MediaQueryData mediaQueryData, TargetPlatform platform, ValueChanged onChanged, SemanticFormatterCallback semanticFormatterCallback, @@ -691,8 +666,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { _value = value, _divisions = divisions, _sliderTheme = sliderTheme, - _textScaleFactor = textScaleFactor, - _sizeWithOverflow = sizeWithOverflow, + _mediaQueryData = mediaQueryData, _onChanged = onChanged, _state = state, _textDirection = textDirection { @@ -847,28 +821,18 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { markNeedsPaint(); } - double get textScaleFactor => _textScaleFactor; - double _textScaleFactor; - set textScaleFactor(double value) { - if (value == _textScaleFactor) { + MediaQueryData get mediaQueryData => _mediaQueryData; + MediaQueryData _mediaQueryData; + set mediaQueryData(MediaQueryData value) { + if (value == _mediaQueryData) { return; } - _textScaleFactor = value; + _mediaQueryData = value; // Media query data includes the textScaleFactor, so we need to update the // label painter. _updateLabelPainter(); } - Size get sizeWithOverflow => _sizeWithOverflow; - Size _sizeWithOverflow; - set sizeWithOverflow(Size value) { - if (value == _sizeWithOverflow) { - return; - } - _sizeWithOverflow = value; - markNeedsPaint(); - } - ValueChanged get onChanged => _onChanged; ValueChanged _onChanged; set onChanged(ValueChanged value) { @@ -942,7 +906,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { text: label, ) ..textDirection = textDirection - ..textScaleFactor = textScaleFactor + ..textScaleFactor = _mediaQueryData.textScaleFactor ..layout(); } else { _labelPainter.text = null; @@ -1123,8 +1087,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { sliderTheme: _sliderTheme, isDiscrete: isDiscrete, ); - final Offset thumbCenter = Offset( - trackRect.left + visualPosition * trackRect.width, trackRect.center.dy); + final Offset thumbCenter = Offset(trackRect.left + visualPosition * trackRect.width, trackRect.center.dy); _sliderTheme.trackShape.paint( context, @@ -1158,7 +1121,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { isEnabled: isInteractive, sliderTheme: _sliderTheme, ).width; - final double adjustedTrackWidth = trackRect.width - trackRect.height; + final double adjustedTrackWidth = trackRect.width - tickMarkWidth; // If the tick marks would be too dense, don't bother painting them. if (adjustedTrackWidth / divisions >= 3.0 * tickMarkWidth) { final double dy = trackRect.center.dy; @@ -1166,7 +1129,7 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { final double value = i / divisions; // The ticks are mapped to be within the track, so the tick mark width // must be subtracted from the track width. - final double dx = trackRect.left + value * adjustedTrackWidth + trackRect.height / 2; + final double dx = trackRect.left + value * adjustedTrackWidth + tickMarkWidth / 2; final Offset tickMarkOffset = Offset(dx, dy); _sliderTheme.tickMarkShape.paint( context, @@ -1195,8 +1158,6 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { sliderTheme: _sliderTheme, textDirection: _textDirection, value: _value, - textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow.isEmpty ? size : sizeWithOverflow, ); } } @@ -1204,14 +1165,13 @@ class _RenderSlider extends RenderBox with RelayoutWhenSystemFontsChangeMixin { _sliderTheme.thumbShape.paint( context, thumbCenter, - activationAnimation: _overlayAnimation, + activationAnimation: _valueIndicatorAnimation, enableAnimation: _enableAnimation, isDiscrete: isDiscrete, labelPainter: _labelPainter, parentBox: this, sliderTheme: _sliderTheme, textDirection: _textDirection, - sizeWithOverflow: sizeWithOverflow.isEmpty ? size : sizeWithOverflow, value: _value, ); } diff --git a/packages/flutter/lib/src/material/slider_theme.dart b/packages/flutter/lib/src/material/slider_theme.dart index a0a7d24ac09..52282c19ecb 100644 --- a/packages/flutter/lib/src/material/slider_theme.dart +++ b/packages/flutter/lib/src/material/slider_theme.dart @@ -278,7 +278,7 @@ enum Thumb { /// by creating subclasses of [SliderTrackShape], /// [SliderComponentShape], and/or [SliderTickMarkShape]. See /// [RoundSliderThumbShape], [RectangularSliderTrackShape], -/// [RoundSliderTickMarkShape], [RectangularSliderValueIndicatorShape], and +/// [RoundSliderTickMarkShape], [PaddleSliderValueIndicatorShape], and /// [RoundSliderOverlayShape] for examples. /// /// The track painting can be skipped by specifying 0 for [trackHeight]. @@ -355,7 +355,6 @@ class SliderThemeData extends Diagnosticable { this.disabledThumbColor, this.overlayColor, this.valueIndicatorColor, - this.surfaceColor, this.overlayShape, this.tickMarkShape, this.thumbShape, @@ -491,14 +490,6 @@ class SliderThemeData extends Diagnosticable { /// The color given to the [valueIndicatorShape] to draw itself with. final Color valueIndicatorColor; - /// The surface color that the slider is resting on. - /// - /// This is used to clear painting regions for possibly transparent thumbs and - /// thumb shadows. - /// - /// Defaults to [ColorScheme.surface]. - final Color surfaceColor; - /// The shape that will be used to draw the [Slider]'s overlay. /// /// Both the [overlayColor] and a non default [overlayShape] may be specified. @@ -665,7 +656,6 @@ class SliderThemeData extends Diagnosticable { Color disabledThumbColor, Color overlayColor, Color valueIndicatorColor, - Color surfaceColor, SliderComponentShape overlayShape, SliderTickMarkShape tickMarkShape, SliderComponentShape thumbShape, @@ -695,7 +685,6 @@ class SliderThemeData extends Diagnosticable { disabledThumbColor: disabledThumbColor ?? this.disabledThumbColor, overlayColor: overlayColor ?? this.overlayColor, valueIndicatorColor: valueIndicatorColor ?? this.valueIndicatorColor, - surfaceColor: surfaceColor ?? this.surfaceColor, overlayShape: overlayShape ?? this.overlayShape, tickMarkShape: tickMarkShape ?? this.tickMarkShape, thumbShape: thumbShape ?? this.thumbShape, @@ -736,7 +725,6 @@ class SliderThemeData extends Diagnosticable { disabledThumbColor: Color.lerp(a.disabledThumbColor, b.disabledThumbColor, t), overlayColor: Color.lerp(a.overlayColor, b.overlayColor, t), valueIndicatorColor: Color.lerp(a.valueIndicatorColor, b.valueIndicatorColor, t), - surfaceColor: Color.lerp(a.surfaceColor, b.surfaceColor, t), overlayShape: t < 0.5 ? a.overlayShape : b.overlayShape, tickMarkShape: t < 0.5 ? a.tickMarkShape : b.tickMarkShape, thumbShape: t < 0.5 ? a.thumbShape : b.thumbShape, @@ -770,7 +758,6 @@ class SliderThemeData extends Diagnosticable { disabledThumbColor, overlayColor, valueIndicatorColor, - surfaceColor, overlayShape, tickMarkShape, thumbShape, @@ -810,7 +797,6 @@ class SliderThemeData extends Diagnosticable { && otherData.disabledThumbColor == disabledThumbColor && otherData.overlayColor == overlayColor && otherData.valueIndicatorColor == valueIndicatorColor - && otherData.surfaceColor == surfaceColor && otherData.overlayShape == overlayShape && otherData.tickMarkShape == tickMarkShape && otherData.thumbShape == thumbShape @@ -844,7 +830,6 @@ class SliderThemeData extends Diagnosticable { properties.add(ColorProperty('disabledThumbColor', disabledThumbColor, defaultValue: defaultData.disabledThumbColor)); properties.add(ColorProperty('overlayColor', overlayColor, defaultValue: defaultData.overlayColor)); properties.add(ColorProperty('valueIndicatorColor', valueIndicatorColor, defaultValue: defaultData.valueIndicatorColor)); - properties.add(ColorProperty('surfaceColor', surfaceColor, defaultValue: defaultData.surfaceColor)); properties.add(DiagnosticsProperty('overlayShape', overlayShape, defaultValue: defaultData.overlayShape)); properties.add(DiagnosticsProperty('tickMarkShape', tickMarkShape, defaultValue: defaultData.tickMarkShape)); properties.add(DiagnosticsProperty('thumbShape', thumbShape, defaultValue: defaultData.thumbShape)); @@ -993,16 +978,6 @@ abstract class SliderComponentShape { /// [labelPainter] already has the [textDirection] set. /// /// [value] is the current parametric value (from 0.0 to 1.0) of the slider. - /// - /// [textScaleFactor] can be used to determine whether the component should - /// paint larger or smaller, depending on whether [textScaleFactor] is greater - /// than 1 for larger, and between 0 and 1 for smaller. It usually comes from - /// [MediaQueryData.textScaleFactor]. - /// - /// [sizeWithOverflow] can be used to determine the bounds the drawing of the - /// components that are outside of the regular slider bounds. It's the size of - /// the box, whose center is aligned with the slider's bounds, that the value - /// indicators must be drawn within. Typically, it is bigger than the slider. void paint( PaintingContext context, Offset center, { @@ -1014,8 +989,6 @@ abstract class SliderComponentShape { SliderThemeData sliderTheme, TextDirection textDirection, double value, - double textScaleFactor, - Size sizeWithOverflow, }); /// Special instance of [SliderComponentShape] to skip the thumb drawing. @@ -1231,9 +1204,6 @@ abstract class RangeSliderThumbShape { /// left and right thumb. /// /// {@macro flutter.material.rangeSlider.shape.thumb} - /// - /// [isPressed] can be used to give the selected thumb additional selected - /// or pressed state visual feedback, such as a larger shadow. void paint( PaintingContext context, Offset center, { @@ -1245,7 +1215,6 @@ abstract class RangeSliderThumbShape { TextDirection textDirection, SliderThemeData sliderTheme, Thumb thumb, - bool isPressed, }); } @@ -1271,17 +1240,7 @@ abstract class RangeSliderValueIndicatorShape { /// /// [labelPainter] helps determine the width of the shape. It is variable /// width because it is derived from a formatted string. - /// - /// [textScaleFactor] can be used to determine whether the component should - /// paint larger or smaller, depending on whether [textScaleFactor] is greater - /// than 1 for larger, and between 0 and 1 for smaller. It usually comes from - /// [MediaQueryData.textScaleFactor]. - Size getPreferredSize( - bool isEnabled, - bool isDiscrete, { - TextPainter labelPainter, - double textScaleFactor, - }); + Size getPreferredSize(bool isEnabled, bool isDiscrete, { TextPainter labelPainter }); /// Determines the best offset to keep this shape on the screen. /// @@ -1292,8 +1251,6 @@ abstract class RangeSliderValueIndicatorShape { Offset center, TextPainter labelPainter, Animation activationAnimation, - double textScaleFactor, - Size sizeWithOverflow, }) { return 0; } @@ -1315,18 +1272,6 @@ abstract class RangeSliderValueIndicatorShape { /// the default case, this is used to paint a stroke around the top indicator /// for better visibility between the two indicators. /// - /// [textScaleFactor] can be used to determine whether the component should - /// paint larger or smaller, depending on whether [textScaleFactor] is greater - /// than 1 for larger, and between 0 and 1 for smaller. It usually comes from - /// [MediaQueryData.textScaleFactor]. - /// - /// [sizeWithOverflow] can be used to determine the bounds the drawing of the - /// components that are outside of the regular slider bounds. It's the size of - /// the box, whose center is aligned with the slider's bounds, that the value - /// indicators must be drawn within. Typically, it is bigger than the slider. - /// - /// {@macro flutter.material.rangeSlider.shape.parentBox} - /// /// {@macro flutter.material.rangeSlider.shape.sliderTheme} /// /// [textDirection] can be used to determine how any extra text or graphics, @@ -1344,8 +1289,6 @@ abstract class RangeSliderValueIndicatorShape { bool isDiscrete, bool isOnTop, TextPainter labelPainter, - double textScaleFactor, - Size sizeWithOverflow, RenderBox parentBox, SliderThemeData sliderTheme, TextDirection textDirection, @@ -1611,17 +1554,17 @@ class RectangularSliderTrackShape extends SliderTrackShape with BaseSliderTrackS assert(thumbCenter != null); assert(isEnabled != null); assert(isDiscrete != null); - // If the slider [SliderThemeData.trackHeight] is less than or equal to 0, - // then it makes no difference whether the track is painted or not, - // therefore the painting can be a no-op. + // If the slider track height is less than or equal to 0, then it makes no + // difference whether the track is painted or not, therefore the painting + // can be a no-op. if (sliderTheme.trackHeight <= 0) { return; } // Assign the track segment paints, which are left: active, right: inactive, // but reversed for right to left text. - final ColorTween activeTrackColorTween = ColorTween(begin: sliderTheme.disabledActiveTrackColor, end: sliderTheme.activeTrackColor); - final ColorTween inactiveTrackColorTween = ColorTween(begin: sliderTheme.disabledInactiveTrackColor, end: sliderTheme.inactiveTrackColor); + final ColorTween activeTrackColorTween = ColorTween(begin: sliderTheme.disabledActiveTrackColor , end: sliderTheme.activeTrackColor); + final ColorTween inactiveTrackColorTween = ColorTween(begin: sliderTheme.disabledInactiveTrackColor , end: sliderTheme.inactiveTrackColor); final Paint activePaint = Paint()..color = activeTrackColorTween.evaluate(enableAnimation); final Paint inactivePaint = Paint()..color = inactiveTrackColorTween.evaluate(enableAnimation); Paint leftTrackPaint; @@ -1645,10 +1588,11 @@ class RectangularSliderTrackShape extends SliderTrackShape with BaseSliderTrackS isDiscrete: isDiscrete, ); - final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left + trackRect.height / 2, trackRect.top, thumbCenter.dx, trackRect.bottom); + final Size thumbSize = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete); + final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left + trackRect.height / 2, trackRect.top, thumbCenter.dx - thumbSize.width / 2, trackRect.bottom); if (!leftTrackSegment.isEmpty) context.canvas.drawRect(leftTrackSegment, leftTrackPaint); - final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx, trackRect.top, trackRect.right, trackRect.bottom); + final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx + thumbSize.width / 2, trackRect.top, trackRect.right, trackRect.bottom); if (!rightTrackSegment.isEmpty) context.canvas.drawRect(rightTrackSegment, rightTrackPaint); } @@ -1704,9 +1648,9 @@ class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackS assert(enableAnimation != null); assert(textDirection != null); assert(thumbCenter != null); - // If the slider [SliderThemeData.trackHeight] is less than or equal to 0, - // then it makes no difference whether the track is painted or not, - // therefore the painting can be a no-op. + // If the slider track height is less than or equal to 0, then it makes no + // difference whether the track is painted or not, therefore the painting + // can be a no-op. if (sliderTheme.trackHeight <= 0) { return; } @@ -1737,30 +1681,22 @@ class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackS isEnabled: isEnabled, isDiscrete: isDiscrete, ); - final Radius trackRadius = Radius.circular(trackRect.height / 2); - context.canvas.drawRRect( - RRect.fromLTRBAndCorners( - trackRect.left, - trackRect.top, - thumbCenter.dx, - trackRect.bottom, - topLeft: trackRadius, - bottomLeft: trackRadius, - ), - leftTrackPaint, - ); - context.canvas.drawRRect( - RRect.fromLTRBAndCorners( - thumbCenter.dx, - trackRect.top, - trackRect.right, - trackRect.bottom, - topRight: trackRadius, - bottomRight: trackRadius, - ), - rightTrackPaint, - ); + // The arc rects create a semi-circle with radius equal to track height. + final Rect leftTrackArcRect = Rect.fromLTWH(trackRect.left, trackRect.top, trackRect.height, trackRect.height); + if (!leftTrackArcRect.isEmpty) + context.canvas.drawArc(leftTrackArcRect, math.pi / 2, math.pi, false, leftTrackPaint); + final Rect rightTrackArcRect = Rect.fromLTWH(trackRect.right - trackRect.height / 2, trackRect.top, trackRect.height, trackRect.height); + if (!rightTrackArcRect.isEmpty) + context.canvas.drawArc(rightTrackArcRect, -math.pi / 2, math.pi, false, rightTrackPaint); + + final Size thumbSize = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete); + final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left + trackRect.height / 2, trackRect.top, thumbCenter.dx - thumbSize.width / 2, trackRect.bottom); + if (!leftTrackSegment.isEmpty) + context.canvas.drawRect(leftTrackSegment, leftTrackPaint); + final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx + thumbSize.width / 2, trackRect.top, trackRect.right, trackRect.bottom); + if (!rightTrackSegment.isEmpty) + context.canvas.drawRect(rightTrackSegment, rightTrackPaint); } } @@ -1976,11 +1912,6 @@ class RoundedRectRangeSliderTrackShape extends RangeSliderTrackShape { assert(isEnabled != null); assert(isDiscrete != null); assert(textDirection != null); - - if (sliderTheme.trackHeight <= 0) { - return; - } - // Assign the track segment paints, which are left: active, right: inactive, // but reversed for right to left text. final ColorTween activeTrackColorTween = ColorTween(begin: sliderTheme.disabledActiveTrackColor , end: sliderTheme.activeTrackColor); @@ -2011,39 +1942,25 @@ class RoundedRectRangeSliderTrackShape extends RangeSliderTrackShape { isEnabled: isEnabled, isDiscrete: isDiscrete, ); - final Radius trackRadius = Radius.circular(trackRect.height / 2); + final double trackRadius = trackRect.height / 2; - context.canvas.drawRRect( - RRect.fromLTRBAndCorners( - trackRect.left, - trackRect.top, - leftThumbOffset.dx, - trackRect.bottom, - topLeft: trackRadius, - bottomLeft: trackRadius, - ), - inactivePaint, - ); - context.canvas.drawRect( - Rect.fromLTRB( - leftThumbOffset.dx, - trackRect.top, - rightThumbOffset.dx, - trackRect.bottom, - ), - activePaint, - ); - context.canvas.drawRRect( - RRect.fromLTRBAndCorners( - rightThumbOffset.dx, - trackRect.top, - trackRect.right, - trackRect.bottom, - topRight: trackRadius, - bottomRight: trackRadius, - ), - inactivePaint, - ); + final Rect leftTrackArcRect = Rect.fromLTWH(trackRect.left, trackRect.top, trackRect.height, trackRect.height); + if (!leftTrackArcRect.isEmpty) + context.canvas.drawArc(leftTrackArcRect, math.pi / 2, math.pi, false, inactivePaint); + + final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left + trackRadius, trackRect.top, leftThumbOffset.dx - thumbRadius, trackRect.bottom); + if (!leftTrackSegment.isEmpty) + context.canvas.drawRect(leftTrackSegment, inactivePaint); + final Rect middleTrackSegment = Rect.fromLTRB(leftThumbOffset.dx + thumbRadius, trackRect.top, rightThumbOffset.dx - thumbRadius, trackRect.bottom); + if (!middleTrackSegment.isEmpty) + context.canvas.drawRect(middleTrackSegment, activePaint); + final Rect rightTrackSegment = Rect.fromLTRB(rightThumbOffset.dx + thumbRadius, trackRect.top, trackRect.right - trackRadius, trackRect.bottom); + if (!rightTrackSegment.isEmpty) + context.canvas.drawRect(rightTrackSegment, inactivePaint); + + final Rect rightTrackArcRect = Rect.fromLTWH(trackRect.right - trackRect.height, trackRect.top, trackRect.height, trackRect.height); + if (!rightTrackArcRect.isEmpty) + context.canvas.drawArc(rightTrackArcRect, -math.pi / 2, math.pi, false, inactivePaint); } } @@ -2071,8 +1988,7 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape { /// The preferred radius of the round tick mark. /// - /// If it is not provided, then 1/4 of the [SliderThemeData.trackHeight] is - /// used. + /// If it is not provided, then half of the track height is used. final double tickMarkRadius; @override @@ -2083,10 +1999,9 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape { assert(sliderTheme != null); assert(sliderTheme.trackHeight != null); assert(isEnabled != null); - // The tick marks are tiny circles. If no radius is provided, then the - // radius is defaulted to be 1/4 of the [SliderThemeData.trackHeight], or a - // diameter of half the [SliderThemeData.trackHeight]. - return Size.fromRadius(tickMarkRadius ?? sliderTheme.trackHeight / 4); + // The tick marks are tiny circles. If no radius is provided, then they are + // defaulted to be the same height as the track. + return Size.fromRadius(tickMarkRadius ?? sliderTheme.trackHeight / 2); } @override @@ -2165,8 +2080,7 @@ class RoundRangeSliderTickMarkShape extends RangeSliderTickMarkShape { /// The preferred radius of the round tick mark. /// - /// If it is not provided, then 1/4 of the [SliderThemeData.trackHeight] is - /// used. + /// If it is not provided, then half of the track height is used. final double tickMarkRadius; @override @@ -2177,7 +2091,7 @@ class RoundRangeSliderTickMarkShape extends RangeSliderTickMarkShape { assert(sliderTheme != null); assert(sliderTheme.trackHeight != null); assert(isEnabled != null); - return Size.fromRadius(tickMarkRadius ?? sliderTheme.trackHeight / 4); + return Size.fromRadius(tickMarkRadius ?? sliderTheme.trackHeight / 2); } @override @@ -2286,8 +2200,6 @@ class _EmptySliderComponentShape extends SliderComponentShape { SliderThemeData sliderTheme, TextDirection textDirection, double value, - double textScaleFactor, - Size sizeWithOverflow, }) { // no-op. } @@ -2305,8 +2217,6 @@ class RoundSliderThumbShape extends SliderComponentShape { const RoundSliderThumbShape({ this.enabledThumbRadius = 10.0, this.disabledThumbRadius, - this.elevation = 1.0, - this.pressedElevation = 6.0, }); /// The preferred radius of the round thumb shape when the slider is enabled. @@ -2321,22 +2231,6 @@ class RoundSliderThumbShape extends SliderComponentShape { final double disabledThumbRadius; double get _disabledThumbRadius => disabledThumbRadius ?? enabledThumbRadius; - /// The resting elevation adds shadow to the unpressed thumb. - /// - /// The default is 1. - /// - /// Use 0 for no shadow. The higher the value, the larger the shadow. For - /// example, a value of 12 will create a very large shadow. - final double elevation; - - /// The pressed elevation adds shadow to the pressed thumb. - /// - /// The default is 6. - /// - /// Use 0 for no shadow. The higher the value, the larger the shadow. For - /// example, a value of 12 will create a very large shadow. - final double pressedElevation; - @override Size getPreferredSize(bool isEnabled, bool isDiscrete) { return Size.fromRadius(isEnabled == true ? enabledThumbRadius : _disabledThumbRadius); @@ -2354,8 +2248,6 @@ class RoundSliderThumbShape extends SliderComponentShape { @required SliderThemeData sliderTheme, TextDirection textDirection, double value, - double textScaleFactor, - Size sizeWithOverflow, }) { assert(context != null); assert(center != null); @@ -2363,7 +2255,6 @@ class RoundSliderThumbShape extends SliderComponentShape { assert(sliderTheme != null); assert(sliderTheme.disabledThumbColor != null); assert(sliderTheme.thumbColor != null); - assert(!sizeWithOverflow.isEmpty); final Canvas canvas = context.canvas; final Tween radiusTween = Tween( @@ -2374,31 +2265,10 @@ class RoundSliderThumbShape extends SliderComponentShape { begin: sliderTheme.disabledThumbColor, end: sliderTheme.thumbColor, ); - final Tween elevationTween = Tween( - begin: elevation, - end: pressedElevation, - ); - - final double evaluatedElevation = elevationTween.evaluate(activationAnimation); - final Color color = colorTween.evaluate(enableAnimation); - final double radius = radiusTween.evaluate(enableAnimation); - final Path path = Path()..addArc(Rect.fromCenter(center: center, width: 2 * radius, height: 2 * radius), 0, math.pi * 2); - canvas.drawShadow(path, Colors.black, evaluatedElevation, true); - - // If the thumb is translucent, clear the space of the track and shadow so - // the thumb can be drawn without interference. - if (color.alpha != 0xff) { - canvas.drawCircle( - center, - radius, - Paint()..color = sliderTheme.surfaceColor.withOpacity(1), - ); - } - canvas.drawCircle( center, - radius, - Paint()..color = color, + radiusTween.evaluate(enableAnimation), + Paint()..color = colorTween.evaluate(enableAnimation), ); } } @@ -2415,8 +2285,6 @@ class RoundRangeSliderThumbShape extends RangeSliderThumbShape { const RoundRangeSliderThumbShape({ this.enabledThumbRadius = 10.0, this.disabledThumbRadius, - this.elevation = 1.0, - this.pressedElevation = 6.0, }) : assert(enabledThumbRadius != null); /// The preferred radius of the round thumb shape when the slider is enabled. @@ -2431,16 +2299,6 @@ class RoundRangeSliderThumbShape extends RangeSliderThumbShape { final double disabledThumbRadius; double get _disabledThumbRadius => disabledThumbRadius ?? enabledThumbRadius; - /// The resting elevation adds shadow to the unpressed thumb. - /// - /// The default is 1. - final double elevation; - - /// The pressed elevation adds shadow to the pressed thumb. - /// - /// The default is 6. - final double pressedElevation; - @override Size getPreferredSize(bool isEnabled, bool isDiscrete) { return Size.fromRadius(isEnabled == true ? enabledThumbRadius : _disabledThumbRadius); @@ -2458,7 +2316,6 @@ class RoundRangeSliderThumbShape extends RangeSliderThumbShape { @required SliderThemeData sliderTheme, TextDirection textDirection, Thumb thumb, - bool isPressed, }) { assert(context != null); assert(center != null); @@ -2477,10 +2334,6 @@ class RoundRangeSliderThumbShape extends RangeSliderThumbShape { end: sliderTheme.thumbColor, ); final double radius = radiusTween.evaluate(enableAnimation); - final Tween elevationTween = Tween( - begin: elevation, - end: pressedElevation, - ); // Add a stroke of 1dp around the circle if this thumb would overlap // the other thumb. @@ -2510,26 +2363,10 @@ class RoundRangeSliderThumbShape extends RangeSliderThumbShape { } } - final double evaluatedElevation = isPressed ? elevationTween.evaluate(activationAnimation) : elevation; - final Color color = colorTween.evaluate(enableAnimation); - final Path shadowPath = Path()..addArc(Rect.fromCenter(center: center, width: 2 * radius, height: 2 * radius), 0, math.pi * 2); - canvas.drawShadow(shadowPath, Colors.black, evaluatedElevation, true); - - // If the thumb is translucent, clear the space of the track and shadow so - // the thumb can be drawn without interference. - if (color.alpha != 0xff) { - canvas.drawCircle( - center, - radius, - Paint() - ..color = sliderTheme.surfaceColor.withOpacity(1), - ); - } - canvas.drawCircle( center, radius, - Paint()..color = color, + Paint()..color = colorTween.evaluate(enableAnimation), ); } } @@ -2555,8 +2392,7 @@ class RoundSliderOverlayShape extends SliderComponentShape { /// The preferred radius of the round thumb shape when enabled. /// - /// If it is not provided, then half of the [SliderThemeData.trackHeight] is - /// used. + /// If it is not provided, then half of the track height is used. final double overlayRadius; @override @@ -2576,8 +2412,6 @@ class RoundSliderOverlayShape extends SliderComponentShape { @required SliderThemeData sliderTheme, @required TextDirection textDirection, @required double value, - double textScaleFactor, - Size sizeWithOverflow, }) { assert(context != null); assert(center != null); @@ -2610,20 +2444,16 @@ class RoundSliderOverlayShape extends SliderComponentShape { /// * [Slider], which includes a value indicator defined by this shape. /// * [SliderTheme], which can be used to configure the slider value indicator /// of all sliders in a widget subtree. -class RectangularSliderValueIndicatorShape extends SliderComponentShape { - /// Create a slider value indicator that resembles a rectangular tooltip. - const RectangularSliderValueIndicatorShape(); +class PaddleSliderValueIndicatorShape extends SliderComponentShape { + /// Create a slider value indicator in the shape of an upside-down pear. + const PaddleSliderValueIndicatorShape(); - static const _RectangularSliderValueIndicatorPathPainter _pathPainter = _RectangularSliderValueIndicatorPathPainter(); + static const _PaddleSliderTrackShapePathPainter _pathPainter = _PaddleSliderTrackShapePathPainter(); @override - Size getPreferredSize(bool isEnabled, bool isDiscrete, { - @required TextPainter labelPainter, - @required double textScaleFactor, - }) { + Size getPreferredSize(bool isEnabled, bool isDiscrete, { @required TextPainter labelPainter }) { assert(labelPainter != null); - assert(textScaleFactor != null && textScaleFactor >= 0); - return _pathPainter.getPreferredSize(isEnabled, isDiscrete, labelPainter, textScaleFactor); + return _pathPainter.getPreferredSize(isEnabled, isDiscrete, labelPainter); } @override @@ -2638,20 +2468,26 @@ class RectangularSliderValueIndicatorShape extends SliderComponentShape { @required SliderThemeData sliderTheme, TextDirection textDirection, double value, - double textScaleFactor, - Size sizeWithOverflow, }) { - final Canvas canvas = context.canvas; - final double scale = activationAnimation.value; - _pathPainter.paint( - parentBox: parentBox, - canvas: canvas, - center: center, - scale: scale, - labelPainter: labelPainter, - textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow, - backgroundPaintColor: sliderTheme.valueIndicatorColor + assert(context != null); + assert(center != null); + assert(activationAnimation != null); + assert(enableAnimation != null); + assert(labelPainter != null); + assert(parentBox != null); + assert(sliderTheme != null); + final ColorTween enableColor = ColorTween( + begin: sliderTheme.disabledThumbColor, + end: sliderTheme.valueIndicatorColor, + ); + _pathPainter.drawValueIndicator( + parentBox, + context.canvas, + center, + Paint()..color = enableColor.evaluate(enableAnimation), + activationAnimation.value, + labelPainter, + null, ); } } @@ -2663,283 +2499,16 @@ class RectangularSliderValueIndicatorShape extends SliderComponentShape { /// * [RangeSlider], which includes value indicators defined by this shape. /// * [SliderTheme], which can be used to configure the range slider value /// indicator of all sliders in a widget subtree. -class RectangularRangeSliderValueIndicatorShape extends RangeSliderValueIndicatorShape { - /// Create a range slider value indicator that resembles a rectangular tooltip. - const RectangularRangeSliderValueIndicatorShape(); - - static const _RectangularSliderValueIndicatorPathPainter _pathPainter = _RectangularSliderValueIndicatorPathPainter(); - - @override - Size getPreferredSize( - bool isEnabled, - bool isDiscrete, { - @required TextPainter labelPainter, - @required double textScaleFactor, - }) { - assert(labelPainter != null); - assert(textScaleFactor != null && textScaleFactor >= 0); - return _pathPainter.getPreferredSize(isEnabled, isDiscrete, labelPainter, textScaleFactor); - } - - @override - double getHorizontalShift({ - RenderBox parentBox, - Offset center, - TextPainter labelPainter, - Animation activationAnimation, - double textScaleFactor, - Size sizeWithOverflow, - }) { - return _pathPainter.getHorizontalShift( - parentBox: parentBox, - center: center, - labelPainter: labelPainter, - textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow, - scale: activationAnimation.value, - ); - } - - @override - void paint( - PaintingContext context, - Offset center, { - Animation activationAnimation, - Animation enableAnimation, - bool isDiscrete, - bool isOnTop, - TextPainter labelPainter, - double textScaleFactor, - Size sizeWithOverflow, - RenderBox parentBox, - SliderThemeData sliderTheme, - TextDirection textDirection, - double value, - Thumb thumb, - }) { - final Canvas canvas = context.canvas; - final double scale = activationAnimation.value; - _pathPainter.paint( - parentBox: parentBox, - canvas: canvas, - center: center, - scale: scale, - labelPainter: labelPainter, - textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow, - backgroundPaintColor: sliderTheme.valueIndicatorColor, - strokePaintColor: isOnTop ? sliderTheme.overlappingShapeStrokeColor : null, - ); - } -} - -class _RectangularSliderValueIndicatorPathPainter { - const _RectangularSliderValueIndicatorPathPainter(); - - static const double _triangleHeight = 8.0; - static const double _labelPadding = 16.0; - static const double _preferredHeight = 32.0; - static const double _minLabelWidth = 16.0; - static const double _bottomTipYOffset = 14.0; - static const double _preferredHalfHeight = _preferredHeight / 2; - static const double _upperRectRadius = 4; - - Size getPreferredSize( - bool isEnabled, - bool isDiscrete, - TextPainter labelPainter, - double textScaleFactor, - ) { - assert(labelPainter != null); - return Size( - _upperRectangleWidth(labelPainter, 1, textScaleFactor), - labelPainter.height + _labelPadding, - ); - } - - double getHorizontalShift({ - RenderBox parentBox, - Offset center, - TextPainter labelPainter, - double textScaleFactor, - Size sizeWithOverflow, - double scale, - }) { - assert(!sizeWithOverflow.isEmpty); - const double edgePadding = 8.0; - final double rectangleWidth = _upperRectangleWidth(labelPainter, scale, textScaleFactor); - - // The rectangle must be shifted towards the center so that it minimizes the - // chance of it rendering outside the bounds of the render box. If the shift - // is negative, then the lobe is shifted from right to left, and if it is - // positive, then the lobe is shifted from left to right. - final double overflowLeft = math.max(0, rectangleWidth / 2 - center.dx + edgePadding); - final double overflowRight = math.max(0, rectangleWidth / 2 - (sizeWithOverflow.width - center.dx - edgePadding)); - return overflowLeft - overflowRight; - } - - double _upperRectangleWidth(TextPainter labelPainter, double scale, double textScaleFactor) { - final double unscaledWidth = math.max(_minLabelWidth * textScaleFactor, labelPainter.width) + _labelPadding * 2; - return unscaledWidth * scale; - } - - void paint({ - RenderBox parentBox, - Canvas canvas, - Offset center, - double scale, - TextPainter labelPainter, - double textScaleFactor, - Size sizeWithOverflow, - Color backgroundPaintColor, - Color strokePaintColor, - }) { - if (scale == 0.0) { - // Zero scale essentially means "do not draw anything", so it's safe to just return. - return; - } - assert(!sizeWithOverflow.isEmpty); - - final double rectangleWidth = _upperRectangleWidth(labelPainter, scale, textScaleFactor); - final double horizontalShift = getHorizontalShift( - parentBox: parentBox, - center: center, - labelPainter: labelPainter, - textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow, - scale: scale, - ); - - final double rectHeight = labelPainter.height + _labelPadding; - final Rect upperRect = Rect.fromLTWH( - -rectangleWidth / 2 + horizontalShift, - -_triangleHeight - rectHeight, - rectangleWidth, - rectHeight, - ); - - final Path trianglePath = Path() - ..lineTo(-_triangleHeight, -_triangleHeight) - ..lineTo(_triangleHeight, -_triangleHeight) - ..close(); - final Paint fillPaint = Paint()..color = backgroundPaintColor; - final RRect upperRRect = RRect.fromRectAndRadius(upperRect, const Radius.circular(_upperRectRadius)); - trianglePath.addRRect(upperRRect); - - canvas.save(); - // Prepare the canvas for the base of the tooltip, which is relative to the - // center of the thumb. - canvas.translate(center.dx, center.dy - _bottomTipYOffset); - canvas.scale(scale, scale); - if (strokePaintColor != null) { - final Paint strokePaint = Paint() - ..color = strokePaintColor - ..strokeWidth = 1.0 - ..style = PaintingStyle.stroke; - canvas.drawPath(trianglePath, strokePaint); - } - canvas.drawPath(trianglePath, fillPaint); - - // The label text is centered within the value indicator. - final double bottomTipToUpperRectTranslateY = -_preferredHalfHeight / 2 - upperRect.height; - canvas.translate(0, bottomTipToUpperRectTranslateY); - final Offset boxCenter = Offset(horizontalShift, upperRect.height / 2); - final Offset halfLabelPainterOffset = Offset(labelPainter.width / 2, labelPainter.height / 2); - final Offset labelOffset = boxCenter - halfLabelPainterOffset; - labelPainter.paint(canvas, labelOffset); - canvas.restore(); - } -} - -/// A variant shape of a [Slider]'s value indicator . -/// -/// See also: -/// -/// * [Slider], which includes a value indicator defined by this shape. -/// * [SliderTheme], which can be used to configure the slider value indicator -/// of all sliders in a widget subtree. -class PaddleSliderValueIndicatorShape extends SliderComponentShape { - /// Create a slider value indicator in the shape of an upside-down pear. - const PaddleSliderValueIndicatorShape(); - - static const _PaddleSliderValueIndicatorPathPainter _pathPainter = _PaddleSliderValueIndicatorPathPainter(); - - @override - Size getPreferredSize( - bool isEnabled, - bool isDiscrete, { - @required TextPainter labelPainter, - @required double textScaleFactor, - }) { - assert(labelPainter != null); - assert(textScaleFactor != null && textScaleFactor >= 0); - return _pathPainter.getPreferredSize(isEnabled, isDiscrete, labelPainter, textScaleFactor); - } - - @override - void paint( - PaintingContext context, - Offset center, { - @required Animation activationAnimation, - @required Animation enableAnimation, - bool isDiscrete, - @required TextPainter labelPainter, - @required RenderBox parentBox, - @required SliderThemeData sliderTheme, - TextDirection textDirection, - double value, - double textScaleFactor, - Size sizeWithOverflow, - }) { - assert(context != null); - assert(center != null); - assert(activationAnimation != null); - assert(enableAnimation != null); - assert(labelPainter != null); - assert(parentBox != null); - assert(sliderTheme != null); - assert(!sizeWithOverflow.isEmpty); - final ColorTween enableColor = ColorTween( - begin: sliderTheme.disabledThumbColor, - end: sliderTheme.valueIndicatorColor, - ); - _pathPainter.paint( - parentBox, - context.canvas, - center, - Paint()..color = enableColor.evaluate(enableAnimation), - activationAnimation.value, - labelPainter, - textScaleFactor, - sizeWithOverflow, - null, - ); - } -} - -/// A variant shape of a [RangeSlider]'s value indicators. -/// -/// See also: -/// -/// * [RangeSlider], which includes value indicators defined by this shape. -/// * [SliderTheme], which can be used to configure the range slider value -/// indicator of all sliders in a widget subtree. class PaddleRangeSliderValueIndicatorShape extends RangeSliderValueIndicatorShape { /// Create a slider value indicator in the shape of an upside-down pear. const PaddleRangeSliderValueIndicatorShape(); - static const _PaddleSliderValueIndicatorPathPainter _pathPainter = _PaddleSliderValueIndicatorPathPainter(); + static const _PaddleSliderTrackShapePathPainter _pathPainter = _PaddleSliderTrackShapePathPainter(); @override - Size getPreferredSize( - bool isEnabled, - bool isDiscrete, { - @required TextPainter labelPainter, - @required double textScaleFactor, - }) { + Size getPreferredSize(bool isEnabled, bool isDiscrete, { @required TextPainter labelPainter }) { assert(labelPainter != null); - assert(textScaleFactor != null && textScaleFactor >= 0); - return _pathPainter.getPreferredSize(isEnabled, isDiscrete, labelPainter, textScaleFactor); + return _pathPainter.getPreferredSize(isEnabled, isDiscrete, labelPainter); } @override @@ -2948,16 +2517,12 @@ class PaddleRangeSliderValueIndicatorShape extends RangeSliderValueIndicatorShap Offset center, TextPainter labelPainter, Animation activationAnimation, - double textScaleFactor, - Size sizeWithOverflow, }) { return _pathPainter.getHorizontalShift( parentBox: parentBox, center: center, labelPainter: labelPainter, scale: activationAnimation.value, - textScaleFactor: textScaleFactor, - sizeWithOverflow: sizeWithOverflow, ); } @@ -2975,8 +2540,6 @@ class PaddleRangeSliderValueIndicatorShape extends RangeSliderValueIndicatorShap TextDirection textDirection, Thumb thumb, double value, - double textScaleFactor, - Size sizeWithOverflow, }) { assert(context != null); assert(center != null); @@ -2985,28 +2548,25 @@ class PaddleRangeSliderValueIndicatorShape extends RangeSliderValueIndicatorShap assert(labelPainter != null); assert(parentBox != null); assert(sliderTheme != null); - assert(!sizeWithOverflow.isEmpty); final ColorTween enableColor = ColorTween( begin: sliderTheme.disabledThumbColor, end: sliderTheme.valueIndicatorColor, ); // Add a stroke of 1dp around the top paddle. - _pathPainter.paint( + _pathPainter.drawValueIndicator( parentBox, context.canvas, center, Paint()..color = enableColor.evaluate(enableAnimation), activationAnimation.value, labelPainter, - textScaleFactor, - sizeWithOverflow, isOnTop ? sliderTheme.overlappingShapeStrokeColor : null, ); } } -class _PaddleSliderValueIndicatorPathPainter { - const _PaddleSliderValueIndicatorPathPainter(); +class _PaddleSliderTrackShapePathPainter { + const _PaddleSliderTrackShapePathPainter(); // These constants define the shape of the default value indicator. // The value indicator changes shape based on the size of @@ -3016,12 +2576,14 @@ class _PaddleSliderValueIndicatorPathPainter { // Radius of the top lobe of the value indicator. static const double _topLobeRadius = 16.0; - static const double _minLabelWidth = 16.0; + // Designed size of the label text. This is the size that the value indicator + // was designed to contain. We scale it from here to fit other sizes. + static const double _labelTextDesignSize = 14.0; // Radius of the bottom lobe of the value indicator. static const double _bottomLobeRadius = 10.0; static const double _labelPadding = 8.0; static const double _distanceBetweenTopBottomCenters = 40.0; - static const double _middleNeckWidth = 3.0; + static const double _middleNeckWidth = 2.0; static const double _bottomNeckRadius = 4.5; // The base of the triangle between the top lobe center and the centers of // the two top neck arcs. @@ -3049,12 +2611,10 @@ class _PaddleSliderValueIndicatorPathPainter { bool isEnabled, bool isDiscrete, TextPainter labelPainter, - double textScaleFactor, ) { assert(labelPainter != null); - assert(textScaleFactor != null && textScaleFactor >= 0); - final double width = math.max(_minLabelWidth * textScaleFactor, labelPainter.width) + _labelPadding * 2 * textScaleFactor; - return Size(width, _preferredHeight * textScaleFactor); + final double textScaleFactor = labelPainter.height / _labelTextDesignSize; + return Size(labelPainter.width + 2 * _labelPadding * textScaleFactor, _preferredHeight * textScaleFactor); } // Adds an arc to the path that has the attributes passed in. This is @@ -3070,17 +2630,15 @@ class _PaddleSliderValueIndicatorPathPainter { Offset center, TextPainter labelPainter, double scale, - double textScaleFactor, - Size sizeWithOverflow, }) { - assert(!sizeWithOverflow.isEmpty); + final double textScaleFactor = labelPainter.height / _labelTextDesignSize; final double inverseTextScale = textScaleFactor != 0 ? 1.0 / textScaleFactor : 0.0; final double labelHalfWidth = labelPainter.width / 2.0; final double halfWidthNeeded = math.max( 0.0, inverseTextScale * labelHalfWidth - (_topLobeRadius - _labelPadding), ); - final double shift = _getIdealOffset(parentBox, halfWidthNeeded, textScaleFactor * scale, center, sizeWithOverflow.width); + final double shift = _getIdealOffset(parentBox, halfWidthNeeded, textScaleFactor * scale, center); return shift * textScaleFactor; } @@ -3091,9 +2649,8 @@ class _PaddleSliderValueIndicatorPathPainter { double halfWidthNeeded, double scale, Offset center, - double widthWithOverflow, ) { - const double edgeMargin = 8.0; + const double edgeMargin = 4.0; final Rect topLobeRect = Rect.fromLTWH( -_topLobeRadius - halfWidthNeeded, -_topLobeRadius - _distanceBetweenTopBottomCenters, @@ -3106,11 +2663,12 @@ class _PaddleSliderValueIndicatorPathPainter { final Offset bottomRight = (topLobeRect.bottomRight * scale) + center; double shift = 0.0; - if (topLeft.dx < edgeMargin) { - shift = edgeMargin - topLeft.dx; + final double startGlobal = parentBox.localToGlobal(Offset.zero).dx; + if (topLeft.dx < startGlobal + edgeMargin) { + shift = startGlobal + edgeMargin - topLeft.dx; } - final double endGlobal = widthWithOverflow; + final double endGlobal = parentBox.localToGlobal(Offset(parentBox.size.width, parentBox.size.height)).dx; if (bottomRight.dx > endGlobal - edgeMargin) { shift = endGlobal - edgeMargin - bottomRight.dx; } @@ -3126,15 +2684,13 @@ class _PaddleSliderValueIndicatorPathPainter { return shift; } - void paint( + void drawValueIndicator( RenderBox parentBox, Canvas canvas, Offset center, Paint paint, double scale, TextPainter labelPainter, - double textScaleFactor, - Size sizeWithOverflow, Color strokePaintColor, ) { if (scale == 0.0) { @@ -3142,10 +2698,10 @@ class _PaddleSliderValueIndicatorPathPainter { // our math below will attempt to divide by zero and send needless NaNs to the engine. return; } - assert(!sizeWithOverflow.isEmpty); // The entire value indicator should scale with the size of the label, // to keep it large enough to encompass the label text. + final double textScaleFactor = labelPainter.height / _labelTextDesignSize; final double overallScale = scale * textScaleFactor; final double inverseTextScale = textScaleFactor != 0 ? 1.0 / textScaleFactor : 0.0; final double labelHalfWidth = labelPainter.width / 2.0; @@ -3187,7 +2743,7 @@ class _PaddleSliderValueIndicatorPathPainter { inverseTextScale * labelHalfWidth - (_topLobeRadius - _labelPadding), ); - final double shift = _getIdealOffset(parentBox, halfWidthNeeded, overallScale, center, sizeWithOverflow.width); + final double shift = _getIdealOffset(parentBox, halfWidthNeeded, overallScale, center); final double leftWidthNeeded = halfWidthNeeded - shift; final double rightWidthNeeded = halfWidthNeeded + shift; @@ -3196,8 +2752,7 @@ class _PaddleSliderValueIndicatorPathPainter { final double leftAmount = math.max(0.0, math.min(1.0, leftWidthNeeded / _neckTriangleBase)); final double rightAmount = math.max(0.0, math.min(1.0, rightWidthNeeded / _neckTriangleBase)); // The angle between the top neck arc's center and the top lobe's center - // and vertical. The base amount is chosen so that the neck is smooth, - // even when the lobe is shifted due to its size. + // and vertical. final double leftTheta = (1.0 - leftAmount) * _thirtyDegrees; final double rightTheta = (1.0 - rightAmount) * _thirtyDegrees; // The center of the top left neck arc. diff --git a/packages/flutter/test/material/inherited_theme_test.dart b/packages/flutter/test/material/inherited_theme_test.dart index dde79202ffd..07ea0673cc3 100644 --- a/packages/flutter/test/material/inherited_theme_test.dart +++ b/packages/flutter/test/material/inherited_theme_test.dart @@ -525,7 +525,7 @@ void main() { await tester.tap(find.text('push wrapped')); await tester.pumpAndSettle(); // route animation RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); - expect(sliderBox, paints..rrect(color: activeTrackColor)..rrect(color: inactiveTrackColor)); + expect(sliderBox, paints..rect(color: activeTrackColor)..rect(color: inactiveTrackColor)); expect(sliderBox, paints..circle(color: thumbColor)); Navigator.of(navigatorContext).pop(); @@ -534,7 +534,7 @@ void main() { await tester.tap(find.text('push unwrapped')); await tester.pumpAndSettle(); // route animation sliderBox = tester.firstRenderObject(find.byType(Slider)); - expect(sliderBox, isNot(paints..rrect(color: activeTrackColor)..rrect(color: inactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: activeTrackColor)..rect(color: inactiveTrackColor))); expect(sliderBox, isNot(paints..circle(color: thumbColor))); }); diff --git a/packages/flutter/test/material/range_slider_test.dart b/packages/flutter/test/material/range_slider_test.dart index b9b3afe1342..4972ea08080 100644 --- a/packages/flutter/test/material/range_slider_test.dart +++ b/packages/flutter/test/material/range_slider_test.dart @@ -1033,17 +1033,15 @@ void main() { // Check default theme for enabled widget. expect(sliderBox, paints - ..rrect(color: sliderTheme.inactiveTrackColor) + ..rect(color: sliderTheme.inactiveTrackColor) ..rect(color: sliderTheme.activeTrackColor) - ..rrect(color: sliderTheme.inactiveTrackColor)); + ..rect(color: sliderTheme.inactiveTrackColor)); expect(sliderBox, paints ..circle(color: sliderTheme.thumbColor) ..circle(color: sliderTheme.thumbColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.activeTickMarkColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor))); }); @@ -1060,22 +1058,18 @@ void main() { expect( sliderBox, paints - ..rrect(color: sliderTheme.inactiveTrackColor) + ..rect(color: sliderTheme.inactiveTrackColor) ..rect(color: activeColor) - ..rrect(color: sliderTheme.inactiveTrackColor)); + ..rect(color: sliderTheme.inactiveTrackColor)); expect( sliderBox, paints - ..circle(color: Colors.white) ..circle(color: activeColor) - ..circle(color: Colors.white) ..circle(color: activeColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); }); testWidgets('Range Slider uses the right theme colors for the right shapes when setting the inactive color', (WidgetTester tester) async { @@ -1090,9 +1084,9 @@ void main() { expect( sliderBox, paints - ..rrect(color: inactiveColor) + ..rect(color: inactiveColor) ..rect(color: sliderTheme.activeTrackColor) - ..rrect(color: inactiveColor)); + ..rect(color: inactiveColor)); expect( sliderBox, paints @@ -1101,8 +1095,6 @@ void main() { expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); }); testWidgets('Range Slider uses the right theme colors for the right shapes with active and inactive colors', (WidgetTester tester) async { @@ -1122,20 +1114,18 @@ void main() { expect( sliderBox, paints - ..rrect(color: inactiveColor) + ..rect(color: inactiveColor) ..rect(color: activeColor) - ..rrect(color: inactiveColor)); + ..rect(color: inactiveColor)); expect( sliderBox, paints - ..circle(color: Colors.white) ..circle(color: activeColor) - ..circle(color: Colors.white) ..circle(color: activeColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); }); testWidgets('Range Slider uses the right theme colors for the right shapes for a discrete slider', (WidgetTester tester) async { @@ -1149,9 +1139,9 @@ void main() { expect( sliderBox, paints - ..rrect(color: sliderTheme.inactiveTrackColor) + ..rect(color: sliderTheme.inactiveTrackColor) ..rect(color: sliderTheme.activeTrackColor) - ..rrect(color: sliderTheme.inactiveTrackColor)); + ..rect(color: sliderTheme.inactiveTrackColor)); expect( sliderBox, paints @@ -1164,8 +1154,6 @@ void main() { expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); }); testWidgets('Range Slider uses the right theme colors for the right shapes for a discrete slider with active and inactive colors', (WidgetTester tester) async { @@ -1187,9 +1175,9 @@ void main() { expect( sliderBox, paints - ..rrect(color: inactiveColor) + ..rect(color: inactiveColor) ..rect(color: activeColor) - ..rrect(color: inactiveColor)); + ..rect(color: inactiveColor)); expect( sliderBox, paints @@ -1197,16 +1185,12 @@ void main() { ..circle(color: activeColor) ..circle(color: inactiveColor) ..circle(color: activeColor) - ..circle(color: Colors.white) ..circle(color: activeColor) - ..circle(color: Colors.white) ..circle(color: activeColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.activeTickMarkColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor))); }); @@ -1222,14 +1206,12 @@ void main() { expect( sliderBox, paints - ..rrect(color: sliderTheme.disabledInactiveTrackColor) + ..rect(color: sliderTheme.disabledInactiveTrackColor) ..rect(color: sliderTheme.disabledActiveTrackColor) - ..rrect(color: sliderTheme.disabledInactiveTrackColor)); + ..rect(color: sliderTheme.disabledInactiveTrackColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.activeTrackColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.inactiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.activeTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor))); }); @@ -1251,17 +1233,17 @@ void main() { expect( sliderBox, paints - ..rrect(color: sliderTheme.disabledInactiveTrackColor) + ..rect(color: sliderTheme.disabledInactiveTrackColor) ..rect(color: sliderTheme.disabledActiveTrackColor) - ..rrect(color: sliderTheme.disabledInactiveTrackColor)); + ..rect(color: sliderTheme.disabledInactiveTrackColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.activeTrackColor))); expect(sliderBox, isNot(paints..rect(color: sliderTheme.inactiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.activeTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor))); }); testWidgets('Range Slider uses the right theme colors for the right shapes when the value indicators are showing', (WidgetTester tester) async { + const Color customColor1 = Color(0xcafefeed); + const Color customColor2 = Color(0xdeadbeef); final ThemeData theme = _buildTheme(); final SliderThemeData sliderTheme = theme.sliderTheme; RangeValues values = const RangeValues(0.5, 0.75); @@ -1303,7 +1285,7 @@ void main() { final RenderBox sliderBox = tester.firstRenderObject(find.byType(RangeSlider)); final Offset topRight = tester.getTopRight(find.byType(RangeSlider)).translate(-24, 0); - final TestGesture gesture = await tester.startGesture(topRight); + TestGesture gesture = await tester.startGesture(topRight); // Wait for value indicator animation to finish. await tester.pumpAndSettle(); expect(values.end, equals(1)); @@ -1316,6 +1298,24 @@ void main() { await gesture.up(); // Wait for value indicator animation to finish. await tester.pumpAndSettle(); + + // Testing the custom colors are used for the indicator. + await tester.pumpWidget(buildApp( + divisions: 3, + activeColor: customColor1, + inactiveColor: customColor2, + )); + gesture = await tester.startGesture(topRight); + // Wait for value indicator animation to finish. + await tester.pumpAndSettle(); + expect(values.end, equals(1)); + expect( + sliderBox, + paints + ..path(color: customColor1) + ..path(color: customColor1), + ); + await gesture.up(); }); testWidgets('Range Slider top thumb gets stroked when overlapping', (WidgetTester tester) async { diff --git a/packages/flutter/test/material/slider_test.dart b/packages/flutter/test/material/slider_test.dart index f1019eed1dc..40416727c9e 100644 --- a/packages/flutter/test/material/slider_test.dart +++ b/packages/flutter/test/material/slider_test.dart @@ -39,8 +39,6 @@ class LoggingThumbShape extends SliderComponentShape { SliderThemeData sliderTheme, TextDirection textDirection, double value, - double textScaleFactor, - Size sizeWithOverflow, }) { log.add(thumbCenter); final Paint thumbPaint = Paint()..color = Colors.red; @@ -584,7 +582,6 @@ void main() { overlayColor: Color(0xff000010), thumbColor: Color(0xff000011), valueIndicatorColor: Color(0xff000012), - surfaceColor: Colors.white, ), ); final SliderThemeData sliderTheme = theme.sliderTheme; @@ -628,47 +625,43 @@ void main() { final RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); // Check default theme for enabled widget. - expect(sliderBox, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: sliderTheme.inactiveTrackColor)); - expect(sliderBox, paints..shadow(color: const Color(0xff000000))); + expect(sliderBox, paints..rect(color: sliderTheme.activeTrackColor)..rect(color: sliderTheme.inactiveTrackColor)); expect(sliderBox, paints..circle(color: sliderTheme.thumbColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.activeTickMarkColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor))); // Test setting only the activeColor. await tester.pumpWidget(buildApp(activeColor: customColor1)); - expect(sliderBox, paints..rrect(color: customColor1)..rrect(color: sliderTheme.inactiveTrackColor)); - expect(sliderBox, paints..shadow(color: Colors.black)); - expect(sliderBox, paints..circle(color: Colors.white)..circle(color: customColor1)); + expect(sliderBox, paints..rect(color: customColor1)..rect(color: sliderTheme.inactiveTrackColor)); + expect(sliderBox, paints..circle(color: customColor1)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); // Test setting only the inactiveColor. await tester.pumpWidget(buildApp(inactiveColor: customColor1)); - expect(sliderBox, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: customColor1)); - expect(sliderBox, paints..shadow(color: Colors.black)); + expect(sliderBox, paints..rect(color: sliderTheme.activeTrackColor)..rect(color: customColor1)); expect(sliderBox, paints..circle(color: sliderTheme.thumbColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); // Test setting both activeColor and inactiveColor. await tester.pumpWidget(buildApp(activeColor: customColor1, inactiveColor: customColor2)); - expect(sliderBox, paints..rrect(color: customColor1)..rrect(color: customColor2)); - expect(sliderBox, paints..shadow(color: Colors.black)); - expect(sliderBox, paints..circle(color: Colors.white)..circle(color: customColor1)); + expect(sliderBox, paints..rect(color: customColor1)..rect(color: customColor2)); + expect(sliderBox, paints..circle(color: customColor1)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); // Test colors for discrete slider. await tester.pumpWidget(buildApp(divisions: 3)); - expect(sliderBox, paints..rrect(color: sliderTheme.activeTrackColor)..rrect(color: sliderTheme.inactiveTrackColor)); + expect(sliderBox, paints..rect(color: sliderTheme.activeTrackColor)..rect(color: sliderTheme.inactiveTrackColor)); expect( sliderBox, paints @@ -676,12 +669,10 @@ void main() { ..circle(color: sliderTheme.activeTickMarkColor) ..circle(color: sliderTheme.inactiveTickMarkColor) ..circle(color: sliderTheme.inactiveTickMarkColor) - ..shadow(color: Colors.black) - ..circle(color: sliderTheme.thumbColor) - ); + ..circle(color: sliderTheme.thumbColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); // Test colors for discrete slider with inactiveColor and activeColor set. await tester.pumpWidget(buildApp( @@ -689,7 +680,7 @@ void main() { inactiveColor: customColor2, divisions: 3, )); - expect(sliderBox, paints..rrect(color: customColor1)..rrect(color: customColor2)); + expect(sliderBox, paints..rect(color: customColor1)..rect(color: customColor2)); expect( sliderBox, paints @@ -697,13 +688,11 @@ void main() { ..circle(color: customColor2) ..circle(color: customColor1) ..circle(color: customColor1) - ..shadow(color: Colors.black) - ..circle(color: Colors.white) ..circle(color: customColor1)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.disabledThumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledActiveTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.disabledInactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledActiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.disabledInactiveTrackColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.activeTickMarkColor))); expect(sliderBox, isNot(paints..circle(color: sliderTheme.inactiveTickMarkColor))); @@ -713,24 +702,24 @@ void main() { expect( sliderBox, paints - ..rrect(color: sliderTheme.disabledActiveTrackColor) - ..rrect(color: sliderTheme.disabledInactiveTrackColor)); - expect(sliderBox, paints..shadow(color: Colors.black)..circle(color: sliderTheme.disabledThumbColor)); + ..rect(color: sliderTheme.disabledActiveTrackColor) + ..rect(color: sliderTheme.disabledInactiveTrackColor)); + expect(sliderBox, paints..circle(color: sliderTheme.disabledThumbColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.activeTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.activeTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.inactiveTrackColor))); // Test setting the activeColor and inactiveColor for disabled widget. await tester.pumpWidget(buildApp(activeColor: customColor1, inactiveColor: customColor2, enabled: false)); expect( sliderBox, paints - ..rrect(color: sliderTheme.disabledActiveTrackColor) - ..rrect(color: sliderTheme.disabledInactiveTrackColor)); - expect(sliderBox, paints..shadow(color: Colors.black)..circle(color: sliderTheme.disabledThumbColor)); + ..rect(color: sliderTheme.disabledActiveTrackColor) + ..rect(color: sliderTheme.disabledInactiveTrackColor)); + expect(sliderBox, paints..circle(color: sliderTheme.disabledThumbColor)); expect(sliderBox, isNot(paints..circle(color: sliderTheme.thumbColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.activeTrackColor))); - expect(sliderBox, isNot(paints..rrect(color: sliderTheme.inactiveTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.activeTrackColor))); + expect(sliderBox, isNot(paints..rect(color: sliderTheme.inactiveTrackColor))); // Test that the default value indicator has the right colors. await tester.pumpWidget(buildApp(divisions: 3)); @@ -742,15 +731,14 @@ void main() { expect( sliderBox, paints - ..rrect(color: sliderTheme.activeTrackColor) - ..rrect(color: sliderTheme.inactiveTrackColor) + ..rect(color: sliderTheme.activeTrackColor) + ..rect(color: sliderTheme.inactiveTrackColor) ..circle(color: sliderTheme.overlayColor) ..circle(color: sliderTheme.activeTickMarkColor) ..circle(color: sliderTheme.activeTickMarkColor) ..circle(color: sliderTheme.inactiveTickMarkColor) ..circle(color: sliderTheme.inactiveTickMarkColor) ..path(color: sliderTheme.valueIndicatorColor) - ..shadow(color: Colors.black) ..circle(color: sliderTheme.thumbColor), ); await gesture.up(); @@ -771,16 +759,14 @@ void main() { expect( sliderBox, paints - ..rrect(color: customColor1) // active track - ..rrect(color: customColor2) // inactive track + ..rect(color: customColor1) // active track + ..rect(color: customColor2) // inactive track ..circle(color: customColor1.withOpacity(0.12)) // overlay ..circle(color: customColor2) // 1st tick mark ..circle(color: customColor2) // 2nd tick mark ..circle(color: customColor2) // 3rd tick mark ..circle(color: customColor1) // 4th tick mark - ..path(color: sliderTheme.valueIndicatorColor) // indicator - ..shadow(color: Colors.black) - ..circle(color: Colors.white) + ..path(color: customColor1) // indicator ..circle(color: customColor1), // thumb ); await gesture.up(); @@ -984,19 +970,7 @@ void main() { TestGesture gesture = await tester.startGesture(center); await tester.pumpAndSettle(); - expect( - tester.renderObject(find.byType(Slider)), - paints - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(0.0, -38.0), - Offset(-30.0, -16.0), - Offset(30.0, -16.0), - ], - color: const Color(0xf55f5f5f), - ), - ); + expect(tester.renderObject(find.byType(Slider)), paints..scale(x: 1.0, y: 1.0)); await gesture.up(); await tester.pumpAndSettle(); @@ -1006,19 +980,7 @@ void main() { gesture = await tester.startGesture(center); await tester.pumpAndSettle(); - expect( - tester.renderObject(find.byType(Slider)), - paints - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(0.0, -52.0), - Offset(-44.0, -16.0), - Offset(44.0, -16.0), - ], - color: const Color(0xf55f5f5f), - ), - ); + expect(tester.renderObject(find.byType(Slider)), paints..scale(x: 2.0, y: 2.0)); await gesture.up(); await tester.pumpAndSettle(); @@ -1033,18 +995,7 @@ void main() { gesture = await tester.startGesture(center); await tester.pumpAndSettle(); - expect(tester.renderObject(find.byType(Slider)), - paints - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(0.0, -38.0), - Offset(-30.0, -16.0), - Offset(30.0, -16.0), - ], - color: const Color(0xf55f5f5f), - ), - ); + expect(tester.renderObject(find.byType(Slider)), paints..scale(x: 1.0, y: 1.0)); await gesture.up(); await tester.pumpAndSettle(); @@ -1058,19 +1009,7 @@ void main() { gesture = await tester.startGesture(center); await tester.pumpAndSettle(); - expect( - tester.renderObject(find.byType(Slider)), - paints - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(0.0, -52.0), - Offset(-44.0, -16.0), - Offset(44.0, -16.0), - ], - color: const Color(0xf55f5f5f), - ), - ); + expect(tester.renderObject(find.byType(Slider)), paints..scale(x: 2.0, y: 2.0)); await gesture.up(); await tester.pumpAndSettle(); @@ -1175,11 +1114,11 @@ void main() { expect( sliderBox, paints - ..circle(x: 26.0, y: 24.0, radius: 1.0) - ..circle(x: 213.0, y: 24.0, radius: 1.0) + ..circle(x: 25.0, y: 24.0, radius: 1.0) + ..circle(x: 212.5, y: 24.0, radius: 1.0) ..circle(x: 400.0, y: 24.0, radius: 1.0) - ..circle(x: 587.0, y: 24.0, radius: 1.0) - ..circle(x: 774.0, y: 24.0, radius: 1.0) + ..circle(x: 587.5, y: 24.0, radius: 1.0) + ..circle(x: 775.0, y: 24.0, radius: 1.0) ..circle(x: 24.0, y: 24.0, radius: 10.0), ); @@ -1192,11 +1131,11 @@ void main() { sliderBox, paints ..circle(x: 111.20703125, y: 24.0, radius: 5.687664985656738) - ..circle(x: 26.0, y: 24.0, radius: 1.0) - ..circle(x: 213.0, y: 24.0, radius: 1.0) + ..circle(x: 25.0, y: 24.0, radius: 1.0) + ..circle(x: 212.5, y: 24.0, radius: 1.0) ..circle(x: 400.0, y: 24.0, radius: 1.0) - ..circle(x: 587.0, y: 24.0, radius: 1.0) - ..circle(x: 774.0, y: 24.0, radius: 1.0) + ..circle(x: 587.5, y: 24.0, radius: 1.0) + ..circle(x: 775.0, y: 24.0, radius: 1.0) ..circle(x: 111.20703125, y: 24.0, radius: 10.0), ); @@ -1212,11 +1151,11 @@ void main() { sliderBox, paints ..circle(x: 190.0135726928711, y: 24.0, radius: 12.0) - ..circle(x: 26.0, y: 24.0, radius: 1.0) - ..circle(x: 213.0, y: 24.0, radius: 1.0) + ..circle(x: 25.0, y: 24.0, radius: 1.0) + ..circle(x: 212.5, y: 24.0, radius: 1.0) ..circle(x: 400.0, y: 24.0, radius: 1.0) - ..circle(x: 587.0, y: 24.0, radius: 1.0) - ..circle(x: 774.0, y: 24.0, radius: 1.0) + ..circle(x: 587.5, y: 24.0, radius: 1.0) + ..circle(x: 775.0, y: 24.0, radius: 1.0) ..circle(x: 190.0135726928711, y: 24.0, radius: 10.0), ); // Wait for animations to finish. @@ -1226,11 +1165,11 @@ void main() { sliderBox, paints ..circle(x: 400.0, y: 24.0, radius: 24.0) - ..circle(x: 26.0, y: 24.0, radius: 1.0) - ..circle(x: 213.0, y: 24.0, radius: 1.0) + ..circle(x: 25.0, y: 24.0, radius: 1.0) + ..circle(x: 212.5, y: 24.0, radius: 1.0) ..circle(x: 400.0, y: 24.0, radius: 1.0) - ..circle(x: 587.0, y: 24.0, radius: 1.0) - ..circle(x: 774.0, y: 24.0, radius: 1.0) + ..circle(x: 587.5, y: 24.0, radius: 1.0) + ..circle(x: 775.0, y: 24.0, radius: 1.0) ..circle(x: 400.0, y: 24.0, radius: 10.0), ); await gesture.up(); @@ -1239,11 +1178,11 @@ void main() { expect( sliderBox, paints - ..circle(x: 26.0, y: 24.0, radius: 1.0) - ..circle(x: 213.0, y: 24.0, radius: 1.0) + ..circle(x: 25.0, y: 24.0, radius: 1.0) + ..circle(x: 212.5, y: 24.0, radius: 1.0) ..circle(x: 400.0, y: 24.0, radius: 1.0) - ..circle(x: 587.0, y: 24.0, radius: 1.0) - ..circle(x: 774.0, y: 24.0, radius: 1.0) + ..circle(x: 587.5, y: 24.0, radius: 1.0) + ..circle(x: 775.0, y: 24.0, radius: 1.0) ..circle(x: 400.0, y: 24.0, radius: 10.0), ); } diff --git a/packages/flutter/test/material/slider_theme_test.dart b/packages/flutter/test/material/slider_theme_test.dart index 8783b59018d..0fe06886023 100644 --- a/packages/flutter/test/material/slider_theme_test.dart +++ b/packages/flutter/test/material/slider_theme_test.dart @@ -107,8 +107,8 @@ void main() { expect( sliderBox, paints - ..rrect(color: sliderTheme.disabledActiveTrackColor) - ..rrect(color: sliderTheme.disabledInactiveTrackColor), + ..rect(color: sliderTheme.disabledActiveTrackColor) + ..rect(color: sliderTheme.disabledInactiveTrackColor), ); }); @@ -129,8 +129,8 @@ void main() { expect( sliderBox, paints - ..rrect(color: customTheme.disabledActiveTrackColor) - ..rrect(color: customTheme.disabledInactiveTrackColor), + ..rect(color: customTheme.disabledActiveTrackColor) + ..rect(color: customTheme.disabledInactiveTrackColor), ); }); @@ -228,15 +228,13 @@ void main() { await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25)); final RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); - const Radius radius = Radius.circular(2); - // The enabled slider thumb has track segments that extend to and from // the center of the thumb. expect( sliderBox, paints - ..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 298.0, 212.0, 302.0, topLeft: radius, bottomLeft: radius), color: sliderTheme.activeTrackColor) - ..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 776.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.inactiveTrackColor), + ..rect(rect: const Rect.fromLTRB(25.0, 299.0, 202.0, 301.0), color: sliderTheme.activeTrackColor) + ..rect(rect: const Rect.fromLTRB(222.0, 299.0, 776.0, 301.0), color: sliderTheme.inactiveTrackColor), ); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false)); @@ -251,8 +249,8 @@ void main() { expect( sliderBox, paints - ..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 298.0, 212.0, 302.0, topLeft: radius, bottomLeft: radius), color: sliderTheme.disabledActiveTrackColor) - ..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 298.0, 776.0, 302.0, topRight: radius, bottomRight: radius), color: sliderTheme.disabledInactiveTrackColor), + ..rect(rect: const Rect.fromLTRB(25.0, 299.0, 202.0, 301.0), color: sliderTheme.disabledActiveTrackColor) + ..rect(rect: const Rect.fromLTRB(222.0, 299.0, 776.0, 301.0), color: sliderTheme.disabledInactiveTrackColor), ); }); @@ -366,189 +364,7 @@ void main() { platform: TargetPlatform.android, primarySwatch: Colors.blue, ); - final SliderThemeData sliderTheme = theme.sliderTheme.copyWith( - thumbColor: Colors.red.shade500, - showValueIndicator: ShowValueIndicator.always, - ); - Widget buildApp(String value, { double sliderValue = 0.5, double textScale = 1.0 }) { - return Directionality( - textDirection: TextDirection.ltr, - child: MediaQuery( - data: MediaQueryData.fromWindow(window).copyWith(textScaleFactor: textScale), - child: Material( - child: Row( - children: [ - Expanded( - child: SliderTheme( - data: sliderTheme, - child: Slider( - value: sliderValue, - label: '$value', - divisions: 3, - onChanged: (double d) { }, - ), - ), - ), - ], - ), - ), - ), - ); - } - - await tester.pumpWidget(buildApp('1')); - - final RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); - - Offset center = tester.getCenter(find.byType(Slider)); - TestGesture gesture = await tester.startGesture(center); - // Wait for value indicator animation to finish. - await tester.pumpAndSettle(); - expect( - sliderBox, - paints - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(-20.0, -12.0), - Offset(20.0, -34.0), - Offset(0.0, -38.0), - ], - color: const Color(0xf55f5f5f), - ), - ); - - await gesture.up(); - - // Test that it expands with a larger label. - await tester.pumpWidget(buildApp('1000')); - center = tester.getCenter(find.byType(Slider)); - gesture = await tester.startGesture(center); - // Wait for value indicator animation to finish. - await tester.pumpAndSettle(); - expect( - sliderBox, - paints - ..rrect() - ..rrect() - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(-30.0, -12.0), - Offset(30.0, -34.0), - Offset(0.0, -38.0), - ], - color: const Color(0xf55f5f5f), - ), - ); - await gesture.up(); - - // Test that it avoids the left edge of the screen. - await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0)); - center = tester.getCenter(find.byType(Slider)); - gesture = await tester.startGesture(center); - // Wait for value indicator animation to finish. - await tester.pumpAndSettle(); - expect( - sliderBox, - paints - ..rrect() - ..rrect() - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(-12.0, -12.0), - Offset(110.0, -34.0), - Offset(0.0, -38.0), - ], - color: const Color(0xf55f5f5f), - ) - ); - await gesture.up(); - - // Test that it avoids the right edge of the screen. - await tester.pumpWidget(buildApp('1000000', sliderValue: 1.0)); - center = tester.getCenter(find.byType(Slider)); - gesture = await tester.startGesture(center); - // Wait for value indicator animation to finish. - await tester.pumpAndSettle(); - expect( - sliderBox, - paints - ..rrect() - ..rrect() - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(-110.0, -12.0), - Offset(12.0, -34.0), - Offset(0.0, -38.0), - ], - color: const Color(0xf55f5f5f), - ) - ); - await gesture.up(); - - // Test that the box decreases in height when the text scale gets smaller. - await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScale: 0.5)); - center = tester.getCenter(find.byType(Slider)); - gesture = await tester.startGesture(center); - // Wait for value indicator animation to finish. - await tester.pumpAndSettle(); - expect( - sliderBox, - paints - ..rrect() - ..rrect() - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(-12.0, -12.0), - Offset(61.0, -16.0), - Offset(0.0, -20.0), - ], - excludes: const [ - Offset(0.0, -38.0) - ], - color: const Color(0xf55f5f5f), - ) - ); - await gesture.up(); - - // Test that the box increases in height when the text scale gets bigger. - await tester.pumpWidget(buildApp('1000000', sliderValue: 0.0, textScale: 2.0)); - center = tester.getCenter(find.byType(Slider)); - gesture = await tester.startGesture(center); - // Wait for value indicator animation to finish. - await tester.pumpAndSettle(); - expect( - sliderBox, - paints - ..rrect() - ..rrect() - ..path( - includes: const [ - Offset(0.0, 0.0), - Offset(-12.0, -16.0), - Offset(208.0, -40.0), - Offset(0.0, -50.0), - ], - color: const Color(0xf55f5f5f), - ) - ); - await gesture.up(); - }, skip: isBrowser); - - testWidgets('Paddle slider value indicator shape draws correctly', (WidgetTester tester) async { - final ThemeData theme = ThemeData( - platform: TargetPlatform.android, - primarySwatch: Colors.blue, - ); - final SliderThemeData sliderTheme = theme.sliderTheme.copyWith( - thumbColor: Colors.red.shade500, - showValueIndicator: ShowValueIndicator.always, - valueIndicatorShape: const PaddleSliderValueIndicatorShape(), - ); + final SliderThemeData sliderTheme = theme.sliderTheme.copyWith(thumbColor: Colors.red.shade500, showValueIndicator: ShowValueIndicator.always); Widget buildApp(String value, { double sliderValue = 0.5, double textScale = 1.0 }) { return Directionality( textDirection: TextDirection.ltr, @@ -716,7 +532,6 @@ void main() { testWidgets('The slider track height can be overridden', (WidgetTester tester) async { final SliderThemeData sliderTheme = ThemeData().sliderTheme.copyWith(trackHeight: 16); - const Radius radius = Radius.circular(8); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25)); @@ -726,8 +541,8 @@ void main() { expect( sliderBox, paints - ..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 292.0, 212.0, 308.0, topLeft: radius, bottomLeft: radius), color: sliderTheme.activeTrackColor) - ..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 292.0, 776.0, 308.0, topRight: radius, bottomRight: radius), color: sliderTheme.inactiveTrackColor), + ..rect(rect: const Rect.fromLTRB(32.0, 292.0, 202.0, 308.0), color: sliderTheme.activeTrackColor) + ..rect(rect: const Rect.fromLTRB(222.0, 292.0, 776.0, 308.0), color: sliderTheme.inactiveTrackColor), ); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false)); @@ -738,8 +553,8 @@ void main() { expect( sliderBox, paints - ..rrect(rrect: RRect.fromLTRBAndCorners(24.0, 292.0, 212.0, 308.0, topLeft: radius, bottomLeft: radius), color: sliderTheme.disabledActiveTrackColor) - ..rrect(rrect: RRect.fromLTRBAndCorners(212.0, 292.0, 776.0, 308.0, topRight: radius, bottomRight: radius), color: sliderTheme.disabledInactiveTrackColor), + ..rect(rect: const Rect.fromLTRB(32.0, 292.0, 202.0, 308.0), color: sliderTheme.disabledActiveTrackColor) + ..rect(rect: const Rect.fromLTRB(222.0, 292.0, 776.0, 308.0), color: sliderTheme.disabledInactiveTrackColor), ); }); @@ -808,9 +623,9 @@ void main() { expect( sliderBox, paints - ..circle(x: 26, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor) + ..circle(x: 29, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor) ..circle(x: 400, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor) - ..circle(x: 774, y: 300, radius: 5, color: sliderTheme.inactiveTickMarkColor), + ..circle(x: 771, y: 300, radius: 5, color: sliderTheme.inactiveTickMarkColor), ); await tester.pumpWidget(_buildApp(sliderTheme, value: 0.5, divisions: 2, enabled: false)); @@ -819,9 +634,9 @@ void main() { expect( sliderBox, paints - ..circle(x: 26, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor) + ..circle(x: 29, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor) ..circle(x: 400, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor) - ..circle(x: 774, y: 300, radius: 5, color: sliderTheme.disabledInactiveTickMarkColor), + ..circle(x: 771, y: 300, radius: 5, color: sliderTheme.disabledInactiveTickMarkColor), ); }); @@ -893,7 +708,7 @@ void main() { final RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); // Only 2 track segments. - expect(sliderBox, paintsExactlyCountTimes(#drawRRect, 2)); + expect(sliderBox, paintsExactlyCountTimes(#drawRect, 2)); expect(sliderBox, paintsExactlyCountTimes(#drawCircle, 0)); expect(sliderBox, paintsExactlyCountTimes(#drawPath, 0)); }); @@ -1000,124 +815,34 @@ void main() { await gesture.up(); }); - testWidgets('PaddleSliderValueIndicatorShape skips all painting at zero scale', (WidgetTester tester) async { - // Pump a slider with just a value indicator. - await tester.pumpWidget(_buildApp( - ThemeData().sliderTheme.copyWith( - trackHeight: 0, - overlayShape: SliderComponentShape.noOverlay, - thumbShape: SliderComponentShape.noThumb, - tickMarkShape: SliderTickMarkShape.noTickMark, - showValueIndicator: ShowValueIndicator.always, - valueIndicatorShape: const PaddleSliderValueIndicatorShape(), - ), - value: 0.5, - divisions: 4, - )); - - final RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); - - // Tap the center of the track to kick off the animation of the value indicator. - final Offset center = tester.getCenter(find.byType(Slider)); - final TestGesture gesture = await tester.startGesture(center); - - // Nothing to paint at scale 0. - await tester.pump(); - expect(sliderBox, paintsNothing); - - // Painting a path for the value indicator. - await tester.pump(const Duration(milliseconds: 16)); - expect(sliderBox, paintsExactlyCountTimes(#drawPath, 1)); - - await gesture.up(); - }); - - testWidgets('Default slider value indicator shape skips all painting at zero scale', (WidgetTester tester) async { - // Pump a slider with just a value indicator. - await tester.pumpWidget(_buildApp( - ThemeData().sliderTheme.copyWith( - trackHeight: 0, - overlayShape: SliderComponentShape.noOverlay, - thumbShape: SliderComponentShape.noThumb, - tickMarkShape: SliderTickMarkShape.noTickMark, - showValueIndicator: ShowValueIndicator.always, - ), - value: 0.5, - divisions: 4, - )); - - final RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); - - // Tap the center of the track to kick off the animation of the value indicator. - final Offset center = tester.getCenter(find.byType(Slider)); - final TestGesture gesture = await tester.startGesture(center); - - // Nothing to paint at scale 0. - await tester.pump(); - expect(sliderBox, paintsNothing); - - // Painting a path for the value indicator. - await tester.pump(const Duration(milliseconds: 16)); - expect(sliderBox, paintsExactlyCountTimes(#drawPath, 1)); - - await gesture.up(); - }); - testWidgets('PaddleRangeSliderValueIndicatorShape skips all painting at zero scale', (WidgetTester tester) async { // Pump a slider with just a value indicator. - await tester.pumpWidget(_buildRangeApp( - ThemeData().sliderTheme.copyWith( - trackHeight: 0, - rangeValueIndicatorShape: const PaddleRangeSliderValueIndicatorShape(), - ), - values: const RangeValues(0, 0.5), - divisions: 4, - )); - - final RenderBox sliderBox = tester.firstRenderObject(find.byType(RangeSlider)); - - // Tap the center of the track to kick off the animation of the value indicator. - final Offset center = tester.getCenter(find.byType(RangeSlider)); - final TestGesture gesture = await tester.startGesture(center); - - // No value indicator path to paint at scale 0. - await tester.pump(); - expect(sliderBox, paintsExactlyCountTimes(#drawPath, 0)); - - // Painting a path for each value indicator. - await tester.pump(const Duration(milliseconds: 16)); - expect(sliderBox, paintsExactlyCountTimes(#drawPath, 2)); - - await gesture.up(); - }); - - testWidgets('Default range indicator shape skips all painting at zero scale', (WidgetTester tester) async { - // Pump a slider with just a value indicator. - await tester.pumpWidget(_buildRangeApp( + await tester.pumpWidget(_buildApp( ThemeData().sliderTheme.copyWith( trackHeight: 0, overlayShape: SliderComponentShape.noOverlay, thumbShape: SliderComponentShape.noThumb, tickMarkShape: SliderTickMarkShape.noTickMark, showValueIndicator: ShowValueIndicator.always, + rangeValueIndicatorShape: const PaddleRangeSliderValueIndicatorShape(), ), - values: const RangeValues(0, 0.5), + value: 0.5, divisions: 4, )); - final RenderBox sliderBox = tester.firstRenderObject(find.byType(RangeSlider)); + final RenderBox sliderBox = tester.firstRenderObject(find.byType(Slider)); // Tap the center of the track to kick off the animation of the value indicator. - final Offset center = tester.getCenter(find.byType(RangeSlider)); + final Offset center = tester.getCenter(find.byType(Slider)); final TestGesture gesture = await tester.startGesture(center); - // No value indicator path to paint at scale 0. + // Nothing to paint at scale 0. await tester.pump(); - expect(sliderBox, paintsExactlyCountTimes(#drawPath, 0)); + expect(sliderBox, paintsNothing); - // Painting a path for each value indicator. + // Painting a path for the value indicator. await tester.pump(const Duration(milliseconds: 16)); - expect(sliderBox, paintsExactlyCountTimes(#drawPath, 2)); + expect(sliderBox, paintsExactlyCountTimes(#drawPath, 1)); await gesture.up(); }); @@ -1146,27 +871,3 @@ Widget _buildApp( ), ); } - -Widget _buildRangeApp( - SliderThemeData sliderTheme, { - RangeValues values = const RangeValues(0, 0), - bool enabled = true, - int divisions, - }) { - final ValueChanged onChanged = enabled ? (RangeValues d) => values = d : null; - return MaterialApp( - home: Scaffold( - body: Center( - child: SliderTheme( - data: sliderTheme, - child: RangeSlider( - values: values, - labels: RangeLabels(values.start.toString(), values.end.toString()), - onChanged: onChanged, - divisions: divisions, - ), - ), - ), - ), - ); -}