From 6d5227ea0c91fd9586d3a47d53c6503ccec1b1cc Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Wed, 3 Jun 2015 14:52:13 -0700 Subject: [PATCH] Make Drawer in components2 work This CL introduces RenderStack and fixes a number of bugs to make the Drawer in components2 work. R=ianh@google.com, eseidel@chromium.org Review URL: https://codereview.chromium.org/1147143005 --- engine/core/events/PointerEvent.h | 4 +- engine/core/events/PointerEvent.idl | 4 +- engine/core/frame/NewEventHandler.cpp | 4 +- sdk/BUILD.gn | 1 + sdk/lib/framework/app.dart | 38 ++++++++++----- sdk/lib/framework/components2/drawer.dart | 40 ++++++---------- sdk/lib/framework/components2/material.dart | 20 ++++---- sdk/lib/framework/fn2.dart | 17 +++++-- sdk/lib/framework/rendering/box.dart | 12 +++-- sdk/lib/framework/rendering/stack.dart | 52 +++++++++++++++++++++ 10 files changed, 132 insertions(+), 60 deletions(-) create mode 100644 sdk/lib/framework/rendering/stack.dart diff --git a/engine/core/events/PointerEvent.h b/engine/core/events/PointerEvent.h index f23ec73d7..9ce08ff72 100644 --- a/engine/core/events/PointerEvent.h +++ b/engine/core/events/PointerEvent.h @@ -77,8 +77,8 @@ public: double orientation() const { return m_orientation; } double tilt() const { return m_tilt; } - void setDX(double dx) { m_dx = dx; } - void setDY(double dy) { m_dy = dy; } + void setDx(double dx) { m_dx = dx; } + void setDy(double dy) { m_dy = dy; } private: PointerEvent(); diff --git a/engine/core/events/PointerEvent.idl b/engine/core/events/PointerEvent.idl index 76979f5fc..3f69823f6 100644 --- a/engine/core/events/PointerEvent.idl +++ b/engine/core/events/PointerEvent.idl @@ -9,8 +9,8 @@ [InitializedByEventConstructor] readonly attribute DOMString kind; [InitializedByEventConstructor] readonly attribute double x; [InitializedByEventConstructor] readonly attribute double y; - [InitializedByEventConstructor] readonly attribute double dx; - [InitializedByEventConstructor] readonly attribute double dy; + [InitializedByEventConstructor] attribute double dx; + [InitializedByEventConstructor] attribute double dy; [InitializedByEventConstructor] readonly attribute long buttons; [InitializedByEventConstructor] readonly attribute boolean down; [InitializedByEventConstructor] readonly attribute boolean primary; diff --git a/engine/core/frame/NewEventHandler.cpp b/engine/core/frame/NewEventHandler.cpp index a7e6c2679..45c985564 100644 --- a/engine/core/frame/NewEventHandler.cpp +++ b/engine/core/frame/NewEventHandler.cpp @@ -79,8 +79,8 @@ HitTestResult NewEventHandler::performHitTest(const LayoutPoint& point) bool NewEventHandler::dispatchPointerEvent(PointerState& state, const WebPointerEvent& event) { RefPtr pointerEvent = PointerEvent::create(event); - pointerEvent->setDX(event.x - state.x); - pointerEvent->setDY(event.y - state.y); + pointerEvent->setDx(event.x - state.x); + pointerEvent->setDy(event.y - state.y); state.x = event.x; state.y = event.y; // TODO(abarth): Keep track of how many pointers are targeting the same node diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 760a1b2da..10bd14c60 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -101,6 +101,7 @@ dart_pkg("sdk") { "lib/framework/rendering/flex.dart", "lib/framework/rendering/node.dart", "lib/framework/rendering/paragraph.dart", + "lib/framework/rendering/stack.dart", "lib/framework/scheduler.dart", "lib/framework/shell.dart", "lib/framework/theme/colors.dart", diff --git a/sdk/lib/framework/app.dart b/sdk/lib/framework/app.dart index 62b76d838..38113d44c 100644 --- a/sdk/lib/framework/app.dart +++ b/sdk/lib/framework/app.dart @@ -7,6 +7,13 @@ import 'rendering/box.dart'; import 'rendering/node.dart'; import 'scheduler.dart' as scheduler; +class PointerState { + HitTestResult result; + sky.Point lastPosition; + + PointerState({ this.result, this.lastPosition }); +} + class AppView { AppView(RenderBox root) { @@ -24,7 +31,7 @@ class AppView { RenderView _renderView; - Map _hitTestResultForPointer = new Map(); + Map _stateForPointer = new Map(); RenderBox get root => _renderView.child; void set root(RenderBox value) { @@ -41,28 +48,35 @@ class AppView { } void _handlePointerEvent(sky.PointerEvent event) { - HitTestResult result; + sky.Point position = new sky.Point(event.x, event.y); + + PointerState state; switch(event.type) { case 'pointerdown': - result = new HitTestResult(); - _renderView.hitTest(result, position: new sky.Point(event.x, event.y)); - _hitTestResultForPointer[event.pointer] = result; + HitTestResult result = new HitTestResult(); + _renderView.hitTest(result, position: position); + state = new PointerState(result: result, lastPosition: position); + _stateForPointer[event.pointer] = state; break; case 'pointerup': case 'pointercancel': - result = _hitTestResultForPointer[event.pointer]; - _hitTestResultForPointer.remove(event.pointer); + state = _stateForPointer[event.pointer]; + _stateForPointer.remove(event.pointer); break; case 'pointermove': - result = _hitTestResultForPointer[event.pointer]; + state = _stateForPointer[event.pointer]; // In the case of mouse hover we won't already have a cached down. - if (result == null) { - result = new HitTestResult(); - _renderView.hitTest(result, position: new sky.Point(event.x, event.y)); + if (state.result == null) { + state.result = new HitTestResult(); + _renderView.hitTest(state.result, position: position); } break; } - dispatchPointerEvent(event, result); + event.dx = position.x - state.lastPosition.x; + event.dy = position.y - state.lastPosition.y; + state.lastPosition = position; + + dispatchPointerEvent(event, state.result); } void dispatchPointerEvent(sky.PointerEvent event, HitTestResult result) { diff --git a/sdk/lib/framework/components2/drawer.dart b/sdk/lib/framework/components2/drawer.dart index 0a348c5b0..c3e0155a5 100644 --- a/sdk/lib/framework/components2/drawer.dart +++ b/sdk/lib/framework/components2/drawer.dart @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'animated_component.dart'; import '../animation/animated_value.dart'; import '../animation/curves.dart'; import '../fn2.dart'; +import '../rendering/box.dart'; import '../theme/colors.dart'; +import 'animated_component.dart'; import 'dart:math' as math; import 'dart:sky' as sky; import 'material.dart'; +import 'package:vector_math/vector_math.dart'; const double _kWidth = 304.0; const double _kMinFlingVelocity = 0.4; @@ -90,22 +92,6 @@ class DrawerController { } class Drawer extends AnimatedComponent { - // TODO(abarth): We need a better way to become a container for absolutely - // positioned elements. - static final Style _style = new Style(''' - transform: translateX(0);'''); - - static final Style _maskStyle = new Style(''' - background-color: black; - will-change: opacity;''' - ); - - static final Style _contentStyle = new Style(''' - background-color: ${Grey[50]}; - will-change: transform; - width: ${_kWidth}px;''' - ); - List children; int level; DrawerController controller; @@ -122,13 +108,15 @@ class Drawer extends AnimatedComponent { } UINode build() { - String maskInlineStyle = 'opacity: ${(_position / _kWidth + 1) * 0.5}'; - String contentInlineStyle = 'transform: translateX(${_position}px)'; + Matrix4 transform = new Matrix4.identity(); + transform.translate(_position); + + sky.Color maskColor = new sky.Color(((_position / _kWidth + 1) * 0xFF).floor() << 24); var mask = new EventListenerNode( new Container( - style: _maskStyle, - inlineStyle: maskInlineStyle + desiredSize: new sky.Size.infinite(), + decoration: new BoxDecoration(backgroundColor: maskColor) ), onGestureTap: controller.handleMaskTap, onGestureFlingStart: controller.handleFlingStart @@ -136,15 +124,15 @@ class Drawer extends AnimatedComponent { Material content = new Material( content: new Container( - style: _contentStyle, - inlineStyle: contentInlineStyle, - children: children + decoration: new BoxDecoration(backgroundColor: new sky.Color(0xFFFFFFFF)), + desiredSize: new sky.Size.fromWidth(_kWidth), + transform: transform, + child: new BlockContainer(children: children) ), level: level); return new EventListenerNode( - new FillStackContainer( - style: _style, + new StackContainer( children: [ mask, content ] ), onPointerDown: controller.handlePointerDown, diff --git a/sdk/lib/framework/components2/material.dart b/sdk/lib/framework/components2/material.dart index 6371e2938..8fe042285 100644 --- a/sdk/lib/framework/components2/material.dart +++ b/sdk/lib/framework/components2/material.dart @@ -6,14 +6,14 @@ import '../fn2.dart'; import '../theme/shadows.dart'; class Material extends Component { - static final List