Unverified Commit 0545c63b authored by MH Johnson's avatar MH Johnson Committed by GitHub

Revert "[Material] Update slider and slider theme with new sizes, shapes, and...

Revert "[Material] Update slider and slider theme with new sizes, shapes, and color mappings (#30390)" (#31339)

This reverts commit b1039f0f.

(This is a temporary revert while some of our customers deal with the breaking changes involved.)
parent 484f6e75
......@@ -428,52 +428,27 @@ class _SliderState extends State<Slider> with TickerProviderStateMixin {
return widget.max > widget.min ? (value - widget.min) / (widget.max - widget.min) : 0.0;
}
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 = PaddleSliderValueIndicatorShape();
static const ShowValueIndicator _defaultShowValueIndicator = ShowValueIndicator.onlyForDiscrete;
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context));
assert(debugCheckHasMediaQuery(context));
final ThemeData theme = Theme.of(context);
SliderThemeData sliderTheme = SliderTheme.of(context);
// If the widget has active or inactive colors specified, then we plug them
// in to the slider theme as best we can. If the developer wants more
// control than that, then they need to use a SliderTheme. The default
// colors come from the ThemeData.colorScheme. These colors, along with
// the default shapes and text styles are aligned to the Material
// Guidelines.
sliderTheme = sliderTheme.copyWith(
trackHeight: sliderTheme.trackHeight ?? _defaultTrackHeight,
activeTrackColor: widget.activeColor ?? sliderTheme.activeTrackColor ?? theme.colorScheme.primary,
inactiveTrackColor: widget.inactiveColor ?? sliderTheme.inactiveTrackColor ?? theme.colorScheme.primary.withOpacity(0.24),
disabledActiveTrackColor: sliderTheme.disabledActiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.32),
disabledInactiveTrackColor: sliderTheme.disabledInactiveTrackColor ?? theme.colorScheme.onSurface.withOpacity(0.12),
activeTickMarkColor: widget.inactiveColor ?? sliderTheme.activeTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.54),
inactiveTickMarkColor: widget.activeColor ?? sliderTheme.inactiveTickMarkColor ?? theme.colorScheme.primary.withOpacity(0.54),
disabledActiveTickMarkColor: sliderTheme.disabledActiveTickMarkColor ?? theme.colorScheme.onPrimary.withOpacity(0.12),
disabledInactiveTickMarkColor: sliderTheme.disabledInactiveTickMarkColor ?? theme.colorScheme.onSurface.withOpacity(0.12),
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: widget.activeColor ?? sliderTheme.valueIndicatorColor ?? theme.colorScheme.primary,
trackShape: sliderTheme.trackShape ?? _defaultTrackShape,
tickMarkShape: sliderTheme.tickMarkShape ?? _defaultTickMarkShape,
thumbShape: sliderTheme.thumbShape ?? _defaultThumbShape,
overlayShape: sliderTheme.overlayShape ?? _defaultOverlayShape,
valueIndicatorShape: sliderTheme.valueIndicatorShape ?? _defaultValueIndicatorShape,
showValueIndicator: sliderTheme.showValueIndicator ?? _defaultShowValueIndicator,
valueIndicatorTextStyle: sliderTheme.valueIndicatorTextStyle ?? theme.textTheme.body2.copyWith(
color: theme.colorScheme.onPrimary,
),
);
// control than that, then they need to use a SliderTheme.
if (widget.activeColor != null || widget.inactiveColor != null) {
sliderTheme = sliderTheme.copyWith(
activeTrackColor: widget.activeColor,
inactiveTrackColor: widget.inactiveColor,
activeTickMarkColor: widget.inactiveColor,
inactiveTickMarkColor: widget.activeColor,
thumbColor: widget.activeColor,
valueIndicatorColor: widget.activeColor,
overlayColor: widget.activeColor?.withAlpha(0x29),
);
}
return _SliderRenderObjectWidget(
value: _unlerp(widget.value),
......@@ -523,6 +498,7 @@ class _SliderRenderObjectWidget extends LeafRenderObjectWidget {
divisions: divisions,
label: label,
sliderTheme: sliderTheme,
theme: Theme.of(context),
mediaQueryData: mediaQueryData,
onChanged: onChanged,
onChangeStart: onChangeStart,
......@@ -560,6 +536,7 @@ class _RenderSlider extends RenderBox {
int divisions,
String label,
SliderThemeData sliderTheme,
ThemeData theme,
MediaQueryData mediaQueryData,
TargetPlatform platform,
ValueChanged<double> onChanged,
......@@ -577,6 +554,7 @@ class _RenderSlider extends RenderBox {
_value = value,
_divisions = divisions,
_sliderTheme = sliderTheme,
_theme = theme,
_mediaQueryData = mediaQueryData,
_onChanged = onChanged,
_state = state,
......@@ -1005,6 +983,7 @@ class _RenderSlider extends RenderBox {
isEnabled: isInteractive,
);
// TODO(closkmith): Move this to paint after the thumb.
if (!_overlayAnimation.isDismissed) {
_sliderTheme.overlayShape.paint(
context,
......@@ -1021,6 +1000,7 @@ class _RenderSlider extends RenderBox {
}
if (isDiscrete) {
// TODO(clocksmith): Align tick mark centers to ends of track by not subtracting diameter from length.
final double tickMarkWidth = _sliderTheme.tickMarkShape.getPreferredSize(
isEnabled: isInteractive,
sliderTheme: _sliderTheme,
......
......@@ -210,27 +210,46 @@ class SliderThemeData extends Diagnosticable {
/// ```
/// {@end-tool}
const SliderThemeData({
this.trackHeight,
this.activeTrackColor,
this.inactiveTrackColor,
this.disabledActiveTrackColor,
this.disabledInactiveTrackColor,
this.activeTickMarkColor,
this.inactiveTickMarkColor,
this.disabledActiveTickMarkColor,
this.disabledInactiveTickMarkColor,
this.thumbColor,
this.disabledThumbColor,
this.overlayColor,
this.valueIndicatorColor,
this.trackShape,
this.tickMarkShape,
this.thumbShape,
this.overlayShape,
this.valueIndicatorShape,
this.showValueIndicator,
this.valueIndicatorTextStyle,
});
@required this.trackHeight,
@required this.activeTrackColor,
@required this.inactiveTrackColor,
@required this.disabledActiveTrackColor,
@required this.disabledInactiveTrackColor,
@required this.activeTickMarkColor,
@required this.inactiveTickMarkColor,
@required this.disabledActiveTickMarkColor,
@required this.disabledInactiveTickMarkColor,
@required this.thumbColor,
@required this.disabledThumbColor,
@required this.overlayColor,
@required this.valueIndicatorColor,
@required this.trackShape,
@required this.tickMarkShape,
@required this.thumbShape,
@required this.overlayShape,
@required this.valueIndicatorShape,
@required this.showValueIndicator,
@required this.valueIndicatorTextStyle,
}) : assert(trackHeight != null),
assert(activeTrackColor != null),
assert(inactiveTrackColor != null),
assert(disabledActiveTrackColor != null),
assert(disabledInactiveTrackColor != null),
assert(activeTickMarkColor != null),
assert(inactiveTickMarkColor != null),
assert(disabledActiveTickMarkColor != null),
assert(disabledInactiveTickMarkColor != null),
assert(thumbColor != null),
assert(disabledThumbColor != null),
assert(overlayColor != null),
assert(valueIndicatorColor != null),
assert(trackShape != null),
assert(tickMarkShape != null),
assert(thumbShape != null),
assert(overlayShape != null),
assert(valueIndicatorShape != null),
assert(valueIndicatorTextStyle != null),
assert(showValueIndicator != null);
/// Generates a SliderThemeData from three main colors.
///
......@@ -264,9 +283,15 @@ class SliderThemeData extends Diagnosticable {
const int disabledInactiveTickMarkAlpha = 0x1f; // 12% opacity
const int thumbAlpha = 0xff;
const int disabledThumbAlpha = 0x52; // 32% opacity
const int overlayAlpha = 0x1f; // 12% opacity
const int valueIndicatorAlpha = 0xff;
// TODO(gspencer): We don't really follow the spec here for overlays.
// The spec says to use 16% opacity for drawing over light material,
// and 32% for colored material, but we don't really have a way to
// know what the underlying color is, so there's no easy way to
// implement this. Choosing the "light" version for now.
const int overlayLightAlpha = 0x29; // 16% opacity
return SliderThemeData(
trackHeight: 2.0,
activeTrackColor: primaryColor.withAlpha(activeTrackAlpha),
......@@ -279,9 +304,9 @@ class SliderThemeData extends Diagnosticable {
disabledInactiveTickMarkColor: primaryColorDark.withAlpha(disabledInactiveTickMarkAlpha),
thumbColor: primaryColor.withAlpha(thumbAlpha),
disabledThumbColor: primaryColorDark.withAlpha(disabledThumbAlpha),
overlayColor: primaryColor.withAlpha(overlayAlpha),
overlayColor: primaryColor.withAlpha(overlayLightAlpha),
valueIndicatorColor: primaryColor.withAlpha(valueIndicatorAlpha),
trackShape: const RoundedRectSliderTrackShape(),
trackShape: const RectangularSliderTrackShape(),
tickMarkShape: const RoundSliderTickMarkShape(),
thumbShape: const RoundSliderThumbShape(),
overlayShape: const RoundSliderOverlayShape(),
......@@ -902,151 +927,15 @@ class _EmptySliderComponentShape extends SliderComponentShape {
}
}
/// Base track shape that provides an implementation of [getPreferredRect] for
/// default sizing.
///
/// See also:
///
/// * [RectangularSliderTrackShape], which is a track shape with sharp
/// rectangular edges
/// * [RoundedRectSliderTrackShape], which is a track shape with round
/// stadium-like edges.
///
/// The height is set from [SliderThemeData.trackHeight] and the width of the
/// parent box less the larger of the widths of [SliderThemeData.thumbShape] and
/// [SliderThemeData.overlayShape].
abstract class BaseSliderTrackShape {
/// Returns a rect that represents the track bounds that fits within the
/// [Slider].
///
/// The width is the width of the [Slider], but padded by the max
/// of the overlay and thumb radius. The height is defined by the
/// [SliderThemeData.trackHeight].
///
/// The [Rect] is centered both horizontally and vertically within the slider
/// bounds.
Rect getPreferredRect({
@required RenderBox parentBox,
Offset offset = Offset.zero,
SliderThemeData sliderTheme,
bool isEnabled = false,
bool isDiscrete = false,
}) {
assert(parentBox != null);
final double thumbWidth = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete).width;
final double overlayWidth = sliderTheme.overlayShape.getPreferredSize(isEnabled, isDiscrete).width;
final double trackHeight = sliderTheme.trackHeight;
assert(overlayWidth >= 0);
assert(trackHeight >= 0);
assert(parentBox.size.width >= overlayWidth);
assert(parentBox.size.height >= trackHeight);
final double trackLeft = offset.dx + overlayWidth / 2;
final double trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2;
final double trackWidth = parentBox.size.width - math.max(thumbWidth, overlayWidth);
return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
}
}
// The following shapes are the material defaults.
/// This is the default shape of a [Slider]'s track.
///
/// It paints a solid colored rectangle with rounded edges, vertically centered
/// in the [parentBox]. The track rectangle extends to the bounds of the
/// [parentBox], but is padded by the larger of [RoundSliderOverlayShape]'s
/// radius and [RoundSliderThumbShape]'s radius. The height is defined by the
/// [SliderThemeData.trackHeight]. The color is determined by the [Slider]'s
/// enabled state and the track segment's active state which are defined by:
/// [SliderThemeData.activeTrackColor],
/// [SliderThemeData.inactiveTrackColor],
/// [SliderThemeData.disabledActiveTrackColor],
/// [SliderThemeData.disabledInactiveTrackColor].
///
/// See also:
///
/// * [Slider], for the component that is meant to display this shape.
/// * [SliderThemeData], where an instance of this class is set to inform the
/// slider of the visual details of the its track.
/// * [SliderTrackShape], which is the base component for creating other
/// custom track shapes.
/// * [RectangularSliderTrackShape], for a similar track with sharp edges.
class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackShape {
/// Create a slider track that draws two rectangles with rounded outer edges.
const RoundedRectSliderTrackShape();
@override
void paint(
PaintingContext context,
Offset offset, {
@required RenderBox parentBox,
@required SliderThemeData sliderTheme,
@required Animation<double> enableAnimation,
@required TextDirection textDirection,
@required Offset thumbCenter,
bool isDiscrete = false,
bool isEnabled = false,
}) {
assert(context != null);
assert(offset != null);
assert(parentBox != null);
assert(sliderTheme != null);
assert(enableAnimation != null);
assert(textDirection != null);
assert(thumbCenter != null);
// 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 leading: active and
// trailing: inactive.
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;
Paint rightTrackPaint;
switch (textDirection) {
case TextDirection.ltr:
leftTrackPaint = activePaint;
rightTrackPaint = inactivePaint;
break;
case TextDirection.rtl:
leftTrackPaint = inactivePaint;
rightTrackPaint = activePaint;
break;
}
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
// 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);
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);
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);
context.canvas.drawRect(leftTrackSegment, leftTrackPaint);
final Rect rightTrackSegment = Rect.fromLTRB(thumbCenter.dx + thumbSize.width / 2, trackRect.top, trackRect.right, trackRect.bottom);
context.canvas.drawRect(rightTrackSegment, rightTrackPaint);
}
}
/// A [Slider] track that's a simple rectangle.
///
/// It paints a solid colored rectangle, vertically centered in the
/// [parentBox]. The track rectangle extends to the bounds of the [parentBox],
/// but is padded by the [RoundSliderOverlayShape] radius. The height is defined
/// by the [SliderThemeData.trackHeight]. The color is determined by the
/// [Slider]'s enabled state and the track segments's active state which are
/// [Slider]'s enabled state and the track piece's active state which are
/// defined by:
/// [SliderThemeData.activeTrackColor],
/// [SliderThemeData.inactiveTrackColor],
......@@ -1055,12 +944,11 @@ class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackS
///
/// See also:
///
/// * [Slider], for the component that is meant to display this shape.
/// * [SliderThemeData], where an instance of this class is set to inform the
/// * [Slider] for the component that this is meant to display this shape.
/// * [SliderThemeData] where an instance of this class is set to inform the
/// slider of the visual details of the its track.
/// * [SliderTrackShape], which is the base component for creating other
/// custom track shapes.
/// * [RoundedRectSliderTrackShape], for a similar track with rounded edges.
/// * [SliderTrackShape] Base component for creating other custom track
/// shapes.
class RectangularSliderTrackShape extends SliderTrackShape {
/// Create a slider track that draws 2 rectangles.
const RectangularSliderTrackShape({ this.disabledThumbGapWidth = 2.0 });
......@@ -1075,15 +963,12 @@ class RectangularSliderTrackShape extends SliderTrackShape {
@override
Rect getPreferredRect({
@required RenderBox parentBox,
RenderBox parentBox,
Offset offset = Offset.zero,
@required SliderThemeData sliderTheme,
bool isEnabled = false,
bool isDiscrete = false,
SliderThemeData sliderTheme,
bool isEnabled,
bool isDiscrete,
}) {
assert(parentBox != null);
assert(sliderTheme != null);
final double thumbWidth = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete).width;
final double overlayWidth = sliderTheme.overlayShape.getPreferredSize(isEnabled, isDiscrete).width;
final double trackHeight = sliderTheme.trackHeight;
assert(overlayWidth >= 0);
......@@ -1093,33 +978,29 @@ class RectangularSliderTrackShape extends SliderTrackShape {
final double trackLeft = offset.dx + overlayWidth / 2;
final double trackTop = offset.dy + (parentBox.size.height - trackHeight) / 2;
final double trackWidth = parentBox.size.width - math.max(thumbWidth, overlayWidth);
// TODO(clocksmith): Although this works for a material, perhaps the default
// rectangular track should be padded not just by the overlay, but by the
// max of the thumb and the overlay, in case there is no overlay.
final double trackWidth = parentBox.size.width - overlayWidth;
return Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight);
}
@override
void paint(
PaintingContext context,
Offset offset, {
@required RenderBox parentBox,
@required SliderThemeData sliderTheme,
@required Animation<double> enableAnimation,
@required TextDirection textDirection,
@required Offset thumbCenter,
bool isDiscrete = false,
bool isEnabled = false,
RenderBox parentBox,
SliderThemeData sliderTheme,
Animation<double> enableAnimation,
TextDirection textDirection,
Offset thumbCenter,
bool isDiscrete,
bool isEnabled,
}) {
assert(context != null);
assert(offset != null);
assert(parentBox != null);
assert(sliderTheme != null);
assert(enableAnimation != null);
assert(textDirection != null);
assert(thumbCenter != null);
// 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) {
// If the slider track height is 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;
}
......@@ -1142,17 +1023,28 @@ class RectangularSliderTrackShape extends SliderTrackShape {
break;
}
// 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;
if (!isEnabled) {
final double disabledThumbRadius = sliderTheme.thumbShape.getPreferredSize(false, isDiscrete).width / 2.0;
final double gap = disabledThumbGapWidth * (1.0 - enableAnimation.value);
horizontalAdjustment = disabledThumbRadius + gap;
}
final Rect trackRect = getPreferredRect(
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
parentBox: parentBox,
offset: offset,
sliderTheme: sliderTheme,
isEnabled: isEnabled,
isDiscrete: isDiscrete,
);
final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left, trackRect.top, thumbCenter.dx, trackRect.bottom);
final Rect leftTrackSegment = Rect.fromLTRB(trackRect.left, trackRect.top, thumbCenter.dx - horizontalAdjustment, trackRect.bottom);
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 + horizontalAdjustment, trackRect.top, trackRect.right, trackRect.bottom);
context.canvas.drawRect(rightTrackSegment, rightTrackPaint);
}
}
......@@ -1198,20 +1090,13 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape {
void paint(
PaintingContext context,
Offset center, {
@required RenderBox parentBox,
@required SliderThemeData sliderTheme,
@required Animation<double> enableAnimation,
@required TextDirection textDirection,
@required Offset thumbCenter,
bool isEnabled = false,
RenderBox parentBox,
SliderThemeData sliderTheme,
Animation<double> enableAnimation,
TextDirection textDirection,
Offset thumbCenter,
bool isEnabled,
}) {
assert(context != null);
assert(center != null);
assert(parentBox != null);
assert(sliderTheme != null);
assert(enableAnimation != null);
assert(textDirection != null);
assert(thumbCenter != null);
// The paint color of the tick mark depends on its position relative
// to the thumb and the text direction.
Color begin;
......@@ -1248,22 +1133,26 @@ class RoundSliderTickMarkShape extends SliderTickMarkShape {
/// sliders in a widget subtree.
class RoundSliderThumbShape extends SliderComponentShape {
/// Create a slider thumb that draws a circle.
// TODO(clocksmith): This needs to be changed to 10 according to spec.
const RoundSliderThumbShape({
this.enabledThumbRadius = 10.0,
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 of 10 is used.
/// If it is not provided, then the material default is used.
final double enabledThumbRadius;
/// The preferred radius of the round thumb shape when the slider is disabled.
///
/// If no disabledRadius is provided, then it is equal to the
/// [enabledThumbRadius]
/// 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;
double get _disabledThumbRadius => disabledThumbRadius ?? enabledThumbRadius;
// 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
Size getPreferredSize(bool isEnabled, bool isDiscrete) {
......@@ -1274,24 +1163,15 @@ class RoundSliderThumbShape extends SliderComponentShape {
void paint(
PaintingContext context,
Offset center, {
@required Animation<double> activationAnimation,
@required Animation<double> enableAnimation,
bool isDiscrete = false,
@required TextPainter labelPainter,
@required RenderBox parentBox,
@required SliderThemeData sliderTheme,
@required TextDirection textDirection,
@required double value,
Animation<double> activationAnimation,
Animation<double> enableAnimation,
bool isDiscrete,
TextPainter labelPainter,
RenderBox parentBox,
SliderThemeData sliderTheme,
TextDirection textDirection,
double value,
}) {
assert(context != null);
assert(center != null);
assert(activationAnimation != null);
assert(enableAnimation != null);
assert(labelPainter != null);
assert(parentBox != null);
assert(sliderTheme != null);
assert(textDirection != null);
assert(value != null);
final Canvas canvas = context.canvas;
final Tween<double> radiusTween = Tween<double>(
begin: _disabledThumbRadius,
......@@ -1326,7 +1206,8 @@ class RoundSliderThumbShape extends SliderComponentShape {
/// sliders in a widget subtree.
class RoundSliderOverlayShape extends SliderComponentShape {
/// Create a slider thumb overlay that draws a circle.
const RoundSliderOverlayShape({ this.overlayRadius = 24.0 });
// TODO(clocksmith): This needs to be changed to 24 according to spec.
const RoundSliderOverlayShape({ this.overlayRadius = 16.0 });
/// The preferred radius of the round thumb shape when enabled.
///
......@@ -1342,30 +1223,26 @@ class RoundSliderOverlayShape extends SliderComponentShape {
void paint(
PaintingContext context,
Offset center, {
@required Animation<double> activationAnimation,
@required Animation<double> enableAnimation,
bool isDiscrete = false,
@required TextPainter labelPainter,
@required RenderBox parentBox,
@required SliderThemeData sliderTheme,
@required TextDirection textDirection,
@required double value,
Animation<double> activationAnimation,
Animation<double> enableAnimation,
bool isDiscrete,
TextPainter labelPainter,
RenderBox parentBox,
SliderThemeData sliderTheme,
TextDirection textDirection,
double value,
}) {
assert(context != null);
assert(center != null);
assert(activationAnimation != null);
assert(enableAnimation != null);
assert(labelPainter != null);
assert(parentBox != null);
assert(sliderTheme != null);
assert(textDirection != null);
assert(value != null);
final Canvas canvas = context.canvas;
final Tween<double> radiusTween = Tween<double>(
begin: 0.0,
end: overlayRadius,
);
// TODO(gspencer): We don't really follow the spec here for overlays.
// The spec says to use 16% opacity for drawing over light material,
// and 32% for colored material, but we don't really have a way to
// know what the underlying color is, so there's no easy way to
// implement this. Choosing the "light" version for now.
canvas.drawCircle(
center,
radiusTween.evaluate(activationAnimation),
......@@ -1447,7 +1324,7 @@ class PaddleSliderValueIndicatorShape extends SliderComponentShape {
final Path path = Path();
final Offset bottomKnobStart = Offset(
_bottomLobeRadius * math.cos(_bottomLobeStartAngle),
_bottomLobeRadius * math.sin(_bottomLobeStartAngle) - 2,
_bottomLobeRadius * math.sin(_bottomLobeStartAngle),
);
final Offset bottomNeckRightCenter = bottomKnobStart +
Offset(
......@@ -1597,7 +1474,7 @@ class PaddleSliderValueIndicatorShape extends SliderComponentShape {
// The distance between the end of the bottom neck arc and the beginning of
// the top neck arc. We use this to shrink/expand it based on the scale
// factor of the value indicator.
final double neckStretchBaseline = math.max(0.0, bottomLobeEnd.dy - math.max(neckLeftCenter.dy, neckRightCenter.dy));
final double neckStretchBaseline = bottomLobeEnd.dy - math.max(neckLeftCenter.dy, neckRightCenter.dy);
final double t = math.pow(inverseTextScale, 3.0);
final double stretch = (neckStretchBaseline * t).clamp(0.0, 10.0 * neckStretchBaseline);
final Offset neckStretch = Offset(0.0, neckStretchBaseline - stretch);
......@@ -1663,24 +1540,15 @@ class PaddleSliderValueIndicatorShape extends SliderComponentShape {
void paint(
PaintingContext context,
Offset center, {
@required Animation<double> activationAnimation,
@required Animation<double> enableAnimation,
bool isDiscrete = false,
@required TextPainter labelPainter,
@required RenderBox parentBox,
@required SliderThemeData sliderTheme,
@required TextDirection textDirection,
@required double value,
Animation<double> activationAnimation,
Animation<double> enableAnimation,
bool isDiscrete,
TextPainter labelPainter,
RenderBox parentBox,
SliderThemeData sliderTheme,
TextDirection textDirection,
double value,
}) {
assert(context != null);
assert(center != null);
assert(activationAnimation != null);
assert(enableAnimation != null);
assert(labelPainter != null);
assert(parentBox != null);
assert(sliderTheme != null);
assert(textDirection != null);
assert(value != null);
final ColorTween enableColor = ColorTween(
begin: sliderTheme.disabledThumbColor,
end: sliderTheme.valueIndicatorColor,
......
......@@ -243,7 +243,12 @@ class ThemeData extends Diagnosticable {
highlightColor ??= isDark ? _kDarkThemeHighlightColor : _kLightThemeHighlightColor;
splashColor ??= isDark ? _kDarkThemeSplashColor : _kLightThemeSplashColor;
sliderTheme ??= const SliderThemeData();
sliderTheme ??= SliderThemeData.fromPrimaryColors(
primaryColor: primaryColor,
primaryColorLight: primaryColorLight,
primaryColorDark: primaryColorDark,
valueIndicatorTextStyle: accentTextTheme.body2,
);
tabBarTheme ??= const TabBarTheme();
appBarTheme ??= const AppBarTheme();
bottomAppBarTheme ??= const BottomAppBarTheme();
......
......@@ -298,8 +298,8 @@ void main() {
);
final List<Offset> expectedLog = <Offset>[
const Offset(24.0, 300.0),
const Offset(24.0, 300.0),
const Offset(16.0, 300.0),
const Offset(16.0, 300.0),
const Offset(400.0, 300.0),
];
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(sliderKey)));
......@@ -313,20 +313,20 @@ void main() {
await tester.pump(const Duration(milliseconds: 10));
expect(value, equals(0.0));
expect(log.length, 5);
expect(log.last.dx, closeTo(386.6, 0.1));
expect(log.last.dx, closeTo(386.3, 0.1));
// With no more gesture or value changes, the thumb position should still
// be redrawn in the animated position.
await tester.pump();
await tester.pump(const Duration(milliseconds: 10));
expect(value, equals(0.0));
expect(log.length, 7);
expect(log.last.dx, closeTo(344.5, 0.1));
expect(log.last.dx, closeTo(343.3, 0.1));
// Final position.
await tester.pump(const Duration(milliseconds: 80));
expectedLog.add(const Offset(24.0, 300.0));
expectedLog.add(const Offset(16.0, 300.0));
expect(value, equals(0.0));
expect(log.length, 8);
expect(log.last.dx, closeTo(24.0, 0.1));
expect(log.last.dx, closeTo(16.0, 0.1));
await gesture.up();
});
......@@ -409,8 +409,8 @@ void main() {
);
final List<Offset> expectedLog = <Offset>[
const Offset(24.0, 300.0),
const Offset(24.0, 300.0),
const Offset(16.0, 300.0),
const Offset(16.0, 300.0),
const Offset(400.0, 300.0),
];
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(sliderKey)));
......@@ -424,20 +424,20 @@ void main() {
await tester.pump(const Duration(milliseconds: 10));
expect(value, equals(0.0));
expect(log.length, 5);
expect(log.last.dx, closeTo(386.6, 0.1));
expect(log.last.dx, closeTo(386.3, 0.1));
// With no more gesture or value changes, the thumb position should still
// be redrawn in the animated position.
await tester.pump();
await tester.pump(const Duration(milliseconds: 10));
expect(value, equals(0.0));
expect(log.length, 7);
expect(log.last.dx, closeTo(344.5, 0.1));
expect(log.last.dx, closeTo(343.3, 0.1));
// Final position.
await tester.pump(const Duration(milliseconds: 80));
expectedLog.add(const Offset(24.0, 300.0));
expectedLog.add(const Offset(16.0, 300.0));
expect(value, equals(0.0));
expect(log.length, 8);
expect(log.last.dx, closeTo(24.0, 0.1));
expect(log.last.dx, closeTo(16.0, 0.1));
await gesture.up();
});
......@@ -546,20 +546,6 @@ void main() {
final ThemeData theme = ThemeData(
platform: TargetPlatform.android,
primarySwatch: Colors.blue,
sliderTheme: const SliderThemeData(
disabledThumbColor: Color(0xff000001),
disabledActiveTickMarkColor: Color(0xff000002),
disabledActiveTrackColor: Color(0xff000003),
disabledInactiveTickMarkColor: Color(0xff000004),
disabledInactiveTrackColor: Color(0xff000005),
activeTrackColor: Color(0xff000006),
activeTickMarkColor: Color(0xff000007),
inactiveTrackColor: Color(0xff000008),
inactiveTickMarkColor: Color(0xff000009),
overlayColor: Color(0xff000010),
thumbColor: Color(0xff000011),
valueIndicatorColor: Color(0xff000012),
)
);
final SliderThemeData sliderTheme = theme.sliderTheme;
double value = 0.45;
......@@ -738,7 +724,7 @@ void main() {
paints
..rect(color: customColor1) // active track
..rect(color: customColor2) // inactive track
..circle(color: customColor1.withOpacity(0.12)) // overlay
..circle(color: customColor1.withAlpha(0x29)) // overlay
..circle(color: customColor2) // 1st tick mark
..circle(color: customColor2) // 2nd tick mark
..circle(color: customColor2) // 3rd tick mark
......@@ -872,7 +858,7 @@ void main() {
),
),
));
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 24.0, 600.0));
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 16.0, 600.0));
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
......@@ -892,7 +878,7 @@ void main() {
),
),
));
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 24.0, 48.0));
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 16.0, 32.0));
});
testWidgets('Slider respects textScaleFactor', (WidgetTester tester) async {
......@@ -1091,12 +1077,12 @@ void main() {
expect(
sliderBox,
paints
..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.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),
..circle(x: 17.0, y: 16.0, radius: 1.0)
..circle(x: 208.5, y: 16.0, radius: 1.0)
..circle(x: 400.0, y: 16.0, radius: 1.0)
..circle(x: 591.5, y: 16.0, radius: 1.0)
..circle(x: 783.0, y: 16.0, radius: 1.0)
..circle(x: 16.0, y: 16.0, radius: 6.0),
);
gesture = await tester.startGesture(center);
......@@ -1107,13 +1093,13 @@ void main() {
expect(
sliderBox,
paints
..circle(x: 111.20703125, y: 24.0, radius: 5.687664985656738)
..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.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),
..circle(x: 105.0625, y: 16.0, radius: 3.791776657104492)
..circle(x: 17.0, y: 16.0, radius: 1.0)
..circle(x: 208.5, y: 16.0, radius: 1.0)
..circle(x: 400.0, y: 16.0, radius: 1.0)
..circle(x: 591.5, y: 16.0, radius: 1.0)
..circle(x: 783.0, y: 16.0, radius: 1.0)
..circle(x: 105.0625, y: 16.0, radius: 6.0),
);
// Reparenting in the middle of an animation should do nothing.
......@@ -1127,13 +1113,13 @@ void main() {
expect(
sliderBox,
paints
..circle(x: 190.0135726928711, y: 24.0, radius: 12.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.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),
..circle(x: 185.5457763671875, y: 16.0, radius: 8.0)
..circle(x: 17.0, y: 16.0, radius: 1.0)
..circle(x: 208.5, y: 16.0, radius: 1.0)
..circle(x: 400.0, y: 16.0, radius: 1.0)
..circle(x: 591.5, y: 16.0, radius: 1.0)
..circle(x: 783.0, y: 16.0, radius: 1.0)
..circle(x: 185.5457763671875, y: 16.0, radius: 6.0),
);
// Wait for animations to finish.
await tester.pumpAndSettle();
......@@ -1141,13 +1127,13 @@ void main() {
expect(
sliderBox,
paints
..circle(x: 400.0, y: 24.0, radius: 24.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.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),
..circle(x: 400.0, y: 16.0, radius: 16.0)
..circle(x: 17.0, y: 16.0, radius: 1.0)
..circle(x: 208.5, y: 16.0, radius: 1.0)
..circle(x: 400.0, y: 16.0, radius: 1.0)
..circle(x: 591.5, y: 16.0, radius: 1.0)
..circle(x: 783.0, y: 16.0, radius: 1.0)
..circle(x: 400.0, y: 16.0, radius: 6.0),
);
await gesture.up();
await tester.pumpAndSettle();
......@@ -1155,12 +1141,12 @@ void main() {
expect(
sliderBox,
paints
..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.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),
..circle(x: 17.0, y: 16.0, radius: 1.0)
..circle(x: 208.5, y: 16.0, radius: 1.0)
..circle(x: 400.0, y: 16.0, radius: 1.0)
..circle(x: 591.5, y: 16.0, radius: 1.0)
..circle(x: 783.0, y: 16.0, radius: 1.0)
..circle(x: 400.0, y: 16.0, radius: 6.0),
);
}
......
......@@ -12,6 +12,17 @@ import 'package:flutter/painting.dart';
import '../rendering/mock_canvas.dart';
void main() {
testWidgets('Slider theme is built by ThemeData', (WidgetTester tester) async {
final ThemeData theme = ThemeData(
platform: TargetPlatform.android,
primarySwatch: Colors.red,
);
final SliderThemeData sliderTheme = theme.sliderTheme;
expect(sliderTheme.activeTrackColor.value, equals(Colors.red.value));
expect(sliderTheme.inactiveTrackColor.value, equals(Colors.red.withAlpha(0x3d).value));
});
testWidgets('Slider uses ThemeData slider theme if present', (WidgetTester tester) async {
final ThemeData theme = ThemeData(
platform: TargetPlatform.android,
......@@ -52,6 +63,20 @@ void main() {
);
});
testWidgets('SliderThemeData assigns the correct default shapes', (WidgetTester tester) async {
final SliderThemeData sliderTheme = ThemeData().sliderTheme;
expect(sliderTheme.trackShape, equals(isInstanceOf<RectangularSliderTrackShape>()));
expect(sliderTheme.tickMarkShape, equals(isInstanceOf<RoundSliderTickMarkShape>()));
expect(sliderTheme.thumbShape, equals(isInstanceOf<RoundSliderThumbShape>()));
expect(sliderTheme.valueIndicatorShape, equals(isInstanceOf<PaddleSliderValueIndicatorShape>()));
expect(sliderTheme.overlayShape, equals(isInstanceOf<RoundSliderOverlayShape>()));
});
testWidgets('SliderThemeData assigns the correct default flags', (WidgetTester tester) async {
final SliderThemeData sliderTheme = ThemeData().sliderTheme;
expect(sliderTheme.showValueIndicator, equals(ShowValueIndicator.onlyForDiscrete));
});
testWidgets('SliderThemeData generates correct opacities for fromPrimaryColors', (WidgetTester tester) async {
const Color customColor1 = Color(0xcafefeed);
const Color customColor2 = Color(0xdeadbeef);
......@@ -75,7 +100,7 @@ void main() {
expect(sliderTheme.disabledInactiveTickMarkColor, equals(customColor2.withAlpha(0x1f)));
expect(sliderTheme.thumbColor, equals(customColor1.withAlpha(0xff)));
expect(sliderTheme.disabledThumbColor, equals(customColor2.withAlpha(0x52)));
expect(sliderTheme.overlayColor, equals(customColor1.withAlpha(0x1f)));
expect(sliderTheme.overlayColor, equals(customColor1.withAlpha(0x29)));
expect(sliderTheme.valueIndicatorColor, equals(customColor1.withAlpha(0xff)));
expect(sliderTheme.valueIndicatorTextStyle.color, equals(customColor4));
});
......@@ -107,7 +132,7 @@ void main() {
expect(lerp.disabledInactiveTickMarkColor, equals(middleGrey.withAlpha(0x1f)));
expect(lerp.thumbColor, equals(middleGrey.withAlpha(0xff)));
expect(lerp.disabledThumbColor, equals(middleGrey.withAlpha(0x52)));
expect(lerp.overlayColor, equals(middleGrey.withAlpha(0x1f)));
expect(lerp.overlayColor, equals(middleGrey.withAlpha(0x29)));
expect(lerp.valueIndicatorColor, equals(middleGrey.withAlpha(0xff)));
expect(lerp.valueIndicatorTextStyle.color, equals(middleGrey.withAlpha(0xff)));
});
......@@ -127,8 +152,8 @@ void main() {
expect(
sliderBox,
paints
..rect(rect: Rect.fromLTRB(25.0, 299.0, 202.0, 301.0), color: sliderTheme.activeTrackColor)
..rect(rect: Rect.fromLTRB(222.0, 299.0, 776.0, 301.0), color: sliderTheme.inactiveTrackColor),
..rect(rect: Rect.fromLTRB(16.0, 299.0, 208.0, 301.0), color: sliderTheme.activeTrackColor)
..rect(rect: Rect.fromLTRB(208.0, 299.0, 784.0, 301.0), color: sliderTheme.inactiveTrackColor),
);
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
......@@ -143,8 +168,8 @@ void main() {
expect(
sliderBox,
paints
..rect(rect: Rect.fromLTRB(25.0, 299.0, 202.0, 301.0), color: sliderTheme.disabledActiveTrackColor)
..rect(rect: Rect.fromLTRB(222.0, 299.0, 776.0, 301.0), color: sliderTheme.disabledInactiveTrackColor),
..rect(rect: Rect.fromLTRB(16.0, 299.0, 202.0, 301.0), color: sliderTheme.disabledActiveTrackColor)
..rect(rect: Rect.fromLTRB(214.0, 299.0, 784.0, 301.0), color: sliderTheme.disabledInactiveTrackColor),
);
});
......@@ -164,9 +189,9 @@ void main() {
paints
..circle(
color: sliderTheme.thumbColor,
x: 212.0,
x: 208.0,
y: 300.0,
radius: 10.0,
radius: 6.0,
),
);
......@@ -181,15 +206,15 @@ void main() {
paints
..circle(
color: sliderTheme.overlayColor,
x: 212.0,
x: 208.0,
y: 300.0,
radius: 24.0,
radius: 16.0,
)
..circle(
color: sliderTheme.thumbColor,
x: 212.0,
x: 208.0,
y: 300.0,
radius: 10.0,
radius: 6.0,
),
);
......@@ -202,9 +227,9 @@ void main() {
paints
..circle(
color: sliderTheme.thumbColor,
x: 212.0,
x: 208.0,
y: 300.0,
radius: 10.0,
radius: 6.0,
),
);
});
......@@ -219,12 +244,12 @@ void main() {
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45));
final RenderBox sliderBox = tester.firstRenderObject<RenderBox>(find.byType(Slider));
expect(sliderBox, paints..circle(color: sliderTheme.thumbColor, radius: 10.0));
expect(sliderBox, paints..circle(color: sliderTheme.thumbColor, radius: 6.0));
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45, enabled: false));
await tester.pumpAndSettle(); // wait for disable animation
expect(sliderBox, paints..circle(color: sliderTheme.disabledThumbColor, radius: 10.0));
expect(sliderBox, paints..circle(color: sliderTheme.disabledThumbColor, radius: 4.0));
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45, divisions: 3));
await tester.pumpAndSettle(); // wait for enable animation
......@@ -236,7 +261,7 @@ void main() {
..circle(color: sliderTheme.activeTickMarkColor)
..circle(color: sliderTheme.inactiveTickMarkColor)
..circle(color: sliderTheme.inactiveTickMarkColor)
..circle(color: sliderTheme.thumbColor, radius: 10.0),
..circle(color: sliderTheme.thumbColor, radius: 6.0),
);
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.45, divisions: 3, enabled: false));
......@@ -249,7 +274,7 @@ void main() {
..circle(color: sliderTheme.disabledInactiveTickMarkColor)
..circle(color: sliderTheme.disabledInactiveTickMarkColor)
..circle(color: sliderTheme.disabledInactiveTickMarkColor)
..circle(color: sliderTheme.disabledThumbColor, radius: 10.0),
..circle(color: sliderTheme.disabledThumbColor, radius: 4.0),
);
});
......@@ -343,10 +368,10 @@ void main() {
color: sliderTheme.valueIndicatorColor,
includes: <Offset>[
const Offset(0.0, -40.0),
const Offset(92.0, -40.0),
const Offset(98.0, -40.0),
const Offset(-16.0, -40.0),
],
excludes: <Offset>[const Offset(98.1, -40.0), const Offset(-20.1, -40.0)],
excludes: <Offset>[const Offset(98.1, -40.0), const Offset(-16.1, -40.0)],
),
);
await gesture.up();
......@@ -365,9 +390,9 @@ void main() {
includes: <Offset>[
const Offset(0.0, -40.0),
const Offset(16.0, -40.0),
const Offset(-92.0, -40.0),
const Offset(-98.0, -40.0),
],
excludes: <Offset>[const Offset(20.1, -40.0), const Offset(-98.1, -40.0)],
excludes: <Offset>[const Offset(16.1, -40.0), const Offset(-98.1, -40.0)],
),
);
await gesture.up();
......@@ -385,14 +410,14 @@ void main() {
color: sliderTheme.valueIndicatorColor,
includes: <Offset>[
const Offset(0.0, -49.0),
const Offset(68.0, -49.0),
const Offset(90.0, -49.0),
const Offset(-24.0, -49.0),
],
excludes: <Offset>[
const Offset(98.0, -32.0), // inside full size, outside small
const Offset(-40.0, -32.0), // inside full size, outside small
const Offset(-16.0, -32.0), // inside full size, outside small
const Offset(90.1, -49.0),
const Offset(-40.1, -49.0),
const Offset(-24.1, -49.0),
],
),
);
......@@ -411,9 +436,10 @@ void main() {
color: sliderTheme.valueIndicatorColor,
includes: <Offset>[
const Offset(0.0, -38.8),
const Offset(92.0, -38.8),
const Offset(8.0, -23.0), // Inside large, outside scale=1.0
const Offset(-2.0, -23.0), // Inside large, outside scale=1.0
const Offset(98.0, -38.8),
const Offset(-16.0, -38.8),
const Offset(10.0, -23.0), // Inside large, outside scale=1.0
const Offset(-4.0, -23.0), // Inside large, outside scale=1.0
],
excludes: <Offset>[
const Offset(98.5, -38.8),
......@@ -435,8 +461,8 @@ void main() {
expect(
sliderBox,
paints
..rect(rect: Rect.fromLTRB(32.0, 292.0, 202.0, 308.0), color: sliderTheme.activeTrackColor)
..rect(rect: Rect.fromLTRB(222.0, 292.0, 776.0, 308.0), color: sliderTheme.inactiveTrackColor),
..rect(rect: Rect.fromLTRB(16.0, 292.0, 208.0, 308.0), color: sliderTheme.activeTrackColor)
..rect(rect: Rect.fromLTRB(208.0, 292.0, 784.0, 308.0), color: sliderTheme.inactiveTrackColor),
);
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
......@@ -447,8 +473,8 @@ void main() {
expect(
sliderBox,
paints
..rect(rect: Rect.fromLTRB(32.0, 292.0, 202.0, 308.0), color: sliderTheme.disabledActiveTrackColor)
..rect(rect: Rect.fromLTRB(222.0, 292.0, 776.0, 308.0), color: sliderTheme.disabledInactiveTrackColor),
..rect(rect: Rect.fromLTRB(16.0, 292.0, 202.0, 308.0), color: sliderTheme.disabledActiveTrackColor)
..rect(rect: Rect.fromLTRB(214.0, 292.0, 784.0, 308.0), color: sliderTheme.disabledInactiveTrackColor),
);
});
......@@ -465,7 +491,7 @@ void main() {
expect(
sliderBox,
paints..circle(x: 212, y: 300, radius: 7, color: sliderTheme.thumbColor),
paints..circle(x: 208, y: 300, radius: 7, color: sliderTheme.thumbColor),
);
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
......@@ -473,7 +499,7 @@ void main() {
expect(
sliderBox,
paints..circle(x: 212, y: 300, radius: 11, color: sliderTheme.disabledThumbColor),
paints..circle(x: 208, y: 300, radius: 11, color: sliderTheme.disabledThumbColor),
);
});
......@@ -489,21 +515,26 @@ void main() {
expect(
sliderBox,
paints..circle(x: 212, y: 300, radius: 9, color: sliderTheme.thumbColor),
paints..circle(x: 208, y: 300, radius: 9, color: sliderTheme.thumbColor),
);
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.25, enabled: false));
await tester.pumpAndSettle(); // wait for disable animation
// Radius should be 6, or 2/3 of 9. 2/3 because the default disabled thumb
// radius is 4 and the default enabled thumb radius is 6.
// TODO(clocksmith): This ratio will change once thumb sizes are updated to spec.
expect(
sliderBox,
paints..circle(x: 212, y: 300, radius: 9, color: sliderTheme.disabledThumbColor),
paints..circle(x: 208, y: 300, radius: 6, color: sliderTheme.disabledThumbColor),
);
});
testWidgets('The default slider tick mark shape size can be overridden', (WidgetTester tester) async {
final SliderThemeData sliderTheme = ThemeData().sliderTheme.copyWith(
tickMarkShape: const RoundSliderTickMarkShape(tickMarkRadius: 5),
tickMarkShape: const RoundSliderTickMarkShape(
tickMarkRadius: 5
),
activeTickMarkColor: const Color(0xfadedead),
inactiveTickMarkColor: const Color(0xfadebeef),
disabledActiveTickMarkColor: const Color(0xfadecafe),
......@@ -517,9 +548,9 @@ void main() {
expect(
sliderBox,
paints
..circle(x: 29, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor)
..circle(x: 21, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor)
..circle(x: 400, y: 300, radius: 5, color: sliderTheme.activeTickMarkColor)
..circle(x: 771, y: 300, radius: 5, color: sliderTheme.inactiveTickMarkColor),
..circle(x: 779, y: 300, radius: 5, color: sliderTheme.inactiveTickMarkColor),
);
await tester.pumpWidget(_buildApp(sliderTheme, value: 0.5, divisions: 2, enabled: false));
......@@ -528,9 +559,9 @@ void main() {
expect(
sliderBox,
paints
..circle(x: 29, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor)
..circle(x: 21, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor)
..circle(x: 400, y: 300, radius: 5, color: sliderTheme.disabledActiveTickMarkColor)
..circle(x: 771, y: 300, radius: 5, color: sliderTheme.disabledInactiveTickMarkColor),
..circle(x: 779, y: 300, radius: 5, color: sliderTheme.disabledInactiveTickMarkColor),
);
});
......
......@@ -56,6 +56,16 @@ void main() {
expect(darkTheme.accentTextTheme.title.color, typography.white.title.color);
});
test('Default slider indicator style gets a default body2 if accentTextTheme.body2 is null', () {
const TextTheme noBody2TextTheme = TextTheme(body2: null);
final ThemeData lightTheme = ThemeData(brightness: Brightness.light, accentTextTheme: noBody2TextTheme);
final ThemeData darkTheme = ThemeData(brightness: Brightness.dark, accentTextTheme: noBody2TextTheme);
final Typography typography = Typography(platform: lightTheme.platform);
expect(lightTheme.sliderTheme.valueIndicatorTextStyle, equals(typography.white.body2));
expect(darkTheme.sliderTheme.valueIndicatorTextStyle, equals(typography.black.body2));
});
test('Default chip label style gets a default body2 if textTheme.body2 is null', () {
const TextTheme noBody2TextTheme = TextTheme(body2: null);
final ThemeData lightTheme = ThemeData(brightness: Brightness.light, textTheme: noBody2TextTheme);
......
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