| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 import 'dart:sky' as sky; |
| 6 import 'dart:sky' show Point, Size, Rect, Color, Paint, Path; |
| 7 import 'shadows.dart'; |
| 8 |
| 9 class BorderSide { |
| 10 const BorderSide({ |
| 11 this.color: const Color(0xFF000000), |
| 12 this.width: 1.0 |
| 13 }); |
| 14 final Color color; |
| 15 final double width; |
| 16 |
| 17 static const none = const BorderSide(width: 0.0); |
| 18 |
| 19 int get hashCode { |
| 20 int value = 373; |
| 21 value = 37 * value * color.hashCode; |
| 22 value = 37 * value * width.hashCode; |
| 23 return value; |
| 24 } |
| 25 String toString() => 'BorderSide($color, $width)'; |
| 26 } |
| 27 |
| 28 class Border { |
| 29 const Border({ |
| 30 this.top: BorderSide.none, |
| 31 this.right: BorderSide.none, |
| 32 this.bottom: BorderSide.none, |
| 33 this.left: BorderSide.none |
| 34 }); |
| 35 |
| 36 const Border.all(BorderSide side) : |
| 37 top = side, |
| 38 right = side, |
| 39 bottom = side, |
| 40 left = side; |
| 41 |
| 42 final BorderSide top; |
| 43 final BorderSide right; |
| 44 final BorderSide bottom; |
| 45 final BorderSide left; |
| 46 |
| 47 int get hashCode { |
| 48 int value = 373; |
| 49 value = 37 * value * top.hashCode; |
| 50 value = 37 * value * right.hashCode; |
| 51 value = 37 * value * bottom.hashCode; |
| 52 value = 37 * value * left.hashCode; |
| 53 return value; |
| 54 } |
| 55 String toString() => 'Border($top, $right, $bottom, $left)'; |
| 56 } |
| 57 |
| 58 class BoxShadow { |
| 59 const BoxShadow({ |
| 60 this.color, |
| 61 this.offset, |
| 62 this.blur |
| 63 }); |
| 64 |
| 65 final Color color; |
| 66 final Size offset; |
| 67 final double blur; |
| 68 |
| 69 String toString() => 'BoxShadow($color, $offset, $blur)'; |
| 70 } |
| 71 |
| 72 abstract class Gradient { |
| 73 sky.Shader createShader(); |
| 74 } |
| 75 |
| 76 class LinearGradient extends Gradient { |
| 77 LinearGradient({ |
| 78 this.endPoints, |
| 79 this.colors, |
| 80 this.colorStops, |
| 81 this.tileMode: sky.TileMode.clamp |
| 82 }); |
| 83 |
| 84 String toString() => |
| 85 'LinearGradient($endPoints, $colors, $colorStops, $tileMode)'; |
| 86 |
| 87 sky.Shader createShader() { |
| 88 return new sky.Gradient.Linear(this.endPoints, this.colors, this.colorStops, |
| 89 this.tileMode); |
| 90 } |
| 91 |
| 92 final List<Point> endPoints; |
| 93 final List<Color> colors; |
| 94 final List<double> colorStops; |
| 95 final sky.TileMode tileMode; |
| 96 } |
| 97 |
| 98 class RadialGradient extends Gradient { |
| 99 RadialGradient({ |
| 100 this.center, |
| 101 this.radius, |
| 102 this.colors, |
| 103 this.colorStops, |
| 104 this.tileMode: sky.TileMode.clamp |
| 105 }); |
| 106 |
| 107 String toString() => |
| 108 'RadialGradient($center, $radius, $colors, $colorStops, $tileMode)'; |
| 109 |
| 110 sky.Shader createShader() { |
| 111 return new sky.Gradient.Radial(this.center, this.radius, this.colors, |
| 112 this.colorStops, this.tileMode); |
| 113 } |
| 114 |
| 115 final Point center; |
| 116 final double radius; |
| 117 final List<Color> colors; |
| 118 final List<double> colorStops; |
| 119 final sky.TileMode tileMode; |
| 120 } |
| 121 |
| 122 // This must be immutable, because we won't notice when it changes |
| 123 class BoxDecoration { |
| 124 const BoxDecoration({ |
| 125 this.backgroundColor, |
| 126 this.border, |
| 127 this.borderRadius, |
| 128 this.boxShadow, |
| 129 this.gradient |
| 130 }); |
| 131 |
| 132 final Color backgroundColor; |
| 133 final double borderRadius; |
| 134 final Border border; |
| 135 final List<BoxShadow> boxShadow; |
| 136 final Gradient gradient; |
| 137 |
| 138 String toString([String prefix = '']) { |
| 139 List<String> result = []; |
| 140 if (backgroundColor != null) |
| 141 result.add('${prefix}backgroundColor: $backgroundColor'); |
| 142 if (border != null) |
| 143 result.add('${prefix}border: $border'); |
| 144 if (borderRadius != null) |
| 145 result.add('${prefix}borderRadius: $borderRadius'); |
| 146 if (boxShadow != null) |
| 147 result.add('${prefix}boxShadow: ${boxShadow.map((shadow) => shadow.toStrin
g())}'); |
| 148 if (gradient != null) |
| 149 result.add('${prefix}gradient: $gradient'); |
| 150 if (result.isEmpty) |
| 151 return '${prefix}<no decorations specified>'; |
| 152 return result.join('\n'); |
| 153 } |
| 154 } |
| 155 |
| 156 class BoxPainter { |
| 157 BoxPainter(BoxDecoration decoration) : _decoration = decoration { |
| 158 assert(decoration != null); |
| 159 } |
| 160 |
| 161 BoxDecoration _decoration; |
| 162 BoxDecoration get decoration => _decoration; |
| 163 void set decoration (BoxDecoration value) { |
| 164 assert(value != null); |
| 165 if (value == _decoration) |
| 166 return; |
| 167 _decoration = value; |
| 168 _cachedBackgroundPaint = null; |
| 169 } |
| 170 |
| 171 Paint _cachedBackgroundPaint; |
| 172 Paint get _backgroundPaint { |
| 173 if (_cachedBackgroundPaint == null) { |
| 174 Paint paint = new Paint(); |
| 175 |
| 176 if (_decoration.backgroundColor != null) |
| 177 paint.color = _decoration.backgroundColor; |
| 178 |
| 179 if (_decoration.boxShadow != null) { |
| 180 var builder = new ShadowDrawLooperBuilder(); |
| 181 for (BoxShadow boxShadow in _decoration.boxShadow) |
| 182 builder.addShadow(boxShadow.offset, boxShadow.color, boxShadow.blur); |
| 183 paint.setDrawLooper(builder.build()); |
| 184 } |
| 185 |
| 186 if (_decoration.gradient != null) |
| 187 paint.setShader(_decoration.gradient.createShader()); |
| 188 |
| 189 _cachedBackgroundPaint = paint; |
| 190 } |
| 191 |
| 192 return _cachedBackgroundPaint; |
| 193 } |
| 194 |
| 195 void paint(sky.Canvas canvas, Rect rect) { |
| 196 if (_decoration.backgroundColor != null || _decoration.boxShadow != null || |
| 197 _decoration.gradient != null) { |
| 198 if (_decoration.borderRadius == null) |
| 199 canvas.drawRect(rect, _backgroundPaint); |
| 200 else |
| 201 canvas.drawRRect(new sky.RRect()..setRectXY(rect, _decoration.borderRadi
us, _decoration.borderRadius), _backgroundPaint); |
| 202 } |
| 203 |
| 204 if (_decoration.border != null) { |
| 205 assert(_decoration.borderRadius == null); // TODO(abarth): Implement borde
rs with border radius. |
| 206 |
| 207 assert(_decoration.border.top != null); |
| 208 assert(_decoration.border.right != null); |
| 209 assert(_decoration.border.bottom != null); |
| 210 assert(_decoration.border.left != null); |
| 211 |
| 212 Paint paint = new Paint(); |
| 213 Path path; |
| 214 |
| 215 paint.color = _decoration.border.top.color; |
| 216 path = new Path(); |
| 217 path.moveTo(rect.left, rect.top); |
| 218 path.lineTo(rect.left + _decoration.border.left.width, rect.top + _decorat
ion.border.top.width); |
| 219 path.lineTo(rect.right - _decoration.border.right.width, rect.top + _decor
ation.border.top.width); |
| 220 path.lineTo(rect.right, rect.top); |
| 221 path.close(); |
| 222 canvas.drawPath(path, paint); |
| 223 |
| 224 paint.color = _decoration.border.right.color; |
| 225 path = new Path(); |
| 226 path.moveTo(rect.right, rect.top); |
| 227 path.lineTo(rect.right - _decoration.border.right.width, rect.top + _decor
ation.border.top.width); |
| 228 path.lineTo(rect.right - _decoration.border.right.width, rect.bottom - _de
coration.border.bottom.width); |
| 229 path.lineTo(rect.right, rect.bottom); |
| 230 path.close(); |
| 231 canvas.drawPath(path, paint); |
| 232 |
| 233 paint.color = _decoration.border.bottom.color; |
| 234 path = new Path(); |
| 235 path.moveTo(rect.right, rect.bottom); |
| 236 path.lineTo(rect.right - _decoration.border.right.width, rect.bottom - _de
coration.border.bottom.width); |
| 237 path.lineTo(rect.left + _decoration.border.left.width, rect.bottom - _deco
ration.border.bottom.width); |
| 238 path.lineTo(rect.left, rect.bottom); |
| 239 path.close(); |
| 240 canvas.drawPath(path, paint); |
| 241 |
| 242 paint.color = _decoration.border.left.color; |
| 243 path = new Path(); |
| 244 path.moveTo(rect.left, rect.bottom); |
| 245 path.lineTo(rect.left + _decoration.border.left.width, rect.bottom - _deco
ration.border.bottom.width); |
| 246 path.lineTo(rect.left + _decoration.border.left.width, rect.top + _decorat
ion.border.top.width); |
| 247 path.lineTo(rect.left, rect.top); |
| 248 path.close(); |
| 249 canvas.drawPath(path, paint); |
| 250 } |
| 251 } |
| 252 } |
| OLD | NEW |