提交 6d5227ea 编写于 作者: A Adam Barth

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
上级 926eafbf
......@@ -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();
......
......@@ -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;
......
......@@ -79,8 +79,8 @@ HitTestResult NewEventHandler::performHitTest(const LayoutPoint& point)
bool NewEventHandler::dispatchPointerEvent(PointerState& state, const WebPointerEvent& event)
{
RefPtr<PointerEvent> 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
......
......@@ -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",
......
......@@ -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<int, HitTestResult> _hitTestResultForPointer = new Map<int, HitTestResult>();
Map<int, PointerState> _stateForPointer = new Map<int, PointerState>();
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) {
......
......@@ -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<UINode> 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,
......
......@@ -6,14 +6,14 @@ import '../fn2.dart';
import '../theme/shadows.dart';
class Material extends Component {
static final List<Style> _shadowStyle = [
null,
new Style('box-shadow: ${Shadow[1]}'),
new Style('box-shadow: ${Shadow[2]}'),
new Style('box-shadow: ${Shadow[3]}'),
new Style('box-shadow: ${Shadow[4]}'),
new Style('box-shadow: ${Shadow[5]}'),
];
// static final List<Style> _shadowStyle = [
// null,
// new Style('box-shadow: ${Shadow[1]}'),
// new Style('box-shadow: ${Shadow[2]}'),
// new Style('box-shadow: ${Shadow[3]}'),
// new Style('box-shadow: ${Shadow[4]}'),
// new Style('box-shadow: ${Shadow[5]}'),
// ];
UINode content;
int level;
......@@ -21,6 +21,8 @@ class Material extends Component {
Material({ Object key, this.content, this.level: 0 }) : super(key: key);
UINode build() {
return new StyleNode(content, _shadowStyle[level]);
// TODO(eseidel): Add a shadow.
// return new StyleNode(content, _shadowStyle[level]);
return content;
}
}
......@@ -16,6 +16,7 @@ import 'rendering/box.dart';
import 'rendering/flex.dart';
import 'rendering/node.dart';
import 'rendering/paragraph.dart';
import 'rendering/stack.dart';
// final sky.Tracing _tracing = sky.window.tracing;
......@@ -390,7 +391,7 @@ class SizedBox extends OneChildRenderNodeWrapper {
RenderSizedBox createNode() => new RenderSizedBox(desiredSize: desiredSize);
void syncRenderNode(DecoratedBox old) {
void syncRenderNode(SizedBox old) {
super.syncRenderNode(old);
root.desiredSize = desiredSize;
}
......@@ -591,6 +592,14 @@ class BlockContainer extends OneChildListRenderNodeWrapper {
: super(key: key, children: children);
}
class StackContainer extends OneChildListRenderNodeWrapper {
RenderStack root;
RenderStack createNode() => new RenderStack();
StackContainer({ Object key, List<UINode> children })
: super(key: key, children: children);
}
class Paragraph extends RenderNodeWrapper {
RenderParagraph root;
RenderParagraph createNode() => new RenderParagraph(text: text);
......@@ -885,9 +894,6 @@ class Container extends Component {
UINode build() {
UINode current = child;
if (transform != null)
current = new Transform(transform: transform, child: current);
if (padding != null)
current = new Padding(padding: padding, child: current);
......@@ -900,6 +906,9 @@ class Container extends Component {
if (margin != null)
current = new Padding(padding: margin, child: current);
if (transform != null)
current = new Transform(transform: transform, child: current);
return current;
}
}
......
......@@ -50,6 +50,12 @@ class BoxConstraints {
minHeight = size.height,
maxHeight = size.height;
BoxConstraints.loose(sky.Size size)
: minWidth = 0.0,
maxWidth = size.width,
minHeight = 0.0,
maxHeight = size.height;
BoxConstraints deflate(EdgeDims edges) {
assert(edges != null);
double horizontal = edges.left + edges.right;
......@@ -347,9 +353,9 @@ class RenderTransform extends RenderProxyBox {
canvas.save();
canvas.concat([
storage[ 0], storage[ 1], storage[ 3],
storage[ 4], storage[ 5], storage[ 7],
storage[12], storage[13], storage[15],
storage[ 0], storage[ 4], storage[12],
storage[ 1], storage[ 5], storage[13],
storage[ 3], storage[ 7], storage[15],
]);
super.paint(canvas);
canvas.restore();
......
// 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 'box.dart';
import 'node.dart';
class StackParentData extends BoxParentData with ContainerParentDataMixin<RenderBox> { }
class RenderStack extends RenderBox with ContainerRenderNodeMixin<RenderBox, StackParentData>,
RenderBoxContainerDefaultsMixin<RenderBox, StackParentData> {
RenderStack({
List<RenderBox> children
}) {
if (children != null)
children.forEach((child) { add(child); });
}
void setParentData(RenderBox child) {
if (child.parentData is! StackParentData)
child.parentData = new StackParentData();
}
sky.Size getIntrinsicDimensions(BoxConstraints constraints) {
return constraints.constrain(new sky.Size.infinite());
}
void performLayout() {
size = constraints.constrain(new sky.Size.infinite());
assert(size.width < double.INFINITY);
assert(size.height < double.INFINITY);
BoxConstraints innerConstraints = new BoxConstraints.loose(size);
sky.Point origin = new sky.Point(0.0, 0.0);
RenderBox child = firstChild;
while (child != null) {
child.layout(innerConstraints);
assert(child.parentData is StackParentData);
child.parentData.position = origin;
child = child.parentData.nextSibling;
}
}
void hitTestChildren(HitTestResult result, { sky.Point position }) {
defaultHitTestChildren(result, position: position);
}
void paint(RenderNodeDisplayList canvas) {
defaultPaint(canvas);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册