Commit 2a69a981 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #781 from Hixie/box_decoration

Make BoxDecoration replaceable.
parents 0fe72b17 2afa87df
...@@ -50,7 +50,7 @@ class Dot extends StatelessComponent { ...@@ -50,7 +50,7 @@ class Dot extends StatelessComponent {
height: size, height: size,
decoration: new BoxDecoration( decoration: new BoxDecoration(
backgroundColor: color, backgroundColor: color,
shape: Shape.circle shape: BoxShape.circle
), ),
child: child child: child
); );
......
...@@ -14,7 +14,7 @@ class Circle extends StatelessComponent { ...@@ -14,7 +14,7 @@ class Circle extends StatelessComponent {
width: 50.0, width: 50.0,
margin: margin + new EdgeDims.symmetric(horizontal: 2.0), margin: margin + new EdgeDims.symmetric(horizontal: 2.0),
decoration: new BoxDecoration( decoration: new BoxDecoration(
shape: Shape.circle, shape: BoxShape.circle,
backgroundColor: const Color(0xFF00FF00) backgroundColor: const Color(0xFF00FF00)
) )
); );
......
...@@ -15,6 +15,8 @@ library painting; ...@@ -15,6 +15,8 @@ library painting;
export 'src/painting/basic_types.dart'; export 'src/painting/basic_types.dart';
export 'src/painting/box_painter.dart'; export 'src/painting/box_painter.dart';
export 'src/painting/colors.dart'; export 'src/painting/colors.dart';
export 'src/painting/decoration.dart';
export 'src/painting/edge_dims.dart';
export 'src/painting/shadows.dart'; export 'src/painting/shadows.dart';
export 'src/painting/text_painter.dart'; export 'src/painting/text_painter.dart';
export 'src/painting/text_style.dart'; export 'src/painting/text_style.dart';
......
...@@ -35,7 +35,7 @@ class CircleAvatar extends StatelessComponent { ...@@ -35,7 +35,7 @@ class CircleAvatar extends StatelessComponent {
duration: kThemeChangeDuration, duration: kThemeChangeDuration,
decoration: new BoxDecoration( decoration: new BoxDecoration(
backgroundColor: color, backgroundColor: color,
shape: Shape.circle shape: BoxShape.circle
), ),
width: 40.0, width: 40.0,
height: 40.0, height: 40.0,
......
...@@ -226,7 +226,7 @@ class DayPicker extends StatelessComponent { ...@@ -226,7 +226,7 @@ class DayPicker extends StatelessComponent {
selectedDate.day == day) selectedDate.day == day)
decoration = new BoxDecoration( decoration = new BoxDecoration(
backgroundColor: theme.primarySwatch[100], backgroundColor: theme.primarySwatch[100],
shape: Shape.circle shape: BoxShape.circle
); );
// Use a different font color for the current day // Use a different font color for the current day
...@@ -377,7 +377,7 @@ class _YearPickerState extends ScrollableWidgetListState<YearPicker> { ...@@ -377,7 +377,7 @@ class _YearPickerState extends ScrollableWidgetListState<YearPicker> {
height: config.itemExtent, height: config.itemExtent,
decoration: year == config.selectedDate.year ? new BoxDecoration( decoration: year == config.selectedDate.year ? new BoxDecoration(
backgroundColor: Theme.of(context).primarySwatch[100], backgroundColor: Theme.of(context).primarySwatch[100],
shape: Shape.circle shape: BoxShape.circle
) : null, ) : null,
child: new Center( child: new Center(
child: new Text(label, style: style) child: new Text(label, style: style)
......
...@@ -37,11 +37,11 @@ class _DropDownMenuPainter extends CustomPainter { ...@@ -37,11 +37,11 @@ class _DropDownMenuPainter extends CustomPainter {
final RenderBox renderBox; final RenderBox renderBox;
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
final BoxPainter painter = new BoxPainter(new BoxDecoration( final BoxPainter painter = new BoxDecoration(
backgroundColor: color, backgroundColor: color,
borderRadius: 2.0, borderRadius: 2.0,
boxShadow: elevationToShadow[elevation] boxShadow: elevationToShadow[elevation]
)); ).createBoxPainter();
double top = renderBox.globalToLocal(new Point(0.0, menuTop)).y; double top = renderBox.globalToLocal(new Point(0.0, menuTop)).y;
double bottom = renderBox.globalToLocal(new Point(0.0, menuBottom)).y; double bottom = renderBox.globalToLocal(new Point(0.0, menuBottom)).y;
......
...@@ -18,7 +18,7 @@ class InkResponse extends StatefulComponent { ...@@ -18,7 +18,7 @@ class InkResponse extends StatefulComponent {
this.onLongPress, this.onLongPress,
this.onHighlightChanged, this.onHighlightChanged,
this.containedInWell: false, this.containedInWell: false,
this.highlightShape: Shape.circle this.highlightShape: BoxShape.circle
}) : super(key: key); }) : super(key: key);
final Widget child; final Widget child;
...@@ -27,7 +27,7 @@ class InkResponse extends StatefulComponent { ...@@ -27,7 +27,7 @@ class InkResponse extends StatefulComponent {
final GestureLongPressCallback onLongPress; final GestureLongPressCallback onLongPress;
final ValueChanged<bool> onHighlightChanged; final ValueChanged<bool> onHighlightChanged;
final bool containedInWell; final bool containedInWell;
final Shape highlightShape; final BoxShape highlightShape;
_InkResponseState createState() => new _InkResponseState<InkResponse>(); _InkResponseState createState() => new _InkResponseState<InkResponse>();
} }
...@@ -170,6 +170,6 @@ class InkWell extends InkResponse { ...@@ -170,6 +170,6 @@ class InkWell extends InkResponse {
onLongPress: onLongPress, onLongPress: onLongPress,
onHighlightChanged: onHighlightChanged, onHighlightChanged: onHighlightChanged,
containedInWell: true, containedInWell: true,
highlightShape: Shape.rectangle highlightShape: BoxShape.rectangle
); );
} }
...@@ -65,7 +65,7 @@ abstract class MaterialInkController { ...@@ -65,7 +65,7 @@ abstract class MaterialInkController {
InkSplash splashAt({ RenderBox referenceBox, Point position, Color color, bool containedInWell, VoidCallback onRemoved }); InkSplash splashAt({ RenderBox referenceBox, Point position, Color color, bool containedInWell, VoidCallback onRemoved });
/// Begin a highlight, coincident with the referenceBox. /// Begin a highlight, coincident with the referenceBox.
InkHighlight highlightAt({ RenderBox referenceBox, Color color, Shape shape: Shape.rectangle, VoidCallback onRemoved }); InkHighlight highlightAt({ RenderBox referenceBox, Color color, BoxShape shape: BoxShape.rectangle, VoidCallback onRemoved });
/// Add an arbitrary InkFeature to this InkController. /// Add an arbitrary InkFeature to this InkController.
void addInkFeature(InkFeature feature); void addInkFeature(InkFeature feature);
...@@ -153,7 +153,7 @@ class _MaterialState extends State<Material> { ...@@ -153,7 +153,7 @@ class _MaterialState extends State<Material> {
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
borderRadius: kMaterialEdges[config.type], borderRadius: kMaterialEdges[config.type],
boxShadow: config.elevation == 0 ? null : elevationToShadow[config.elevation], boxShadow: config.elevation == 0 ? null : elevationToShadow[config.elevation],
shape: config.type == MaterialType.circle ? Shape.circle : Shape.rectangle shape: config.type == MaterialType.circle ? BoxShape.circle : BoxShape.rectangle
), ),
child: contents child: contents
); );
...@@ -217,7 +217,7 @@ class RenderInkFeatures extends RenderProxyBox implements MaterialInkController ...@@ -217,7 +217,7 @@ class RenderInkFeatures extends RenderProxyBox implements MaterialInkController
InkHighlight highlightAt({ InkHighlight highlightAt({
RenderBox referenceBox, RenderBox referenceBox,
Color color, Color color,
Shape shape: Shape.rectangle, BoxShape shape: BoxShape.rectangle,
VoidCallback onRemoved VoidCallback onRemoved
}) { }) {
_InkHighlight highlight = new _InkHighlight( _InkHighlight highlight = new _InkHighlight(
...@@ -423,7 +423,7 @@ class _InkHighlight extends InkFeature implements InkHighlight { ...@@ -423,7 +423,7 @@ class _InkHighlight extends InkFeature implements InkHighlight {
renderer.markNeedsPaint(); renderer.markNeedsPaint();
} }
final Shape shape; final BoxShape shape;
bool get active => _active; bool get active => _active;
bool _active = true; bool _active = true;
...@@ -452,7 +452,7 @@ class _InkHighlight extends InkFeature implements InkHighlight { ...@@ -452,7 +452,7 @@ class _InkHighlight extends InkFeature implements InkHighlight {
} }
void _paintHighlight(Canvas canvas, Rect rect, paint) { void _paintHighlight(Canvas canvas, Rect rect, paint) {
if (shape == Shape.rectangle) if (shape == BoxShape.rectangle)
canvas.drawRect(rect, paint); canvas.drawRect(rect, paint);
else else
canvas.drawCircle(rect.center, _kDefaultSplashRadius, paint); canvas.drawCircle(rect.center, _kDefaultSplashRadius, paint);
......
...@@ -170,7 +170,8 @@ class _RenderSwitch extends RenderToggleable { ...@@ -170,7 +170,8 @@ class _RenderSwitch extends RenderToggleable {
super.handleEvent(event, entry); super.handleEvent(event, entry);
} }
final BoxPainter _thumbPainter = new BoxPainter(const BoxDecoration()); Color _cachedThumbColor;
BoxPainter _thumbPainter;
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
final Canvas canvas = context.canvas; final Canvas canvas = context.canvas;
...@@ -200,11 +201,14 @@ class _RenderSwitch extends RenderToggleable { ...@@ -200,11 +201,14 @@ class _RenderSwitch extends RenderToggleable {
paintRadialReaction(canvas, thumbOffset); paintRadialReaction(canvas, thumbOffset);
_thumbPainter.decoration = new BoxDecoration( if (_cachedThumbColor != thumbColor) {
backgroundColor: thumbColor, _thumbPainter = new BoxDecoration(
shape: Shape.circle, backgroundColor: thumbColor,
boxShadow: elevationToShadow[1] shape: BoxShape.circle,
); boxShadow: elevationToShadow[1]
).createBoxPainter();
_cachedThumbColor = thumbColor;
}
// The thumb contracts slightly during the animation // The thumb contracts slightly during the animation
double inset = 2.0 - (position.value - 0.5).abs() * 2.0; double inset = 2.0 - (position.value - 0.5).abs() * 2.0;
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'edge_dims.dart';
export 'edge_dims.dart' show EdgeDims;
// This group of classes is intended for painting in cartesian coordinates.
abstract class Decoration {
const Decoration();
bool debugAssertValid() => true;
EdgeDims get padding => null;
Decoration lerpFrom(Decoration a, double t) => this;
Decoration lerpTo(Decoration b, double t) => b;
bool hitTest(ui.Size size, ui.Point position) => true;
bool get needsListeners => false;
void addChangeListener(ui.VoidCallback listener) { assert(false); }
void removeChangeListener(ui.VoidCallback listener) { assert(false); }
BoxPainter createBoxPainter();
String toString([String prefix = '']) => '$prefix$runtimeType';
}
abstract class BoxPainter {
void paint(ui.Canvas canvas, ui.Rect rect);
}
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
/// An immutable set of offsets in each of the four cardinal directions.
///
/// Typically used for an offset from each of the four sides of a box. For
/// example, the padding inside a box can be represented using this class.
class EdgeDims {
/// Constructs an EdgeDims from offsets from the top, right, bottom and left.
const EdgeDims.TRBL(this.top, this.right, this.bottom, this.left);
/// Constructs an EdgeDims where all the offsets are value.
const EdgeDims.all(double value)
: top = value, right = value, bottom = value, left = value;
/// Constructs an EdgeDims with only the given values non-zero.
const EdgeDims.only({ this.top: 0.0,
this.right: 0.0,
this.bottom: 0.0,
this.left: 0.0 });
/// Constructs an EdgeDims with symmetrical vertical and horizontal offsets.
const EdgeDims.symmetric({ double vertical: 0.0,
double horizontal: 0.0 })
: top = vertical, left = horizontal, bottom = vertical, right = horizontal;
/// The offset from the top.
final double top;
/// The offset from the right.
final double right;
/// The offset from the bottom.
final double bottom;
/// The offset from the left.
final double left;
/// Whether every dimension is non-negative.
bool get isNonNegative => top >= 0.0 && right >= 0.0 && bottom >= 0.0 && left >= 0.0;
/// The size that this edge dims would occupy with an empty interior.
ui.Size get collapsedSize => new ui.Size(left + right, top + bottom);
ui.Rect inflateRect(ui.Rect rect) {
return new ui.Rect.fromLTRB(rect.left - left, rect.top - top, rect.right + right, rect.bottom + bottom);
}
EdgeDims operator -(EdgeDims other) {
return new EdgeDims.TRBL(
top - other.top,
right - other.right,
bottom - other.bottom,
left - other.left
);
}
EdgeDims operator +(EdgeDims other) {
return new EdgeDims.TRBL(
top + other.top,
right + other.right,
bottom + other.bottom,
left + other.left
);
}
EdgeDims operator *(double other) {
return new EdgeDims.TRBL(
top * other,
right * other,
bottom * other,
left * other
);
}
EdgeDims operator /(double other) {
return new EdgeDims.TRBL(
top / other,
right / other,
bottom / other,
left / other
);
}
EdgeDims operator ~/(double other) {
return new EdgeDims.TRBL(
(top ~/ other).toDouble(),
(right ~/ other).toDouble(),
(bottom ~/ other).toDouble(),
(left ~/ other).toDouble()
);
}
EdgeDims operator %(double other) {
return new EdgeDims.TRBL(
top % other,
right % other,
bottom % other,
left % other
);
}
/// Linearly interpolate between two EdgeDims.
///
/// If either is null, this function interpolates from [EdgeDims.zero].
static EdgeDims lerp(EdgeDims a, EdgeDims b, double t) {
if (a == null && b == null)
return null;
if (a == null)
return b * t;
if (b == null)
return a * (1.0 - t);
return new EdgeDims.TRBL(
ui.lerpDouble(a.top, b.top, t),
ui.lerpDouble(a.right, b.right, t),
ui.lerpDouble(a.bottom, b.bottom, t),
ui.lerpDouble(a.left, b.left, t)
);
}
/// An EdgeDims with zero offsets in each direction.
static const EdgeDims zero = const EdgeDims.TRBL(0.0, 0.0, 0.0, 0.0);
bool operator ==(dynamic other) {
if (identical(this, other))
return true;
if (other is! EdgeDims)
return false;
final EdgeDims typedOther = other;
return top == typedOther.top &&
right == typedOther.right &&
bottom == typedOther.bottom &&
left == typedOther.left;
}
int get hashCode {
int value = 373;
value = 37 * value + top.hashCode;
value = 37 * value + left.hashCode;
value = 37 * value + bottom.hashCode;
value = 37 * value + right.hashCode;
return value;
}
String toString() => "EdgeDims($top, $right, $bottom, $left)";
}
...@@ -13,7 +13,7 @@ import 'package:vector_math/vector_math_64.dart'; ...@@ -13,7 +13,7 @@ import 'package:vector_math/vector_math_64.dart';
import 'debug.dart'; import 'debug.dart';
import 'object.dart'; import 'object.dart';
export 'package:flutter/painting.dart' show FractionalOffset, TextBaseline; export 'package:flutter/painting.dart' show EdgeDims, FractionalOffset, TextBaseline;
// This class should only be used in debug builds // This class should only be used in debug builds
class _DebugSize extends Size { class _DebugSize extends Size {
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math;
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
...@@ -13,13 +12,13 @@ import 'box.dart'; ...@@ -13,13 +12,13 @@ import 'box.dart';
import 'debug.dart'; import 'debug.dart';
import 'object.dart'; import 'object.dart';
export 'package:flutter/src/painting/box_painter.dart';
export 'package:flutter/gestures.dart' show export 'package:flutter/gestures.dart' show
PointerEvent, PointerEvent,
PointerDownEvent, PointerDownEvent,
PointerMoveEvent, PointerMoveEvent,
PointerUpEvent, PointerUpEvent,
PointerCancelEvent; PointerCancelEvent;
export 'package:flutter/painting.dart' show Decoration, BoxDecoration;
/// A base class for render objects that resemble their children. /// A base class for render objects that resemble their children.
/// ///
...@@ -704,9 +703,11 @@ class RenderClipOval extends _RenderCustomClip<Rect> { ...@@ -704,9 +703,11 @@ class RenderClipOval extends _RenderCustomClip<Rect> {
bool hitTest(HitTestResult result, { Point position }) { bool hitTest(HitTestResult result, { Point position }) {
Rect clipBounds = _clip; Rect clipBounds = _clip;
Point center = clipBounds.center; Point center = clipBounds.center;
// convert the position to an offset from the center of the unit circle
Offset offset = new Offset((position.x - center.x) / clipBounds.width, Offset offset = new Offset((position.x - center.x) / clipBounds.width,
(position.y - center.y) / clipBounds.height); (position.y - center.y) / clipBounds.height);
if (offset.distance > 0.5) // check if the point is outside the unit circle
if (offset.distanceSquared > 0.25) // x^2 + y^2 > r^2
return false; return false;
return super.hitTest(result, position: position); return super.hitTest(result, position: position);
} }
...@@ -720,7 +721,7 @@ class RenderClipOval extends _RenderCustomClip<Rect> { ...@@ -720,7 +721,7 @@ class RenderClipOval extends _RenderCustomClip<Rect> {
} }
/// Where to paint a box decoration. /// Where to paint a box decoration.
enum BoxDecorationPosition { enum DecorationPosition {
/// Paint the box decoration behind the children. /// Paint the box decoration behind the children.
background, background,
...@@ -728,97 +729,90 @@ enum BoxDecorationPosition { ...@@ -728,97 +729,90 @@ enum BoxDecorationPosition {
foreground, foreground,
} }
/// Paints a [BoxDecoration] either before or after its child paints. /// Paints a [Decoration] either before or after its child paints.
class RenderDecoratedBox extends RenderProxyBox { class RenderDecoratedBox extends RenderProxyBox {
RenderDecoratedBox({ RenderDecoratedBox({
BoxDecoration decoration, Decoration decoration,
RenderBox child, DecorationPosition position: DecorationPosition.background,
BoxDecorationPosition position: BoxDecorationPosition.background RenderBox child
}) : _painter = new BoxPainter(decoration), }) : _decoration = decoration,
_position = position, _position = position,
super(child) { super(child) {
assert(decoration != null); assert(decoration != null);
assert(position != null); assert(position != null);
} }
/// Where to paint the box decoration. BoxPainter _painter;
BoxDecorationPosition get position => _position;
BoxDecorationPosition _position;
void set position (BoxDecorationPosition newPosition) {
assert(newPosition != null);
if (newPosition == _position)
return;
markNeedsPaint();
}
/// What decoration to paint. /// What decoration to paint.
BoxDecoration get decoration => _painter.decoration; Decoration get decoration => _decoration;
void set decoration (BoxDecoration newDecoration) { Decoration _decoration;
void set decoration (Decoration newDecoration) {
assert(newDecoration != null); assert(newDecoration != null);
if (newDecoration == _painter.decoration) if (newDecoration == _decoration)
return; return;
_removeBackgroundImageListenerIfNeeded(); _removeListenerIfNeeded();
_painter.decoration = newDecoration; _painter = null;
_addBackgroundImageListenerIfNeeded(); _decoration = newDecoration;
_addListenerIfNeeded();
markNeedsPaint(); markNeedsPaint();
} }
final BoxPainter _painter; /// Where to paint the box decoration.
DecorationPosition get position => _position;
DecorationPosition _position;
void set position (DecorationPosition newPosition) {
assert(newPosition != null);
if (newPosition == _position)
return;
_position = newPosition;
markNeedsPaint();
}
bool get _needsBackgroundImageListener { bool get _needsListeners {
return attached && return attached && _decoration.needsListeners;
_painter.decoration != null &&
_painter.decoration.backgroundImage != null;
} }
void _addBackgroundImageListenerIfNeeded() { void _addListenerIfNeeded() {
if (_needsBackgroundImageListener) if (_needsListeners)
_painter.decoration.backgroundImage.addChangeListener(markNeedsPaint); _decoration.addChangeListener(markNeedsPaint);
} }
void _removeBackgroundImageListenerIfNeeded() { void _removeListenerIfNeeded() {
if (_needsBackgroundImageListener) if (_needsListeners)
_painter.decoration.backgroundImage.removeChangeListener(markNeedsPaint); _decoration.removeChangeListener(markNeedsPaint);
} }
void attach() { void attach() {
super.attach(); super.attach();
_addBackgroundImageListenerIfNeeded(); _addListenerIfNeeded();
} }
void detach() { void detach() {
_removeBackgroundImageListenerIfNeeded(); _removeListenerIfNeeded();
super.detach(); super.detach();
} }
bool hitTestSelf(Point position) { bool hitTestSelf(Point position) {
switch (_painter.decoration.shape) { return _decoration.hitTest(size, position);
case Shape.rectangle:
// TODO(abarth): We should check the border radius.
return true;
case Shape.circle:
// Circles are inscribed into our smallest dimension.
Point center = size.center(Point.origin);
double distance = (position - center).distance;
return distance <= math.min(size.width, size.height) / 2.0;
}
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
assert(size.width != null); assert(size.width != null);
assert(size.height != null); assert(size.height != null);
if (position == BoxDecorationPosition.background) _painter ??= _decoration.createBoxPainter();
if (position == DecorationPosition.background)
_painter.paint(context.canvas, offset & size); _painter.paint(context.canvas, offset & size);
super.paint(context, offset); super.paint(context, offset);
if (position == BoxDecorationPosition.foreground) if (position == DecorationPosition.foreground)
_painter.paint(context.canvas, offset & size); _painter.paint(context.canvas, offset & size);
} }
void debugDescribeSettings(List<String> settings) { void debugDescribeSettings(List<String> settings) {
super.debugDescribeSettings(settings); super.debugDescribeSettings(settings);
settings.add('decoration:'); settings.add('decoration:');
settings.addAll(_painter.decoration.toString(" ").split('\n')); settings.addAll(_decoration.toString(" ").split('\n'));
} }
} }
......
...@@ -16,11 +16,17 @@ class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> { ...@@ -16,11 +16,17 @@ class AnimatedBoxConstraintsValue extends AnimatedValue<BoxConstraints> {
BoxConstraints lerp(double t) => BoxConstraints.lerp(begin, end, t); BoxConstraints lerp(double t) => BoxConstraints.lerp(begin, end, t);
} }
class AnimatedBoxDecorationValue extends AnimatedValue<BoxDecoration> { class AnimatedDecorationValue extends AnimatedValue<Decoration> {
AnimatedBoxDecorationValue(BoxDecoration begin, { BoxDecoration end, Curve curve, Curve reverseCurve }) AnimatedDecorationValue(Decoration begin, { Decoration end, Curve curve, Curve reverseCurve })
: super(begin, end: end, curve: curve, reverseCurve: reverseCurve); : super(begin, end: end, curve: curve, reverseCurve: reverseCurve);
BoxDecoration lerp(double t) => BoxDecoration.lerp(begin, end, t); Decoration lerp(double t) {
if (begin == null && end == null)
return null;
if (end == null)
return begin.lerpTo(end, t);
return end.lerpFrom(begin, t);
}
} }
class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> { class AnimatedEdgeDimsValue extends AnimatedValue<EdgeDims> {
...@@ -62,14 +68,14 @@ class AnimatedContainer extends StatefulComponent { ...@@ -62,14 +68,14 @@ class AnimatedContainer extends StatefulComponent {
assert(margin == null || margin.isNonNegative); assert(margin == null || margin.isNonNegative);
assert(padding == null || padding.isNonNegative); assert(padding == null || padding.isNonNegative);
assert(curve != null); assert(curve != null);
assert(duration != null); assert(duration != null || decoration.debugAssertValid());
} }
final Widget child; final Widget child;
final BoxConstraints constraints; final BoxConstraints constraints;
final BoxDecoration decoration; final Decoration decoration;
final BoxDecoration foregroundDecoration; final Decoration foregroundDecoration;
final EdgeDims margin; final EdgeDims margin;
final EdgeDims padding; final EdgeDims padding;
final Matrix4 transform; final Matrix4 transform;
...@@ -84,8 +90,8 @@ class AnimatedContainer extends StatefulComponent { ...@@ -84,8 +90,8 @@ class AnimatedContainer extends StatefulComponent {
class _AnimatedContainerState extends State<AnimatedContainer> { class _AnimatedContainerState extends State<AnimatedContainer> {
AnimatedBoxConstraintsValue _constraints; AnimatedBoxConstraintsValue _constraints;
AnimatedBoxDecorationValue _decoration; AnimatedDecorationValue _decoration;
AnimatedBoxDecorationValue _foregroundDecoration; AnimatedDecorationValue _foregroundDecoration;
AnimatedEdgeDimsValue _margin; AnimatedEdgeDimsValue _margin;
AnimatedEdgeDimsValue _padding; AnimatedEdgeDimsValue _padding;
AnimatedMatrix4Value _transform; AnimatedMatrix4Value _transform;
...@@ -167,7 +173,7 @@ class _AnimatedContainerState extends State<AnimatedContainer> { ...@@ -167,7 +173,7 @@ class _AnimatedContainerState extends State<AnimatedContainer> {
} }
if (config.decoration != null) { if (config.decoration != null) {
_decoration ??= new AnimatedBoxDecorationValue(config.decoration); _decoration ??= new AnimatedDecorationValue(config.decoration);
if (_configVariable(_decoration, config.decoration)) if (_configVariable(_decoration, config.decoration))
needsAnimation = true; needsAnimation = true;
} else { } else {
...@@ -175,7 +181,7 @@ class _AnimatedContainerState extends State<AnimatedContainer> { ...@@ -175,7 +181,7 @@ class _AnimatedContainerState extends State<AnimatedContainer> {
} }
if (config.foregroundDecoration != null) { if (config.foregroundDecoration != null) {
_foregroundDecoration ??= new AnimatedBoxDecorationValue(config.foregroundDecoration); _foregroundDecoration ??= new AnimatedDecorationValue(config.foregroundDecoration);
if (_configVariable(_foregroundDecoration, config.foregroundDecoration)) if (_configVariable(_foregroundDecoration, config.foregroundDecoration))
needsAnimation = true; needsAnimation = true;
} else { } else {
......
...@@ -16,13 +16,15 @@ export 'package:flutter/rendering.dart' show ...@@ -16,13 +16,15 @@ export 'package:flutter/rendering.dart' show
BorderSide, BorderSide,
BoxConstraints, BoxConstraints,
BoxDecoration, BoxDecoration,
BoxDecorationPosition,
BoxShadow, BoxShadow,
BoxShape,
Canvas, Canvas,
Color, Color,
ColorFilter, ColorFilter,
CustomClipper, CustomClipper,
CustomPainter, CustomPainter,
Decoration,
DecorationPosition,
EdgeDims, EdgeDims,
FlexAlignItems, FlexAlignItems,
FlexDirection, FlexDirection,
...@@ -51,7 +53,6 @@ export 'package:flutter/rendering.dart' show ...@@ -51,7 +53,6 @@ export 'package:flutter/rendering.dart' show
RadialGradient, RadialGradient,
Rect, Rect,
ScrollDirection, ScrollDirection,
Shape,
Size, Size,
StyledTextSpan, StyledTextSpan,
TextAlign, TextAlign,
...@@ -135,7 +136,7 @@ class DecoratedBox extends OneChildRenderObjectWidget { ...@@ -135,7 +136,7 @@ class DecoratedBox extends OneChildRenderObjectWidget {
DecoratedBox({ DecoratedBox({
Key key, Key key,
this.decoration, this.decoration,
this.position: BoxDecorationPosition.background, this.position: DecorationPosition.background,
Widget child Widget child
}) : super(key: key, child: child) { }) : super(key: key, child: child) {
assert(decoration != null); assert(decoration != null);
...@@ -143,10 +144,10 @@ class DecoratedBox extends OneChildRenderObjectWidget { ...@@ -143,10 +144,10 @@ class DecoratedBox extends OneChildRenderObjectWidget {
} }
/// What decoration to paint. /// What decoration to paint.
final BoxDecoration decoration; final Decoration decoration;
/// Where to paint the box decoration. /// Where to paint the box decoration.
final BoxDecorationPosition position; final DecorationPosition position;
RenderDecoratedBox createRenderObject() => new RenderDecoratedBox(decoration: decoration, position: position); RenderDecoratedBox createRenderObject() => new RenderDecoratedBox(decoration: decoration, position: position);
...@@ -782,26 +783,26 @@ class Container extends StatelessComponent { ...@@ -782,26 +783,26 @@ class Container extends StatelessComponent {
}) : super(key: key) { }) : super(key: key) {
assert(margin == null || margin.isNonNegative); assert(margin == null || margin.isNonNegative);
assert(padding == null || padding.isNonNegative); assert(padding == null || padding.isNonNegative);
assert(decoration == null || decoration.shape != Shape.circle || decoration.borderRadius == null); // can't have a border radius if you're a circle assert(decoration == null || decoration.debugAssertValid());
} }
final Widget child; final Widget child;
final BoxConstraints constraints; final BoxConstraints constraints;
final BoxDecoration decoration; final Decoration decoration;
final BoxDecoration foregroundDecoration; final Decoration foregroundDecoration;
final EdgeDims margin; final EdgeDims margin;
final EdgeDims padding; final EdgeDims padding;
final Matrix4 transform; final Matrix4 transform;
final double width; final double width;
final double height; final double height;
EdgeDims get _paddingIncludingBorder { EdgeDims get _paddingIncludingDecoration {
if (decoration == null || decoration.border == null) if (decoration == null || decoration.padding == null)
return padding; return padding;
EdgeDims borderPadding = decoration.border.dimensions; EdgeDims decorationPadding = decoration.padding;
if (padding == null) if (padding == null)
return borderPadding; return decorationPadding;
return padding + borderPadding; return padding + decorationPadding;
} }
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -810,7 +811,7 @@ class Container extends StatelessComponent { ...@@ -810,7 +811,7 @@ class Container extends StatelessComponent {
if (child == null && (width == null || height == null)) if (child == null && (width == null || height == null))
current = new ConstrainedBox(constraints: const BoxConstraints.expand()); current = new ConstrainedBox(constraints: const BoxConstraints.expand());
EdgeDims effectivePadding = _paddingIncludingBorder; EdgeDims effectivePadding = _paddingIncludingDecoration;
if (effectivePadding != null) if (effectivePadding != null)
current = new Padding(padding: effectivePadding, child: current); current = new Padding(padding: effectivePadding, child: current);
...@@ -820,7 +821,7 @@ class Container extends StatelessComponent { ...@@ -820,7 +821,7 @@ class Container extends StatelessComponent {
if (foregroundDecoration != null) { if (foregroundDecoration != null) {
current = new DecoratedBox( current = new DecoratedBox(
decoration: foregroundDecoration, decoration: foregroundDecoration,
position: BoxDecorationPosition.foreground, position: DecorationPosition.foreground,
child: current child: current
); );
} }
......
...@@ -21,6 +21,8 @@ void main() { ...@@ -21,6 +21,8 @@ void main() {
backgroundColor: new Color(0xFF0000FF) backgroundColor: new Color(0xFF0000FF)
); );
BoxDecoration actualDecoration;
tester.pumpWidget( tester.pumpWidget(
new AnimatedContainer( new AnimatedContainer(
key: key, key: key,
...@@ -30,7 +32,8 @@ void main() { ...@@ -30,7 +32,8 @@ void main() {
); );
RenderDecoratedBox box = key.currentState.context.findRenderObject(); RenderDecoratedBox box = key.currentState.context.findRenderObject();
expect(box.decoration.backgroundColor, equals(decorationA.backgroundColor)); actualDecoration = box.decoration;
expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor));
tester.pumpWidget( tester.pumpWidget(
new AnimatedContainer( new AnimatedContainer(
...@@ -41,11 +44,13 @@ void main() { ...@@ -41,11 +44,13 @@ void main() {
); );
expect(key.currentState.context.findRenderObject(), equals(box)); expect(key.currentState.context.findRenderObject(), equals(box));
expect(box.decoration.backgroundColor, equals(decorationA.backgroundColor)); actualDecoration = box.decoration;
expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor));
tester.pump(const Duration(seconds: 1)); tester.pump(const Duration(seconds: 1));
expect(box.decoration.backgroundColor, equals(decorationB.backgroundColor)); actualDecoration = box.decoration;
expect(actualDecoration.backgroundColor, equals(decorationB.backgroundColor));
}); });
}); });
......
...@@ -14,7 +14,7 @@ void main() { ...@@ -14,7 +14,7 @@ void main() {
new Container( new Container(
padding: new EdgeDims.all(50.0), padding: new EdgeDims.all(50.0),
decoration: new BoxDecoration( decoration: new BoxDecoration(
shape: Shape.circle, shape: BoxShape.circle,
border: new Border.all(width: 10.0, color: const Color(0x80FF00FF)), border: new Border.all(width: 10.0, color: const Color(0x80FF00FF)),
backgroundColor: Colors.teal[600] backgroundColor: Colors.teal[600]
) )
......
...@@ -27,7 +27,7 @@ void main() { ...@@ -27,7 +27,7 @@ void main() {
expect(element.renderObject is RenderDecoratedBox, isTrue); expect(element.renderObject is RenderDecoratedBox, isTrue);
RenderDecoratedBox renderObject = element.renderObject; RenderDecoratedBox renderObject = element.renderObject;
expect(renderObject.decoration, equals(kBoxDecorationA)); expect(renderObject.decoration, equals(kBoxDecorationA));
expect(renderObject.position, equals(BoxDecorationPosition.background)); expect(renderObject.position, equals(DecorationPosition.background));
tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationB)); tester.pumpWidget(new DecoratedBox(decoration: kBoxDecorationB));
element = tester.findElement((Element element) => element is OneChildRenderObjectElement); element = tester.findElement((Element element) => element is OneChildRenderObjectElement);
...@@ -35,7 +35,7 @@ void main() { ...@@ -35,7 +35,7 @@ void main() {
expect(element.renderObject is RenderDecoratedBox, isTrue); expect(element.renderObject is RenderDecoratedBox, isTrue);
renderObject = element.renderObject; renderObject = element.renderObject;
expect(renderObject.decoration, equals(kBoxDecorationB)); expect(renderObject.decoration, equals(kBoxDecorationB));
expect(renderObject.position, equals(BoxDecorationPosition.background)); expect(renderObject.position, equals(DecorationPosition.background));
}); });
}); });
...@@ -49,12 +49,12 @@ void main() { ...@@ -49,12 +49,12 @@ void main() {
expect(element.renderObject is RenderDecoratedBox, isTrue); expect(element.renderObject is RenderDecoratedBox, isTrue);
RenderDecoratedBox renderObject = element.renderObject; RenderDecoratedBox renderObject = element.renderObject;
expect(renderObject.decoration, equals(kBoxDecorationA)); expect(renderObject.decoration, equals(kBoxDecorationA));
expect(renderObject.position, equals(BoxDecorationPosition.background)); expect(renderObject.position, equals(DecorationPosition.background));
expect(renderObject.child, isNotNull); expect(renderObject.child, isNotNull);
expect(renderObject.child is RenderDecoratedBox, isTrue); expect(renderObject.child is RenderDecoratedBox, isTrue);
RenderDecoratedBox child = renderObject.child; RenderDecoratedBox child = renderObject.child;
expect(child.decoration, equals(kBoxDecorationB)); expect(child.decoration, equals(kBoxDecorationB));
expect(child.position, equals(BoxDecorationPosition.background)); expect(child.position, equals(DecorationPosition.background));
expect(child.child, isNull); expect(child.child, isNull);
} }
...@@ -65,7 +65,7 @@ void main() { ...@@ -65,7 +65,7 @@ void main() {
expect(element.renderObject is RenderDecoratedBox, isTrue); expect(element.renderObject is RenderDecoratedBox, isTrue);
RenderDecoratedBox renderObject = element.renderObject; RenderDecoratedBox renderObject = element.renderObject;
expect(renderObject.decoration, equals(kBoxDecorationA)); expect(renderObject.decoration, equals(kBoxDecorationA));
expect(renderObject.position, equals(BoxDecorationPosition.background)); expect(renderObject.position, equals(DecorationPosition.background));
expect(renderObject.child, isNull); expect(renderObject.child, isNull);
} }
......
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