From 6cf4451a2ca24128fb0f069ae159e69e10189156 Mon Sep 17 00:00:00 2001 From: Hixie Date: Thu, 11 Jun 2015 13:08:00 -0700 Subject: [PATCH] Add an example of an app that manipulates both a RenderObject tree and has some fn logic in it. Also: - Make RenderProxyBox non-abstract - Upgrade the old container.dart example - Minor fixes to ui_mode.dart to make this work R=abarth@chromium.org Review URL: https://codereview.chromium.org/1183503003. --- examples/stocks2/lib/stock_app.dart | 3 +- examples/widgets/container.dart | 59 ++++++++--------- examples/widgets/spinning_mixed.dart | 91 ++++++++++++++++++++++++++ sdk/lib/framework/rendering/box.dart | 6 +- sdk/lib/framework/widgets/ui_node.dart | 5 +- 5 files changed, 125 insertions(+), 39 deletions(-) create mode 100644 examples/widgets/spinning_mixed.dart diff --git a/examples/stocks2/lib/stock_app.dart b/examples/stocks2/lib/stock_app.dart index 4e29072c872..66e4eb25a83 100644 --- a/examples/stocks2/lib/stock_app.dart +++ b/examples/stocks2/lib/stock_app.dart @@ -16,6 +16,7 @@ import 'package:sky/framework/widgets/popup_menu.dart'; import 'package:sky/framework/widgets/radio.dart'; import 'package:sky/framework/widgets/scaffold.dart'; import 'package:sky/framework/widgets/tool_bar.dart'; +import 'package:sky/framework/widgets/ui_node.dart'; import 'package:sky/framework/widgets/wrappers.dart'; import 'stock_data.dart'; @@ -213,7 +214,7 @@ class StocksApp extends App { void main() { print("starting stocks app!"); App app = new StocksApp(); - app.appView.onFrame = () { + UINodeAppView.appView.onFrame = () { // uncomment this for debugging: // app.appView.debugDumpRenderTree(); }; diff --git a/examples/widgets/container.dart b/examples/widgets/container.dart index 437784078ad..14b5663d13f 100644 --- a/examples/widgets/container.dart +++ b/examples/widgets/container.dart @@ -5,51 +5,44 @@ import 'dart:sky' as sky; import 'package:sky/framework/rendering/box.dart'; +import 'package:sky/framework/rendering/flex.dart'; import 'package:sky/framework/widgets/ui_node.dart'; import 'package:sky/framework/widgets/wrappers.dart'; -import '../lib/solid_color_box.dart'; - -class Rectangle extends RenderObjectWrapper { - RenderSolidColorBox root; - RenderSolidColorBox createNode() => - new RenderSolidColorBox(color, desiredSize: new sky.Size(40.0, 130.0)); - - final int color; +class Rectangle extends Component { Rectangle(this.color, { Object key }) : super(key: key); + + final Color color; + + UINode build() { + return new FlexExpandingChild( + new Container( + decoration: new BoxDecoration(backgroundColor: color) + ) + ); + } + } class ContainerApp extends App { UINode build() { - return new EventListenerNode( - new Block([ + return new Flex([ + new Rectangle(const Color(0xFF00FFFF), key: 'a'), new Container( padding: new EdgeDims.all(10.0), margin: new EdgeDims.all(10.0), - height: 100.0, - decoration: new BoxDecoration(backgroundColor: const sky.Color(0xFF00FF00)), - child: new Block([ - new Container( - decoration: new BoxDecoration(backgroundColor: const sky.Color(0xFFFFFF00)), - height: 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, - onGestureTap: _handleGestureTap); - } - - void _handlePointerDown(sky.PointerEvent event) { - print("_handlePointerDown"); - } - - void _handleGestureTap(sky.GestureEvent event) { - print("_handleGestureTap"); + decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)), + child: new Image(src: "https://www.dartlang.org/logos/dart-logo.png", + size: new Size(300.0, 300.0), + key: 1 + ) + ), + new Rectangle(const Color(0xFFFFFF00), key: 'b'), + ], + direction: FlexDirection.vertical, + justifyContent: FlexJustifyContent.spaceBetween + ); } } diff --git a/examples/widgets/spinning_mixed.dart b/examples/widgets/spinning_mixed.dart new file mode 100644 index 00000000000..407fbde30e9 --- /dev/null +++ b/examples/widgets/spinning_mixed.dart @@ -0,0 +1,91 @@ +// 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' as sky; + +import 'package:sky/framework/rendering/box.dart'; +import 'package:sky/framework/rendering/flex.dart'; +import 'package:sky/framework/scheduler.dart'; +import 'package:sky/framework/widgets/ui_node.dart'; +import 'package:sky/framework/widgets/wrappers.dart'; +import 'package:vector_math/vector_math.dart'; + +import '../lib/solid_color_box.dart'; + +// Solid colour, RenderObject version +void addFlexChildSolidColor(RenderFlex parent, sky.Color backgroundColor, { int flex: 0 }) { + RenderSolidColorBox child = new RenderSolidColorBox(backgroundColor); + parent.add(child); + child.parentData.flex = flex; +} + +// Solid colour, Widget version +class Rectangle extends Component { + Rectangle(this.color, { Object key }) : super(key: key); + final Color color; + UINode build() { + return new FlexExpandingChild( + new Container( + decoration: new BoxDecoration(backgroundColor: color) + ) + ); + } +} + +UINode builder() { + return new Flex([ + new Rectangle(const Color(0xFF00FFFF), key: 'a'), + new Container( + padding: new EdgeDims.all(10.0), + margin: new EdgeDims.all(10.0), + decoration: new BoxDecoration(backgroundColor: const Color(0xFFCCCCCC)), + child: new Image(src: "https://www.dartlang.org/logos/dart-logo.png", + size: new Size(300.0, 300.0), + key: 1 + ) + ), + new Rectangle(const Color(0xFFFFFF00), key: 'b'), + ], + direction: FlexDirection.vertical, + justifyContent: FlexJustifyContent.spaceBetween + ); +} + +double timeBase; +RenderTransform transformBox; + +void rotate(double timeStamp) { + if (timeBase == null) + timeBase = timeStamp; + double delta = (timeStamp - timeBase) / 1000; // radians + + transformBox.setIdentity(); + transformBox.translate(transformBox.size.width / 2.0, transformBox.size.height / 2.0); + transformBox.rotateZ(delta); + transformBox.translate(-transformBox.size.width / 2.0, -transformBox.size.height / 2.0); +} + +void main() { + RenderFlex flexRoot = new RenderFlex(direction: FlexDirection.vertical); + + RenderProxyBox proxy = new RenderProxyBox(); + new RenderObjectToUINodeAdapter(proxy, builder); // adds itself to proxy + + addFlexChildSolidColor(flexRoot, const sky.Color(0xFFFF00FF), flex: 1); + flexRoot.add(proxy); + addFlexChildSolidColor(flexRoot, const sky.Color(0xFF0000FF), flex: 1); + + transformBox = new RenderTransform(child: flexRoot, transform: new Matrix4.identity()); + RenderPadding root = new RenderPadding(padding: new EdgeDims.all(20.0), child: transformBox); + + // Because we're going to use UINodes, we want to initialise its + // AppView, not use the default one. We don't really need to do + // this, because RenderObjectToUINodeAdapter does it for us, but + // it's good practice in case we happen to not have a + // RenderObjectToUINodeAdapter in our tree at startup. + UINodeAppView.initUINodeAppView(); + UINodeAppView.appView.root = root; + + addPersistentFrameCallback(rotate); +} diff --git a/sdk/lib/framework/rendering/box.dart b/sdk/lib/framework/rendering/box.dart index f6bf0da0977..993916962b2 100644 --- a/sdk/lib/framework/rendering/box.dart +++ b/sdk/lib/framework/rendering/box.dart @@ -248,8 +248,9 @@ abstract class RenderBox extends RenderObject { String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}size: ${size}\n'; } -abstract class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin { - RenderProxyBox(RenderBox child) { +class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin { + + RenderProxyBox([RenderBox child = null]) { this.child = child; } @@ -297,6 +298,7 @@ abstract class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin< if (child != null) child.paint(canvas); } + } class RenderSizedBox extends RenderProxyBox { diff --git a/sdk/lib/framework/widgets/ui_node.dart b/sdk/lib/framework/widgets/ui_node.dart index 2d1cd2497b7..d8d5968fe3a 100644 --- a/sdk/lib/framework/widgets/ui_node.dart +++ b/sdk/lib/framework/widgets/ui_node.dart @@ -28,7 +28,7 @@ abstract class UINode { UINode({ Object key }) { _key = key == null ? "$runtimeType" : "$runtimeType-$key"; - assert(this is App || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build() + assert(this is AbstractUINodeRoot || _inRenderDirtyComponents); // you should not build the UI tree ahead of time, build it only during build() } String _key; @@ -752,6 +752,7 @@ class UINodeAppView extends AppView { } static UINodeAppView _appView; + static AppView get appView => _appView; static void initUINodeAppView() { if (_appView == null) _appView = new UINodeAppView(); @@ -801,8 +802,6 @@ abstract class App extends AbstractUINodeRoot { App(); - AppView get appView => UINodeAppView._appView; - void _buildIfDirty() { super._buildIfDirty();