// Copyright 2014 The Flutter 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:flutter/foundation.dart';

import 'basic.dart';
import 'focus_manager.dart';
import 'framework.dart';
import 'inherited_notifier.dart';

/// A widget that manages a [FocusNode] to allow keyboard focus to be given
/// to this widget and its descendants.
///
/// When the focus is gained or lost, [onFocusChanged] is called.
///
/// For keyboard events, [onKey] is called if [FocusNode.hasFocus] is true for
/// this widget's [focusNode], unless a focused descendant's [onKey] callback
/// returns false when called.
///
/// This widget does not provide any visual indication that the focus has
/// changed. Any desired visual changes should be made when [onFocusChanged] is
/// called.
///
/// To access the [FocusNode] of the nearest ancestor [Focus] widget and
/// establish a relationship that will rebuild the widget when the focus
/// changes, use the [Focus.of] and [FocusScope.of] static methods.
///
/// To access the focused state of the nearest [Focus] widget, use
/// [Focus.hasFocus] from a build method, which also establishes a relationship
/// between the calling widget and the [Focus] widget that will rebuild the
/// calling widget when the focus changes.
///
/// Managing a [FocusNode] means managing its lifecycle, listening for changes
/// in focus, and re-parenting it when needed to keep the focus hierarchy in
/// sync with the widget hierarchy. This widget does all of those things for
/// you. See [FocusNode] for more information about the details of what node
/// management entails if you are not using a [Focus] widget and you need to do
/// it yourself.
///
/// To collect a sub-tree of nodes into an exclusive group that restricts focus
/// traversal to the group, use a [FocusScope]. To collect a sub-tree of nodes
/// into a group that has a specific order to its traversal but allows the
/// traversal to escape the group, use a [FocusTraversalGroup].
///
/// To move the focus, use methods on [FocusNode] by getting the [FocusNode]
/// through the [of] method. For instance, to move the focus to the next node in
/// the focus traversal order, call `Focus.of(context).nextFocus()`. To unfocus
/// a widget, call `Focus.of(context).unfocus()`.
///
/// {@tool dartpad --template=stateful_widget_scaffold}
/// This example shows how to manage focus using the [Focus] and [FocusScope]
/// widgets. See [FocusNode] for a similar example that doesn't use [Focus] or
/// [FocusScope].
///
/// ```dart imports
/// import 'package:flutter/services.dart';
/// ```
///
/// ```dart
/// Color _color = Colors.white;
///
/// bool _handleKeyPress(FocusNode node, RawKeyEvent event) {
///   if (event is RawKeyDownEvent) {
///     print('Focus node ${node.debugLabel} got key event: ${event.logicalKey}');
///     if (event.logicalKey == LogicalKeyboardKey.keyR) {
///       print('Changing color to red.');
///       setState(() {
///         _color = Colors.red;
///       });
///       return true;
///     } else if (event.logicalKey == LogicalKeyboardKey.keyG) {
///       print('Changing color to green.');
///       setState(() {
///         _color = Colors.green;
///       });
///       return true;
///     } else if (event.logicalKey == LogicalKeyboardKey.keyB) {
///       print('Changing color to blue.');
///       setState(() {
///         _color = Colors.blue;
///       });
///       return true;
///     }
///   }
///   return false;
/// }
///
/// @override
/// Widget build(BuildContext context) {
///   final TextTheme textTheme = Theme.of(context).textTheme;
///   return FocusScope(
///     debugLabel: 'Scope',
///     autofocus: true,
///     child: DefaultTextStyle(
///       style: textTheme.headline4,
///       child: Focus(
///         onKey: _handleKeyPress,
///         debugLabel: 'Button',
///         child: Builder(
///           builder: (BuildContext context) {
///             final FocusNode focusNode = Focus.of(context);
///             final bool hasFocus = focusNode.hasFocus;
///             return GestureDetector(
///               onTap: () {
///                 if (hasFocus) {
///                   focusNode.unfocus();
///                 } else {
///                   focusNode.requestFocus();
///                 }
///               },
///               child: Center(
///                 child: Container(
///                   width: 400,
///                   height: 100,
///                   alignment: Alignment.center,
///                   color: hasFocus ? _color : Colors.white,
///                   child: Text(hasFocus ? "I'm in color! Press R,G,B!" : 'Press to focus'),
///                 ),
///               ),
///             );
///           },
///         ),
///       ),
///     ),
///   );
/// }
/// ```
/// {@end-tool}
///
/// {@tool dartpad --template=stateless_widget_material}
/// This example shows how to wrap another widget in a [Focus] widget to make it
/// focusable. It wraps a [Container], and changes the container's color when it
/// is set as the [FocusManager.primaryFocus].
///
/// If you also want to handle mouse hover and/or keyboard actions on a widget,
/// consider using a [FocusableActionDetector], which combines several different
/// widgets to provide those capabilities.
///
/// ```dart preamble
/// class FocusableText extends StatelessWidget {
///   const FocusableText(this.data, {Key key, this.autofocus}) : super(key: key);
///
///   /// The string to display as the text for this widget.
///   final String data;
///
///   /// Whether or not to focus this widget initially if nothing else is focused.
///   final bool autofocus;
///
///   @override
///   Widget build(BuildContext context) {
///     return Focus(
///       autofocus: autofocus,
///       child: Builder(builder: (BuildContext context) {
///         // The contents of this Builder are being made focusable. It is inside
///         // of a Builder because the builder provides the correct context
///         // variable for Focus.of() to be able to find the Focus widget that is
///         // the Builder's parent. Without the builder, the context variable used
///         // would be the one given the FocusableText build function, and that
///         // would start looking for a Focus widget ancestor of the FocusableText
///         // instead of finding the one inside of its build function.
///         return Container(
///           padding: EdgeInsets.all(8.0),
///           // Change the color based on whether or not this Container has focus.
///           color: Focus.of(context).hasPrimaryFocus ? Colors.black12 : null,
///           child: Text(data),
///         );
///       }),
///     );
///   }
/// }
/// ```
///
/// ```dart
/// Widget build(BuildContext context) {
///   return Scaffold(
///     body: ListView.builder(
///       itemBuilder: (context, index) => FocusableText(
///         'Item $index',
///         autofocus: index == 0,
///       ),
///       itemCount: 50,
///     ),
///   );
/// }
/// ```
/// {@end-tool}
///
/// {@tool dartpad --template=stateful_widget_material}
/// This example shows how to focus a newly-created widget immediately after it
/// is created.
///
/// The focus node will not actually be given the focus until after the frame in
/// which it has requested focus is drawn, so it is OK to call
/// [FocusNode.requestFocus] on a node which is not yet in the focus tree.
///
/// ```dart
/// int focusedChild = 0;
/// List<Widget> children = <Widget>[];
/// List<FocusNode> childFocusNodes = <FocusNode>[];
///
/// @override
/// void initState() {
///   super.initState();
///   // Add the first child.
///   _addChild();
/// }
///
/// @override
/// void dispose() {
///   super.dispose();
///   childFocusNodes.forEach((FocusNode node) => node.dispose());
/// }
///
/// void _addChild() {
///   // Calling requestFocus here creates a deferred request for focus, since the
///   // node is not yet part of the focus tree.
///   childFocusNodes
///       .add(FocusNode(debugLabel: 'Child ${children.length}')..requestFocus());
///
///   children.add(Padding(
///     padding: const EdgeInsets.all(2.0),
///     child: ActionChip(
///       focusNode: childFocusNodes.last,
///       label: Text('CHILD ${children.length}'),
///       onPressed: () {},
///     ),
///   ));
/// }
///
/// @override
/// Widget build(BuildContext context) {
///   return Scaffold(
///     body: Center(
///       child: Wrap(
///         children: children,
///       ),
///     ),
///     floatingActionButton: FloatingActionButton(
///       onPressed: () {
///         setState(() {
///           focusedChild = children.length;
///           _addChild();
///         });
///       },
///       child: Icon(Icons.add),
///     ),
///   );
/// }
/// ```
/// {@end-tool}
///
/// See also:
///
///  * [FocusNode], which represents a node in the focus hierarchy and
///    [FocusNode]'s API documentation includes a detailed explanation of its role
///    in the overall focus system.
///  * [FocusScope], a widget that manages a group of focusable widgets using a
///    [FocusScopeNode].
///  * [FocusScopeNode], a node that collects focus nodes into a group for
///    traversal.
///  * [FocusManager], a singleton that manages the primary focus and
///    distributes key events to focused nodes.
///  * [FocusTraversalPolicy], an object used to determine how to move the focus
///    to other nodes.
///  * [FocusTraversalGroup], a widget that groups together and imposes a
///    traversal policy on the [Focus] nodes below it in the widget hierarchy.
class Focus extends StatefulWidget {
  /// Creates a widget that manages a [FocusNode].
  ///
  /// The [child] argument is required and must not be null.
  ///
  /// The [autofocus] argument must not be null.
  const Focus({
    Key key,
    @required this.child,
    this.focusNode,
    this.autofocus = false,
    this.onFocusChange,
    this.onKey,
    this.debugLabel,
    this.canRequestFocus,
    this.descendantsAreFocusable = true,
    this.skipTraversal,
    this.includeSemantics = true,
  })  : assert(child != null),
        assert(autofocus != null),
        assert(descendantsAreFocusable != null),
        assert(includeSemantics != null),
        super(key: key);

  /// A debug label for this widget.
  ///
  /// Not used for anything except to be printed in the diagnostic output from
  /// [toString] or [toStringDeep]. Also unused if a [focusNode] is provided,
  /// since that node can have its own [FocusNode.debugLabel].
  ///
  /// To get a string with the entire tree, call [debugDescribeFocusTree]. To
  /// print it to the console call [debugDumpFocusTree].
  ///
  /// Defaults to null.
  final String debugLabel;

  /// The child widget of this [Focus].
  ///
  /// {@macro flutter.widgets.child}
  final Widget child;

  /// Handler for keys pressed when this object or one of its children has
  /// focus.
  ///
  /// Key events are first given to the [FocusNode] that has primary focus, and
  /// if its [onKey] method return false, then they are given to each ancestor
  /// node up the focus hierarchy in turn. If an event reaches the root of the
  /// hierarchy, it is discarded.
  ///
  /// This is not the way to get text input in the manner of a text field: it
  /// leaves out support for input method editors, and doesn't support soft
  /// keyboards in general. For text input, consider [TextField],
  /// [EditableText], or [CupertinoTextField] instead, which do support these
  /// things.
  final FocusOnKeyCallback onKey;

  /// Handler called when the focus changes.
  ///
  /// Called with true if this widget's node gains focus, and false if it loses
  /// focus.
  final ValueChanged<bool> onFocusChange;

  /// {@template flutter.widgets.Focus.autofocus}
  /// True if this widget will be selected as the initial focus when no other
  /// node in its scope is currently focused.
  ///
  /// Ideally, there is only one widget with autofocus set in each [FocusScope].
  /// If there is more than one widget with autofocus set, then the first one
  /// added to the tree will get focus.
  ///
  /// Must not be null. Defaults to false.
  /// {@endtemplate}
  final bool autofocus;

  /// {@template flutter.widgets.Focus.focusNode}
  /// An optional focus node to use as the focus node for this widget.
  ///
  /// If one is not supplied, then one will be automatically allocated, owned,
  /// and managed by this widget. The widget will be focusable even if a
  /// [focusNode] is not supplied. If supplied, the given `focusNode` will be
  /// _hosted_ by this widget, but not owned. See [FocusNode] for more
  /// information on what being hosted and/or owned implies.
  ///
  /// Supplying a focus node is sometimes useful if an ancestor to this widget
  /// wants to control when this widget has the focus. The owner will be
  /// responsible for calling [FocusNode.dispose] on the focus node when it is
  /// done with it, but this widget will attach/detach and reparent the node
  /// when needed.
  /// {@endtemplate}
  final FocusNode focusNode;

  /// Sets the [FocusNode.skipTraversal] flag on the focus node so that it won't
  /// be visited by the [FocusTraversalPolicy].
  ///
  /// This is sometimes useful if a [Focus] widget should receive key events as
  /// part of the focus chain, but shouldn't be accessible via focus traversal.
  ///
  /// This is different from [canRequestFocus] because it only implies that the
  /// widget can't be reached via traversal, not that it can't be focused. It may
  /// still be focused explicitly.
  final bool skipTraversal;

  /// Include semantics information in this [Focus] widget.
  ///
  /// If true, this [Focus] widget will include a [Semantics] node that
  /// indicates the [Semantics.focusable] and [Semantics.focused] properties.
  ///
  /// It is not typical to set this to false, as that can affect the semantics
  /// information available to accessibility systems.
  ///
  /// Must not be null, defaults to true.
  final bool includeSemantics;

  /// {@template flutter.widgets.Focus.canRequestFocus}
  /// If true, this widget may request the primary focus.
  ///
  /// Defaults to true.  Set to false if you want the [FocusNode] this widget
  /// manages to do nothing when [requestFocus] is called on it. Does not affect
  /// the children of this node, and [FocusNode.hasFocus] can still return true
  /// if this node is the ancestor of the primary focus.
  ///
  /// This is different than [skipTraversal] because [skipTraversal] still
  /// allows the widget to be focused, just not traversed to.
  ///
  /// Setting [canRequestFocus] to false implies that the widget will also be
  /// skipped for traversal purposes.
  ///
  /// See also:
  ///
  ///  * [DefaultFocusTraversal], a widget that sets the traversal policy for
  ///    its descendants.
  ///  * [FocusTraversalPolicy], a class that can be extended to describe a
  ///    traversal policy.
  /// {@endtemplate}
  final bool canRequestFocus;

  /// {@template flutter.widgets.Focus.descendantsAreFocusable}
  /// If false, will make this widget's descendants unfocusable.
  ///
  /// Defaults to true. Does not affect focusability of this node (just its
  /// descendants): for that, use [canRequestFocus].
  ///
  /// If any descendants are focused when this is set to false, they will be
  /// unfocused. When `descendantsAreFocusable` is set to true again, they will
  /// not be refocused, although they will be able to accept focus again.
  ///
  /// Does not affect the value of [canRequestFocus] on the descendants.
  ///
  /// See also:
  ///
  ///  * [ExcludeFocus], a widget that uses this property to conditionally
  ///    exclude focus for a subtree.
  ///  * [FocusTraversalGroup], a widget used to group together and configure
  ///    the focus traversal policy for a widget subtree that has a
  ///    `descendantsAreFocusable` parameter to conditionally block focus for a
  ///    subtree.
  /// {@endtemplate}
  final bool descendantsAreFocusable;

  /// Returns the [focusNode] of the [Focus] that most tightly encloses the
  /// given [BuildContext].
  ///
  /// If no [Focus] node is found before reaching the nearest [FocusScope]
  /// widget, or there is no [Focus] widget in scope, then this method will
  /// throw an exception. To return null instead of throwing, pass true for
  /// [nullOk].
  ///
  /// The [context] and [nullOk] arguments must not be null.
  ///
  /// Calling this function creates a dependency that will rebuild the given
  /// context when the focus changes.
  static FocusNode of(BuildContext context, { bool nullOk = false, bool scopeOk = false }) {
    assert(context != null);
    assert(nullOk != null);
    assert(scopeOk != null);
    final _FocusMarker marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>();
    final FocusNode node = marker?.notifier;
    if (node == null) {
      if (!nullOk) {
        throw FlutterError(
          'Focus.of() was called with a context that does not contain a Focus widget.\n'
          'No Focus widget ancestor could be found starting from the context that was passed to '
          'Focus.of(). This can happen because you are using a widget that looks for a Focus '
          'ancestor, and do not have a Focus widget descendant in the nearest FocusScope.\n'
          'The context used was:\n'
          '  $context'
        );
      }
      return null;
    }
    if (!scopeOk && node is FocusScopeNode) {
      if (!nullOk) {
        throw FlutterError(
          'Focus.of() was called with a context that does not contain a Focus between the given '
          'context and the nearest FocusScope widget.\n'
          'No Focus ancestor could be found starting from the context that was passed to '
          'Focus.of() to the point where it found the nearest FocusScope widget. This can happen '
          'because you are using a widget that looks for a Focus ancestor, and do not have a '
          'Focus widget ancestor in the current FocusScope.\n'
          'The context used was:\n'
          '  $context'
        );
      }
      return null;
    }
    return node;
  }

  /// Returns true if the nearest enclosing [Focus] widget's node is focused.
  ///
  /// A convenience method to allow build methods to write:
  /// `Focus.isAt(context)` to get whether or not the nearest [Focus] above them
  /// in the widget hierarchy currently has the input focus.
  ///
  /// Returns false if no [Focus] widget is found before reaching the nearest
  /// [FocusScope], or if the root of the focus tree is reached without finding
  /// a [Focus] widget.
  ///
  /// Calling this function creates a dependency that will rebuild the given
  /// context when the focus changes.
  static bool isAt(BuildContext context) => Focus.of(context, nullOk: true)?.hasFocus ?? false;

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(StringProperty('debugLabel', debugLabel, defaultValue: null));
    properties.add(FlagProperty('autofocus', value: autofocus, ifTrue: 'AUTOFOCUS', defaultValue: false));
    properties.add(FlagProperty('canRequestFocus', value: canRequestFocus, ifFalse: 'NOT FOCUSABLE', defaultValue: false));
    properties.add(FlagProperty('descendantsAreFocusable', value: descendantsAreFocusable, ifFalse: 'DESCENDANTS UNFOCUSABLE', defaultValue: true));
    properties.add(DiagnosticsProperty<FocusNode>('focusNode', focusNode, defaultValue: null));
  }

  @override
  _FocusState createState() => _FocusState();
}

class _FocusState extends State<Focus> {
  FocusNode _internalNode;
  FocusNode get focusNode => widget.focusNode ?? _internalNode;
  bool _hasPrimaryFocus;
  bool _canRequestFocus;
  bool _descendantsAreFocusable;
  bool _didAutofocus = false;
  FocusAttachment _focusAttachment;

  @override
  void initState() {
    super.initState();
    _initNode();
  }

  void _initNode() {
    if (widget.focusNode == null) {
      // Only create a new node if the widget doesn't have one.
      // This calls a function instead of just allocating in place because
      // _createNode is overridden in _FocusScopeState.
      _internalNode ??= _createNode();
    }
    if (widget.descendantsAreFocusable != null) {
      focusNode.descendantsAreFocusable = widget.descendantsAreFocusable;
    }
    if (widget.skipTraversal != null) {
      focusNode.skipTraversal = widget.skipTraversal;
    }
    if (widget.canRequestFocus != null) {
      focusNode.canRequestFocus = widget.canRequestFocus;
    }
    _canRequestFocus = focusNode.canRequestFocus;
    _descendantsAreFocusable = focusNode.descendantsAreFocusable;
    _hasPrimaryFocus = focusNode.hasPrimaryFocus;
    _focusAttachment = focusNode.attach(context, onKey: widget.onKey);

    // Add listener even if the _internalNode existed before, since it should
    // not be listening now if we're re-using a previous one because it should
    // have already removed its listener.
    focusNode.addListener(_handleFocusChanged);
  }

  FocusNode _createNode() {
    return FocusNode(
      debugLabel: widget.debugLabel,
      canRequestFocus: widget.canRequestFocus ?? true,
      descendantsAreFocusable: widget.descendantsAreFocusable ?? false,
      skipTraversal: widget.skipTraversal ?? false,
    );
  }

  @override
  void dispose() {
    // Regardless of the node owner, we need to remove it from the tree and stop
    // listening to it.
    focusNode.removeListener(_handleFocusChanged);
    _focusAttachment.detach();

    // Don't manage the lifetime of external nodes given to the widget, just the
    // internal node.
    _internalNode?.dispose();
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _focusAttachment?.reparent();
    _handleAutofocus();
  }

  void _handleAutofocus() {
    if (!_didAutofocus && widget.autofocus) {
      FocusScope.of(context).autofocus(focusNode);
      _didAutofocus = true;
    }
  }

  @override
  void deactivate() {
    super.deactivate();
    // The focus node's location in the tree is no longer valid here. But
    // we can't unfocus or remove the node from the tree because if the widget
    // is moved to a different part of the tree (via global key) it should
    // retain its focus state. That's why we temporarily park it on the root
    // focus node (via reparent) until it either gets moved to a different part
    // of the tree (via didChangeDependencies) or until it is disposed.
    _focusAttachment?.reparent();
    _didAutofocus = false;
  }

  @override
  void didUpdateWidget(Focus oldWidget) {
    super.didUpdateWidget(oldWidget);
    assert(() {
      // Only update the debug label in debug builds, and only if we own the
      // node.
      if (oldWidget.debugLabel != widget.debugLabel && _internalNode != null) {
        _internalNode.debugLabel = widget.debugLabel;
      }
      return true;
    }());

    if (oldWidget.focusNode == widget.focusNode) {
      if (widget.skipTraversal != null) {
        focusNode.skipTraversal = widget.skipTraversal;
      }
      if (widget.canRequestFocus != null) {
        focusNode.canRequestFocus = widget.canRequestFocus;
      }
      if (widget.descendantsAreFocusable != null) {
        focusNode.descendantsAreFocusable = widget.descendantsAreFocusable;
      }
    } else {
      _focusAttachment.detach();
      focusNode.removeListener(_handleFocusChanged);
      _initNode();
    }

    if (oldWidget.autofocus != widget.autofocus) {
      _handleAutofocus();
    }
  }

  void _handleFocusChanged() {
    final bool hasPrimaryFocus = focusNode.hasPrimaryFocus;
    final bool canRequestFocus = focusNode.canRequestFocus;
    final bool descendantsAreFocusable = focusNode.descendantsAreFocusable;
    if (widget.onFocusChange != null) {
      widget.onFocusChange(focusNode.hasFocus);
    }
    if (_hasPrimaryFocus != hasPrimaryFocus) {
      setState(() {
        _hasPrimaryFocus = hasPrimaryFocus;
      });
    }
    if (_canRequestFocus != canRequestFocus) {
      setState(() {
        _canRequestFocus = canRequestFocus;
      });
    }
    if (_descendantsAreFocusable != descendantsAreFocusable) {
      setState(() {
        _descendantsAreFocusable = descendantsAreFocusable;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    _focusAttachment.reparent();
    Widget child = widget.child;
    if (widget.includeSemantics) {
      child = Semantics(
        focusable: _canRequestFocus,
        focused: _hasPrimaryFocus,
        child: widget.child,
      );
    }
    return _FocusMarker(
      node: focusNode,
      child: child,
    );
  }
}

/// A [FocusScope] is similar to a [Focus], but also serves as a scope for its
/// descendants, restricting focus traversal to the scoped controls.
///
/// For example a new [FocusScope] is created automatically when a route is
/// pushed, keeping the focus traversal from moving to a control in a previous
/// route.
///
/// If you just want to group widgets together in a group so that they are
/// traversed in a particular order, but the focus can still leave the group,
/// use a [FocusTraversalGroup].
///
/// Like [Focus], [FocusScope] provides an [onFocusChange] as a way to be
/// notified when the focus is given to or removed from this widget.
///
/// The [onKey] argument allows specification of a key event handler that is
/// invoked when this node or one of its children has focus. Keys are handed to
/// the primary focused widget first, and then they propagate through the
/// ancestors of that node, stopping if one of them returns true from [onKey],
/// indicating that it has handled the event.
///
/// Managing a [FocusScopeNode] means managing its lifecycle, listening for
/// changes in focus, and re-parenting it when needed to keep the focus
/// hierarchy in sync with the widget hierarchy. This widget does all of those
/// things for you. See [FocusScopeNode] for more information about the details
/// of what node management entails if you are not using a [FocusScope] widget
/// and you need to do it yourself.
///
/// [FocusScopeNode]s remember the last [FocusNode] that was focused within
/// their descendants, and can move that focus to the next/previous node, or a
/// node in a particular direction when the [FocusNode.nextFocus],
/// [FocusNode.previousFocus], or [FocusNode.focusInDirection] are called on a
/// [FocusNode] or [FocusScopeNode].
///
/// To move the focus, use methods on [FocusNode] by getting the [FocusNode]
/// through the [of] method. For instance, to move the focus to the next node in
/// the focus traversal order, call `Focus.of(context).nextFocus()`. To unfocus
/// a widget, call `Focus.of(context).unfocus()`.
///
/// {@tool dartpad --template=stateful_widget_material}
/// This example demonstrates using a [FocusScope] to restrict focus to a particular
/// portion of the app. In this case, restricting focus to the visible part of a
/// Stack.
///
/// ```dart preamble
/// /// A demonstration pane.
/// ///
/// /// This is just a separate widget to simplify the example.
/// class Pane extends StatelessWidget {
///   const Pane({
///     Key key,
///     this.focusNode,
///     this.onPressed,
///     this.child,
///     this.backgroundColor,
///     this.icon,
///   }) : super(key: key);
///
///   final FocusNode focusNode;
///   final VoidCallback onPressed;
///   final Widget child;
///   final Color backgroundColor;
///   final Widget icon;
///
///   @override
///   Widget build(BuildContext context) {
///     return Material(
///       color: backgroundColor,
///       child: Stack(
///         fit: StackFit.expand,
///         children: <Widget>[
///           Center(
///             child: child,
///           ),
///           Align(
///             alignment: Alignment.topLeft,
///             child: IconButton(
///               autofocus: true,
///               focusNode: focusNode,
///               onPressed: onPressed,
///               icon: icon,
///             ),
///           ),
///         ],
///       ),
///     );
///   }
/// }
/// ```
///
/// ```dart
///   bool backdropIsVisible = false;
///   FocusNode backdropNode = FocusNode(debugLabel: 'Close Backdrop Button');
///   FocusNode foregroundNode = FocusNode(debugLabel: 'Option Button');
///
///   @override
///   void dispose() {
///     super.dispose();
///     backdropNode.dispose();
///     foregroundNode.dispose();
///   }
///
///   Widget _buildStack(BuildContext context, BoxConstraints constraints) {
///     Size stackSize = constraints.biggest;
///     return Stack(
///       fit: StackFit.expand,
///       // The backdrop is behind the front widget in the Stack, but the widgets
///       // would still be active and traversable without the FocusScope.
///       children: <Widget>[
///         // TRY THIS: Try removing this FocusScope entirely to see how it affects
///         // the behavior. Without this FocusScope, the "ANOTHER BUTTON TO FOCUS"
///         // button, and the IconButton in the backdrop Pane would be focusable
///         // even when the backdrop wasn't visible.
///         FocusScope(
///           // TRY THIS: Try commenting out this line. Notice that the focus
///           // starts on the backdrop and is stuck there? It seems like the app is
///           // non-responsive, but it actually isn't. This line makes sure that
///           // this focus scope and its children can't be focused when they're not
///           // visible. It might help to make the background color of the
///           // foreground pane semi-transparent to see it clearly.
///           canRequestFocus: backdropIsVisible,
///           child: Pane(
///             icon: Icon(Icons.close),
///             focusNode: backdropNode,
///             backgroundColor: Colors.lightBlue,
///             onPressed: () => setState(() => backdropIsVisible = false),
///             child: Column(
///               mainAxisAlignment: MainAxisAlignment.center,
///               children: <Widget>[
///                 // This button would be not visible, but still focusable from
///                 // the foreground pane without the FocusScope.
///                 RaisedButton(
///                   onPressed: () => print('You pressed the other button!'),
///                   child: Text('ANOTHER BUTTON TO FOCUS'),
///                 ),
///                 DefaultTextStyle(
///                     style: Theme.of(context).textTheme.headline2,
///                     child: Text('BACKDROP')),
///               ],
///             ),
///           ),
///         ),
///         AnimatedPositioned(
///           curve: Curves.easeInOut,
///           duration: const Duration(milliseconds: 300),
///           top: backdropIsVisible ? stackSize.height * 0.9 : 0.0,
///           width: stackSize.width,
///           height: stackSize.height,
///           onEnd: () {
///             if (backdropIsVisible) {
///               backdropNode.requestFocus();
///             } else {
///               foregroundNode.requestFocus();
///             }
///           },
///           child: Pane(
///             icon: Icon(Icons.menu),
///             focusNode: foregroundNode,
///             // TRY THIS: Try changing this to Colors.green.withOpacity(0.8) to see for
///             // yourself that the hidden components do/don't get focus.
///             backgroundColor: Colors.green,
///             onPressed: backdropIsVisible
///                 ? null
///                 : () => setState(() => backdropIsVisible = true),
///             child: DefaultTextStyle(
///                 style: Theme.of(context).textTheme.headline2,
///                 child: Text('FOREGROUND')),
///           ),
///         ),
///       ],
///     );
///   }
///
///   @override
///   Widget build(BuildContext context) {
///     // Use a LayoutBuilder so that we can base the size of the stack on the size
///     // of its parent.
///     return LayoutBuilder(builder: _buildStack);
///   }
/// ```
/// {@end-tool}
///
/// See also:
///
///  * [FocusScopeNode], which represents a scope node in the focus hierarchy.
///  * [FocusNode], which represents a node in the focus hierarchy and has an
///    explanation of the focus system.
///  * [Focus], a widget that manages a [FocusNode] and allows easy access to
///    managing focus without having to manage the node.
///  * [FocusManager], a singleton that manages the focus and distributes key
///    events to focused nodes.
///  * [FocusTraversalPolicy], an object used to determine how to move the focus
///    to other nodes.
///  * [FocusTraversalGroup], a widget used to configure the focus traversal
///    policy for a widget subtree.
class FocusScope extends Focus {
  /// Creates a widget that manages a [FocusScopeNode].
  ///
  /// The [child] argument is required and must not be null.
  ///
  /// The [autofocus], and [showDecorations] arguments must not be null.
  const FocusScope({
    Key key,
    FocusScopeNode node,
    @required Widget child,
    bool autofocus = false,
    ValueChanged<bool> onFocusChange,
    bool canRequestFocus,
    bool skipTraversal,
    FocusOnKeyCallback onKey,
    String debugLabel,
  })  : assert(child != null),
        assert(autofocus != null),
        super(
          key: key,
          child: child,
          focusNode: node,
          autofocus: autofocus,
          onFocusChange: onFocusChange,
          canRequestFocus: canRequestFocus,
          skipTraversal: skipTraversal,
          onKey: onKey,
          debugLabel: debugLabel,
        );

  /// Returns the [FocusScopeNode] of the [FocusScope] that most tightly
  /// encloses the given [context].
  ///
  /// If this node doesn't have a [Focus] widget ancestor, then the
  /// [FocusManager.rootScope] is returned.
  ///
  /// The [context] argument must not be null.
  static FocusScopeNode of(BuildContext context) {
    assert(context != null);
    final _FocusMarker marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>();
    return marker?.notifier?.nearestScope ?? context.owner.focusManager.rootScope;
  }

  @override
  _FocusScopeState createState() => _FocusScopeState();
}

class _FocusScopeState extends _FocusState {
  @override
  FocusScopeNode _createNode() {
    return FocusScopeNode(
      debugLabel: widget.debugLabel,
      canRequestFocus: widget.canRequestFocus ?? true,
      skipTraversal: widget.skipTraversal ?? false,
    );
  }

  @override
  Widget build(BuildContext context) {
    _focusAttachment.reparent();
    return Semantics(
      explicitChildNodes: true,
      child: _FocusMarker(
        node: focusNode,
        child: widget.child,
      ),
    );
  }
}

// The InheritedWidget marker for Focus and FocusScope.
class _FocusMarker extends InheritedNotifier<FocusNode> {
  const _FocusMarker({
    Key key,
    @required FocusNode node,
    @required Widget child,
  })  : assert(node != null),
        assert(child != null),
        super(key: key, notifier: node, child: child);
}

/// A widget that controls whether or not the descendants of this widget are
/// focusable.
///
/// Does not affect the value of [canRequestFocus] on the descendants.
///
/// See also:
///
///  * [Focus], a widget for adding and managing a [FocusNode] in the widget tree.
///  * [FocusTraversalGroup], a widget that groups widgets for focus traversal,
///    and can also be used in the same way as this widget by setting its
///    `descendantsAreFocusable` attribute.
class ExcludeFocus extends StatelessWidget {
  /// Const constructor for [ExcludeFocus] widget.
  ///
  /// The [excluding] argument must not be null.
  ///
  /// The [child] argument is required, and must not be null.
  const ExcludeFocus({
    Key key,
    this.excluding = true,
    @required this.child,
  })  : assert(excluding != null),
        assert(child != null),
        super(key: key);

  /// If true, will make this widget's descendants unfocusable.
  ///
  /// Defaults to true.
  ///
  /// If any descendants are focused when this is set to true, they will be
  /// unfocused. When `excluding` is set to false again, they will not be
  /// refocused, although they will be able to accept focus again.
  ///
  /// Does not affect the value of [canRequestFocus] on the descendants.
  ///
  /// See also:
  ///
  ///  * [Focus.descendantsAreFocusable], the attribute of a [Focus] widget that
  ///    controls this same property for focus widgets.
  ///  * [FocusTraversalGroup], a widget used to group together and configure
  ///    the focus traversal policy for a widget subtree that has a
  ///    `descendantsAreFocusable` parameter to conditionally block focus for a
  ///    subtree.
  final bool excluding;

  /// The child widget of this [ExcludeFocus].
  ///
  /// {@macro flutter.widgets.child}
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Focus(
      canRequestFocus: false,
      skipTraversal: true,
      descendantsAreFocusable: !excluding,
      child: child,
    );
  }
}
