Initial snap offset support for ScrollableWidgetList (and ScrollableList<T>) and ScrollableMixedWidgetList. If a ```toSnapOffset(scrollOffset)``` function is provided, fling Scrolls will coast to the returned value. If ```alignmentOffset``` is specified then fling scrolls conclude when toSnapOffset's value lines up with the Scrollable widget's origin + alignmentOffset. For example if the Scrollable widget's height was 200.0, and alignmentOffset:100.0 was specified, then fling scrolls would end with the value returned by toSnapOffset() lined up with the center of the Scrollable.
This approach to Scrollable snapping assumes that the layout of whatever the Scrollable contains is known at the outset. This is often true however a ScrollableMixedWidgetList may not know its items' sizes until they've been reached by scrolling.
This is a first cut at snapping support. Among the things that remain to be done:
- Scrolling limits trump snapping. Snapping should probably trump scrolling limits.
- Drag scrolls aren't snapped. This may be desirable so perhaps the feature should be controlled with a flag.
- Specifying alignmentOffset as a percentage would probably be more convenient.
- It would be nice if one could wrap items in a SnapOffset value like: ```new SnapOffset(0.5, child: myItem)``` to snap to the center of the item.
Updated the CardCollection example: snapping and fixed size items can be turned on/off with Drawer checkboxes.
Also, introduce Colors and Typography to hold the material colors and the
typography declarations. Previously we expected clients of these libraries to
import them into a namespace, but that doesn't play nice with re-exporting them
from material.dart.
Move the animation libraries into src/animation and change importers to use
package:sky/animation.dart. Also, move scheduler.dart into the animation
library so that the animation library can be self-contained.
Turns out many of the functions on BoxConstraints weren't used or had callers
that could easily be updated to other functions. I've added dartdoc to all the
public functions as well as renamed some functions that had similar names but
did different things.
```
enum DismissDirection {
vertical,
horizontal,
left,
right,
up,
down
}
```
To only enable dismissing to the right create the `Dismissable` with `direction: DismissDirection.right`. By default direction is `DismissDirection.horizontal` (left or right).
Updated the card_collection "Swipe Away" demo with a drawer that can be used to select one of the three X axis dismiss directions. Currently the MixedViewport class doesn't support horizontal scrolling, so the demo doesn't support the X axis dismiss directions.
Add a way of having keys based on numeric types or DateTimes by having a ValueKey<T> class.
Remove the redundant ways of declaring things, except for leaving one shorthand -- you can say `new Key(s)` instead of `new ValueKey<String>(s)`.
This still leaves Flex and FlexDirection available. At some point once
people have transitioned to Row/Column we should rename Flex to _Flex
and stop reexporting FlexDirection from basic.dart.
Adds itemsWrap:bool (default false) to ScrollableList and PageableList. If itemsWrap is true then scrolling past the last item wraps around to the first. Similarly, scrolling before the first item wraps around to the last.
Added abstract ExtentScrollBehavior of ScrollBehavior. Renamed fields called contentsExtents to contentExtent, containerExtents to containerExtent, contentSize to contentExtent, etc.
BoundedBehavior is now a subclass of ExtentScrollBehavior.
Added UnboundedBehavior subclass of ExtentScrollBehvaior; contentExtent and maxScrollOffset are double.INFINITY, minScrollExtent is double.NEGATIVE_INFINITY.
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.
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.
- 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.
We had a remarkable number of analyzer failures.
I'll fix the bots to analyze across the whole project
in a follow-up patch, that should prevent this
in the future.
@abarth
Widgets that want to receive drops should include a DropTarget in their build.
Currently there's no widget for initiating a drag. Components can use the
DragController directly. In the future, we'll probably want to add a Draggable
that knows how to do some of this work automatically.
Fixes#612
Setting a ProgressIndicator's value to null (the default) makes it an "indeterminate progress" or activity indicator.
The indeterminate animations for both kinds of progress bars are essentially the same and wrong vis the Material Design spec, http://www.google.com/design/spec/components/progress-activity.html. I'll improve conformity with the visual design in a future CL.
Set the scrollOffset of a widget's Scrollable ancestor so that the
widget is centered within the scrollable. A future CL will add
support for specifying exactly where the widget appears. The scroll
can be animated by specifying the animation: parameter.
Changed the duration Scrollable.scrollTo() parameter from a Duration
to an AnimationPerformance so that one can configure all aspects of
the animation. The caller may also listen to the animation to schedule
other work while it updates or when its status changes.
complete
Added a ScrollListener listener to Scrollable. The ScrollListener runs each time the Scrollable's scrollOffset changes. This can be used to keep overlay widgets in sync with a Scrollable below them.
Removed the Scrollable ScrollClient API. It was no longer used and was clumsy to use as a ScrollListener.
Added global function findScrollableAncestor() to scrollable.dart.
Added examples/widgets/overlay_geometry.dart. The app's Scaffold is contained by a Stack. The Stack is used to display green overlay "Markers" at the corners of the most recently selected list item and where the corresponding tap occurred. The app uses widget.localToGlobal() to compute the global overlay positions of the markers. The ScrollListener is used to keep the markers' positions up to date.
Currently you lose your scroll and drawer state when coming back from the settings pane.
I think we should solve this by having the Navigator maintain a Stack and
keeping the StockHome alive underneath it. But this is good enough for a first iteration.
R=abarth@chromium.org, abarth
Review URL: https://codereview.chromium.org/1191153002.
tree of InlineStyle and InlineText elements.
StyledText builds an Inline that renders the tree.
For example this StyledText object:
new StyledText(["FOO", [boldLargerStyle, [greenStyle "BAR"], "BAZ"] BORF]);
Renders the same way the following HTML would,
assuming that TextStyles boldLargerStyle and
greenStyle were defined.
<style>
div {
display: inline;
}
</style>
<p>
<div>
FOO
<div style="font-weight:bold; font-size:larger">
<div style="color:green">
BAR
</div>
BAZ
</div>
BORF
</div>
</p>
R=abarth@chromium.org
Review URL: https://codereview.chromium.org/1194693002.
Some files are moved by this:
Copy framework/node.dart into types/ - preparing for framework/'s decomissioning.
Move app/scheduler.dart into sky/scheduler.dart - "app" doesn't really make sense.
As part of the SkyBinding cleanup, I made the hit-testing less
RenderBox-specific, by having the HitTestEntry.target member be a
HitTestTarget, which is an interface with the handleEvent() function,
which is then implemented by RenderBox. In theory, someone could now
extend hit testing from the RenderBox world into their own tree of
nodes, and take part in all the same dispatch logic automatically.
This involved moving all the hit testing type definitions into a new
sky/hittest.dart file.
Renamed SkyBinding._app to SkyBinding._instance for clarity.
Moved code around in SkyBinding so that related things are together.
Made WidgetSkyBinding use the existing SkyBinding.instance singleton
logic rather than having its own copy.
I also added some stub README.md files that describe dependencies.
R=abarth@chromium.org
Review URL: https://codereview.chromium.org/1187393002.
Move app/view.dart to rendering/sky_binding.dart since it's part of the RenderObject API, really (it knows about RenderView intimately).
The tests pass. I didn't check every last example.
R=abarth@chromium.org
Review URL: https://codereview.chromium.org/1183913006.
This also moves the test for stocks into a new tests/examples/
directory, where we can put tests that test the examples.
TBR=abarth
Review URL: https://codereview.chromium.org/1182223004.
The underlying problem is that we lacked a RenderObjectWrapper for the
RenderView, which meant we couldn't handle changing the RenderObject that was
the root of the RenderView. This CL introduces a RenderViewWrapper and uses it
in a new AppContainer widget root. This change allows us to make App a
non-magical Component that is inserted into the AppContainer in the newly
introduced runApp function.
R=ianh@google.com
Review URL: https://codereview.chromium.org/1184823006.
Sector changes:
- implement the intrinsic sizing box API on RenderBoxToRenderSectorAdapter
- remove some debug print statements
- fix getIntrinsicDimensions() on RenderSolidColor to return true values
- factor out the default demo
RenderObject changes:
- BoxConstraints.isInfinite() now returns true only if both dimensions are infinite
fn changes:
- implement UINodeToRenderBoxAdapter
- rename RenderObjectToUINodeAdapter to RenderBoxToUINodeAdapter
Tests:
- add a test for sector layout
- make TestRenderView support being run without the unit test framework
R=abarth@chromium.org
Review URL: https://codereview.chromium.org/1175423007.
Make Material actually create material, with opinions about what that
means.
Make FloatingActionButton use this.
Make Scrollable use this.
Make BoxDecoration support drawing a circle instead of a rectangle, so
that floating action button doesn't need a custom painter.
Implement RaisedButton (and remove button.dart, since there's no
"button" in Material Design).
Make InkWell have a "child" argument instead of "children", and not
have it introduce a Flex into the hierarchy.
Update container.dart example. Clean up some imports.
R=abarth@chromium.org
Review URL: https://codereview.chromium.org/1179713004.
This moves input.dart to editing2/, since that way we can define the layering as strictly unidirectional.
It also reorders a bunch of imports to fit the style guide.
I removed the old remnants of the widgets example, and put the fn2 examples into the examples/widgets/ directory, to parallel the framework directory names.
R=abarth@chromium.org
Review URL: https://codereview.chromium.org/1177243002.
This CL updates sky-box, sky-button, sky-checkbox, sky-input, and sky-radio to
work in Dart. We don't have a data binding system yet, so there's a bit more
plumbing in the code.
This CL adds support for sky-element@attributes, which lets you specify which
attributes your element supports. We use this information to synthesize getters
and setters for those attributes and to dispatch to mumbleChanged methods when
the attributes change.
I've also wrapped the widgets demo itself in a sky-scrollable so the whole
thing scrolls.
R=eseidel@chromium.org
Review URL: https://codereview.chromium.org/946813005
Instead of having a separate directory for every Sky element, we should just
put them in the general framework directory. Once the framework is more
complicated, we'll probably want to organize it a bit better, but for now there
aren't enough files to justify having so many directories.
R=esprehn@chromium.org
Review URL: https://codereview.chromium.org/874303003
We were cloning elements with all the attributes that contained
expressions like attrName="{{ foo }}" which meant we'd go through the
reflection process converting that value and also call the
attrNameChanged() callback and the attributeChanged() with the braced
string which the element didn't really want to know about.
After this patch we create a "clone source node" which is a copy of the
original element without the attributes that have the expressions and
use that when cloning, then we assign the properties using data binding
later.
R=abarth@chromium.org, ojan@chromium.org
Review URL: https://codereview.chromium.org/868973002
All reflected attributes two way bind on SkyElement, so now doing
<sky-element name="sky-input" attributes="value:string"> is enough
to get two way binding on the value attribute so users doing
<sky-input value="{{ inputValue }}"> will get the inputValue property
updated as the user types.
R=abarth@chromium.org, ojan@chromium.org
Review URL: https://codereview.chromium.org/850383002
Log an error whenever an element has an unknown attribute in a template.
This means you can't use generic attributes like Polymer, but we
probably want to discourage that anyway since attribute selectors should
be avoided for most things.
R=ojan@chromium.org
Review URL: https://codereview.chromium.org/845523004
Now inside the <template> of a SkyElement you can use
on-eventName="method" on any element to add event listeners.
For example you can write <sky-button on-click="handleClick">
and then define handleClick(event) on the element class that
contains the button.
In adding this and tests I also realized that property bindings
were not setup on the initial call to bind(), which is now
fixed in this patch (See change to Node.prototype.bind).
R=eseidel@google.com, rafaelw@chromium.org
Review URL: https://codereview.chromium.org/812713005
Eventually we'll want to replace these with something
fancier like polymer, but this exercise helped us
find several bugs in the engine as well as
removed one more blocker from using Sky to
replace mojo/views usage in mojo/examples.
R=esprehn@chromium.org
BUG=443439
Review URL: https://codereview.chromium.org/809233002