From 50eac9559adebaae259047536a4eb855542cc1cb Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Tue, 21 Jul 2015 13:46:10 -0700 Subject: [PATCH] Separate width and height parameters for Image widgets This change makes it easier to defined only the width or the height of an image and let the other value be filled in from the image's intrinsic aspect ratio. Fixes #175 --- .../example/rendering/interactive_flex.dart | 8 +-- sky/sdk/example/widgets/container.dart | 3 +- sky/sdk/lib/rendering/box.dart | 58 +++++++++++-------- sky/sdk/lib/widgets/basic.dart | 44 +++++++++----- sky/sdk/lib/widgets/icon.dart | 3 +- 5 files changed, 69 insertions(+), 47 deletions(-) diff --git a/sky/sdk/example/rendering/interactive_flex.dart b/sky/sdk/example/rendering/interactive_flex.dart index 24f6f605a..940aacfc7 100644 --- a/sky/sdk/example/rendering/interactive_flex.dart +++ b/sky/sdk/example/rendering/interactive_flex.dart @@ -25,15 +25,15 @@ class Touch { class RenderImageGrow extends RenderImage { final Size _startingSize; - RenderImageGrow(Image image, Size size) : _startingSize = size, super(image, size); + RenderImageGrow(Image image, Size size) + : _startingSize = size, super(image: image, width: size.width, height: size.height); double _growth = 0.0; double get growth => _growth; void set growth(double value) { _growth = value; - double newWidth = _startingSize.width == null ? null : _startingSize.width + growth; - double newHeight = _startingSize.height == null ? null : _startingSize.height + growth; - requestedSize = new Size(newWidth, newHeight); + width = _startingSize.width == null ? null : _startingSize.width + growth; + height = _startingSize.height == null ? null : _startingSize.height + growth; } } diff --git a/sky/sdk/example/widgets/container.dart b/sky/sdk/example/widgets/container.dart index 9ebea3aa6..836d731fa 100644 --- a/sky/sdk/example/widgets/container.dart +++ b/sky/sdk/example/widgets/container.dart @@ -16,7 +16,8 @@ class ContainerApp extends App { decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)), child: new NetworkImage( src: "https://www.dartlang.org/logos/dart-logo.png", - size: new Size(300.0, 300.0) + width: 300.0, + height: 300.0 ) ), new Container( diff --git a/sky/sdk/lib/rendering/box.dart b/sky/sdk/lib/rendering/box.dart index 5f6142a55..eafd40d1e 100644 --- a/sky/sdk/lib/rendering/box.dart +++ b/sky/sdk/lib/rendering/box.dart @@ -1249,9 +1249,10 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin _requestedSize; - void set requestedSize (Size value) { - if (value == null) - value = const Size(null, null); - if (value == _requestedSize) + double _width; + double get width => _width; + void set width (double value) { + if (value == _width) return; - _requestedSize = value; + _width = value; + markNeedsLayout(); + } + + double _height; + double get height => _height; + void set height (double value) { + if (value == _height) + return; + _height = value; markNeedsLayout(); } @@ -1299,8 +1307,8 @@ class RenderImage extends RenderBox { Size _sizeForConstraints(BoxConstraints constraints) { // If there's no image, we can't size ourselves automatically if (_image == null) { - double width = requestedSize.width == null ? 0.0 : requestedSize.width; - double height = requestedSize.height == null ? 0.0 : requestedSize.height; + double width = _width == null ? 0.0 : _width; + double height = _height == null ? 0.0 : _height; return constraints.constrain(new Size(width, height)); } @@ -1310,8 +1318,8 @@ class RenderImage extends RenderBox { // other dimension to maintain the aspect ratio. In both cases, // constrain dimensions first, otherwise we end up losing the // ratio after constraining. - if (requestedSize.width == null) { - if (requestedSize.height == null) { + if (_width == null) { + if (_height == null) { // autosize double width = constraints.constrainWidth(_image.width.toDouble()); double maxHeight = constraints.constrainHeight(_image.height.toDouble()); @@ -1323,21 +1331,21 @@ class RenderImage extends RenderBox { } return constraints.constrain(new Size(width, height)); } - // determine width from height - double width = requestedSize.height * _image.width / _image.height; - return constraints.constrain(new Size(width, requestedSize.height)); + // Determine width from height + double width = _height * _image.width / _image.height; + return constraints.constrain(new Size(width, height)); } - if (requestedSize.height == null) { - // determine height from width - double height = requestedSize.width * _image.height / _image.width; - return constraints.constrain(new Size(requestedSize.width, height)); + if (_height == null) { + // Determine height from width + double height = _width * _image.height / _image.width; + return constraints.constrain(new Size(width, height)); } } - return constraints.constrain(requestedSize); + return constraints.constrain(new Size(width, height)); } double getMinIntrinsicWidth(BoxConstraints constraints) { - if (requestedSize.width == null && requestedSize.height == null) + if (_width == null && _height == null) return constraints.constrainWidth(0.0); return _sizeForConstraints(constraints).width; } @@ -1347,7 +1355,7 @@ class RenderImage extends RenderBox { } double getMinIntrinsicHeight(BoxConstraints constraints) { - if (requestedSize.width == null && requestedSize.height == null) + if (_width == null && _height == null) return constraints.constrainHeight(0.0); return _sizeForConstraints(constraints).height; } @@ -1377,7 +1385,7 @@ class RenderImage extends RenderBox { canvas.restore(); } - String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}dimensions: ${requestedSize}\n'; + String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}width: ${width}\n${prefix}height: ${height}\n'; } class RenderDecoratedBox extends RenderProxyBox { diff --git a/sky/sdk/lib/widgets/basic.dart b/sky/sdk/lib/widgets/basic.dart index 29521687e..8e3e8f786 100644 --- a/sky/sdk/lib/widgets/basic.dart +++ b/sky/sdk/lib/widgets/basic.dart @@ -488,31 +488,34 @@ class Text extends Component { } class Image extends LeafRenderObjectWrapper { - Image({ sky.Image image, this.size, this.colorFilter }) + Image({ sky.Image image, this.width, this.height, this.colorFilter }) : image = image, super(key: image.hashCode.toString()); // TODO(ianh): Find a way to uniquely identify the sky.Image rather than using hashCode, which could collide final sky.Image image; - final Size size; + final double width; + final double height; final sky.ColorFilter colorFilter; - RenderImage createNode() => new RenderImage(image, size, colorFilter: colorFilter); + RenderImage createNode() => new RenderImage(image: image, width: width, height: height, colorFilter: colorFilter); RenderImage get root => super.root; void syncRenderObject(Widget old) { super.syncRenderObject(old); root.image = image; - root.requestedSize = size; + root.width = width; + root.height = height; root.colorFilter = colorFilter; } } class FutureImage extends StatefulComponent { - FutureImage({ String key, this.image, this.size, this.colorFilter }) + FutureImage({ String key, this.image, this.width, this.height, this.colorFilter }) : super(key: key); Future image; - Size size; + double width; + double height; sky.ColorFilter colorFilter; sky.Image _resolvedImage; @@ -535,48 +538,57 @@ class FutureImage extends StatefulComponent { void syncFields(FutureImage source) { bool needToResolveImage = (image != source.image); image = source.image; - size = source.size; + width = source.width; + height = source.height; if (needToResolveImage) _resolveImage(); } Widget build() { - return new Image(image: _resolvedImage, size: size, colorFilter: colorFilter); + return new Image( + image: _resolvedImage, + width: width, + height: height, + colorFilter: colorFilter + ); } } class NetworkImage extends Component { - NetworkImage({ String src, this.size, this.colorFilter }) - : src = src, - super(key: src); + NetworkImage({ String src, this.width, this.height, this.colorFilter }) + : src = src, super(key: src); final String src; - final Size size; + final double width; + final double height; final sky.ColorFilter colorFilter; Widget build() { return new FutureImage( image: image_cache.load(src), - size: size, + width: width, + height: height, colorFilter: colorFilter ); } } class AssetImage extends Component { - AssetImage({ String name, this.bundle, this.size, this.colorFilter }) + AssetImage({ String name, this.bundle, this.width, this.height, this.colorFilter }) : name = name, super(key: name); final String name; final AssetBundle bundle; - final Size size; + final double width; + final double height; final sky.ColorFilter colorFilter; Widget build() { return new FutureImage( image: bundle.loadImage(name), - size: size, + width: width, + height: height, colorFilter: colorFilter ); } diff --git a/sky/sdk/lib/widgets/icon.dart b/sky/sdk/lib/widgets/icon.dart index 7229d9e17..c460228c8 100644 --- a/sky/sdk/lib/widgets/icon.dart +++ b/sky/sdk/lib/widgets/icon.dart @@ -93,7 +93,8 @@ class Icon extends Component { return new AssetImage( bundle: _iconBundle, name: '${category}/${density}/ic_${subtype}_${colorSuffix}_${size}dp.png', - size: new Size(size.toDouble(), size.toDouble()), + width: size.toDouble(), + height: size.toDouble(), colorFilter: colorFilter ); } -- GitLab