Unverified Commit b356b94a authored by Anthony's avatar Anthony Committed by GitHub

[Material] Allow slider shapes to be easily resized (#27510)

* Add size configs for round default shapes, and add tests, for all shapes that can be sized without creating new custom shape painters
parent 3dbec840
...@@ -601,7 +601,7 @@ class _RenderSlider extends RenderBox { ...@@ -601,7 +601,7 @@ class _RenderSlider extends RenderBox {
_sliderTheme.thumbShape.getPreferredSize(isInteractive, isDiscrete), _sliderTheme.thumbShape.getPreferredSize(isInteractive, isDiscrete),
_sliderTheme.tickMarkShape.getPreferredSize(isEnabled: isInteractive, sliderTheme: sliderTheme), _sliderTheme.tickMarkShape.getPreferredSize(isEnabled: isInteractive, sliderTheme: sliderTheme),
]; ];
double get _minPreferredTrackHeight =>_sliderTheme.trackHeight; double get _minPreferredTrackHeight => _sliderTheme.trackHeight;
_SliderState _state; _SliderState _state;
Animation<double> _overlayAnimation; Animation<double> _overlayAnimation;
......
...@@ -846,9 +846,16 @@ abstract class SliderComponentShape { ...@@ -846,9 +846,16 @@ abstract class SliderComponentShape {
/// * [SliderTrackShape] Base component for creating other custom track /// * [SliderTrackShape] Base component for creating other custom track
/// shapes. /// shapes.
class RectangularSliderTrackShape extends SliderTrackShape { class RectangularSliderTrackShape extends SliderTrackShape {
/// Abstract const constructor. This constructor enables subclasses to provide /// Create a slider track that draws 2 rectangles.
/// const constructors so that they can be used in const expressions. const RectangularSliderTrackShape({ this.disabledThumbGapWidth = 2.0 });
const RectangularSliderTrackShape();
/// Horizontal spacing, or gap, between the disabled thumb and the track.
///
/// This is only used when the slider is disabled. There is no gap around
/// the thumb and any part of the track when the slider is enabled. The
/// Material spec defaults this gap width 2, which is half of the disabled
/// thumb radius.
final double disabledThumbGapWidth;
@override @override
Rect getPreferredRect({ Rect getPreferredRect({
...@@ -874,8 +881,6 @@ class RectangularSliderTrackShape extends SliderTrackShape { ...@@ -874,8 +881,6 @@ class RectangularSliderTrackShape extends SliderTrackShape {
return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight); return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
} }
// Spacing for disabled slider state.
static const double _thumbGap = 2.0;
@override @override
void paint( void paint(
...@@ -909,11 +914,15 @@ class RectangularSliderTrackShape extends SliderTrackShape { ...@@ -909,11 +914,15 @@ class RectangularSliderTrackShape extends SliderTrackShape {
} }
// Used to create a gap around the thumb iff the slider is disabled. // Used to create a gap around the thumb iff the slider is disabled.
// If the slider is enabled, the track can be drawn beneath the thumb
// without a gap. But when the slider is disabled, the track is shortened
// and this gap helps determine how much shorter it should be.
// TODO(clocksmith): The new Material spec has a gray circle in place of this gap.
double horizontalAdjustment = 0.0; double horizontalAdjustment = 0.0;
if (!isEnabled) { if (!isEnabled) {
final double thumbRadius = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete).width / 2.0; final double disabledThumbRadius = sliderTheme.thumbShape.getPreferredSize(false, isDiscrete).width / 2.0;
final double gap = _thumbGap * (1.0 - enableAnimation.value); final double gap = disabledThumbGapWidth * (1.0 - enableAnimation.value);
horizontalAdjustment = thumbRadius + gap; horizontalAdjustment = disabledThumbRadius + gap;
} }
final Rect trackRect = getPreferredRect( final Rect trackRect = getPreferredRect(
...@@ -949,16 +958,22 @@ class RectangularSliderTrackShape extends SliderTrackShape { ...@@ -949,16 +958,22 @@ class RectangularSliderTrackShape extends SliderTrackShape {
/// * [SliderTheme], which can be used to configure the tick mark shape of all /// * [SliderTheme], which can be used to configure the tick mark shape of all
/// sliders in a widget subtree. /// sliders in a widget subtree.
class RoundSliderTickMarkShape extends SliderTickMarkShape { class RoundSliderTickMarkShape extends SliderTickMarkShape {
/// Abstract const constructor. This constructor enables subclasses to provide /// Create a slider tick mark that draws a circle.
/// const constructors so that they can be used in const expressions. const RoundSliderTickMarkShape({ this.tickMarkRadius });
const RoundSliderTickMarkShape();
/// The preferred radius of the round tick mark.
///
/// If it is not provided, then half of the track height is used.
final double tickMarkRadius;
@override @override
Size getPreferredSize({ Size getPreferredSize({
bool isEnabled, bool isEnabled,
SliderThemeData sliderTheme, SliderThemeData sliderTheme,
}) { }) {
return Size.fromRadius(sliderTheme.trackHeight / 2); // 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 @override
...@@ -991,7 +1006,10 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape { ...@@ -991,7 +1006,10 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape {
final Paint paint = Paint()..color = ColorTween(begin: begin, end: end).evaluate(enableAnimation); final Paint paint = Paint()..color = ColorTween(begin: begin, end: end).evaluate(enableAnimation);
// The tick marks are tiny circles that are the same height as the track. // The tick marks are tiny circles that are the same height as the track.
final double tickMarkRadius = sliderTheme.trackHeight / 2; final double tickMarkRadius = getPreferredSize(
isEnabled: isEnabled,
sliderTheme: sliderTheme,
).width / 2;
context.canvas.drawCircle(center, tickMarkRadius, paint); context.canvas.drawCircle(center, tickMarkRadius, paint);
} }
} }
...@@ -1005,14 +1023,30 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape { ...@@ -1005,14 +1023,30 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape {
/// sliders in a widget subtree. /// sliders in a widget subtree.
class RoundSliderThumbShape extends SliderComponentShape { class RoundSliderThumbShape extends SliderComponentShape {
/// Create a slider thumb that draws a circle. /// Create a slider thumb that draws a circle.
const RoundSliderThumbShape(); // TODO(clocksmith): This needs to be changed to 10 according to spec.
const RoundSliderThumbShape({
this.enabledThumbRadius = 6.0,
this.disabledThumbRadius
});
/// The preferred radius of the round thumb shape when the slider is enabled.
///
/// If it is not provided, then the material default is used.
final double enabledThumbRadius;
static const double _thumbRadius = 6.0; /// The preferred radius of the round thumb shape when the slider is disabled.
static const double _disabledThumbRadius = 4.0; ///
/// If no disabledRadius is provided, then it is is derived from the enabled
/// thumb radius and has the same ratio of enabled size to disabled size as
/// the Material spec. The default resolves to 4, which is 2 / 3 of the
/// default enabled thumb.
final double disabledThumbRadius;
// TODO(clocksmith): This needs to be updated once the thumb size is updated to the Material spec.
double get _disabledThumbRadius => disabledThumbRadius ?? enabledThumbRadius * 2 / 3;
@override @override
Size getPreferredSize(bool isEnabled, bool isDiscrete) { Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return Size.fromRadius(isEnabled ? _thumbRadius : _disabledThumbRadius); return Size.fromRadius(isEnabled ? enabledThumbRadius : _disabledThumbRadius);
} }
@override @override
...@@ -1031,7 +1065,7 @@ class RoundSliderThumbShape extends SliderComponentShape { ...@@ -1031,7 +1065,7 @@ class RoundSliderThumbShape extends SliderComponentShape {
final Canvas canvas = context.canvas; final Canvas canvas = context.canvas;
final Tween<double> radiusTween = Tween<double>( final Tween<double> radiusTween = Tween<double>(
begin: _disabledThumbRadius, begin: _disabledThumbRadius,
end: _thumbRadius, end: enabledThumbRadius,
); );
final ColorTween colorTween = ColorTween( final ColorTween colorTween = ColorTween(
begin: sliderTheme.disabledThumbColor, begin: sliderTheme.disabledThumbColor,
...@@ -1062,13 +1096,17 @@ class RoundSliderThumbShape extends SliderComponentShape { ...@@ -1062,13 +1096,17 @@ class RoundSliderThumbShape extends SliderComponentShape {
/// sliders in a widget subtree. /// sliders in a widget subtree.
class RoundSliderOverlayShape extends SliderComponentShape { class RoundSliderOverlayShape extends SliderComponentShape {
/// Create a slider thumb overlay that draws a circle. /// Create a slider thumb overlay that draws a circle.
const RoundSliderOverlayShape(); // TODO(clocksmith): This needs to be changed to 24 according to spec.
const RoundSliderOverlayShape({ this.overlayRadius = 16.0 });
static const double _overlayRadius = 16.0; /// The preferred radius of the round thumb shape when enabled.
///
/// If it is not provided, then half of the track height is used.
final double overlayRadius;
@override @override
Size getPreferredSize(bool isEnabled, bool isDiscrete) { Size getPreferredSize(bool isEnabled, bool isDiscrete) {
return const Size.fromRadius(_overlayRadius); return Size.fromRadius(overlayRadius);
} }
@override @override
...@@ -1087,7 +1125,7 @@ class RoundSliderOverlayShape extends SliderComponentShape { ...@@ -1087,7 +1125,7 @@ class RoundSliderOverlayShape extends SliderComponentShape {
final Canvas canvas = context.canvas; final Canvas canvas = context.canvas;
final Tween<double> radiusTween = Tween<double>( final Tween<double> radiusTween = Tween<double>(
begin: 0.0, begin: 0.0,
end: _overlayRadius, end: overlayRadius,
); );
// TODO(gspencer): We don't really follow the spec here for overlays. // TODO(gspencer): We don't really follow the spec here for overlays.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment