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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 import 'dart:sky' as sky; 5 import 'dart:sky' as sky;
6 6
7 import 'package:sky/theme2/colors.dart' as colors; 7 import 'package:sky/theme2/colors.dart' as colors;
8 import 'package:sky/theme2/shadows.dart';
8 9
9 import '../framework/animation/animated_value.dart'; 10 import '../framework/animation/animated_value.dart';
10 import '../framework/animation/curves.dart'; 11 import '../framework/animation/curves.dart';
12 import '../painting/shadows.dart';
11 import '../rendering/box.dart'; 13 import '../rendering/box.dart';
12 import 'animated_component.dart'; 14 import 'animated_component.dart';
13 import 'basic.dart'; 15 import 'basic.dart';
14 16
15 typedef void ValueChanged(value); 17 typedef void ValueChanged(value);
16 18
17 const double _kMidpoint = 0.5; 19 const double _kMidpoint = 0.5;
18 const double _kCheckDuration = 200.0; 20 const double _kCheckDuration = 200.0;
19 const sky.Color _kUncheckedColor = const sky.Color(0x8A000000); 21 const sky.Color _kUncheckedColor = const sky.Color(0x8A000000);
20 // TODO(jackson): This should change colors with the theme 22 // TODO(jackson): This should change colors with the theme
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 _checkedAnimation.animateTo(targetValue, duration, curve: curve); 56 _checkedAnimation.animateTo(targetValue, duration, curve: curve);
55 } 57 }
56 } 58 }
57 super.syncFields(source); 59 super.syncFields(source);
58 } 60 }
59 61
60 void _handleClick(sky.Event e) { 62 void _handleClick(sky.Event e) {
61 onChanged(!checked); 63 onChanged(!checked);
62 } 64 }
63 65
66 void _customPaintCallback(sky.Canvas canvas, Size size) {
67 // Choose a color between grey and the theme color
68 sky.Paint paint = new sky.Paint()..strokeWidth = 2.0
69 ..color = _kUncheckedColor;
70
71 // The rrect contracts slightly during the animation
72 double inset = 2.0 - (_checkedAnimation.value - _kMidpoint).abs() * 2.0;
73 sky.Rect rect = new sky.Rect.fromLTRB(inset, inset, _kEdgeSize - inset, _kEd geSize - inset);
74 sky.RRect rrect = new sky.RRect()..setRectXY(rect, _kEdgeRadius, _kEdgeRadiu s);
75
76 // Outline of the empty rrect
77 paint.setStyle(sky.PaintingStyle.stroke);
78 canvas.drawRRect(rrect, paint);
79
80 // Radial gradient that changes size
81 if (_checkedAnimation.value > 0) {
82 paint.setStyle(sky.PaintingStyle.fill);
83 paint.setShader(
84 new sky.Gradient.radial(
85 new Point(_kEdgeSize / 2.0, _kEdgeSize / 2.0),
86 _kEdgeSize * (_kMidpoint - _checkedAnimation.value) * 8.0,
87 [const sky.Color(0x00000000), _kUncheckedColor],
88 [0.0, 1.0]
Matt Perry 2015/06/15 18:22:10 FYI, [0, 1] is the default, so you can just leave
89 )
90 );
91 canvas.drawRRect(rrect, paint);
92 }
93
94 if (_checkedAnimation.value > _kMidpoint) {
95 double t = (_checkedAnimation.value - _kMidpoint) / (1.0 - _kMidpoint);
96
97 // Solid filled rrect
98 paint.setStyle(sky.PaintingStyle.strokeAndFill);
99 paint.color = new Color.fromARGB((t * 255).floor(),
100 _kCheckedColor.red,
101 _kCheckedColor.green,
102 _kCheckedColor.blue);
103 canvas.drawRRect(rrect, paint);
104
105 // White inner check
106 paint.color = const sky.Color(0xFFFFFFFF);
107 paint.setStyle(sky.PaintingStyle.stroke);
108 sky.Path path = new sky.Path();
109 sky.Point start = new sky.Point(_kEdgeSize * 0.2, _kEdgeSize * 0.5);
110 sky.Point mid = new sky.Point(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
111 sky.Point end = new sky.Point(_kEdgeSize * 0.8, _kEdgeSize * 0.3);
112 Point lerp(Point p1, Point p2, double t)
113 => new Point(p1.x * (1.0 - t) + p2.x * t, p1.y * (1.0 - t) + p2.y * t);
114 sky.Point drawStart = lerp(start, mid, 1.0 - t);
115 sky.Point drawEnd = lerp(mid, end, t);
116 path.moveTo(drawStart.x, drawStart.y);
117 path.lineTo(mid.x, mid.y);
118 path.lineTo(drawEnd.x, drawEnd.y);
119 canvas.drawPath(path, paint);
120 }
121 }
122
123 double get _width => _kEdgeSize + 2.0;
124 double get _height => _kEdgeSize + 2.0;
125 EdgeDims get _margin => const EdgeDims.symmetric(horizontal: 5.0);
126
64 UINode build() { 127 UINode build() {
65 return new EventListenerNode( 128 return new EventListenerNode(
66 new Container( 129 new Container(
67 margin: const EdgeDims.symmetric(horizontal: 5.0), 130 margin: const EdgeDims.symmetric(horizontal: 5.0),
68 width: _kEdgeSize + 2.0, 131 width: _width,
69 height: _kEdgeSize + 2.0, 132 height: _height,
70 child: new CustomPaint( 133 child: new CustomPaint(
71 token: _checkedAnimation.value, 134 token: _checkedAnimation.value,
72 callback: (sky.Canvas canvas, Size size) { 135 callback: _customPaintCallback
73 // Choose a color between grey and the theme color
74 sky.Paint paint = new sky.Paint()..strokeWidth = 2.0
75 ..color = _kUncheckedColor;
76
77 // The rrect contracts slightly during the animation
78 double inset = 2.0 - (_checkedAnimation.value - _kMidpoint).abs() * 2.0;
79 sky.Rect rect = new sky.Rect.fromLTRB(inset, inset, _kEdgeSize - ins et, _kEdgeSize - inset);
80 sky.RRect rrect = new sky.RRect()..setRectXY(rect, _kEdgeRadius, _kE dgeRadius);
81
82
83 // Outline of the empty rrect
84 paint.setStyle(sky.PaintingStyle.stroke);
85 canvas.drawRRect(rrect, paint);
86
87 // Radial gradient that changes size
88 if (_checkedAnimation.value > 0) {
89 paint.setStyle(sky.PaintingStyle.fill);
90 paint.setShader(
91 new sky.Gradient.radial(
92 new Point(_kEdgeSize / 2.0, _kEdgeSize / 2.0),
93 _kEdgeSize * (_kMidpoint - _checkedAnimation.value) * 8.0,
94 [const sky.Color(0x00000000), _kUncheckedColor],
95 [0.0, 1.0]
96 )
97 );
98 canvas.drawRRect(rrect, paint);
99 }
100
101 if (_checkedAnimation.value > _kMidpoint) {
102 double t = (_checkedAnimation.value - _kMidpoint) / (1.0 - _kMidpo int);
103
104 // Solid filled rrect
105 paint.setStyle(sky.PaintingStyle.strokeAndFill);
106 paint.color = new Color.fromARGB((t * 255).floor(),
107 _kCheckedColor.red,
108 _kCheckedColor.green,
109 _kCheckedColor.blue);
110 canvas.drawRRect(rrect, paint);
111
112 // White inner check
113 paint.color = const sky.Color(0xFFFFFFFF);
114 paint.setStyle(sky.PaintingStyle.stroke);
115 sky.Path path = new sky.Path();
116 sky.Point start = new sky.Point(_kEdgeSize * 0.2, _kEdgeSize * 0.5 );
117 sky.Point mid = new sky.Point(_kEdgeSize * 0.4, _kEdgeSize * 0.7);
118 sky.Point end = new sky.Point(_kEdgeSize * 0.8, _kEdgeSize * 0.3);
119 Point lerp(Point p1, Point p2, double t)
120 => new Point(p1.x * (1.0 - t) + p2.x * t, p1.y * (1.0 - t) + p2. y * t);
121 sky.Point drawStart = lerp(start, mid, 1.0 - t);
122 sky.Point drawEnd = lerp(mid, end, t);
123 path.moveTo(drawStart.x, drawStart.y);
124 path.lineTo(mid.x, mid.y);
125 path.lineTo(drawEnd.x, drawEnd.y);
126 canvas.drawPath(path, paint);
127 }
128 }
129 ) 136 )
130 ), 137 ),
131 onGestureTap: _handleClick 138 onGestureTap: _handleClick
132 ); 139 );
133 } 140 }
141 }
134 142
143 // TODO(jackson): This should change colors with the theme
144 sky.Color _kSwitchOnColor = colors.Purple[500];
145 const sky.Color _kSwitchOffColor = const sky.Color(0xFFFAFAFA);
146 sky.Color _kTrackOnColor = new sky.Color(_kSwitchOnColor.value & (0x80 << 24));
147 const sky.Color _kTrackOffColor = const sky.Color(0x42000000);
148 const double _kSwitchWidth = 35.0;
149 const double _kThumbRadius = 10.0;
150 const double _kSwitchHeight = _kThumbRadius * 2.0;
151 const double _kTrackHeight = 10.0;
152 const double _kTrackRadius = _kTrackHeight / 2.0;
153 const double _kTrackWidth = _kSwitchWidth - (_kThumbRadius - _kTrackRadius) * 2. 0;
154
155 class Switch extends Checkbox {
156 // TODO(jackson): Hit-test the switch so that it can respond to both taps and swipe gestures
157
158 Switch({
159 Object key,
160 bool checked,
161 ValueChanged onChanged
162 }) : super(key: key, checked: checked, onChanged: onChanged);
163
164 double get _width => _kSwitchWidth + 2.0;
165 double get _height => _kSwitchHeight + 2.0;
166 EdgeDims get _margin => const EdgeDims.symmetric(horizontal: 5.0);
167
168 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
169 sky.Color thumbColor = checked ? _kSwitchOnColor : _kSwitchOffColor;
170 sky.Color trackColor = checked ? _kTrackOnColor : _kTrackOffColor;
171
172 // Draw the track rrect
173 sky.Paint paint = new sky.Paint()..color = trackColor;
174 paint.setStyle(sky.PaintingStyle.fill);
175 sky.Rect rect = new sky.Rect.fromLTRB(
176 0.0,
177 _kSwitchHeight / 2.0 - _kTrackHeight / 2.0,
178 _kTrackWidth,
179 _kSwitchHeight / 2.0 + _kTrackHeight / 2.0
180 );
181 sky.RRect rrect = new sky.RRect()..setRectXY(rect, _kTrackRadius, _kTrackRad ius);
182 canvas.drawRRect(rrect, paint);
183
184 // Draw the raised thumb with a shadow
185 paint.color = thumbColor;
186 var builder = new ShadowDrawLooperBuilder();
187 for (BoxShadow boxShadow in shadows[1])
188 builder.addShadow(boxShadow.offset, boxShadow.color, boxShadow.blur);
189 paint.setDrawLooper(builder.build());
190
191 // The thumb contracts slightly during the animation
192 double inset = 2.0 - (_checkedAnimation.value - _kMidpoint).abs() * 2.0;
193 Point thumbPos = new Point(
194 _kTrackRadius + _checkedAnimation.value * (_kTrackWidth - _kTrackRadius * 2),
195 _kSwitchHeight / 2.0
196 );
197 canvas.drawCircle(thumbPos.x, thumbPos.y, _kThumbRadius - inset, paint);
198 }
135 } 199 }
OLDNEW
« 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