mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
Merge pull request #2824 from abarth/update_mojo
Update ChildView after Mojo roll
This commit is contained in:
commit
a8c108dea5
2
bin/cache/engine.version
vendored
2
bin/cache/engine.version
vendored
|
@ -1 +1 @@
|
|||
56bca69d7a9112af22e6873599b57b5b2fe90395
|
||||
b7419de14af49f61b67b290a2b66a3416f94cb62
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:mojo_services/mojo/gfx/composition/scene_token.mojom.dart' as mojom;
|
||||
import 'package:mojo_services/mojo/ui/layouts.mojom.dart' as mojom;
|
||||
import 'package:mojo_services/mojo/ui/view_containers.mojom.dart' as mojom;
|
||||
import 'package:mojo_services/mojo/ui/view_provider.mojom.dart' as mojom;
|
||||
import 'package:mojo_services/mojo/ui/view_token.mojom.dart' as mojom;
|
||||
import 'package:mojo_services/mojo/ui/views.mojom.dart' as mojom;
|
||||
import 'package:mojo/application.dart';
|
||||
import 'package:mojo/core.dart' as core;
|
||||
|
@ -32,6 +35,37 @@ mojom.ViewProxy _initViewProxy() {
|
|||
final mojom.ViewProxy _viewProxy = _initViewProxy();
|
||||
final mojom.View _view = _viewProxy?.ptr;
|
||||
|
||||
mojom.ViewContainer _initViewContainer() {
|
||||
mojom.ViewContainerProxy viewContainerProxy = new mojom.ViewContainerProxy.unbound();
|
||||
_view.getContainer(viewContainerProxy);
|
||||
viewContainerProxy.ptr.setListener(new mojom.ViewContainerListenerStub.unbound()..impl = _ViewContainerListenerImpl.instance);
|
||||
return viewContainerProxy.ptr;
|
||||
}
|
||||
|
||||
final mojom.ViewContainer _viewContainer = _initViewContainer();
|
||||
|
||||
typedef dynamic _ResponseFactory();
|
||||
|
||||
class _ViewContainerListenerImpl extends mojom.ViewContainerListener {
|
||||
static final _ViewContainerListenerImpl instance = new _ViewContainerListenerImpl();
|
||||
|
||||
@override
|
||||
dynamic onChildAttached(int childKey, mojom.ViewInfo childViewInfo, [_ResponseFactory responseFactory = null]) {
|
||||
ChildViewConnection connection = _connections[childKey];
|
||||
connection?._onAttachedToContainer(childViewInfo);
|
||||
return responseFactory();
|
||||
}
|
||||
|
||||
@override
|
||||
dynamic onChildUnavailable(int childKey, [_ResponseFactory responseFactory = null]) {
|
||||
ChildViewConnection connection = _connections[childKey];
|
||||
connection?._onUnavailable();
|
||||
return responseFactory();
|
||||
}
|
||||
|
||||
final Map<int, ChildViewConnection> _connections = new HashMap<int, ChildViewConnection>();
|
||||
}
|
||||
|
||||
/// (mojo-only) A connection with a child view.
|
||||
///
|
||||
/// Used with the [ChildView] widget to display a child view.
|
||||
|
@ -66,22 +100,42 @@ class ChildViewConnection {
|
|||
static int _nextViewKey = 1;
|
||||
int _viewKey;
|
||||
|
||||
VoidCallback _onViewInfoAvailable;
|
||||
mojom.ViewInfo _viewInfo;
|
||||
|
||||
void _onAttachedToContainer(mojom.ViewInfo viewInfo) {
|
||||
assert(_viewInfo == null);
|
||||
_viewInfo = viewInfo;
|
||||
if (_onViewInfoAvailable != null)
|
||||
_onViewInfoAvailable();
|
||||
}
|
||||
|
||||
void _onUnavailable() {
|
||||
_viewInfo = null;
|
||||
}
|
||||
|
||||
void _addChildToViewHost() {
|
||||
assert(_attached);
|
||||
assert(_viewOwner != null);
|
||||
assert(_viewKey == null);
|
||||
_viewKey = _nextViewKey++;
|
||||
_view?.addChild(_viewKey, _viewOwner.impl);
|
||||
_viewInfo = null;
|
||||
_viewContainer?.addChild(_viewKey, _viewOwner.impl);
|
||||
_viewOwner = null;
|
||||
assert(!_ViewContainerListenerImpl.instance._connections.containsKey(_viewKey));
|
||||
_ViewContainerListenerImpl.instance._connections[_viewKey] = this;
|
||||
}
|
||||
|
||||
void _removeChildFromViewHost() {
|
||||
assert(!_attached);
|
||||
assert(_viewOwner == null);
|
||||
assert(_viewKey != null);
|
||||
assert(_ViewContainerListenerImpl.instance._connections[_viewKey] == this);
|
||||
_ViewContainerListenerImpl.instance._connections.remove(_viewKey);
|
||||
_viewOwner = new mojom.ViewOwnerProxy.unbound();
|
||||
_view?.removeChild(_viewKey, _viewOwner);
|
||||
_viewContainer?.removeChild(_viewKey, _viewOwner);
|
||||
_viewKey = null;
|
||||
_viewInfo = null;
|
||||
}
|
||||
|
||||
// The number of render objects attached to this view. In between frames, we
|
||||
|
@ -110,26 +164,24 @@ class ChildViewConnection {
|
|||
_removeChildFromViewHost();
|
||||
}
|
||||
|
||||
Future<mojom.ViewLayoutInfo> _layout({ Size size, double scale }) async {
|
||||
void _layout({ int physicalWidth, int physicalHeight, double devicePixelRatio }) {
|
||||
assert(_attached);
|
||||
assert(_attachments == 1);
|
||||
assert(_viewKey != null);
|
||||
if (_view == null)
|
||||
return new Future<mojom.ViewLayoutInfo>.value(null);
|
||||
int width = (size.width * scale).round();
|
||||
int height = (size.height * scale).round();
|
||||
return;
|
||||
// TODO(abarth): Ideally we would propagate our actual constraints to be
|
||||
// able to support rich cross-app layout. For now, we give the child tight
|
||||
// constraints for simplicity.
|
||||
mojom.BoxConstraints childConstraints = new mojom.BoxConstraints()
|
||||
..minWidth = width
|
||||
..maxWidth = width
|
||||
..minHeight = height
|
||||
..maxHeight = height;
|
||||
..minWidth = physicalWidth
|
||||
..maxWidth = physicalWidth
|
||||
..minHeight = physicalHeight
|
||||
..maxHeight = physicalHeight;
|
||||
mojom.ViewLayoutParams layoutParams = new mojom.ViewLayoutParams()
|
||||
..constraints = childConstraints
|
||||
..devicePixelRatio = scale;
|
||||
return (await _view.layoutChild(_viewKey, layoutParams)).info;
|
||||
..devicePixelRatio = devicePixelRatio;
|
||||
_viewContainer.layoutChild(_viewKey, layoutParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +190,9 @@ class RenderChildView extends RenderBox {
|
|||
RenderChildView({
|
||||
ChildViewConnection child,
|
||||
double scale
|
||||
}) : _child = child, _scale = scale;
|
||||
}) : _scale = scale {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
/// The child to display.
|
||||
ChildViewConnection get child => _child;
|
||||
|
@ -146,12 +200,17 @@ class RenderChildView extends RenderBox {
|
|||
void set child (ChildViewConnection value) {
|
||||
if (value == _child)
|
||||
return;
|
||||
if (attached)
|
||||
_child?._detach();
|
||||
if (attached && _child != null) {
|
||||
_child._detach();
|
||||
assert(_child._onViewInfoAvailable != null);
|
||||
_child._onViewInfoAvailable = null;
|
||||
}
|
||||
_child = value;
|
||||
_layoutInfo = null;
|
||||
if (attached)
|
||||
_child?._attach();
|
||||
if (attached && _child != null) {
|
||||
_child._attach();
|
||||
assert(_child._onViewInfoAvailable == null);
|
||||
_child._onViewInfoAvailable = markNeedsPaint;
|
||||
}
|
||||
if (_child == null) {
|
||||
markNeedsPaint();
|
||||
} else {
|
||||
|
@ -185,20 +244,18 @@ class RenderChildView extends RenderBox {
|
|||
@override
|
||||
bool get alwaysNeedsCompositing => true;
|
||||
|
||||
@override
|
||||
bool get sizedByParent => true;
|
||||
|
||||
@override
|
||||
void performResize() {
|
||||
size = constraints.biggest;
|
||||
}
|
||||
|
||||
TextPainter _debugErrorMessage;
|
||||
|
||||
int _physicalWidth;
|
||||
int _physicalHeight;
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
size = constraints.biggest;
|
||||
if (_child != null) {
|
||||
_child._layout(size: size, scale: scale).then(_handleLayoutInfoChanged);
|
||||
_physicalWidth = (size.width * scale).round();
|
||||
_physicalHeight = (size.height * scale).round();
|
||||
_child._layout(physicalWidth: _physicalWidth, physicalHeight: _physicalHeight, devicePixelRatio: scale);
|
||||
assert(() {
|
||||
if (_view == null) {
|
||||
_debugErrorMessage ??= new TextPainter()
|
||||
|
@ -215,21 +272,14 @@ class RenderChildView extends RenderBox {
|
|||
}
|
||||
}
|
||||
|
||||
mojom.ViewLayoutInfo _layoutInfo;
|
||||
|
||||
void _handleLayoutInfoChanged(mojom.ViewLayoutInfo layoutInfo) {
|
||||
_layoutInfo = layoutInfo;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
@override
|
||||
bool hitTestSelf(Point position) => true;
|
||||
|
||||
@override
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
assert(needsCompositing);
|
||||
if (_layoutInfo != null)
|
||||
context.pushChildScene(offset, scale, _layoutInfo);
|
||||
if (_child?._viewInfo != null)
|
||||
context.pushChildScene(offset, scale, _physicalWidth, _physicalHeight, _child._viewInfo.sceneToken);
|
||||
assert(() {
|
||||
if (_view == null) {
|
||||
context.canvas.drawRect(offset & size, new Paint()..color = const Color(0xFF0000FF));
|
||||
|
|
|
@ -7,7 +7,7 @@ import 'dart:ui' show Offset;
|
|||
|
||||
import 'package:flutter/painting.dart';
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
import 'package:mojo_services/mojo/ui/layouts.mojom.dart' as mojom;
|
||||
import 'package:mojo_services/mojo/gfx/composition/scene_token.mojom.dart' as mojom;
|
||||
|
||||
import 'debug.dart';
|
||||
|
||||
|
@ -110,20 +110,22 @@ class PictureLayer extends Layer {
|
|||
}
|
||||
|
||||
class ChildSceneLayer extends Layer {
|
||||
ChildSceneLayer({ this.offset, this.devicePixelRatio, this.layoutInfo });
|
||||
ChildSceneLayer({ this.offset, this.devicePixelRatio, this.physicalWidth, this.physicalHeight, this.sceneToken });
|
||||
|
||||
Offset offset;
|
||||
double devicePixelRatio;
|
||||
mojom.ViewLayoutInfo layoutInfo;
|
||||
int physicalWidth;
|
||||
int physicalHeight;
|
||||
mojom.SceneToken sceneToken;
|
||||
|
||||
@override
|
||||
void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
|
||||
builder.addChildScene(
|
||||
offset + layerOffset,
|
||||
devicePixelRatio,
|
||||
layoutInfo.size.width,
|
||||
layoutInfo.size.height,
|
||||
layoutInfo.sceneToken.value
|
||||
physicalWidth,
|
||||
physicalHeight,
|
||||
sceneToken.value
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -131,9 +133,9 @@ class ChildSceneLayer extends Layer {
|
|||
void debugFillDescription(List<String> description) {
|
||||
super.debugFillDescription(description);
|
||||
description.add('offset: $offset');
|
||||
description.add('physicalWidth: ${layoutInfo.size.width}');
|
||||
description.add('physicalHeight: ${layoutInfo.size.height}');
|
||||
description.add('sceneToken.value: ${layoutInfo.sceneToken.value}');
|
||||
description.add('physicalWidth: $physicalWidth');
|
||||
description.add('physicalHeight: $physicalHeight');
|
||||
description.add('sceneToken.value: ${sceneToken.value}');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:flutter/gestures.dart';
|
|||
import 'package:flutter/painting.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:mojo_services/mojo/ui/layouts.mojom.dart' as mojom;
|
||||
import 'package:mojo_services/mojo/gfx/composition/scene_token.mojom.dart' as mojom;
|
||||
import 'package:vector_math/vector_math_64.dart';
|
||||
|
||||
import 'debug.dart';
|
||||
|
@ -201,9 +201,15 @@ class PaintingContext {
|
|||
));
|
||||
}
|
||||
|
||||
void pushChildScene(Offset offset, double devicePixelRatio, mojom.ViewLayoutInfo layoutInfo) {
|
||||
void pushChildScene(Offset offset, double devicePixelRatio, int physicalWidth, int physicalHeight, mojom.SceneToken sceneToken) {
|
||||
_stopRecordingIfNeeded();
|
||||
_appendLayer(new ChildSceneLayer(offset: offset, devicePixelRatio: devicePixelRatio, layoutInfo: layoutInfo));
|
||||
_appendLayer(new ChildSceneLayer(
|
||||
offset: offset,
|
||||
devicePixelRatio: devicePixelRatio,
|
||||
physicalWidth: physicalWidth,
|
||||
physicalHeight: physicalHeight,
|
||||
sceneToken: sceneToken
|
||||
));
|
||||
}
|
||||
|
||||
/// Push a rectangular clip rect.
|
||||
|
|
Loading…
Reference in a new issue