Greg Spencer 4218c0bc38
Implement focus traversal for desktop platforms, shoehorn edition. (#30040)
Implements focus traversal for desktop platforms, including re-implementing the existing focus manager and focus tree.

This implements a Focus widget that can be put into a widget tree to allow input focus to be given to a particular part of a widget tree.

It incorporates with the existing FocusScope and FocusNode infrastructure, and has minimal breakage to the API, although FocusScope.reparentIfNeeded is removed, replaced by a call to FocusAttachment.reparent(), so this is a breaking change:

FocusScopeNodes must now be attached to the focus tree using FocusScopeNode.attach, which takes a context and an optional onKey callback, and returns a FocusAttachment that should be kept by the widget that hosts the FocusScopeNode. This is necessary because of the need to make sure that the focus tree reflects the widget hierarchy.

Callers that used to call FocusScope(context).reparentIfNeeded in their build method will call reparent  on a FocusAttachment instead, which they will obtain by calling FocusScopeNode.attach in their initState method. Widgets that own FocusNodes will need to call dispose on the focus node in their dispose method.

Addresses #11344, #1608, #13264, and #1678
Fixes #30084
Fixes #26704
2019-04-22 09:51:40 -07:00
..
2019-03-01 08:17:55 +01:00

Snippet Tool

This is a dartdoc extension tool that takes code snippets and expands how they are presented so that Flutter can have more interactive and useful code snippets.

This takes code in dartdocs, like this:

/// {@tool snippet --template="stateless_widget"}
/// The following is a skeleton of a stateless widget subclass called `GreenFrog`.
/// ```dart
/// class GreenFrog extends StatelessWidget {
///   const GreenFrog({ Key key }) : super(key: key);
///
///   @override
///   Widget build(BuildContext context) {
///     return Container(color: const Color(0xFF2DBD3A));
///   }
/// }
/// ```
/// {@end-tool}

And converts it into something which has a nice visual presentation, and a button to automatically copy the sample to the clipboard.

It does this by processing the source input and emitting HTML for output, which dartdoc places back into the documentation. Any options given to the {@tool ...} directive are passed on verbatim to the tool.

To render the above, the snippets tool needs to render the code in a combination of markdown and HTML, using the {@inject-html} dartdoc directive.

Templates

In order to support showing an entire app when you click on the right tab of the code snippet UI, we have to be able to insert the snippet into the template and instantiate the right parts.

To do this, there is a config/templates directory that contains a list of templates. These templates represent an entire app that the snippet can be placed into, basically a replacement for lib/main.dart in a flutter app package.

Skeletons

A skeleton (in relation to this tool, in the config/skeletons directory) is an HTML template into which the snippet Dart code and description are interpolated, in order to display it nicely.

There is currently one skeleton for application snippets and one for sample snippets, but there could be more. It uses moustache notation (e.g. {{code}}) to mark where the components to be interpolated into the template should go.

(It doesn't actually use the moustache package, since the only things that need substituting are simple strings, but it uses the same syntax).