This patch adds a new test harness and a first, trivial test to run with the
harness. The new test harness is built on package:test and should run on
Travis. Over time, we'll migrate our existing tests into this harness.
This also changes the way we insert nodes into a
MultiChildRenderObjectWrapper's renderObject, which fixes issue #626.
Now, instead of the slot being a renderObject, it's the Widget that
currently uses that renderObject. That way when the Widget changes
which renderObject to use, the siblings of that Widget in the same
child list don't have to be notified of the change.
I tested performance of the new algorithm vs the old algorithm using
the stocks demo at idle and the stocks demo scrolling steadily. The
data suggests the algorithms are roughly equivalent in performance.
Workaround for Drawer.initState() fails
This is a hack to avoid #715
In theory, the navigator's state should be updated in the event handler that triggers opening the drawer. It's not obvious how to do this, since we only build the Drawer when it's supposed to be visible (and once we're building it's too late).
When laying out positioned children inside a stack, we should give them
unbounded constraints because if they draw outside of the stack, we'll just
clip them.
- Introduce some new Layer classes.
- Introduce paintChildWith* methods.
- Convert paint() methods to use paintChildWith* where appropriate.
- Fix paintBounds logic in Layer world.
- Introduce Layer.replaceWith(), so that it's clearer what's going on.
- Make RenderObjects have a ContainerLayer, not a PictureLayer.
- Introduce a PaintingContext.replacingLayer() constructor to highlight
where we are creating a layer just to replace an older one.
- Rename some layer-related methods and fields for clarity:
requiresCompositing -> hasLayer
hasCompositedDescendant -> needsCompositing
updateCompositing -> updateCompositingBits
_needsCompositingUpdate -> _needsCompositingBitsUpdate
markNeedsCompositingUpdate -> markNeedsCompositingBitsUpdate
- After updating compositing bits, if we find that the bit changed, we
now call markNeedsPaint().
- Reorder markNeedsPaint() logic for clarity.
- Make flushPaint() start at the deepest node.
- Make _compositeChild() avoid repainting children with hasLayer that
aren't dirty, instead it just reuses their existing layer.
- Made RenderView reuse the RenderObject layer instead of having its own.
- Made RenderView have hasLayer set to true.
- Add various asserts and comments.
Changed the pageable_list.dart example: tapping on the toolbar changes
the scroll direction. This exposed some problems:
- Scrollable.syncFields() didn't update scrollDirection
- Viewport updated its RenderObject fields in the wrong order
- FixedHeightScrollable scrollDirection changes didn't update the scrollBehavior
There may be similar problems with VariableHeightList and ScrollableViewport.
I will fix those in a separate CL.
Rather than using a Padding widget to provide padding along the scrolling axis,
we now just figure the padding into where we draw the items. This patch fixes
an issue where we would remove the first topmost item in a scrollable list too
early because we thought it was already off screen.
Fixes#697
- Clarify comment about RenderObjectWrapper.
- Assert that we never sync a RenderObjectWrapper with an instance of a different type.
- Assert that MultiChildRenderObjectWrapper subclasses always have multi-child RenderObjects.
- Assert that renderObject doesn't change identity when syncing.
- Make searchForOldNode() return void since the return value is ignored.
- Remove code that handled renderObject changing during sync.
- PageableList extends ScrollableList
One fixed width or height item is visible and centered at a
time. Fling and drag gestures scroll to the next/previous item.
- Scrollable.scrollTo(), Scrollable.scrollBy(), ensureWidgetIsVisible() API changed
The named animation parameter for these methods was replaced by
duration and curve. All of the methods now return a Future. The Future
completes when the scroll does.
This change eliminates the need for Scrollable to temporarily take ownership
of a ValueAnimation object (see #645).
- Using Future.then() instead of an AnimationPerformance status listener
In ensure_visible.dart _handleTap() uses ensureWidgetIsVisible() to
center the card roughly as before and then. When the implicit scroll
animation is complete, it changes the centered card's label font. The
change is made when the Future returned by ensureWidgetIsVisible()
completes.
- FixedHeightScrollable's itemHeight parameter is now itemExtent
If scrollDirection is ScrollDirection.vertical (the default) then itemExtent should
be the height of each item; otherwise it should be the width of each item.
Replaced _velocityForFlingGesture() in scrollable.dart with Scrollable._eventVelocity()
The original version clamped pixels/ms against pixels/sec constants. The new version
also deals with scrollDirection.
- Plumbed scrollDirection though FixedHeightScrollable and ScrollableList
Both classes should now support horizontal scrolling.
Similar to widgets.dart, rendering.dart exports the entire rendering layer.
Also, update the examples to use rendering.dart and widgets.dart. Also clean up
some exports so that the examples have more sensible imports.
Sadly, box.dart has grown much longer than 1000 lines. This patch splits it up
into several files based on the class hierarchy. Fortunately, many of these
classes are loosely coupled to each other.
When given a null image, RenderImage should be as small as possible (isntead of
being NaNxNaN).
Also, plumb ImageFit and ImageRepeat through the various image widgets.
This CL inflates the padding of Container to account for the borders so that
the borders are allocated space in the layout and don't draw behind the
Container's child.
We now fold the width and height properties into the constraints and try to
find a size for the image that perserves the image's intrinsict aspect ratio
while fitting within the given constraints.
These properties should apply to foreground images as well as background
images. Also, rename these types from BackgroundFit and BackgroundRepeat
because they apply to things other than backgrounds.
... as long as it doesn't have a child. If it has a child, it should size
according to that child. Essentially, if Container doesn't have a child, it
pretends like it has a child that expands to fill its constraints.