Skip to content

Conversation

@clocksmith
Copy link
Contributor

@clocksmith clocksmith commented Apr 2, 2019

Description

This PR makes a number of changes to the visual appearance of material sliders:

  • Sizes/Shapes
    ** enabled thumb radius from 6 to 10
    ** disabled thumb radius from 4 to 10 with no gap
    ** default track shape is a rounded rect rather than a rect
    **
  • Colors
    ** all of the colors now use the new color scheme
    ** overlay opacity has been reduce from 16% to 12%
    ** value indicator text color now respects the indicator it is on by using onPrimary
    ** disabledThumb color no respects the surface it is on by using onSurface

The slider theme is also now constructed consistently with other theme objects within the ThemeData. By default, all values are null, and have default values that are resolved in the slider itself, rather than in the slider theme.

Related Issues

Closes #28706
Closes #30314
Closes #30315
Closes #30316
Closes #30317

Tests

No new tests were added, but many had to be updated to the new sizes and colors. Tests for default slider theme data property resolving were removed since the SliderThemeData no longer does that.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

@HansMuller HansMuller added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Apr 2, 2019
@clocksmith clocksmith changed the title [Material] Update slider and slider theme with new sizes, shapes, and color mappings [WIP] [Material] Update slider and slider theme with new sizes, shapes, and color mappings Apr 2, 2019
@clocksmith clocksmith changed the title [WIP] [Material] Update slider and slider theme with new sizes, shapes, and color mappings [Material] Update slider and slider theme with new sizes, shapes, and color mappings Apr 4, 2019
Copy link
Contributor

@rami-a rami-a left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from as much as I know about sliders

bool isEnabled,
bool isDiscrete,
}) {
isEnabled = isEnabled ?? false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these 2 be set to false as default values in the param list instead of here?

bool isEnabled,
bool isDiscrete,
}) {
isEnabled = isEnabled ?? false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these 2 be set to false as default values in the param list instead of here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

// The following shapes are the material defaults.
/// Base track shape with default sizing.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain just a little more in the first line of the description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

///
/// See also:
///
/// * [Slider] for the component that this is meant to display this shape.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed this, and where it was in other places. Also updated these to follow the "See also" pattern so its more consistent throughout this file.

/// See also:
///
/// * [Slider] for the component that this is meant to display this shape.
/// * [SliderThemeData] where an instance of this class is set to inform the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize the W in Where

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to adding a comma after the [Foo] to be consistent with the other "See also" sections

/// shapes.
/// * [RectangularSliderTrackShape] for a similar track with blunt edges.
class RoundedRectSliderTrackShape extends SliderTrackShape with BaseSliderTrackShape {
/// Create a slider track that draws 2 rectangles with rounded outer edges.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 => two

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return;
}

// Assign the track segment paints, which are left: active, right: inactive,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the left and right in RTL?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I see one line below that they are.

Change this to leading and trailing instead of right and left and you get all that for free.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the comments will be clear without having to say what happens in RTL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is noted that it is reversed for RTL on the next line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@willlarche willlarche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! It's a big one!!

isDiscrete: isDiscrete,
);

final Rect leftTrackArcRect = Rect.fromLTWH(trackRect.left, trackRect.top, trackRect.height, trackRect.height);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment explaining why you have the height for both width and height/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

log.clear();
});

// TODO(clocksmith): delete this test in favor of something in slider_theme_test
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this stale?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks. Deleted.

),
));
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 16.0, 600.0));
expect(tester.renderObject<RenderBox>(find.byType(Slider)).size, const Size(144.0 + 2.0 * 24.0, 600.0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anywhere you're doing math, you can drop the .0s.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping for consistency within file.

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks pretty good.

It would be useful to include a regression test that verifies (as best we can) that the new dimensions and appearance of a default enabled/disabled slider never changes. Although this could be done with a golden image test, a unit test would be better at pinpointing the source of regressions. I added similar tests for buttons recently: https://github.com/flutter/flutter/blob/master/packages/flutter/test/material/buttons_test.dart#L18

// 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(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is OK, since it's straightforward, although it's a bit of a monster. If we added a SliderTheme.merge() method that only changed null properties, then what's going on it might be a little clearer:

final SliderThemeData sliderTheme = SliderTheme.of(
  // Non-null widget properties override SliderTheme values.
  .copyWith(
    activeTrackColor: widget.activeColor,
    inactiveTrackColor: widget.inactiveColor,
    activeTickMarkColor: widget.inactiveColor,
    inactiveTickMarkColor: widget.activeColor,
    thumbColor: widget.activeColor,
    overlayColor: widget.activeColor?.withOpacity(0.12),
    valueIndicatorColor: widget.activeColor)
  // Default all of the remaining null SliderTheme properties.
  .merge(
    activeTrackColor: theme.colorScheme.primary,
    inactiveTrackColor: theme.colorScheme.primary.withOpacity(0.24),
    disabledActiveTrackColor: theme.colorScheme.onSurface.withOpacity(0.32),
    disabledInactiveTrackColor: theme.colorScheme.onSurface.withOpacity(0.12),
    activeTickMarkColor: theme.colorScheme.onPrimary.withOpacity(0.54),
    inactiveTickMarkColor: theme.colorScheme.primary.withOpacity(0.54),
    disabledActiveTickMarkColor: theme.colorScheme.onPrimary.withOpacity(0.12),
    disabledInactiveTickMarkColor: theme.colorScheme.onSurface.withOpacity(0.12),
    thumbColor: theme.colorScheme.primary,
    disabledThumbColor: theme.colorScheme.onSurface.withOpacity(0.38),
    overlayColor: theme.colorScheme.primary.withOpacity(0.12),
    valueIndicatorColor: theme.colorScheme.primary,
    trackShape: _defaultTrackShape,
    tickMarkShape: _defaultTickMarkShape,
    thumbShape: _defaultThumbShape,
    overlayShape: _defaultOverlayShape,
    valueIndicatorShape: _defaultValueIndicatorShape,
    showValueIndicator:_defaultShowValueIndicator,
    valueIndicatorTextStyle: theme.textTheme.body2.copyWith(color: theme.colorScheme.onPrimary),
  );
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some experimentation, I do not think the .merge method needed would be similar enough to the merge on TextTheme and TextStyle, so it might be confusing to have .merge methods in different objects that behave differently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we haven't established a consistent meaning for "merge" methods and adding one here that works like ListTileTheme.merge but not like TextStyle.merge or Border.merge will not help matters.

We can solve the general problem and then update this monster in a separate PR.

/// Base track shape that provides an implementation of [getPreferredRect] for
/// default sizing.
///
/// The [SliderTrackShape]s that use this base class are:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be needed, DartDoc will generate a list of implementers. A "See also" section that named these subclasses and provided a one-liner explanation of what they mean would be useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/// [parentBox], but is padded by the larger of [RoundSliderOverlayShape]
/// radius and [RoundSliderThumbShape]. The height is defined by the
/// [SliderThemeData.trackHeight]. The color is determined by the [Slider]'s
/// enabled state and the track piece's active state which are defined by:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"track piece"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

bool isEnabled = false,
bool isDiscrete = false,
}) {
final double thumbWidth = sliderTheme.thumbShape.getPreferredSize(isEnabled, isDiscrete).width;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assert sliderTheme != null etc. Here and elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in all getPreferredFoo and paint methods

// TODO(clocksmith): This needs to be changed to 10 according to spec.
const RoundSliderThumbShape({
this.enabledThumbRadius = 6.0,
this.enabledThumbRadius = 10.0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc for the enabledThumbRadius property should admit that the default is 10

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

final Offset bottomKnobStart = Offset(
_bottomLobeRadius * math.cos(_bottomLobeStartAngle),
_bottomLobeRadius * math.sin(_bottomLobeStartAngle),
_bottomLobeRadius * math.sin(_bottomLobeStartAngle) - 2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the "-2" doing here (it seems odd to be subtracting 2 from a radians value)? It's OK to say that it was derived "experimentally" so long as we explain what effect it has.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is the y value of the offset, it was experimentally to get the bottom lobe in the right place after adjusting the lobe radius

Copy link
Contributor

@HansMuller HansMuller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

// 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(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we haven't established a consistent meaning for "merge" methods and adding one here that works like ListTileTheme.merge but not like TextStyle.merge or Border.merge will not help matters.

We can solve the general problem and then update this monster in a separate PR.

@clocksmith clocksmith merged commit b1039f0 into flutter:master Apr 18, 2019
johnsonmh added a commit that referenced this pull request Apr 20, 2019
johnsonmh added a commit that referenced this pull request Apr 20, 2019
…pes, and color mappings (#30390)" (#31339)

This reverts commit b1039f0.

(This is a temporary revert while some of our customers deal with the breaking changes involved.)
clocksmith added a commit that referenced this pull request Apr 24, 2019
… color mappings (2nd attempt) (#31564)

#30390 was rolled back. This PR will re-roll it forward.

This PR makes a number of changes to the visual appearance of material sliders:

Sizes/Shapes
** enabled thumb radius from 6 to 10
** disabled thumb radius from 4 to 10 with no gap
** default track shape is a rounded rect rather than a rect
**
Colors
** all of the colors now use the new color scheme
** overlay opacity has been reduce from 16% to 12%
** value indicator text color now respects the indicator it is on by using onPrimary
** disabledThumb color no respects the surface it is on by using onSurface
The slider theme is also now constructed consistently with other theme objects within the ThemeData. By default, all values are null, and have default values that are resolved in the slider itself, rather than in the slider theme.
@clocksmith clocksmith deleted the slider-breaking branch September 12, 2019 16:55
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

6 participants