Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Unified Diff: sky/sdk/lib/widgets/checkbox.dart

Issue 1185173002: Really basic Switch implementation in Sky. Could definitely use some polish (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/sdk/lib/widgets/checkbox.dart
diff --git a/sky/sdk/lib/widgets/checkbox.dart b/sky/sdk/lib/widgets/checkbox.dart
index 9f709c0241edb80fe16e0a4db006af7937e1fd0f..94adaed2abc16dc9aa6eb077d58c0a43327a39b7 100644
--- a/sky/sdk/lib/widgets/checkbox.dart
+++ b/sky/sdk/lib/widgets/checkbox.dart
@@ -5,9 +5,11 @@
import 'dart:sky' as sky;
import 'package:sky/theme2/colors.dart' as colors;
+import 'package:sky/theme2/shadows.dart';
import '../framework/animation/animated_value.dart';
import '../framework/animation/curves.dart';
+import '../painting/shadows.dart';
import '../rendering/box.dart';
import 'animated_component.dart';
import 'basic.dart';
@@ -61,75 +63,137 @@ class Checkbox extends AnimatedComponent {
onChanged(!checked);
}
+ void _customPaintCallback(sky.Canvas canvas, Size size) {
+ // Choose a color between grey and the theme color
+ sky.Paint paint = new sky.Paint()..strokeWidth = 2.0
+ ..color = _kUncheckedColor;
+
+ // The rrect contracts slightly during the animation
+ double inset = 2.0 - (_checkedAnimation.value - _kMidpoint).abs() * 2.0;
+ sky.Rect rect = new sky.Rect.fromLTRB(inset, inset, _kEdgeSize - inset, _kEdgeSize - inset);
+ sky.RRect rrect = new sky.RRect()..setRectXY(rect, _kEdgeRadius, _kEdgeRadius);
+
+ // Outline of the empty rrect
+ paint.setStyle(sky.PaintingStyle.stroke);
+ canvas.drawRRect(rrect, paint);
+
+ // Radial gradient that changes size
+ if (_checkedAnimation.value > 0) {
+ paint.setStyle(sky.PaintingStyle.fill);
+ paint.setShader(
+ new sky.Gradient.radial(
+ new Point(_kEdgeSize / 2.0, _kEdgeSize / 2.0),
+ _kEdgeSize * (_kMidpoint - _checkedAnimation.value) * 8.0,
+ [const sky.Color(0x00000000), _kUncheckedColor],
+ [0.0, 1.0]
Matt Perry 2015/06/15 18:22:10 FYI, [0, 1] is the default, so you can just leave
+ )
+ );
+ canvas.drawRRect(rrect, paint);
+ }
+
+ if (_checkedAnimation.value > _kMidpoint) {
+ double t = (_checkedAnimation.value - _kMidpoint) / (1.0 - _kMidpoint);
+
+ // Solid filled rrect
+ paint.setStyle(sky.PaintingStyle.strokeAndFill);
+ paint.color = new Color.fromARGB((t * 255).floor(),
+ _kCheckedColor.red,
+ _kCheckedColor.green,
+ _kCheckedColor.blue);
+ canvas.drawRRect(rrect, paint);
+
+ // White inner check
+ paint.color = const sky.Color(0xFFFFFFFF);
+ paint.setStyle(sky.PaintingStyle.stroke);
+ sky.Path path = new sky.Path();
+ sky.Point start = new sky.Point(_kEdgeSize * 0.2, _kEdgeSize * 0.5);
+ sky.Point mid = new sky.Point(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
+ sky.Point end = new sky.Point(_kEdgeSize * 0.8, _kEdgeSize * 0.3);
+ Point lerp(Point p1, Point p2, double t)
+ => new Point(p1.x * (1.0 - t) + p2.x * t, p1.y * (1.0 - t) + p2.y * t);
+ sky.Point drawStart = lerp(start, mid, 1.0 - t);
+ sky.Point drawEnd = lerp(mid, end, t);
+ path.moveTo(drawStart.x, drawStart.y);
+ path.lineTo(mid.x, mid.y);
+ path.lineTo(drawEnd.x, drawEnd.y);
+ canvas.drawPath(path, paint);
+ }
+ }
+
+ double get _width => _kEdgeSize + 2.0;
+ double get _height => _kEdgeSize + 2.0;
+ EdgeDims get _margin => const EdgeDims.symmetric(horizontal: 5.0);
+
UINode build() {
return new EventListenerNode(
new Container(
margin: const EdgeDims.symmetric(horizontal: 5.0),
- width: _kEdgeSize + 2.0,
- height: _kEdgeSize + 2.0,
+ width: _width,
+ height: _height,
child: new CustomPaint(
token: _checkedAnimation.value,
- callback: (sky.Canvas canvas, Size size) {
- // Choose a color between grey and the theme color
- sky.Paint paint = new sky.Paint()..strokeWidth = 2.0
- ..color = _kUncheckedColor;
-
- // The rrect contracts slightly during the animation
- double inset = 2.0 - (_checkedAnimation.value - _kMidpoint).abs() * 2.0;
- sky.Rect rect = new sky.Rect.fromLTRB(inset, inset, _kEdgeSize - inset, _kEdgeSize - inset);
- sky.RRect rrect = new sky.RRect()..setRectXY(rect, _kEdgeRadius, _kEdgeRadius);
-
-
- // Outline of the empty rrect
- paint.setStyle(sky.PaintingStyle.stroke);
- canvas.drawRRect(rrect, paint);
-
- // Radial gradient that changes size
- if (_checkedAnimation.value > 0) {
- paint.setStyle(sky.PaintingStyle.fill);
- paint.setShader(
- new sky.Gradient.radial(
- new Point(_kEdgeSize / 2.0, _kEdgeSize / 2.0),
- _kEdgeSize * (_kMidpoint - _checkedAnimation.value) * 8.0,
- [const sky.Color(0x00000000), _kUncheckedColor],
- [0.0, 1.0]
- )
- );
- canvas.drawRRect(rrect, paint);
- }
-
- if (_checkedAnimation.value > _kMidpoint) {
- double t = (_checkedAnimation.value - _kMidpoint) / (1.0 - _kMidpoint);
-
- // Solid filled rrect
- paint.setStyle(sky.PaintingStyle.strokeAndFill);
- paint.color = new Color.fromARGB((t * 255).floor(),
- _kCheckedColor.red,
- _kCheckedColor.green,
- _kCheckedColor.blue);
- canvas.drawRRect(rrect, paint);
-
- // White inner check
- paint.color = const sky.Color(0xFFFFFFFF);
- paint.setStyle(sky.PaintingStyle.stroke);
- sky.Path path = new sky.Path();
- sky.Point start = new sky.Point(_kEdgeSize * 0.2, _kEdgeSize * 0.5);
- sky.Point mid = new sky.Point(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
- sky.Point end = new sky.Point(_kEdgeSize * 0.8, _kEdgeSize * 0.3);
- Point lerp(Point p1, Point p2, double t)
- => new Point(p1.x * (1.0 - t) + p2.x * t, p1.y * (1.0 - t) + p2.y * t);
- sky.Point drawStart = lerp(start, mid, 1.0 - t);
- sky.Point drawEnd = lerp(mid, end, t);
- path.moveTo(drawStart.x, drawStart.y);
- path.lineTo(mid.x, mid.y);
- path.lineTo(drawEnd.x, drawEnd.y);
- canvas.drawPath(path, paint);
- }
- }
+ callback: _customPaintCallback
)
),
onGestureTap: _handleClick
);
}
+}
+// TODO(jackson): This should change colors with the theme
+sky.Color _kSwitchOnColor = colors.Purple[500];
+const sky.Color _kSwitchOffColor = const sky.Color(0xFFFAFAFA);
+sky.Color _kTrackOnColor = new sky.Color(_kSwitchOnColor.value & (0x80 << 24));
+const sky.Color _kTrackOffColor = const sky.Color(0x42000000);
+const double _kSwitchWidth = 35.0;
+const double _kThumbRadius = 10.0;
+const double _kSwitchHeight = _kThumbRadius * 2.0;
+const double _kTrackHeight = 10.0;
+const double _kTrackRadius = _kTrackHeight / 2.0;
+const double _kTrackWidth = _kSwitchWidth - (_kThumbRadius - _kTrackRadius) * 2.0;
+
+class Switch extends Checkbox {
+ // TODO(jackson): Hit-test the switch so that it can respond to both taps and swipe gestures
+
+ Switch({
+ Object key,
+ bool checked,
+ ValueChanged onChanged
+ }) : super(key: key, checked: checked, onChanged: onChanged);
+
+ double get _width => _kSwitchWidth + 2.0;
+ double get _height => _kSwitchHeight + 2.0;
+ EdgeDims get _margin => const EdgeDims.symmetric(horizontal: 5.0);
+
+ void _customPaintCallback(sky.Canvas canvas, Size size) {
abarth-chromium 2015/06/15 18:19:12 You probably want to extract a base class from Che
+ sky.Color thumbColor = checked ? _kSwitchOnColor : _kSwitchOffColor;
+ sky.Color trackColor = checked ? _kTrackOnColor : _kTrackOffColor;
+
+ // Draw the track rrect
+ sky.Paint paint = new sky.Paint()..color = trackColor;
+ paint.setStyle(sky.PaintingStyle.fill);
+ sky.Rect rect = new sky.Rect.fromLTRB(
+ 0.0,
+ _kSwitchHeight / 2.0 - _kTrackHeight / 2.0,
+ _kTrackWidth,
+ _kSwitchHeight / 2.0 + _kTrackHeight / 2.0
+ );
+ sky.RRect rrect = new sky.RRect()..setRectXY(rect, _kTrackRadius, _kTrackRadius);
+ canvas.drawRRect(rrect, paint);
+
+ // Draw the raised thumb with a shadow
+ paint.color = thumbColor;
+ var builder = new ShadowDrawLooperBuilder();
+ for (BoxShadow boxShadow in shadows[1])
+ builder.addShadow(boxShadow.offset, boxShadow.color, boxShadow.blur);
+ paint.setDrawLooper(builder.build());
+
+ // The thumb contracts slightly during the animation
+ double inset = 2.0 - (_checkedAnimation.value - _kMidpoint).abs() * 2.0;
+ Point thumbPos = new Point(
+ _kTrackRadius + _checkedAnimation.value * (_kTrackWidth - _kTrackRadius * 2),
+ _kSwitchHeight / 2.0
+ );
+ canvas.drawCircle(thumbPos.x, thumbPos.y, _kThumbRadius - inset, paint);
+ }
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698