Commit dca4e4aa authored by Adam Barth's avatar Adam Barth

Polish selection controls

The touch ripple now starts at the touch location instead of being
centered on the widget.

Fixes #2652
parent db9a92e5
......@@ -112,7 +112,7 @@ class _RenderCheckbox extends RenderToggleable {
final double offsetX = _kOffset + offset.dx;
final double offsetY = _kOffset + offset.dy;
paintRadialReaction(canvas, offset + const Offset(kRadialReactionRadius, kRadialReactionRadius));
paintRadialReaction(canvas, offset, const Point(kRadialReactionRadius, kRadialReactionRadius));
double t = position.value;
......
......@@ -112,7 +112,7 @@ class _RenderRadio extends RenderToggleable {
void paint(PaintingContext context, Offset offset) {
final Canvas canvas = context.canvas;
paintRadialReaction(canvas, offset + const Offset(kRadialReactionRadius, kRadialReactionRadius));
paintRadialReaction(canvas, offset, const Point(kRadialReactionRadius, kRadialReactionRadius));
Point center = (offset & size).center;
Color radioColor = onChanged != null ? activeColor : inactiveColor;
......
......@@ -135,7 +135,6 @@ class _RenderSwitch extends RenderToggleable {
activeColor: activeColor,
inactiveColor: inactiveColor,
onChanged: onChanged,
minRadialReactionRadius: _kThumbRadius,
size: const Size(_kSwitchWidth, _kSwitchHeight)
) {
_drag = new HorizontalDragGestureRecognizer()
......@@ -248,12 +247,12 @@ class _RenderSwitch extends RenderToggleable {
RRect trackRRect = new RRect.fromRectXY(trackRect, _kTrackRadius, _kTrackRadius);
canvas.drawRRect(trackRRect, paint);
Offset thumbOffset = new Offset(
offset.dx + kRadialReactionRadius + currentPosition * _trackInnerLength,
offset.dy + size.height / 2.0
Point thumbPosition = new Point(
kRadialReactionRadius + currentPosition * _trackInnerLength,
size.height / 2.0
);
paintRadialReaction(canvas, thumbOffset);
paintRadialReaction(canvas, offset, thumbPosition);
BoxPainter thumbPainter;
if (_inactiveThumbDecoration == null && _activeThumbDecoration == null) {
......@@ -272,10 +271,10 @@ class _RenderSwitch extends RenderToggleable {
// The thumb contracts slightly during the animation
double inset = 2.0 - (currentPosition - 0.5).abs() * 2.0;
double radius = _kThumbRadius - inset;
Rect thumbRect = new Rect.fromLTRB(thumbOffset.dx - radius,
thumbOffset.dy - radius,
thumbOffset.dx + radius,
thumbOffset.dy + radius);
Rect thumbRect = new Rect.fromLTRB(thumbPosition.x + offset.dx - radius,
thumbPosition.y + offset.dy - radius,
thumbPosition.x + offset.dx + radius,
thumbPosition.y + offset.dy + radius);
thumbPainter.paint(canvas, thumbRect);
}
}
......@@ -9,6 +9,7 @@ import 'package:flutter/rendering.dart';
import 'constants.dart';
const Duration _kToggleDuration = const Duration(milliseconds: 200);
final Tween<double> _kRadialReactionRadiusTween = new Tween<double>(begin: 0.0, end: kRadialReactionRadius);
// RenderToggleable is a base class for material style toggleable controls with
// toggle animations. It handles storing the current value, dispatching
......@@ -20,8 +21,7 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
Size size,
Color activeColor,
Color inactiveColor,
ValueChanged<bool> onChanged,
double minRadialReactionRadius: 0.0
ValueChanged<bool> onChanged
}) : _value = value,
_activeColor = activeColor,
_inactiveColor = inactiveColor,
......@@ -46,13 +46,10 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
..addStatusListener(_handlePositionStateChanged);
_reactionController = new AnimationController(duration: kRadialReactionDuration);
_reaction = new Tween<double>(
begin: minRadialReactionRadius,
end: kRadialReactionRadius
).animate(new CurvedAnimation(
_reaction = new CurvedAnimation(
parent: _reactionController,
curve: Curves.ease
))..addListener(markNeedsPaint);
)..addListener(markNeedsPaint);
}
bool get value => _value;
......@@ -118,6 +115,7 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
Animation<double> _reaction;
TapGestureRecognizer _tap;
Point _downPosition;
void _handlePositionStateChanged(AnimationStatus status) {
if (isInteractive) {
......@@ -129,8 +127,10 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
}
void _handleTapDown(Point globalPosition) {
if (isInteractive)
if (isInteractive) {
_downPosition = globalToLocal(globalPosition);
_reactionController.forward();
}
}
void _handleTap() {
......@@ -139,11 +139,13 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
}
void _handleTapUp(Point globalPosition) {
_downPosition = null;
if (isInteractive)
_reactionController.reverse();
}
void _handleTapCancel() {
_downPosition = null;
if (isInteractive)
_reactionController.reverse();
}
......@@ -157,11 +159,13 @@ abstract class RenderToggleable extends RenderConstrainedBox implements Semantic
_tap.addPointer(event);
}
void paintRadialReaction(Canvas canvas, Offset offset) {
void paintRadialReaction(Canvas canvas, Offset offset, Point origin) {
if (!_reaction.isDismissed) {
// TODO(abarth): We should have a different reaction color when position is zero.
Paint reactionPaint = new Paint()..color = activeColor.withAlpha(kRadialReactionAlpha);
canvas.drawCircle(offset.toPoint(), _reaction.value, reactionPaint);
Point center = Point.lerp(_downPosition ?? origin, origin, _reaction.value);
double radius = _kRadialReactionRadiusTween.evaluate(_reaction);
canvas.drawCircle(center + offset, radius, reactionPaint);
}
}
......
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