浏览代码

fix focus

/siyaoH-1.17-PlatformMessage
Shiyun Wen 4 年前
当前提交
28a40a7f
共有 3 个文件被更改,包括 76 次插入550 次删除
  1. 7
      com.unity.uiwidgets/Runtime/widgets/editable_text.cs
  2. 475
      com.unity.uiwidgets/Runtime/widgets/focus_manager.cs
  3. 144
      com.unity.uiwidgets/Runtime/widgets/focus_scope.cs

7
com.unity.uiwidgets/Runtime/widgets/editable_text.cs


_openInputConnection();
}
else {
List<FocusScopeNode> ancestorScopes = FocusScope.ancestorsOf(context);
for (int i = ancestorScopes.Count - 1; i >= 1; i -= 1) {
ancestorScopes[i].setFirstFocus(ancestorScopes[i - 1]);
}
FocusScope.of(context).requestFocus(widget.focusNode);
widget.focusNode.requestFocus();
}
}

475
com.unity.uiwidgets/Runtime/widgets/focus_manager.cs


public static bool _focusDebug(string message, List<string> details = null) {
if (_kDebugFocus) {
//UnityEngine.Debug.Log();
UnityEngine.Debug.Log($"FOCUS: {message}");
if (details != null && details.Count() != 0) {
foreach (string detail in details) {

}
}
public class FocusNode : ChangeNotifier {
//DiagnosticableTreeMixin,
public class FocusNode : ChangeNotifier//DiagnosticableTreeMixin,
{
public FocusNode(
string debugLabel = "",
FocusOnKeyCallback onKey = null,

D.assert(canRequestFocus != null);
_skipTraversal = skipTraversal;
_canRequestFocus = canRequestFocus;
/*_onKey = onKey {
this.debugLabel = debugLabel; ///????
}*/
_onKey = onKey;
this.debugLabel = debugLabel;
}
public bool skipTraversal {

}
}
}
bool _skipTraversal;

get { return _context; }
}
BuildContext _context;
FocusOnKeyCallback onKey {

FocusOnKeyCallback _onKey;
public FocusManager _manager;

get { return _parent; }
}
public FocusNode _parent;

}
public readonly List<FocusNode> _children = new List<FocusNode>();
IEnumerable<FocusNode> traversalChildren {

}
List<FocusNode> nodes = new List<FocusNode>();
foreach (FocusNode node in children) {
if (!node.skipTraversal && node.canRequestFocus)
nodes.Add(node);
}
return nodes;
return children.Where(
(FocusNode node) => !node.skipTraversal && node.canRequestFocus
);
}
}

}
string _debugLabel;
IEnumerable<FocusNode> descendants {
get {
if (_descendants == null) {

IEnumerable<FocusNode> traversalDescendants {
get {
List<FocusNode> nodes = new List<FocusNode>();
foreach (FocusNode node in descendants) {
if (!node.skipTraversal && node.canRequestFocus) {
nodes.Add(node);
}
}
// descendants.where((FocusNode node) => !node.skipTraversal && node.canRequestFocus);
return nodes;
return descendants.Where((FocusNode node) => !node.skipTraversal && node.canRequestFocus);
}
}

get { return FocusManager.instance.highlightMode; }
}
FocusScopeNode nearestScope {
public FocusScopeNode nearestScope {
get { return enclosingScope; }
}

/*bool nextFocus() {
return FocusTraversalGroup.of(context).next(this);
}*
}
bool previousFocus() {

}
public FocusScopeNode nearestScope {
get { return enclosingScope; }
get { return this; }
}
public bool isFirstFocus {

}
public void autofocus(FocusNode node) {
D.assert(FocusManagerUtils._focusDebug("Node autofocusing: $node"));
D.assert(FocusManagerUtils._focusDebug($"Node autofocusing: {node}"));
if (focusedChild == null) {
if (node._parent == null) {
_reparent(node);

primaryFocus = scope.focusedChild;
}
if (primaryFocus == this) {
if (primaryFocus.canRequestFocus) {
_setAsFocusedChildForScope();
_markNextFocus(this);
}
if (primaryFocus.canRequestFocus) {
_setAsFocusedChildForScope();
_markNextFocus(this);
}
primaryFocus._doRequestFocus(findFirstFocus: findFirstFocus);
primaryFocus._doRequestFocus(findFirstFocus: findFirstFocus);
}
}

}
}
/*
public class FocusNode : ChangeNotifier {
internal FocusScopeNode _parent;
internal FocusManager _manager;
internal bool _hasKeyboardToken = false;
public bool hasFocus {
get {
FocusNode node = null;
if (_manager != null) {
node = _manager._currentFocus;
}
return node == this;
}
}
public bool consumeKeyboardToken() {
if (!_hasKeyboardToken) {
return false;
}
_hasKeyboardToken = false;
return true;
}
public void unfocus() {
if (_parent != null) {
_parent._resignFocus(this);
}
D.assert(_parent == null);
D.assert(_manager == null);
}
public override void dispose() {
if (_manager != null) {
_manager._willDisposeFocusNode(this);
}
if (_parent != null) {
_parent._resignFocus(this);
}
D.assert(_parent == null);
D.assert(_manager == null);
base.dispose();
}
internal void _notify() {
notifyListeners();
}
public override string ToString() {
return $"{foundation_.describeIdentity(this)} hasFocus: {hasFocus}";
}
}
public class FocusScopeNode : DiagnosticableTree {
internal FocusManager _manager;
internal FocusScopeNode _parent;
internal FocusScopeNode _nextSibling;
internal FocusScopeNode _previousSibling;
internal FocusScopeNode _firstChild;
internal FocusScopeNode _lastChild;
internal FocusNode _focus;
internal List<FocusScopeNode> _focusPath;
public bool isFirstFocus {
get { return _parent == null || _parent._firstChild == this; }
}
internal List<FocusScopeNode> _getFocusPath() {
List<FocusScopeNode> nodes = new List<FocusScopeNode> {this};
FocusScopeNode node = _parent;
while (node != null && node != _manager?.rootScope) {
nodes.Add(node);
node = node._parent;
}
return nodes;
}
internal void _prepend(FocusScopeNode child) {
D.assert(child != this);
D.assert(child != _firstChild);
D.assert(child != _lastChild);
D.assert(child._parent == null);
D.assert(child._manager == null);
D.assert(child._nextSibling == null);
D.assert(child._previousSibling == null);
D.assert(() => {
var node = this;
while (node._parent != null) {
node = node._parent;
}
D.assert(node != child);
return true;
});
child._parent = this;
child._nextSibling = _firstChild;
if (_firstChild != null) {
_firstChild._previousSibling = child;
}
_firstChild = child;
_lastChild = _lastChild ?? child;
child._updateManager(_manager);
}
void _updateManager(FocusManager manager) {
Action<FocusScopeNode> update = null;
update = (child) => {
if (child._manager == manager) {
return;
}
child._manager = manager;
// We don"t proactively null out the manager for FocusNodes because the
// manager holds the currently active focus node until the end of the
// microtask, even if that node is detached from the focus tree.
if (manager != null && child._focus != null) {
child._focus._manager = manager;
}
child._visitChildren(update);
};
update(this);
}
void _visitChildren(Action<FocusScopeNode> vistor) {
FocusScopeNode child = _firstChild;
while (child != null) {
vistor.Invoke(child);
child = child._nextSibling;
}
}
bool _debugUltimatePreviousSiblingOf(FocusScopeNode child, FocusScopeNode equals) {
while (child._previousSibling != null) {
D.assert(child._previousSibling != child);
child = child._previousSibling;
}
return child == equals;
}
bool _debugUltimateNextSiblingOf(FocusScopeNode child, FocusScopeNode equals) {
while (child._nextSibling != null) {
D.assert(child._nextSibling != child);
child = child._nextSibling;
}
return child == equals;
}
internal void _remove(FocusScopeNode child) {
D.assert(child._parent == this);
D.assert(child._manager == _manager);
D.assert(_debugUltimatePreviousSiblingOf(child, equals: _firstChild));
D.assert(_debugUltimateNextSiblingOf(child, equals: _lastChild));
if (child._previousSibling == null) {
D.assert(_firstChild == child);
_firstChild = child._nextSibling;
}
else {
child._previousSibling._nextSibling = child._nextSibling;
}
if (child._nextSibling == null) {
D.assert(_lastChild == child);
_lastChild = child._previousSibling;
}
else {
child._nextSibling._previousSibling = child._previousSibling;
}
child._previousSibling = null;
child._nextSibling = null;
child._parent = null;
child._updateManager(null);
}
internal void _didChangeFocusChain() {
if (isFirstFocus && _manager != null) {
_manager._markNeedsUpdate();
}
}
// TODO: need update
public void requestFocus(FocusNode node = null) {
// D.assert(node != null);
var focusPath = _manager?._getCurrentFocusPath();
if (_focus == node &&
(_focusPath == focusPath || (focusPath != null && _focusPath != null &&
_focusPath.SequenceEqual(focusPath)))) {
return;
}
if (_focus != null) {
_focus.unfocus();
}
node._hasKeyboardToken = true;
_setFocus(node);
}
public void autofocus(FocusNode node) {
D.assert(node != null);
if (_focus == null) {
node._hasKeyboardToken = true;
_setFocus(node);
}
}
public void reparentIfNeeded(FocusNode node) {
D.assert(node != null);
if (node._parent == null || node._parent == this) {
return;
}
node.unfocus();
D.assert(node._parent == null);
if (_focus == null) {
_setFocus(node);
}
}
internal void _setFocus(FocusNode node) {
D.assert(node != null);
D.assert(node._parent == null);
D.assert(_focus == null);
_focus = node;
_focus._parent = this;
_focus._manager = _manager;
_focus._hasKeyboardToken = true;
_didChangeFocusChain();
_focusPath = _getFocusPath();
}
internal void _resignFocus(FocusNode node) {
D.assert(node != null);
if (_focus != node) {
return;
}
_focus._parent = null;
_focus._manager = null;
_focus = null;
_didChangeFocusChain();
}
public void setFirstFocus(FocusScopeNode child) {
D.assert(child != null);
D.assert(child._parent == null || child._parent == this);
if (_firstChild == child) {
return;
}
child.detach();
_prepend(child);
D.assert(child._parent == this);
_didChangeFocusChain();
}
public void reparentScopeIfNeeded(FocusScopeNode child) {
D.assert(child != null);
if (child._parent == null || child._parent == this) {
return;
}
if (child.isFirstFocus) {
setFirstFocus(child);
}
else {
child.detach();
}
}
public void detach() {
_didChangeFocusChain();
if (_parent != null) {
_parent._remove(this);
}
D.assert(_parent == null);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
if (_focus != null) {
properties.add(new DiagnosticsProperty<FocusNode>("focus", _focus));
}
}
public override List<DiagnosticsNode> debugDescribeChildren() {
var children = new List<DiagnosticsNode>();
if (_firstChild != null) {
FocusScopeNode child = _firstChild;
int count = 1;
while (true) {
children.Add(child.toDiagnosticsNode(name: $"child {count}"));
if (child == _lastChild) {
break;
}
child = child._nextSibling;
count += 1;
}
}
return children;
}
}
public class FocusManager {
public FocusManager() {
rootScope._manager = this;
D.assert(rootScope._firstChild == null);
D.assert(rootScope._lastChild == null);
}
public readonly FocusScopeNode rootScope = new FocusScopeNode();
internal readonly FocusScopeNode _noneScope = new FocusScopeNode();
public FocusNode currentFocus {
get { return _currentFocus; }
}
internal FocusNode _currentFocus;
internal void _willDisposeFocusNode(FocusNode node) {
D.assert(node != null);
if (_currentFocus == node) {
_currentFocus = null;
}
}
bool _haveScheduledUpdate = false;
internal void _markNeedsUpdate() {
if (_haveScheduledUpdate) {
return;
}
_haveScheduledUpdate = true;
async_.scheduleMicrotask(() => {
_update();
return null;
});
}
internal FocusNode _findNextFocus() {
FocusScopeNode scope = rootScope;
while (scope._firstChild != null) {
scope = scope._firstChild;
}
return scope._focus;
}
internal void _update() {
_haveScheduledUpdate = false;
var nextFocus = _findNextFocus();
if (_currentFocus == nextFocus) {
return;
}
var previousFocus = _currentFocus;
_currentFocus = nextFocus;
if (previousFocus != null) {
previousFocus._notify();
}
if (_currentFocus != null) {
_currentFocus._notify();
}
}
internal List<FocusScopeNode> _getCurrentFocusPath() {
return _currentFocus?._parent?._getFocusPath();
}
public void focusNone(bool focus) {
if (focus) {
if (_noneScope._parent != null && _noneScope.isFirstFocus) {
return;
}
rootScope.setFirstFocus(_noneScope);
}
else {
if (_noneScope._parent == null) {
return;
}
_noneScope.detach();
}
}
public override string ToString() {
var status = _haveScheduledUpdate ? " UPDATE SCHEDULED" : "";
var indent = " ";
return string.Format("{1}{2}\n{0}currentFocus: {3}\n{4}", indent, foundation_.describeIdentity(this),
status, _currentFocus,
rootScope.toStringDeep(prefixLineOne: indent, prefixOtherLines: indent));
}
}*/

144
com.unity.uiwidgets/Runtime/widgets/focus_scope.cs


}
}
public class FocusScope : StatefulWidget {
public FocusScope(FocusScopeNode node, Widget child, Key key = null, bool autofocus = false) : base(key) {
this.node = node;
this.child = child;
this.autofocus = autofocus;
public class FocusScope : Focus {
public FocusScope(
Key key = null,
FocusScopeNode node = null,
Widget child = null,
bool autofocus = false,
ValueChanged<bool> onFocusChange = null,
bool? canRequestFocus = null,
bool? skipTraversal = null,
FocusOnKeyCallback onKey = null,
string debugLabel = null
) : base(
key: key,
child: child,
focusNode: node,
autofocus: autofocus,
onFocusChange: onFocusChange,
canRequestFocus: canRequestFocus,
skipTraversal: skipTraversal,
onKey: onKey,
debugLabel: debugLabel) {
D.assert(child != null);
D.assert(autofocus != null);
public readonly FocusScopeNode node;
public readonly bool autofocus;
public readonly Widget child;
var scope = (_FocusScopeMarker) context.inheritFromWidgetOfExactType(typeof(_FocusScopeMarker));
if (scope != null && scope.node != null) {
return scope.node;
}
return context.owner.focusManager.rootScope;
}
public static List<FocusScopeNode> ancestorsOf(BuildContext context) {
D.assert(context != null);
List<FocusScopeNode> ancestors = new List<FocusScopeNode> { };
while (true) {
context = context.ancestorInheritedElementForWidgetOfExactType(typeof(_FocusScopeMarker));
if (context == null) {
return ancestors;
}
_FocusScopeMarker scope = (_FocusScopeMarker) context.widget;
ancestors.Add(scope.node);
context.visitAncestorElements((Element parent) => {
context = parent;
return false;
});
}
_FocusMarker marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>();
return marker?.notifier?.nearestScope ?? context.owner.focusManager.rootScope;
class _FocusScopeState : _FocusState {
public FocusScopeNode _createNode() {
return new FocusScopeNode(
debugLabel: widget.debugLabel,
canRequestFocus: widget.canRequestFocus ?? true,
skipTraversal: widget.skipTraversal ?? false
);
}
public override Widget build(BuildContext context) {
_focusAttachment.reparent();
return new _FocusMarker(
node: focusNode,
child: widget.child);
}
}
class _FocusMarker : InheritedNotifier<FocusNode> {
public _FocusMarker(
Key key = null,
FocusNode node = null,
Widget child = null
) : base(key: key, notifier: node, child: child) {
D.assert(node != null);
D.assert(child != null);
}
}
public class Focus : StatefulWidget {
public Focus(

}
return node;
}
//public static bool isAt(BuildContext context) => Focus.of(context, nullOk: true)?.hasFocus ?? false;
public static bool isAt(BuildContext context) => Focus.of(context, nullOk: true)?.hasFocus ?? false;
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {
base.debugFillProperties(properties);
properties.add(new StringProperty("debugLabel", debugLabel, defaultValue: null));

public class _FocusState : State<Focus> {
FocusNode _internalNode;
public FocusNode focusNode {
get {
return widget.focusNode ?? _internalNode;

base.didUpdateWidget(oldWidget);
D.assert(()=> {
if (((Focus)oldWidget).debugLabel != widget.debugLabel && _internalNode != null) {
_internalNode.debugLabel = widget.debugLabel;
}
return true;
_internalNode.debugLabel = widget.debugLabel;
}
return true;
});
if (((Focus)oldWidget).focusNode == widget.focusNode) {

}
}
/*class _FocusScopeState : State<FocusScope> {
bool _didAutofocus = false;
public override void didChangeDependencies() {
base.didChangeDependencies();
if (!_didAutofocus && widget.autofocus) {
FocusScope.of(context).setFirstFocus(widget.node);
_didAutofocus = true;
}
}
public override void dispose() {
widget.node.detach();
base.dispose();
}
public override Widget build(BuildContext context) {
FocusScope.of(context).reparentScopeIfNeeded(widget.node);
return new _FocusScopeMarker(node: widget.node, child: widget.child);
}
}*/
class _FocusScopeState : _FocusState {
public FocusScopeNode _createNode() {
return new FocusScopeNode(
debugLabel: widget.debugLabel,
canRequestFocus: widget.canRequestFocus ?? true,
skipTraversal: widget.skipTraversal ?? false
);
}
public override Widget build(BuildContext context) {
_focusAttachment.reparent();
return new _FocusMarker(
node: focusNode,
child: widget.child);
}
}
class _FocusMarker : InheritedNotifier<FocusNode> {
public _FocusMarker(
Key key = null,
FocusNode node = null,
Widget child = null
) : base(key: key, notifier: node, child: child) {
D.assert(node != null);
D.assert(child != null);
}
}
}
正在加载...
取消
保存