提交 e16e10d8 编写于 作者: C Collin Jackson

Implement RenderImage and Image for Sky

This also fixes a bug that was preventing markNeedsLayout from working

R=abarth@chromium.org, eseidel@chromium.org, abarth, eseidel

Review URL: https://codereview.chromium.org/1160013004
上级 ef070b2c
...@@ -5,6 +5,17 @@ ...@@ -5,6 +5,17 @@
import 'dart:sky' as sky; import 'dart:sky' as sky;
import 'package:sky/framework/fn2.dart'; import 'package:sky/framework/fn2.dart';
import 'package:sky/framework/rendering/box.dart'; import 'package:sky/framework/rendering/box.dart';
import '../lib/solid_color_box.dart';
class Rectangle extends RenderNodeWrapper {
RenderSolidColorBox root;
RenderSolidColorBox createNode() =>
new RenderSolidColorBox(color, desiredSize: new sky.Size(40.0, 130.0));
final int color;
Rectangle(this.color, { Object key }) : super(key: key);
}
class ContainerApp extends App { class ContainerApp extends App {
UINode build() { UINode build() {
...@@ -20,7 +31,11 @@ class ContainerApp extends App { ...@@ -20,7 +31,11 @@ class ContainerApp extends App {
new Container( new Container(
decoration: new BoxDecoration(backgroundColor: const sky.Color(0xFFFFFF00)), decoration: new BoxDecoration(backgroundColor: const sky.Color(0xFFFFFF00)),
desiredSize: new sky.Size(double.INFINITY, 20.0) desiredSize: new sky.Size(double.INFINITY, 20.0)
) ),
new Image(src: "https://www.dartlang.org/logos/dart-logo.png",
size: new sky.Size(300.0, 300.0),
key: 1
),
])), ])),
]), ]),
onPointerDown: _handlePointerDown); onPointerDown: _handlePointerDown);
......
// 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:sky';
import 'package:sky/framework/rendering/box.dart';
class RenderSolidColorBox extends RenderDecoratedBox {
final Size desiredSize;
final Color backgroundColor;
RenderSolidColorBox(Color backgroundColor, { this.desiredSize: const Size.infinite() })
: backgroundColor = backgroundColor,
super(decoration: new BoxDecoration(backgroundColor: backgroundColor));
Size getIntrinsicDimensions(BoxConstraints constraints) {
return constraints.constrain(desiredSize);
}
void performLayout() {
size = constraints.constrain(desiredSize);
}
void handlePointer(PointerEvent event) {
if (event.type == 'pointerdown')
decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000));
else if (event.type == 'pointerup')
decoration = new BoxDecoration(backgroundColor: backgroundColor);
}
}
\ No newline at end of file
// 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:sky';
import 'dart:math' as math;
import 'package:sky/framework/net/image_cache.dart' as image_cache;
import 'package:sky/framework/app.dart';
import 'package:sky/framework/rendering/box.dart';
import 'package:sky/framework/rendering/block.dart';
import 'package:sky/framework/rendering/flex.dart';
import 'package:sky/framework/rendering/node.dart';
import 'package:sky/framework/rendering/paragraph.dart';
import '../lib/solid_color_box.dart';
class Touch {
final double x;
final double y;
const Touch(this.x, this.y);
}
class RenderImageGrow extends RenderImage {
final Size _startingSize;
RenderImageGrow(String src, Size size) : _startingSize = size, super(src, size);
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);
}
}
AppView app;
RenderImageGrow image;
Map<int, Touch> touches = new Map();
void handleEvent(event) {
if (event is PointerEvent) {
if (event.type == 'pointermove')
image.growth = math.max(0.0, image.growth + event.x - touches[event.pointer].x);
touches[event.pointer] = new Touch(event.x, event.y);
}
}
void main() {
void addFlexChildSolidColor(RenderFlex parent, Color backgroundColor, { int flex: 0 }) {
RenderSolidColorBox child = new RenderSolidColorBox(backgroundColor);
parent.add(child);
child.parentData.flex = flex;
}
var row = new RenderFlex(direction: FlexDirection.Horizontal);
// Left cell
addFlexChildSolidColor(row, const Color(0xFF00D2B8), flex: 1);
// Resizeable image
image = new RenderImageGrow("https://www.dartlang.org/logos/dart-logo.png",
new Size(100.0, null));
var padding = new RenderPadding(padding: const EdgeDims.all(10.0), child: image);
row.add(padding);
RenderFlex column = new RenderFlex(direction: FlexDirection.Vertical);
// Top cell
addFlexChildSolidColor(column, const Color(0xFF55DDCA), flex: 1);
// The internet is a beautiful place. https://baconipsum.com/
String meatyString = """Bacon ipsum dolor amet ham fatback tri-tip, prosciutto
porchetta bacon kevin meatball meatloaf pig beef ribs chicken. Brisket ribeye
andouille leberkas capicola meatloaf. Chicken pig ball tip pork picanha bresaola
alcatra. Pork pork belly alcatra, flank chuck drumstick biltong doner jowl.
Pancetta meatball tongue tenderloin rump tail jowl boudin.""";
RenderParagraph paragraph = new RenderParagraph(text: meatyString, color: const Color(0xFF009900));
padding = new RenderPadding(padding: const EdgeDims.all(10.0), child: paragraph);
column.add(padding);
// Bottom cell
addFlexChildSolidColor(column, const Color(0xFF0081C6), flex: 2);
row.add(column);
column.parentData.flex = 8;
RenderDecoratedBox root = new RenderDecoratedBox(
decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFFFF)),
child: row
);
app = new AppView(root);
view.setEventCallback(handleEvent);
}
...@@ -8,30 +8,7 @@ import 'package:sky/framework/rendering/box.dart'; ...@@ -8,30 +8,7 @@ import 'package:sky/framework/rendering/box.dart';
import 'package:sky/framework/rendering/node.dart'; import 'package:sky/framework/rendering/node.dart';
import 'package:sky/framework/rendering/flex.dart'; import 'package:sky/framework/rendering/flex.dart';
import 'package:sky/framework/rendering/paragraph.dart'; import 'package:sky/framework/rendering/paragraph.dart';
import '../lib/solid_color_box.dart';
class RenderSolidColor extends RenderDecoratedBox {
final Size desiredSize;
final Color backgroundColor;
RenderSolidColor(Color backgroundColor, { this.desiredSize: const Size.infinite() })
: backgroundColor = backgroundColor,
super(decoration: new BoxDecoration(backgroundColor: backgroundColor));
Size getIntrinsicDimensions(BoxConstraints constraints) {
return constraints.constrain(desiredSize);
}
void performLayout() {
size = constraints.constrain(desiredSize);
}
void handlePointer(PointerEvent event) {
if (event.type == 'pointerdown')
decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000));
else if (event.type == 'pointerup')
decoration = new BoxDecoration(backgroundColor: backgroundColor);
}
}
AppView app; AppView app;
...@@ -43,7 +20,7 @@ void main() { ...@@ -43,7 +20,7 @@ void main() {
child: flexRoot child: flexRoot
); );
RenderNode child = new RenderSolidColor(const Color(0xFFFFFF00)); RenderNode child = new RenderSolidColorBox(const Color(0xFFFFFF00));
flexRoot.add(child); flexRoot.add(child);
child.parentData.flex = 2; child.parentData.flex = 2;
......
...@@ -638,23 +638,22 @@ class FlexExpandingChild extends ParentDataNode { ...@@ -638,23 +638,22 @@ class FlexExpandingChild extends ParentDataNode {
} }
class Image extends RenderNodeWrapper { class Image extends RenderNodeWrapper {
RenderCSSImage root; RenderImage root;
RenderCSSImage createNode() => new RenderCSSImage(this, this.src, this.width, this.height); RenderImage createNode() => new RenderImage(this.src, this.size);
final String src; final String src;
final int width; final sky.Size size;
final int height;
Image({ Image({
Object key, Object key,
this.width, this.src,
this.height, this.size
this.src
}) : super(key: key); }) : super(key: key);
void syncRenderNode(UINode old) { void syncRenderNode(UINode old) {
super.syncRenderNode(old); super.syncRenderNode(old);
root.configure(this.src, this.width, this.height); root.src = src;
root.requestedSize = size;
} }
} }
......
...@@ -7,6 +7,7 @@ import 'dart:sky' as sky; ...@@ -7,6 +7,7 @@ import 'dart:sky' as sky;
import 'dart:typed_data'; import 'dart:typed_data';
import 'node.dart'; import 'node.dart';
import 'package:vector_math/vector_math.dart'; import 'package:vector_math/vector_math.dart';
import 'package:sky/framework/net/image_cache.dart' as image_cache;
// GENERIC BOX RENDERING // GENERIC BOX RENDERING
// Anything that has a concept of x, y, width, height is going to derive from this // Anything that has a concept of x, y, width, height is going to derive from this
...@@ -255,6 +256,80 @@ class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> { ...@@ -255,6 +256,80 @@ class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> {
} }
class RenderImage extends RenderBox {
RenderImage(String url, sky.Size dimensions) {
requestedSize = dimensions;
src = url;
}
sky.Image _image;
String _src;
String get src => _src;
void set src (String value) {
if (value == _src)
return;
_src = value;
image_cache.load(_src, (result) {
_image = result;
if (requestedSize.width == null || requestedSize.height == null)
markNeedsLayout();
markNeedsPaint();
});
}
sky.Size _requestedSize;
sky.Size get requestedSize => _requestedSize;
void set requestedSize (sky.Size value) {
if (value == _requestedSize)
return;
_requestedSize = value;
markNeedsLayout();
}
void performLayout() {
// 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;
size = constraints.constrain(new sky.Size(width, height));
return;
}
// If neither height nor width are specified, use inherent image dimensions
// If only one dimension is specified, adjust the other dimension to
// maintain the aspect ratio
if (requestedSize.width == null) {
if (requestedSize.height == null) {
size = constraints.constrain(new sky.Size(_image.width, _image.height));
} else {
double width = requestedSize.height * _image.width / _image.height;
size = constraints.constrain(new sky.Size(width, requestedSize.height));
}
} else if (requestedSize.height == null) {
double height = requestedSize.width * _image.height / _image.width;
size = constraints.constrain(new sky.Size(requestedSize.width, height));
} else {
size = constraints.constrain(requestedSize);
}
}
void paint(RenderNodeDisplayList canvas) {
if (_image == null) return;
bool needsScale = size.width != _image.width || size.height != _image.height;
if (needsScale) {
double widthScale = size.width / _image.width;
double heightScale = size.height / _image.height;
canvas.save();
canvas.scale(widthScale, heightScale);
}
sky.Paint paint = new sky.Paint();
canvas.drawImage(_image, 0.0, 0.0, paint);
if (needsScale)
canvas.restore();
}
}
// This must be immutable, because we won't notice when it changes // This must be immutable, because we won't notice when it changes
class BoxDecoration { class BoxDecoration {
const BoxDecoration({this.backgroundColor}); const BoxDecoration({this.backgroundColor});
......
...@@ -229,6 +229,14 @@ abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> { ...@@ -229,6 +229,14 @@ abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> {
adoptChild(_child); adoptChild(_child);
markNeedsLayout(); markNeedsLayout();
} }
void attachChildren() {
if (_child != null)
_child.attach();
}
void detachChildren() {
if (_child != null)
_child.detach();
}
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册