Merge pull request #684 from abarth/explode_box
Split box.dart into many files
This commit is contained in:
commit
ce8f75dac8
@ -9,6 +9,8 @@ import 'package:sky/rendering/box.dart';
|
|||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
import 'package:sky/rendering/paragraph.dart';
|
import 'package:sky/rendering/paragraph.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
import 'solid_color_box.dart';
|
import 'solid_color_box.dart';
|
||||||
|
@ -9,6 +9,8 @@ import 'package:sky/rendering/box.dart';
|
|||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
import 'package:sky/rendering/paragraph.dart';
|
import 'package:sky/rendering/paragraph.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
RenderBox getBox(double lh) {
|
RenderBox getBox(double lh) {
|
||||||
|
@ -6,6 +6,8 @@ import 'dart:sky' as sky;
|
|||||||
|
|
||||||
import 'package:sky/rendering/block.dart';
|
import 'package:sky/rendering/block.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -6,6 +6,8 @@ import 'dart:sky' as sky;
|
|||||||
|
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
class RenderSolidColor extends RenderDecoratedBox {
|
class RenderSolidColor extends RenderDecoratedBox {
|
||||||
|
@ -8,10 +8,12 @@ import 'dart:math' as math;
|
|||||||
import 'package:sky/mojo/activity.dart' as activity;
|
import 'package:sky/mojo/activity.dart' as activity;
|
||||||
import 'package:sky/mojo/net/image_cache.dart' as image_cache;
|
import 'package:sky/mojo/net/image_cache.dart' as image_cache;
|
||||||
import 'package:sky/painting/text_style.dart';
|
import 'package:sky/painting/text_style.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
|
import 'package:sky/rendering/image.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
import 'package:sky/rendering/paragraph.dart';
|
import 'package:sky/rendering/paragraph.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
import 'solid_color_box.dart';
|
import 'solid_color_box.dart';
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
import 'dart:sky';
|
import 'dart:sky';
|
||||||
|
|
||||||
import 'package:sky/painting/text_style.dart';
|
import 'package:sky/painting/text_style.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
import 'package:sky/rendering/paragraph.dart';
|
import 'package:sky/rendering/paragraph.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
import 'solid_color_box.dart';
|
import 'solid_color_box.dart';
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
import 'dart:sky';
|
import 'dart:sky';
|
||||||
|
|
||||||
import 'package:sky/painting/text_style.dart';
|
import 'package:sky/painting/text_style.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
import 'package:sky/rendering/paragraph.dart';
|
import 'package:sky/rendering/paragraph.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
|
||||||
import 'solid_color_box.dart';
|
import 'solid_color_box.dart';
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import 'dart:sky' as sky;
|
|||||||
|
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
const double kTwoPi = 2 * math.PI;
|
const double kTwoPi = 2 * math.PI;
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
import 'dart:sky';
|
import 'dart:sky';
|
||||||
|
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
import 'package:sky/theme/colors.dart';
|
import 'package:sky/theme/colors.dart';
|
||||||
import 'package:sky/theme/shadows.dart';
|
import 'package:sky/theme/shadows.dart';
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:sky';
|
import 'dart:sky';
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/object.dart';
|
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
|
||||||
import 'package:sky/rendering/auto_layout.dart';
|
|
||||||
import 'package:cassowary/cassowary.dart' as al;
|
import 'package:cassowary/cassowary.dart' as al;
|
||||||
|
import 'package:sky/rendering/auto_layout.dart';
|
||||||
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
RenderDecoratedBox c1 = new RenderDecoratedBox(
|
RenderDecoratedBox c1 = new RenderDecoratedBox(
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:sky' as sky;
|
import 'dart:sky' as sky;
|
||||||
import 'package:sky/rendering/object.dart';
|
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
|
||||||
class RenderSolidColorBox extends RenderDecoratedBox {
|
class RenderSolidColorBox extends RenderDecoratedBox {
|
||||||
final Size desiredSize;
|
final Size desiredSize;
|
||||||
|
@ -5,8 +5,9 @@
|
|||||||
import 'dart:sky' as sky;
|
import 'dart:sky' as sky;
|
||||||
|
|
||||||
import 'package:sky/base/scheduler.dart';
|
import 'package:sky/base/scheduler.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
import 'package:vector_math/vector_math.dart';
|
import 'package:vector_math/vector_math.dart';
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import 'dart:sky' as sky;
|
|||||||
|
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
import 'package:vector_math/vector_math.dart';
|
import 'package:vector_math/vector_math.dart';
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import 'dart:sky' as sky;
|
|||||||
|
|
||||||
import 'package:sky/editing/input.dart';
|
import 'package:sky/editing/input.dart';
|
||||||
import 'package:sky/painting/text_style.dart';
|
import 'package:sky/painting/text_style.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/theme/colors.dart' as colors;
|
import 'package:sky/theme/colors.dart' as colors;
|
||||||
import 'package:sky/theme/typography.dart' as typography;
|
import 'package:sky/theme/typography.dart' as typography;
|
||||||
import 'package:sky/widgets.dart';
|
import 'package:sky/widgets.dart';
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
import 'package:sky/widgets/raised_button.dart';
|
import 'package:sky/widgets/raised_button.dart';
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
|
@ -8,7 +8,6 @@ import 'package:sky/animation/curves.dart';
|
|||||||
import 'package:sky/base/lerp.dart';
|
import 'package:sky/base/lerp.dart';
|
||||||
import 'package:sky/painting/box_painter.dart';
|
import 'package:sky/painting/box_painter.dart';
|
||||||
import 'package:sky/painting/text_style.dart';
|
import 'package:sky/painting/text_style.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/theme/colors.dart';
|
import 'package:sky/theme/colors.dart';
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
import 'package:sky/widgets/block_viewport.dart';
|
import 'package:sky/widgets/block_viewport.dart';
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
import 'package:mojo/mojo/url_response.mojom.dart';
|
import 'package:mojo/mojo/url_response.mojom.dart';
|
||||||
import 'package:sky/mojo/net/fetch.dart';
|
import 'package:sky/mojo/net/fetch.dart';
|
||||||
import 'package:sky/mojo/shell.dart' as shell;
|
import 'package:sky/mojo/shell.dart' as shell;
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
import 'package:sky/theme/colors.dart' as colors;
|
import 'package:sky/theme/colors.dart' as colors;
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
|
@ -5,12 +5,13 @@
|
|||||||
import 'dart:sky' as sky;
|
import 'dart:sky' as sky;
|
||||||
|
|
||||||
import 'package:sky/base/scheduler.dart' as scheduler;
|
import 'package:sky/base/scheduler.dart' as scheduler;
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
import 'package:sky/widgets/raised_button.dart';
|
|
||||||
import 'package:sky/widgets/framework.dart';
|
import 'package:sky/widgets/framework.dart';
|
||||||
|
import 'package:sky/widgets/raised_button.dart';
|
||||||
import 'package:vector_math/vector_math.dart';
|
import 'package:vector_math/vector_math.dart';
|
||||||
|
|
||||||
import '../rendering/solid_color_box.dart';
|
import '../rendering/solid_color_box.dart';
|
||||||
|
File diff suppressed because it is too large
Load Diff
170
packages/flutter/lib/rendering/image.dart
Normal file
170
packages/flutter/lib/rendering/image.dart
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
// 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/painting/box_painter.dart';
|
||||||
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/box.dart';
|
||||||
|
|
||||||
|
class RenderImage extends RenderBox {
|
||||||
|
RenderImage({
|
||||||
|
sky.Image image,
|
||||||
|
double width,
|
||||||
|
double height,
|
||||||
|
sky.ColorFilter colorFilter,
|
||||||
|
fit: ImageFit.scaleDown,
|
||||||
|
repeat: ImageRepeat.noRepeat
|
||||||
|
}) : _image = image,
|
||||||
|
_width = width,
|
||||||
|
_height = height,
|
||||||
|
_colorFilter = colorFilter,
|
||||||
|
_fit = fit,
|
||||||
|
_repeat = repeat;
|
||||||
|
|
||||||
|
sky.Image _image;
|
||||||
|
sky.Image get image => _image;
|
||||||
|
void set image (sky.Image value) {
|
||||||
|
if (value == _image)
|
||||||
|
return;
|
||||||
|
_image = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
if (_width == null || _height == null)
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
double _width;
|
||||||
|
double get width => _width;
|
||||||
|
void set width (double value) {
|
||||||
|
if (value == _width)
|
||||||
|
return;
|
||||||
|
_width = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
double _height;
|
||||||
|
double get height => _height;
|
||||||
|
void set height (double value) {
|
||||||
|
if (value == _height)
|
||||||
|
return;
|
||||||
|
_height = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
sky.ColorFilter _colorFilter;
|
||||||
|
sky.ColorFilter get colorFilter => _colorFilter;
|
||||||
|
void set colorFilter (sky.ColorFilter value) {
|
||||||
|
if (value == _colorFilter)
|
||||||
|
return;
|
||||||
|
_colorFilter = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageFit _fit;
|
||||||
|
ImageFit get fit => _fit;
|
||||||
|
void set fit (ImageFit value) {
|
||||||
|
if (value == _fit)
|
||||||
|
return;
|
||||||
|
_fit = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageRepeat _repeat;
|
||||||
|
ImageRepeat get repeat => _repeat;
|
||||||
|
void set repeat (ImageRepeat value) {
|
||||||
|
if (value == _repeat)
|
||||||
|
return;
|
||||||
|
_repeat = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
Size _sizeForConstraints(BoxConstraints constraints) {
|
||||||
|
// Folds the given |width| and |height| into |cosntraints| so they can all
|
||||||
|
// be treated uniformly.
|
||||||
|
constraints = new BoxConstraints.tightFor(
|
||||||
|
width: _width,
|
||||||
|
height: _height
|
||||||
|
).apply(constraints);
|
||||||
|
|
||||||
|
if (constraints.isTight || _image == null)
|
||||||
|
return constraints.smallest;
|
||||||
|
|
||||||
|
// This algorithm attempts to find a size for the RenderImage that fits in
|
||||||
|
// the given constraints and preserves the image's intrinisc aspect ratio.
|
||||||
|
// Its goals as follow:
|
||||||
|
//
|
||||||
|
// - The dimensions of the RenderImage fit within the constraints.
|
||||||
|
// - The aspect ratio of the RenderImage matches the instrinsic aspect
|
||||||
|
// ratio of the image.
|
||||||
|
// - The RenderImage's dimension are maximal subject to being smaller than
|
||||||
|
// the intrinsic size of the image.
|
||||||
|
|
||||||
|
double width = _image.width.toDouble();
|
||||||
|
double height = _image.height.toDouble();
|
||||||
|
assert(width > 0.0);
|
||||||
|
assert(height > 0.0);
|
||||||
|
double aspectRatio = width / height;
|
||||||
|
|
||||||
|
if (width > constraints.maxWidth) {
|
||||||
|
width = constraints.maxWidth;
|
||||||
|
height = width / aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height > constraints.maxHeight) {
|
||||||
|
height = constraints.maxHeight;
|
||||||
|
width = height * aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width < constraints.minWidth) {
|
||||||
|
width = constraints.minWidth;
|
||||||
|
height = width / aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height < constraints.minHeight) {
|
||||||
|
height = constraints.minHeight;
|
||||||
|
width = height * aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
return constraints.constrain(new Size(width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (_width == null && _height == null)
|
||||||
|
return constraints.constrainWidth(0.0);
|
||||||
|
return _sizeForConstraints(constraints).width;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
return _sizeForConstraints(constraints).width;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (_width == null && _height == null)
|
||||||
|
return constraints.constrainHeight(0.0);
|
||||||
|
return _sizeForConstraints(constraints).height;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
return _sizeForConstraints(constraints).height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
size = _sizeForConstraints(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (_image == null)
|
||||||
|
return;
|
||||||
|
paintImage(
|
||||||
|
canvas: context.canvas,
|
||||||
|
rect: offset & size,
|
||||||
|
image: _image,
|
||||||
|
colorFilter: _colorFilter,
|
||||||
|
fit: _fit,
|
||||||
|
repeat: _repeat
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}width: ${width}\n${prefix}height: ${height}\n';
|
||||||
|
}
|
637
packages/flutter/lib/rendering/proxy_box.dart
Normal file
637
packages/flutter/lib/rendering/proxy_box.dart
Normal file
@ -0,0 +1,637 @@
|
|||||||
|
// 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/painting/box_painter.dart';
|
||||||
|
import 'package:sky/painting/text_style.dart';
|
||||||
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/box.dart';
|
||||||
|
import 'package:vector_math/vector_math.dart';
|
||||||
|
|
||||||
|
export 'package:sky/painting/box_painter.dart';
|
||||||
|
|
||||||
|
class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
|
||||||
|
|
||||||
|
// ProxyBox assumes the child will be at 0,0 and will have the same size
|
||||||
|
|
||||||
|
RenderProxyBox([RenderBox child = null]) {
|
||||||
|
this.child = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicWidth(constraints);
|
||||||
|
return super.getMinIntrinsicWidth(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicWidth(constraints);
|
||||||
|
return super.getMaxIntrinsicWidth(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicHeight(constraints);
|
||||||
|
return super.getMinIntrinsicHeight(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicHeight(constraints);
|
||||||
|
return super.getMaxIntrinsicHeight(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double computeDistanceToActualBaseline(TextBaseline baseline) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getDistanceToActualBaseline(baseline);
|
||||||
|
return super.computeDistanceToActualBaseline(baseline);
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null) {
|
||||||
|
child.layout(constraints, parentUsesSize: true);
|
||||||
|
size = child.size;
|
||||||
|
} else {
|
||||||
|
performResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void hitTestChildren(HitTestResult result, { Point position }) {
|
||||||
|
if (child != null)
|
||||||
|
child.hitTest(result, position: position);
|
||||||
|
else
|
||||||
|
super.hitTestChildren(result, position: position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null)
|
||||||
|
context.paintChild(child, offset.toPoint());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderConstrainedBox extends RenderProxyBox {
|
||||||
|
RenderConstrainedBox({
|
||||||
|
RenderBox child,
|
||||||
|
BoxConstraints additionalConstraints
|
||||||
|
}) : super(child), _additionalConstraints = additionalConstraints {
|
||||||
|
assert(additionalConstraints != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxConstraints _additionalConstraints;
|
||||||
|
BoxConstraints get additionalConstraints => _additionalConstraints;
|
||||||
|
void set additionalConstraints (BoxConstraints value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_additionalConstraints == value)
|
||||||
|
return;
|
||||||
|
_additionalConstraints = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicWidth(_additionalConstraints.apply(constraints));
|
||||||
|
return _additionalConstraints.apply(constraints).constrainWidth(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicWidth(_additionalConstraints.apply(constraints));
|
||||||
|
return _additionalConstraints.apply(constraints).constrainWidth(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicHeight(_additionalConstraints.apply(constraints));
|
||||||
|
return _additionalConstraints.apply(constraints).constrainHeight(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicHeight(_additionalConstraints.apply(constraints));
|
||||||
|
return _additionalConstraints.apply(constraints).constrainHeight(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null) {
|
||||||
|
child.layout(_additionalConstraints.apply(constraints), parentUsesSize: true);
|
||||||
|
size = child.size;
|
||||||
|
} else {
|
||||||
|
size = _additionalConstraints.apply(constraints).constrain(Size.zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}additionalConstraints: ${additionalConstraints}\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderAspectRatio extends RenderProxyBox {
|
||||||
|
RenderAspectRatio({
|
||||||
|
RenderBox child,
|
||||||
|
double aspectRatio
|
||||||
|
}) : super(child), _aspectRatio = aspectRatio {
|
||||||
|
assert(_aspectRatio != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _aspectRatio;
|
||||||
|
double get aspectRatio => _aspectRatio;
|
||||||
|
void set aspectRatio (double value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_aspectRatio == value)
|
||||||
|
return;
|
||||||
|
_aspectRatio = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
return _applyAspectRatio(constraints).height;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
return _applyAspectRatio(constraints).height;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size _applyAspectRatio(BoxConstraints constraints) {
|
||||||
|
double width = constraints.constrainWidth();
|
||||||
|
double height = constraints.constrainHeight(width / _aspectRatio);
|
||||||
|
return new Size(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get sizedByParent => true;
|
||||||
|
|
||||||
|
void performResize() {
|
||||||
|
size = _applyAspectRatio(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null)
|
||||||
|
child.layout(new BoxConstraints.tight(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}aspectRatio: ${aspectRatio}\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderShrinkWrapWidth extends RenderProxyBox {
|
||||||
|
|
||||||
|
// This class will attempt to size its child to the child's maximum
|
||||||
|
// intrinsic width, snapped to a multiple of the stepWidth, if one
|
||||||
|
// is provided, and given the provided constraints; and will then
|
||||||
|
// adopt the child's resulting dimensions.
|
||||||
|
|
||||||
|
// Note: laying out this class is relatively expensive. Avoid using
|
||||||
|
// it where possible.
|
||||||
|
|
||||||
|
RenderShrinkWrapWidth({
|
||||||
|
double stepWidth,
|
||||||
|
double stepHeight,
|
||||||
|
RenderBox child
|
||||||
|
}) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child);
|
||||||
|
|
||||||
|
double _stepWidth;
|
||||||
|
double get stepWidth => _stepWidth;
|
||||||
|
void set stepWidth(double value) {
|
||||||
|
if (value == _stepWidth)
|
||||||
|
return;
|
||||||
|
_stepWidth = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
double _stepHeight;
|
||||||
|
double get stepHeight => _stepHeight;
|
||||||
|
void set stepHeight(double value) {
|
||||||
|
if (value == _stepHeight)
|
||||||
|
return;
|
||||||
|
_stepHeight = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
static double applyStep(double input, double step) {
|
||||||
|
if (step == null)
|
||||||
|
return input;
|
||||||
|
return (input / step).ceil() * step;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
|
||||||
|
if (constraints.hasTightWidth)
|
||||||
|
return constraints;
|
||||||
|
double width = child.getMaxIntrinsicWidth(constraints);
|
||||||
|
assert(width == constraints.constrainWidth(width));
|
||||||
|
return constraints.applyWidth(applyStep(width, _stepWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
return getMaxIntrinsicWidth(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child == null)
|
||||||
|
return constraints.constrainWidth(0.0);
|
||||||
|
double childResult = child.getMaxIntrinsicWidth(constraints);
|
||||||
|
return constraints.constrainWidth(applyStep(childResult, _stepWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child == null)
|
||||||
|
return constraints.constrainWidth(0.0);
|
||||||
|
double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constraints));
|
||||||
|
return constraints.constrainHeight(applyStep(childResult, _stepHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child == null)
|
||||||
|
return constraints.constrainWidth(0.0);
|
||||||
|
double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constraints));
|
||||||
|
return constraints.constrainHeight(applyStep(childResult, _stepHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null) {
|
||||||
|
BoxConstraints childConstraints = _getInnerConstraints(constraints);
|
||||||
|
if (_stepHeight != null)
|
||||||
|
childConstraints.applyHeight(getMaxIntrinsicHeight(childConstraints));
|
||||||
|
child.layout(childConstraints, parentUsesSize: true);
|
||||||
|
size = child.size;
|
||||||
|
} else {
|
||||||
|
performResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}stepWidth: ${stepWidth}\n${prefix}stepHeight: ${stepHeight}\n';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderOpacity extends RenderProxyBox {
|
||||||
|
RenderOpacity({ RenderBox child, double opacity })
|
||||||
|
: this._opacity = opacity, super(child) {
|
||||||
|
assert(opacity >= 0.0 && opacity <= 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _opacity;
|
||||||
|
double get opacity => _opacity;
|
||||||
|
void set opacity (double value) {
|
||||||
|
assert(value != null);
|
||||||
|
assert(value >= 0.0 && value <= 1.0);
|
||||||
|
if (_opacity == value)
|
||||||
|
return;
|
||||||
|
_opacity = value;
|
||||||
|
_cachedPaint = null;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
int get _alpha => (_opacity * 255).round();
|
||||||
|
|
||||||
|
Paint _cachedPaint;
|
||||||
|
Paint get _paint {
|
||||||
|
if (_cachedPaint == null) {
|
||||||
|
_cachedPaint = new Paint()
|
||||||
|
..color = new Color.fromARGB(_alpha, 0, 0, 0)
|
||||||
|
..setTransferMode(sky.TransferMode.srcOver)
|
||||||
|
..isAntiAlias = false;
|
||||||
|
}
|
||||||
|
return _cachedPaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null) {
|
||||||
|
int a = _alpha;
|
||||||
|
|
||||||
|
if (a == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (a == 255) {
|
||||||
|
context.paintChild(child, offset.toPoint());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.canvas.saveLayer(null, _paint); // TODO(abarth): layerize
|
||||||
|
context.paintChild(child, offset.toPoint());
|
||||||
|
context.canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderColorFilter extends RenderProxyBox {
|
||||||
|
RenderColorFilter({ RenderBox child, Color color, sky.TransferMode transferMode })
|
||||||
|
: _color = color, _transferMode = transferMode, super(child) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _color;
|
||||||
|
Color get color => _color;
|
||||||
|
void set color (Color value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_color == value)
|
||||||
|
return;
|
||||||
|
_color = value;
|
||||||
|
_cachedPaint = null;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
sky.TransferMode _transferMode;
|
||||||
|
sky.TransferMode get transferMode => _transferMode;
|
||||||
|
void set transferMode (sky.TransferMode value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_transferMode == value)
|
||||||
|
return;
|
||||||
|
_transferMode = value;
|
||||||
|
_cachedPaint = null;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
Paint _cachedPaint;
|
||||||
|
Paint get _paint {
|
||||||
|
if (_cachedPaint == null) {
|
||||||
|
_cachedPaint = new Paint()
|
||||||
|
..setColorFilter(new sky.ColorFilter.mode(_color, _transferMode))
|
||||||
|
..isAntiAlias = false;
|
||||||
|
}
|
||||||
|
return _cachedPaint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null) {
|
||||||
|
context.canvas.saveLayer(offset & size, _paint); // TODO(abarth): layerize
|
||||||
|
context.paintChild(child, offset.toPoint());
|
||||||
|
context.canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderClipRect extends RenderProxyBox {
|
||||||
|
RenderClipRect({ RenderBox child }) : super(child);
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null)
|
||||||
|
context.paintChildWithClip(child, offset.toPoint(), Offset.zero & size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderClipRRect extends RenderProxyBox {
|
||||||
|
RenderClipRRect({ RenderBox child, double xRadius, double yRadius })
|
||||||
|
: _xRadius = xRadius, _yRadius = yRadius, super(child) {
|
||||||
|
assert(_xRadius != null);
|
||||||
|
assert(_yRadius != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _xRadius;
|
||||||
|
double get xRadius => _xRadius;
|
||||||
|
void set xRadius (double value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_xRadius == value)
|
||||||
|
return;
|
||||||
|
_xRadius = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
double _yRadius;
|
||||||
|
double get yRadius => _yRadius;
|
||||||
|
void set yRadius (double value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_yRadius == value)
|
||||||
|
return;
|
||||||
|
_yRadius = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Paint _paint = new Paint()..isAntiAlias = false;
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null) {
|
||||||
|
Rect rect = offset & size;
|
||||||
|
context.canvas.saveLayer(rect, _paint); // TODO(abarth): layerize
|
||||||
|
sky.RRect rrect = new sky.RRect()..setRectXY(rect, xRadius, yRadius);
|
||||||
|
context.canvas.clipRRect(rrect);
|
||||||
|
context.paintChild(child, offset.toPoint());
|
||||||
|
context.canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderClipOval extends RenderProxyBox {
|
||||||
|
RenderClipOval({ RenderBox child }) : super(child);
|
||||||
|
|
||||||
|
final Paint _paint = new Paint()..isAntiAlias = false;
|
||||||
|
|
||||||
|
Rect _cachedRect;
|
||||||
|
Path _cachedPath;
|
||||||
|
|
||||||
|
Path _getPath(Rect rect) {
|
||||||
|
if (rect != _cachedRect) {
|
||||||
|
_cachedRect = rect;
|
||||||
|
_cachedPath = new Path()..addOval(_cachedRect);
|
||||||
|
}
|
||||||
|
return _cachedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null) {
|
||||||
|
Rect rect = offset & size;
|
||||||
|
context.canvas.saveLayer(rect, _paint); // TODO(abarth): layerize
|
||||||
|
context.canvas.clipPath(_getPath(rect));
|
||||||
|
context.paintChild(child, offset.toPoint());
|
||||||
|
context.canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderDecoratedBox extends RenderProxyBox {
|
||||||
|
|
||||||
|
RenderDecoratedBox({
|
||||||
|
BoxDecoration decoration,
|
||||||
|
RenderBox child
|
||||||
|
}) : _painter = new BoxPainter(decoration), super(child);
|
||||||
|
|
||||||
|
final BoxPainter _painter;
|
||||||
|
|
||||||
|
BoxDecoration get decoration => _painter.decoration;
|
||||||
|
void set decoration (BoxDecoration value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (value == _painter.decoration)
|
||||||
|
return;
|
||||||
|
_removeBackgroundImageListenerIfNeeded();
|
||||||
|
_painter.decoration = value;
|
||||||
|
_addBackgroundImageListenerIfNeeded();
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get _needsBackgroundImageListener {
|
||||||
|
return attached &&
|
||||||
|
_painter.decoration != null &&
|
||||||
|
_painter.decoration.backgroundImage != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _addBackgroundImageListenerIfNeeded() {
|
||||||
|
if (_needsBackgroundImageListener)
|
||||||
|
_painter.decoration.backgroundImage.addChangeListener(markNeedsPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeBackgroundImageListenerIfNeeded() {
|
||||||
|
if (_needsBackgroundImageListener)
|
||||||
|
_painter.decoration.backgroundImage.removeChangeListener(markNeedsPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach() {
|
||||||
|
super.attach();
|
||||||
|
_addBackgroundImageListenerIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void detach() {
|
||||||
|
_removeBackgroundImageListenerIfNeeded();
|
||||||
|
super.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
assert(size.width != null);
|
||||||
|
assert(size.height != null);
|
||||||
|
_painter.paint(context.canvas, offset & size);
|
||||||
|
super.paint(context, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}decoration:\n${_painter.decoration.toString(prefix + " ")}\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderTransform extends RenderProxyBox {
|
||||||
|
RenderTransform({
|
||||||
|
Matrix4 transform,
|
||||||
|
RenderBox child
|
||||||
|
}) : super(child) {
|
||||||
|
assert(transform != null);
|
||||||
|
this.transform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4 _transform;
|
||||||
|
|
||||||
|
void set transform(Matrix4 value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_transform == value)
|
||||||
|
return;
|
||||||
|
_transform = new Matrix4.copy(value);
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIdentity() {
|
||||||
|
_transform.setIdentity();
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotateX(double radians) {
|
||||||
|
_transform.rotateX(radians);
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotateY(double radians) {
|
||||||
|
_transform.rotateY(radians);
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotateZ(double radians) {
|
||||||
|
_transform.rotateZ(radians);
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void translate(x, [double y = 0.0, double z = 0.0]) {
|
||||||
|
_transform.translate(x, y, z);
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scale(x, [double y, double z]) {
|
||||||
|
_transform.scale(x, y, z);
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hitTest(HitTestResult result, { Point position }) {
|
||||||
|
Matrix4 inverse = new Matrix4.zero();
|
||||||
|
// TODO(abarth): Check the determinant for degeneracy.
|
||||||
|
inverse.copyInverse(_transform);
|
||||||
|
|
||||||
|
Vector3 position3 = new Vector3(position.x, position.y, 0.0);
|
||||||
|
Vector3 transformed3 = inverse.transform3(position3);
|
||||||
|
Point transformed = new Point(transformed3.x, transformed3.y);
|
||||||
|
return super.hitTest(result, position: transformed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
context.canvas.save();
|
||||||
|
context.canvas.translate(offset.dx, offset.dy);
|
||||||
|
context.canvas.concat(_transform.storage);
|
||||||
|
super.paint(context, Offset.zero);
|
||||||
|
context.canvas.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyPaintTransform(Matrix4 transform) {
|
||||||
|
super.applyPaintTransform(transform);
|
||||||
|
transform.multiply(_transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) {
|
||||||
|
List<String> result = _transform.toString().split('\n').map((s) => '$prefix $s\n').toList();
|
||||||
|
result.removeLast();
|
||||||
|
return '${super.debugDescribeSettings(prefix)}${prefix}transform matrix:\n${result.join()}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void SizeChangedCallback(Size newSize);
|
||||||
|
|
||||||
|
class RenderSizeObserver extends RenderProxyBox {
|
||||||
|
RenderSizeObserver({
|
||||||
|
this.callback,
|
||||||
|
RenderBox child
|
||||||
|
}) : super(child) {
|
||||||
|
assert(callback != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
SizeChangedCallback callback;
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
Size oldSize = size;
|
||||||
|
|
||||||
|
super.performLayout();
|
||||||
|
|
||||||
|
if (oldSize != size)
|
||||||
|
callback(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void CustomPaintCallback(PaintingCanvas canvas, Size size);
|
||||||
|
|
||||||
|
class RenderCustomPaint extends RenderProxyBox {
|
||||||
|
|
||||||
|
RenderCustomPaint({
|
||||||
|
CustomPaintCallback callback,
|
||||||
|
RenderBox child
|
||||||
|
}) : super(child) {
|
||||||
|
assert(callback != null);
|
||||||
|
_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomPaintCallback _callback;
|
||||||
|
void set callback (CustomPaintCallback value) {
|
||||||
|
assert(value != null || !attached);
|
||||||
|
if (_callback == value)
|
||||||
|
return;
|
||||||
|
_callback = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
void attach() {
|
||||||
|
assert(_callback != null);
|
||||||
|
super.attach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
assert(_callback != null);
|
||||||
|
context.canvas.translate(offset.dx, offset.dy);
|
||||||
|
_callback(context.canvas, size);
|
||||||
|
// TODO(abarth): We should translate back before calling super because in
|
||||||
|
// the future, super.paint might switch our compositing layer.
|
||||||
|
super.paint(context, Offset.zero);
|
||||||
|
context.canvas.translate(-offset.dx, -offset.dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderIgnorePointer extends RenderProxyBox {
|
||||||
|
RenderIgnorePointer({ RenderBox child }) : super(child);
|
||||||
|
bool hitTest(HitTestResult result, { Point position }) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
238
packages/flutter/lib/rendering/shifted_box.dart
Normal file
238
packages/flutter/lib/rendering/shifted_box.dart
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
// 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 'package:sky/painting/box_painter.dart';
|
||||||
|
import 'package:sky/painting/text_style.dart';
|
||||||
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/box.dart';
|
||||||
|
|
||||||
|
abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
|
||||||
|
|
||||||
|
// Abstract class for one-child-layout render boxes
|
||||||
|
|
||||||
|
RenderShiftedBox(RenderBox child) {
|
||||||
|
this.child = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicWidth(constraints);
|
||||||
|
return super.getMinIntrinsicWidth(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicWidth(constraints);
|
||||||
|
return super.getMaxIntrinsicWidth(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicHeight(constraints);
|
||||||
|
return super.getMinIntrinsicHeight(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicHeight(constraints);
|
||||||
|
return super.getMaxIntrinsicHeight(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double computeDistanceToActualBaseline(TextBaseline baseline) {
|
||||||
|
double result;
|
||||||
|
if (child != null) {
|
||||||
|
assert(!needsLayout);
|
||||||
|
result = child.getDistanceToActualBaseline(baseline);
|
||||||
|
assert(child.parentData is BoxParentData);
|
||||||
|
if (result != null)
|
||||||
|
result += child.parentData.position.y;
|
||||||
|
} else {
|
||||||
|
result = super.computeDistanceToActualBaseline(baseline);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null)
|
||||||
|
context.paintChild(child, child.parentData.position + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hitTestChildren(HitTestResult result, { Point position }) {
|
||||||
|
if (child != null) {
|
||||||
|
assert(child.parentData is BoxParentData);
|
||||||
|
child.hitTest(result, position: new Point(position.x - child.parentData.position.x,
|
||||||
|
position.y - child.parentData.position.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderPadding extends RenderShiftedBox {
|
||||||
|
|
||||||
|
RenderPadding({ EdgeDims padding, RenderBox child }) : super(child) {
|
||||||
|
assert(padding != null);
|
||||||
|
this.padding = padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeDims _padding;
|
||||||
|
EdgeDims get padding => _padding;
|
||||||
|
void set padding (EdgeDims value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_padding == value)
|
||||||
|
return;
|
||||||
|
_padding = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
double totalPadding = padding.left + padding.right;
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicWidth(constraints.deflate(padding)) + totalPadding;
|
||||||
|
return constraints.constrainWidth(totalPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
double totalPadding = padding.left + padding.right;
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicWidth(constraints.deflate(padding)) + totalPadding;
|
||||||
|
return constraints.constrainWidth(totalPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
double totalPadding = padding.top + padding.bottom;
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicHeight(constraints.deflate(padding)) + totalPadding;
|
||||||
|
return constraints.constrainHeight(totalPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
double totalPadding = padding.top + padding.bottom;
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicHeight(constraints.deflate(padding)) + totalPadding;
|
||||||
|
return constraints.constrainHeight(totalPadding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
assert(padding != null);
|
||||||
|
if (child == null) {
|
||||||
|
size = constraints.constrain(new Size(
|
||||||
|
padding.left + padding.right,
|
||||||
|
padding.top + padding.bottom
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BoxConstraints innerConstraints = constraints.deflate(padding);
|
||||||
|
child.layout(innerConstraints, parentUsesSize: true);
|
||||||
|
assert(child.parentData is BoxParentData);
|
||||||
|
child.parentData.position = new Point(padding.left, padding.top);
|
||||||
|
size = constraints.constrain(new Size(
|
||||||
|
padding.left + child.size.width + padding.right,
|
||||||
|
padding.top + child.size.height + padding.bottom
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}padding: ${padding}\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderPositionedBox extends RenderShiftedBox {
|
||||||
|
|
||||||
|
// This box aligns a child box within itself. It's only useful for
|
||||||
|
// children that don't always size to fit their parent. For example,
|
||||||
|
// to align a box at the bottom right, you would pass this box a
|
||||||
|
// tight constraint that is bigger than the child's natural size,
|
||||||
|
// with horizontal and vertical set to 1.0.
|
||||||
|
|
||||||
|
RenderPositionedBox({
|
||||||
|
RenderBox child,
|
||||||
|
double horizontal: 0.5,
|
||||||
|
double vertical: 0.5
|
||||||
|
}) : _horizontal = horizontal,
|
||||||
|
_vertical = vertical,
|
||||||
|
super(child) {
|
||||||
|
assert(horizontal != null);
|
||||||
|
assert(vertical != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _horizontal;
|
||||||
|
double get horizontal => _horizontal;
|
||||||
|
void set horizontal (double value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_horizontal == value)
|
||||||
|
return;
|
||||||
|
_horizontal = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
double _vertical;
|
||||||
|
double get vertical => _vertical;
|
||||||
|
void set vertical (double value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_vertical == value)
|
||||||
|
return;
|
||||||
|
_vertical = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null) {
|
||||||
|
child.layout(constraints.loosen(), parentUsesSize: true);
|
||||||
|
size = constraints.constrain(child.size);
|
||||||
|
assert(child.parentData is BoxParentData);
|
||||||
|
Offset delta = size - child.size;
|
||||||
|
child.parentData.position = (delta.scale(horizontal, vertical)).toPoint();
|
||||||
|
} else {
|
||||||
|
performResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}horizontal: ${horizontal}\n${prefix}vertical: ${vertical}\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderBaseline extends RenderShiftedBox {
|
||||||
|
|
||||||
|
RenderBaseline({
|
||||||
|
RenderBox child,
|
||||||
|
double baseline,
|
||||||
|
TextBaseline baselineType
|
||||||
|
}) : _baseline = baseline,
|
||||||
|
_baselineType = baselineType,
|
||||||
|
super(child) {
|
||||||
|
assert(baseline != null);
|
||||||
|
assert(baselineType != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _baseline;
|
||||||
|
double get baseline => _baseline;
|
||||||
|
void set baseline (double value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_baseline == value)
|
||||||
|
return;
|
||||||
|
_baseline = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBaseline _baselineType;
|
||||||
|
TextBaseline get baselineType => _baselineType;
|
||||||
|
void set baselineType (TextBaseline value) {
|
||||||
|
assert(value != null);
|
||||||
|
if (_baselineType == value)
|
||||||
|
return;
|
||||||
|
_baselineType = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null) {
|
||||||
|
child.layout(constraints.loosen(), parentUsesSize: true);
|
||||||
|
size = constraints.constrain(child.size);
|
||||||
|
assert(child.parentData is BoxParentData);
|
||||||
|
double delta = baseline - child.getDistanceToBaseline(baselineType);
|
||||||
|
child.parentData.position = new Point(0.0, delta);
|
||||||
|
} else {
|
||||||
|
performResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(prefix)}${prefix}baseline: ${baseline}\nbaselineType: ${baselineType}';
|
||||||
|
}
|
@ -4,10 +4,11 @@
|
|||||||
|
|
||||||
import 'dart:sky' as sky;
|
import 'dart:sky' as sky;
|
||||||
|
|
||||||
import 'package:sky/base/scheduler.dart' as scheduler;
|
|
||||||
import 'package:sky/base/hit_test.dart';
|
import 'package:sky/base/hit_test.dart';
|
||||||
|
import 'package:sky/base/scheduler.dart' as scheduler;
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/view.dart';
|
||||||
|
|
||||||
int _hammingWeight(int value) {
|
int _hammingWeight(int value) {
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
|
@ -9,6 +9,7 @@ import 'package:sky/animation/animation_performance.dart';
|
|||||||
import 'package:sky/animation/curves.dart';
|
import 'package:sky/animation/curves.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
|
||||||
typedef void ValueChanged(bool value);
|
typedef void ValueChanged(bool value);
|
||||||
|
|
||||||
|
115
packages/flutter/lib/rendering/view.dart
Normal file
115
packages/flutter/lib/rendering/view.dart
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// 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/rendering/layer.dart';
|
||||||
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/box.dart';
|
||||||
|
import 'package:vector_math/vector_math.dart';
|
||||||
|
|
||||||
|
class ViewConstraints {
|
||||||
|
const ViewConstraints({
|
||||||
|
this.size: Size.zero,
|
||||||
|
this.orientation
|
||||||
|
});
|
||||||
|
final Size size;
|
||||||
|
final int orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> {
|
||||||
|
RenderView({
|
||||||
|
RenderBox child,
|
||||||
|
this.timeForRotation: const Duration(microseconds: 83333)
|
||||||
|
}) {
|
||||||
|
this.child = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size _size = Size.zero;
|
||||||
|
Size get size => _size;
|
||||||
|
|
||||||
|
int _orientation; // 0..3
|
||||||
|
int get orientation => _orientation;
|
||||||
|
Duration timeForRotation;
|
||||||
|
|
||||||
|
ViewConstraints _rootConstraints;
|
||||||
|
ViewConstraints get rootConstraints => _rootConstraints;
|
||||||
|
void set rootConstraints(ViewConstraints value) {
|
||||||
|
if (_rootConstraints == value)
|
||||||
|
return;
|
||||||
|
_rootConstraints = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
ContainerLayer _rootLayer;
|
||||||
|
|
||||||
|
// We never call layout() on this class, so this should never get
|
||||||
|
// checked. (This class is laid out using scheduleInitialLayout().)
|
||||||
|
bool debugDoesMeetConstraints() { assert(false); return false; }
|
||||||
|
|
||||||
|
void performResize() {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (_rootConstraints.orientation != _orientation) {
|
||||||
|
if (_orientation != null && child != null)
|
||||||
|
child.rotate(oldAngle: _orientation, newAngle: _rootConstraints.orientation, time: timeForRotation);
|
||||||
|
_orientation = _rootConstraints.orientation;
|
||||||
|
}
|
||||||
|
_size = _rootConstraints.size;
|
||||||
|
assert(!_size.isInfinite);
|
||||||
|
|
||||||
|
if (child != null)
|
||||||
|
child.layout(new BoxConstraints.tight(_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void rotate({ int oldAngle, int newAngle, Duration time }) {
|
||||||
|
assert(false); // nobody tells the screen to rotate, the whole rotate() dance is started from our performResize()
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hitTest(HitTestResult result, { Point position }) {
|
||||||
|
if (child != null) {
|
||||||
|
Rect childBounds = Point.origin & child.size;
|
||||||
|
if (childBounds.contains(position))
|
||||||
|
child.hitTest(result, position: position);
|
||||||
|
}
|
||||||
|
result.add(new HitTestEntry(this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null)
|
||||||
|
context.paintChild(child, offset.toPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
void paintFrame() {
|
||||||
|
sky.tracing.begin('RenderView.paintFrame');
|
||||||
|
try {
|
||||||
|
final double devicePixelRatio = sky.view.devicePixelRatio;
|
||||||
|
Matrix4 transform = new Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0);
|
||||||
|
_rootLayer = new TransformLayer(transform: transform);
|
||||||
|
PaintingContext context = new PaintingContext(Offset.zero, size);
|
||||||
|
_rootLayer.add(context.layer);
|
||||||
|
context.paintChild(child, Point.origin);
|
||||||
|
context.endRecording();
|
||||||
|
} finally {
|
||||||
|
sky.tracing.end('RenderView.paintFrame');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compositeFrame() {
|
||||||
|
sky.tracing.begin('RenderView.compositeFrame');
|
||||||
|
try {
|
||||||
|
sky.PictureRecorder recorder = new sky.PictureRecorder();
|
||||||
|
sky.Canvas canvas = new sky.Canvas(recorder, Point.origin & (size * sky.view.devicePixelRatio));
|
||||||
|
_rootLayer.paint(canvas);
|
||||||
|
sky.view.picture = recorder.endRecording();
|
||||||
|
} finally {
|
||||||
|
sky.tracing.end('RenderView.compositeFrame');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect get paintBounds => Point.origin & size;
|
||||||
|
}
|
147
packages/flutter/lib/rendering/viewport.dart
Normal file
147
packages/flutter/lib/rendering/viewport.dart
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
// 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/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/box.dart';
|
||||||
|
import 'package:vector_math/vector_math.dart';
|
||||||
|
|
||||||
|
enum ScrollDirection { horizontal, vertical, both }
|
||||||
|
|
||||||
|
class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
|
||||||
|
|
||||||
|
RenderViewport({
|
||||||
|
RenderBox child,
|
||||||
|
Offset scrollOffset,
|
||||||
|
ScrollDirection scrollDirection: ScrollDirection.vertical
|
||||||
|
}) : _scrollOffset = scrollOffset,
|
||||||
|
_scrollDirection = scrollDirection {
|
||||||
|
assert(_offsetIsSane(scrollOffset, scrollDirection));
|
||||||
|
this.child = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _offsetIsSane(Offset offset, ScrollDirection direction) {
|
||||||
|
switch (direction) {
|
||||||
|
case ScrollDirection.both:
|
||||||
|
return true;
|
||||||
|
case ScrollDirection.horizontal:
|
||||||
|
return offset.dy == 0.0;
|
||||||
|
case ScrollDirection.vertical:
|
||||||
|
return offset.dx == 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset _scrollOffset;
|
||||||
|
Offset get scrollOffset => _scrollOffset;
|
||||||
|
void set scrollOffset(Offset value) {
|
||||||
|
if (value == _scrollOffset)
|
||||||
|
return;
|
||||||
|
assert(_offsetIsSane(value, scrollDirection));
|
||||||
|
_scrollOffset = value;
|
||||||
|
markNeedsPaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollDirection _scrollDirection;
|
||||||
|
ScrollDirection get scrollDirection => _scrollDirection;
|
||||||
|
void set scrollDirection(ScrollDirection value) {
|
||||||
|
if (value == _scrollDirection)
|
||||||
|
return;
|
||||||
|
assert(_offsetIsSane(scrollOffset, value));
|
||||||
|
_scrollDirection = value;
|
||||||
|
markNeedsLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxConstraints _getInnerConstraints(BoxConstraints constraints) {
|
||||||
|
BoxConstraints innerConstraints;
|
||||||
|
switch (scrollDirection) {
|
||||||
|
case ScrollDirection.both:
|
||||||
|
innerConstraints = new BoxConstraints();
|
||||||
|
break;
|
||||||
|
case ScrollDirection.horizontal:
|
||||||
|
innerConstraints = constraints.heightConstraints();
|
||||||
|
break;
|
||||||
|
case ScrollDirection.vertical:
|
||||||
|
innerConstraints = constraints.widthConstraints();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return innerConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicWidth(_getInnerConstraints(constraints));
|
||||||
|
return super.getMinIntrinsicWidth(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicWidth(_getInnerConstraints(constraints));
|
||||||
|
return super.getMaxIntrinsicWidth(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMinIntrinsicHeight(_getInnerConstraints(constraints));
|
||||||
|
return super.getMinIntrinsicHeight(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
||||||
|
if (child != null)
|
||||||
|
return child.getMaxIntrinsicHeight(_getInnerConstraints(constraints));
|
||||||
|
return super.getMaxIntrinsicHeight(constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't override computeDistanceToActualBaseline(), because we
|
||||||
|
// want the default behaviour (returning null). Otherwise, as you
|
||||||
|
// scroll the RenderViewport, it would shift in its parent if the
|
||||||
|
// parent was baseline-aligned, which makes no sense.
|
||||||
|
|
||||||
|
void performLayout() {
|
||||||
|
if (child != null) {
|
||||||
|
child.layout(_getInnerConstraints(constraints), parentUsesSize: true);
|
||||||
|
size = constraints.constrain(child.size);
|
||||||
|
assert(child.parentData is BoxParentData);
|
||||||
|
child.parentData.position = Point.origin;
|
||||||
|
} else {
|
||||||
|
performResize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset get _scrollOffsetRoundedToIntegerDevicePixels {
|
||||||
|
double devicePixelRatio = sky.view.devicePixelRatio;
|
||||||
|
int dxInDevicePixels = (scrollOffset.dx * devicePixelRatio).round();
|
||||||
|
int dyInDevicePixels = (scrollOffset.dy * devicePixelRatio).round();
|
||||||
|
return new Offset(dxInDevicePixels / devicePixelRatio,
|
||||||
|
dyInDevicePixels / devicePixelRatio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(PaintingContext context, Offset offset) {
|
||||||
|
if (child != null) {
|
||||||
|
Offset roundedScrollOffset = _scrollOffsetRoundedToIntegerDevicePixels;
|
||||||
|
bool _needsClip = offset < Offset.zero ||
|
||||||
|
!(offset & size).contains(((offset - roundedScrollOffset) & child.size).bottomRight);
|
||||||
|
if (_needsClip) {
|
||||||
|
context.canvas.save();
|
||||||
|
context.canvas.clipRect(offset & size);
|
||||||
|
}
|
||||||
|
context.paintChild(child, (offset - roundedScrollOffset).toPoint());
|
||||||
|
if (_needsClip)
|
||||||
|
context.canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyPaintTransform(Matrix4 transform) {
|
||||||
|
super.applyPaintTransform(transform);
|
||||||
|
transform.translate(-scrollOffset.dx, -scrollOffset.dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hitTestChildren(HitTestResult result, { Point position }) {
|
||||||
|
if (child != null) {
|
||||||
|
assert(child.parentData is BoxParentData);
|
||||||
|
Point transformed = position + _scrollOffsetRoundedToIntegerDevicePixels;
|
||||||
|
child.hitTest(result, position: transformed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,18 +14,24 @@ import 'package:sky/painting/paragraph_painter.dart';
|
|||||||
import 'package:sky/rendering/block.dart';
|
import 'package:sky/rendering/block.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/flex.dart';
|
import 'package:sky/rendering/flex.dart';
|
||||||
|
import 'package:sky/rendering/image.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
import 'package:sky/rendering/paragraph.dart';
|
import 'package:sky/rendering/paragraph.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
|
import 'package:sky/rendering/shifted_box.dart';
|
||||||
import 'package:sky/rendering/stack.dart';
|
import 'package:sky/rendering/stack.dart';
|
||||||
|
import 'package:sky/rendering/viewport.dart';
|
||||||
import 'package:sky/widgets/default_text_style.dart';
|
import 'package:sky/widgets/default_text_style.dart';
|
||||||
import 'package:sky/widgets/framework.dart';
|
import 'package:sky/widgets/framework.dart';
|
||||||
|
|
||||||
export 'package:sky/base/hit_test.dart' show EventDisposition, combineEventDispositions;
|
export 'package:sky/base/hit_test.dart' show EventDisposition, combineEventDispositions;
|
||||||
export 'package:sky/rendering/block.dart' show BlockDirection;
|
export 'package:sky/rendering/block.dart' show BlockDirection;
|
||||||
export 'package:sky/rendering/box.dart' show BackgroundImage, BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims, ScrollDirection;
|
export 'package:sky/rendering/box.dart' show BoxConstraints;
|
||||||
export 'package:sky/rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems;
|
export 'package:sky/rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems;
|
||||||
export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path;
|
export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path;
|
||||||
|
export 'package:sky/rendering/proxy_box.dart' show BackgroundImage, BoxDecoration, BoxShadow, Border, BorderSide, EdgeDims;
|
||||||
export 'package:sky/rendering/toggleable.dart' show ValueChanged;
|
export 'package:sky/rendering/toggleable.dart' show ValueChanged;
|
||||||
|
export 'package:sky/rendering/viewport.dart' show ScrollDirection;
|
||||||
export 'package:sky/widgets/framework.dart' show Key, GlobalKey, Widget, Component, StatefulComponent, App, runApp, Listener, ParentDataNode;
|
export 'package:sky/widgets/framework.dart' show Key, GlobalKey, Widget, Component, StatefulComponent, App, runApp, Listener, ParentDataNode;
|
||||||
|
|
||||||
// PAINTING NODES
|
// PAINTING NODES
|
||||||
|
@ -12,6 +12,7 @@ import 'package:sky/mojo/activity.dart' as activity;
|
|||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
import 'package:sky/rendering/sky_binding.dart';
|
import 'package:sky/rendering/sky_binding.dart';
|
||||||
|
import 'package:sky/rendering/view.dart';
|
||||||
|
|
||||||
export 'package:sky/base/hit_test.dart' show EventDisposition, combineEventDispositions;
|
export 'package:sky/base/hit_test.dart' show EventDisposition, combineEventDispositions;
|
||||||
export 'package:sky/rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims;
|
export 'package:sky/rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims;
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
import 'dart:sky' as sky;
|
import 'dart:sky' as sky;
|
||||||
|
|
||||||
import 'package:sky/rendering/box.dart';
|
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
import 'package:sky/widgets/icon.dart';
|
import 'package:sky/widgets/icon.dart';
|
||||||
import 'package:sky/widgets/framework.dart';
|
import 'package:sky/widgets/framework.dart';
|
||||||
|
@ -10,6 +10,7 @@ import 'package:sky/animation/animation_performance.dart';
|
|||||||
import 'package:sky/animation/curves.dart';
|
import 'package:sky/animation/curves.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/proxy_box.dart';
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
import 'package:sky/widgets/framework.dart';
|
import 'package:sky/widgets/framework.dart';
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import 'package:sky/animation/animated_simulation.dart';
|
|||||||
import 'package:sky/animation/animation_performance.dart';
|
import 'package:sky/animation/animation_performance.dart';
|
||||||
import 'package:sky/animation/scroll_behavior.dart';
|
import 'package:sky/animation/scroll_behavior.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
|
import 'package:sky/rendering/viewport.dart';
|
||||||
import 'package:sky/theme/view_configuration.dart' as config;
|
import 'package:sky/theme/view_configuration.dart' as config;
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
import 'package:sky/widgets/block_viewport.dart';
|
import 'package:sky/widgets/block_viewport.dart';
|
||||||
|
@ -13,6 +13,7 @@ import 'package:sky/animation/scroll_behavior.dart';
|
|||||||
import 'package:sky/painting/text_style.dart';
|
import 'package:sky/painting/text_style.dart';
|
||||||
import 'package:sky/rendering/box.dart';
|
import 'package:sky/rendering/box.dart';
|
||||||
import 'package:sky/rendering/object.dart';
|
import 'package:sky/rendering/object.dart';
|
||||||
|
import 'package:sky/rendering/viewport.dart';
|
||||||
import 'package:sky/theme/colors.dart' as colors;
|
import 'package:sky/theme/colors.dart' as colors;
|
||||||
import 'package:sky/theme/typography.dart' as typography;
|
import 'package:sky/theme/typography.dart' as typography;
|
||||||
import 'package:sky/widgets/basic.dart';
|
import 'package:sky/widgets/basic.dart';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user