Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 } |
| OLD | NEW |