public void _markDetached(FocusNode node)
 {
     D.assert(FocusManagerUtils._focusDebug($"Node was detached: {node}"));
     if (_primaryFocus == node)
     {
         _primaryFocus = null;
     }
     _dirtyNodes?.Remove(node);
 }
 public void autofocus(FocusNode node)
 {
     D.assert(FocusManagerUtils._focusDebug($"Node autofocusing: {node}"));
     if (focusedChild == null)
     {
         if (node._parent == null)
         {
             _reparent(node);
         }
         D.assert(node.ancestors.Contains(this), () => "Autofocus was requested for a node that is not a descendant of the scope from which it was requested.");
         node._doRequestFocus(findFirstFocus: true);
     }
 }
 void _markNeedsUpdate()
 {
     D.assert(FocusManagerUtils._focusDebug($"Scheduling update, current focus is {_primaryFocus}, next focus will be {_markedForFocus}"));
     if (_haveScheduledUpdate)
     {
         return;
     }
     _haveScheduledUpdate = true;
     async_.scheduleMicrotask(() => {
         _applyFocusChange();
         return(null);
     });
 }
 public void setFirstFocus(FocusScopeNode scope)
 {
     D.assert(scope != null);
     D.assert(scope != this, () => "Unexpected self-reference in setFirstFocus.");
     D.assert(FocusManagerUtils._focusDebug($"Setting scope as first focus in {this} to node:", new List <string> {
         scope.ToString()
     }));
     if (scope._parent == null)
     {
         _reparent(scope);
     }
     D.assert(scope.ancestors.Contains(this), () => $"{typeof(FocusScopeNode)}" + $"{scope} must be a child of" + $" {this} to set it as first focus.");
     if (hasFocus)
     {
         scope._doRequestFocus(findFirstFocus: true);
     }
     else
     {
         scope._setAsFocusedChildForScope();
     }
 }
    void _handleRawKeyEvent(RawKeyEvent Event)
    {
        if (_lastInteractionWasTouch)
        {
            _lastInteractionWasTouch = false;
            _updateHighlightMode();
        }

        //D.assert(FocusManagerUtils._focusDebug($"Received key event {Event.logicalKey}"));

        if (_primaryFocus == null)
        {
            D.assert(FocusManagerUtils._focusDebug($"No primary focus for key event, ignored: {Event}"));
            return;
        }

        bool             handled = false;
        List <FocusNode> nodes   = new List <FocusNode>();

        nodes.Add(_primaryFocus);
        foreach (var node in _primaryFocus.ancestors)
        {
            nodes.Add(node);
        }
        foreach (FocusNode node in nodes)
        {
            if (node.onKey != null && node.onKey(node, Event))
            {
                D.assert(FocusManagerUtils._focusDebug($"Node {node} handled key event {Event}."));
                handled = true;
                break;
            }
        }
        if (!handled)
        {
            D.assert(FocusManagerUtils._focusDebug($"Key event not handled by anyone: {Event}."));
        }
    }
 public void _markPropertiesChanged(FocusNode node)
 {
     _markNeedsUpdate();
     D.assert(FocusManagerUtils._focusDebug($"Properties changed for node {node}."));
     _dirtyNodes?.Add(node);
 }
    void _applyFocusChange()
    {
        _haveScheduledUpdate = false;
        FocusNode previousFocus = _primaryFocus;

        if (_primaryFocus == null && _markedForFocus == null)
        {
            _markedForFocus = rootScope;
        }
        D.assert(FocusManagerUtils._focusDebug($"Refreshing focus state. Next focus will be {_markedForFocus}"));

        if (_markedForFocus != null && _markedForFocus != _primaryFocus)
        {
            HashSet <FocusNode> previousPath = previousFocus?.ancestors != null ? new HashSet <FocusNode>(previousFocus.ancestors) : new HashSet <FocusNode>();
            HashSet <FocusNode> nextPath     = new HashSet <FocusNode>(_markedForFocus.ancestors);
            foreach (FocusNode node in FocusTravesalUtils.difference(nextPath, previousPath))
            {
                _dirtyNodes.Add(node);
            }
            foreach (FocusNode node in FocusTravesalUtils.difference(previousPath, nextPath))
            {
                _dirtyNodes.Add(node);
            }

            _primaryFocus   = _markedForFocus;
            _markedForFocus = null;
        }
        if (previousFocus != _primaryFocus)
        {
            D.assert(FocusManagerUtils._focusDebug($"Updating focus from {previousFocus} to {_primaryFocus}"));
            if (previousFocus != null)
            {
                _dirtyNodes.Add(previousFocus);
            }
            if (_primaryFocus != null)
            {
                _dirtyNodes.Add(_primaryFocus);
            }
        }
        D.assert(FocusManagerUtils._focusDebug($"Notifying {_dirtyNodes.Count} dirty nodes:",
                                               LinqUtils <string, FocusNode> .SelectList(_dirtyNodes, ((FocusNode node) => {
            return(node.toString());
        }))
                                               ));
        foreach (FocusNode node in _dirtyNodes)
        {
            node._notify();
        }
        _dirtyNodes.Clear();
        if (previousFocus != _primaryFocus)
        {
            notifyListeners();
        }
        D.assert(() => {
            if (FocusManagerUtils._kDebugFocus)
            {
                FocusManagerUtils.debugDumpFocusTree();
            }
            return(true);
        });
    }