This introduces a GlobalKey registry so that you can tell when a key
has gone away (so you can unfocus dead dialogs).
Also I added an assert that you're not calling setState() during a
build. It turns out that doing so means you have a bug, because since
you're dirty already (you're building), you won't get rebuilt.
The focus code itself is gnarly. It uses a Component and an internal
Inherited TagNode to manage the focus state, and does crazy things
like updating its state during build to pretend retroactively that it
was built with some other state, once someone asks for focus the first
time (i.e. the first time it's examined, so you can't tell that it was
in a different state before). It does this so that it can autofocus
controls which otherwise wouldn't be focused.
This moves all the focus management into Navigator and showDialog(),
so the complexity is all buried deep and not visible to apps,
hopefully.
To do something like two tabs that each have an Input widget that
needs to be focused when you switch panes, you'd need to have two
Focus objects, one in each tab, and you need to set their autofocus to
true (maybe that should be the default?).
This removes the need to manually include the dialog builder in the main window's build() function.
It also removes the need to track if a dialog is visible.
Other changes:
- I made dialog.dart a bit more readable.
- I renamed transitionFinished to fullyOpaque since that's what actually matters.
- I made Routes track if they're opaque. Eventually this should probably be more configurable when creating the route.
Directions for Future Research:
- Use this for focus management somehow.
- The popup menu should use something like this.
- We should factor the following out into a showDialog() function that returns a future for the dialog's exit result:
navigator.push(new DialogRoute(builder: (navigator, route) { ... }));
- Maybe navigator.pop() should take a value to return to that Future.
Converted demo launcher example to library
Converted fitness example to library
Converted hello world example to library
Converted mine digger example to library
Converted stocks example to library
The workbench package exists to pull in pub packages from both pub.dartlang.org
and from the source tree (using dependency overrides). The idea is that
workbench will reflect a typical Sky developer's environment so that we can use
the same tools as a typical sky developer by running them with the workbench as
the cwd.
This CL introduces a SkyShell.apk that is separate from the SkyDemo.apk that we
upload to the store to show our demos. The SkyShell.apk is just an empty shell
that can run Sky applications on Android.
I've noticed an anti-pattern emerge where people call scheduleBuild()
when they think they've changed enough state that they should rebuild,
instead of just wrapping their changes in setState(). This leads to
them missing state changes, having extraneous scheduleBuild() calls,
and other similar bugs.
By removing scheduleBuild(), the only way to actually schedule a build
now is to call setState(), and hopefully that'll make it much clearer
that you're only supposed to do this when you change state.
Assert that there are no duplicates.
Export GlobalKey from basic.dart, so that people don't have to import widgets.dart just for that.
Fix the "initialFocus" feature which actually didn't work.
This is supposed to make Viktor's game faster, but it's not clear
to me that it actually does. I've left the code
using the dart version of drawAtlas for now until Viktor can
verify that it looks correct.
I also added a wrapper for SkFilterQuality in the process of
debugging SkCanvas.drawAtlas since all drawAtlas examples
in Skia use FilterQuality.low. The bug which blocked me for
so long turned out to be that SkCanvas.drawAtlas doesn't
draw anything if antialiasing is turned on.
Issue #138.
R=abarth@google.com