namespace Unity.UIWidgets.widgets {
/ * public class FocusTraversalGroup : StatefulWidget {
public enum TraversalDirection {
up ,
right ,
down ,
left ,
// TODO(gspencer): Add diagonal traversal directions used by TV remotes and
// game controllers when we support them.
}
public class FocusTravesalUtils {
public static void _focusAndEnsureVisible (
FocusNode node ,
ScrollPositionAlignmentPolicy alignmentPolicy = ScrollPositionAlignmentPolicy . explicitPolicy
) {
node . requestFocus ( ) ;
Scrollable . ensureVisible ( node . context , alignment : 1.0f , alignmentPolicy : alignmentPolicy ) ;
}
public static BuildContext _getAncestor ( BuildContext context , int count = 1 ) {
BuildContext target = null ;
context . visitAncestorElements ( ( Element ancestor ) = > {
count - - ;
if ( count = = 0 ) {
target = ancestor ;
return false ;
}
return true ;
} ) ;
return target ;
}
public static HashSet < T > difference < T > ( HashSet < T > aSet , HashSet < T > bSet ) {
HashSet < T > result = new HashSet < T > ( ) ;
foreach ( var a in aSet ) {
if ( ! bSet . Contains ( a ) ) {
result . Add ( a ) ;
}
}
return result ;
}
public static HashSet < T > intersaction < T > ( HashSet < T > aSet , HashSet < T > bSet ) {
HashSet < T > result = new HashSet < T > ( ) ;
result = aSet ;
foreach ( var b in bSet ) {
if ( ! aSet . Contains ( b ) ) {
result . Add ( b ) ;
}
}
return result ;
}
}
public class FocusTraversalGroup : StatefulWidget {
public FocusTraversalGroup (
Key key = null ,
FocusTraversalPolicy policy = null ,
public override void debugFillProperties ( DiagnosticPropertiesBuilder properties ) {
base . debugFillProperties ( properties ) ;
properties . add ( new TextTreeRenderer . DiagnosticsProperty < FocusTraversalPolicy > ( "policy" , policy ) ) ;
properties . add ( new DiagnosticsProperty < FocusTraversalPolicy > ( "policy" , policy ) ) ;
}
}
public class _FocusTraversalGroupState : State < FocusTraversalGroup > {
public override bool updateShouldNotify ( InheritedWidget oldWidget ) = > false ;
}
public abstract class FocusTraversalPolicy : TextTreeRenderer . Diagnosticable {
public abstract class FocusTraversalPolicy : Diagnosticable {
public class _FocusTraversalGroupInfo {
public _FocusTraversalGroupInfo (
_FocusTraversalGroupMarker marker ,
FocusTraversalPolicy defaultPolicy = null ,
List < FocusNode > members = null
) {
groupNode = marker ? . focusNode ;
policy = marker ? . policy ? ? defaultPolicy ? ? new ReadingOrderTraversalPolicy ( ) ;
members = members ? ? new List < FocusNode > ( ) ;
}
public readonly FocusNode groupNode ;
public readonly FocusTraversalPolicy policy ;
public readonly List < FocusNode > members ;
}
public virtual FocusNode findFirstFocus ( FocusNode currentNode ) {
D . assert ( currentNode ! = null ) ;
public List < FocusNode > _sortAllDescendants ( FocusScopeNode scope ) {
D . assert ( scope ! = null ) ;
_FocusTraversalGroupMarker scopeGroupMarker = _getMarker ( scope . context ) ;
FocusTraversalPolicy defaultPolicy = scopeGroupMarker ? . policy ? ? ReadingOrderTraversalPolicy ( ) ;
FocusTraversalPolicy defaultPolicy = scopeGroupMarker ? . policy ? ? new ReadingOrderTraversalPolicy ( ) ;
BuildContext parentContext = _getAncestor ( groupNode . context , count : 2 ) ;
BuildContext parentContext = FocusTravesalUtils . _getAncestor ( groupNode . context , count : 2 ) ;
groups [ parentNode ] . members . a dd( groupNode ) ;
groups [ parentNode ] . members . A dd( groupNode ) ;
groups [ groupNode ] ? ? = _FocusTraversalGroupInfo ( groupMarker , members : new List < FocusNode > ( ) , defaultPolicy : defaultPolicy ) ;
D . assert ( ! groups [ groupNode ] . members . c ontains( node ) ) ;
groups [ groupNode ] . members . a dd( node ) ;
groups [ groupNode ] ? ? = new _FocusTraversalGroupInfo ( groupMarker , members : new List < FocusNode > ( ) , defaultPolicy : defaultPolicy ) ;
D . assert ( ! groups [ groupNode ] . members . C ontains( node ) ) ;
groups [ groupNode ] . members . A dd( node ) ;
HashSet < FocusNode > groupKeys = groups . Keys . ToSet ( ) ;
foreach ( FocusNode key in groups . k eys) {
List < FocusNode > sortedMembers = groups [ key ] . policy . sortDescendants ( groups [ key ] . members ) . t oList( ) ;
groups [ key ] . members . c lear( ) ;
groups [ key ] . members . addAll ( sortedMembers ) ;
HashSet < FocusNode > groupKeys = new HashSet < FocusNode > ( groups . Keys ) ;
foreach ( FocusNode key in groups . K eys) {
List < FocusNode > sortedMembers = groups [ key ] . policy . sortDescendants ( groups [ key ] . members ) . T oList( ) ;
groups [ key ] . members . C lear( ) ;
groups [ key ] . members . AddRange ( sortedMembers ) ;
}
List < FocusNode > sortedDescendants = new List < FocusNode > ( ) ;
}
visitGroups ( groups [ scopeGroupMarker ? . focusNode ] ) ;
D . assert (
sortedDescendants . toSet ( ) . difference ( scope . traversalDescendants . toSet ( ) ) . isEmpty ,
$"sorted descendants contains more nodes than it should: ({sortedDescendants.toSet().difference(scope.traversalDescendants.toSet( ))})"
FocusTravesalUtils . difference ( new HashSet < FocusNode > ( sortedDescendants ) , ( new HashSet < FocusNode > ( scope . traversalDescendants ) ) ) . isEmpty ( ) ,
( ) = > $"sorted descendants contains more nodes than it should: ({FocusTravesalUtils.difference(new HashSet<FocusNode>(sortedDescendants),(new HashSet<FocusNode>(scope.traversalDescendants) ))})"
scope . traversalDescendants . toSet ( ) . difference ( sortedDescendants . toSet ( ) ) . isEmpty ,
"sorted descendants are missing some nodes: (${scope.traversalDescendants.toSet().difference(sortedDescendants.toSet( ))})"
FocusTravesalUtils . difference ( new HashSet < FocusNode > ( scope . traversalDescendants ) , new HashSet < FocusNode > ( sortedDescendants ) ) . isEmpty ( ) ,
( ) = > $"sorted descendants are missing some nodes: ({FocusTravesalUtils.difference(new HashSet<FocusNode>(scope.traversalDescendants),new HashSet<FocusNode>(sortedDescendants ))})"
) ;
return sortedDescendants ;
}
if ( focusedChild = = null ) {
FocusNode firstFocus = findFirstFocus ( currentNode ) ;
if ( firstFocus ! = null ) {
_focusAndEnsureVisible (
FocusTravesalUtils . _focusAndEnsureVisible (
alignmentPolicy : forward ? ScrollPositionAlignmentPolicy . keepVisibleAtEnd : ScrollPositionAlignmentPolicy . keepVisibleAtStart ,
alignmentPolicy : forward ? ScrollPositionAlignmentPolicy . keepVisibleAtEnd : ScrollPositionAlignmentPolicy . keepVisibleAtStart
) ;
return true ;
}
_focusAndEnsureVisible ( sortedNodes . First ( ) , alignmentPolicy : ScrollPositionAlignmentPolicy . keepVisibleAtEnd ) ;
FocusTravesalUtils . _focusAndEnsureVisible ( sortedNodes . First ( ) , alignmentPolicy : ScrollPositionAlignmentPolicy . keepVisibleAtEnd ) ;
_focusAndEnsureVisible ( sortedNodes . Last ( ) , alignmentPolicy : ScrollPositionAlignmentPolicy . keepVisibleAtStart ) ;
FocusTravesalUtils . _focusAndEnsureVisible ( sortedNodes . Last ( ) , alignmentPolicy : ScrollPositionAlignmentPolicy . keepVisibleAtStart ) ;
return true ;
}
FocusNode previousNode = null ;
foreach ( FocusNode node in maybeFlipped ) {
if ( previousNode = = focusedChild ) {
_focusAndEnsureVisible (
FocusTravesalUtils . _focusAndEnsureVisible (
alignmentPolicy : forward ? ScrollPositionAlignmentPolicy . keepVisibleAtEnd : ScrollPositionAlignmentPolicy . keepVisibleAtStart ,
alignmentPolicy : forward ? ScrollPositionAlignmentPolicy . keepVisibleAtEnd : ScrollPositionAlignmentPolicy . keepVisibleAtStart
) ;
return true ;
}
public readonly TraversalDirection direction ;
public readonly FocusNode node ;
}
class _ReadingOrderDirectionalGroupData : Diagnosticable {
public class _ReadingOrderSortData : Diagnosticable {
public _ReadingOrderSortData ( FocusNode node ) {
D . assert ( node ! = null ) ;
this . node = node ;
rect = node . rect ;
directionality = _findDirectionality ( node . context ) ;
}
public readonly TextDirection directionality ;
public readonly Rect rect ;
public readonly FocusNode node ;
public static TextDirection _findDirectionality ( BuildContext context ) {
return ( context . getElementForInheritedWidgetOfExactType < Directionality > ( ) . widget as Directionality ) . textDirection ;
}
public static TextDirection commonDirectionalityOf ( List < _ReadingOrderSortData > list ) {
IEnumerable < HashSet < Directionality > > allAncestors = list . Select ( ( _ReadingOrderSortData member ) = > new HashSet < Directionality > ( member . directionalAncestors ) ) ;
HashSet < Directionality > common = null ;
foreach ( HashSet < Directionality > ancestorSet in allAncestors ) {
common ? ? = ancestorSet ;
common = FocusTravesalUtils . intersaction ( common , ancestorSet ) ;
}
if ( common . isEmpty ( ) ) {
return list . First ( ) . directionality ;
}
foreach ( var com in list . First ( ) . directionalAncestors ) {
if ( common . Contains ( com ) ) {
return com . textDirection ;
}
}
return common . First ( ) . textDirection ;
}
/ * public static void sortWithDirectionality ( List < _ReadingOrderSortData > list , TextDirection directionality ) {
mergeSort < _ReadingOrderSortData > ( list , compare : ( _ReadingOrderSortData a , _ReadingOrderSortData b ) = > {
switch ( directionality ) {
case TextDirection . ltr :
return a . rect . left . CompareTo ( b . rect . left ) ;
case TextDirection . rtl :
return b . rect . right . CompareTo ( a . rect . right ) ;
}
D . assert ( false , ( ) = > "Unhandled directionality $directionality" ) ;
return 0 ;
} ) ;
} * /
public IEnumerable < Directionality > directionalAncestors {
get {
List < Directionality > getDirectionalityAncestors ( BuildContext context ) {
List < Directionality > result = new List < Directionality > ( ) ;
InheritedElement directionalityElement = context . getElementForInheritedWidgetOfExactType < Directionality > ( ) ;
while ( directionalityElement ! = null ) {
result . Add ( directionalityElement . widget as Directionality ) ;
directionalityElement = FocusTravesalUtils . _getAncestor ( directionalityElement ) ? . getElementForInheritedWidgetOfExactType < Directionality > ( ) ;
}
return result ;
}
_directionalAncestors ? ? = getDirectionalityAncestors ( node . context ) ;
return _directionalAncestors ;
}
}
List < Directionality > _directionalAncestors ;
public override void debugFillProperties ( DiagnosticPropertiesBuilder properties ) {
base . debugFillProperties ( properties ) ;
properties . add ( new DiagnosticsProperty < TextDirection > ( "directionality" , directionality ) ) ;
properties . add ( new StringProperty ( "name" , node . debugLabel , defaultValue : null ) ) ;
properties . add ( new DiagnosticsProperty < Rect > ( "rect" , rect ) ) ;
}
}
public class _ReadingOrderDirectionalGroupData : Diagnosticable {
public _ReadingOrderDirectionalGroupData ( List < _ReadingOrderSortData > members ) {
this . members = members ;
}
TextDirection directionality {
public TextDirection directionality {
get {
return members . First ( ) . directionality ;
}
Rect rect {
get { if ( _rect = = null ) {
foreach ( Rect rect in members . Select < Rect > (
foreach ( Rect rect in members . Select (
( _ReadingOrderSortData data ) = > data . rect ) ) {
_rect ? ? = rect ;
_rect = _rect . expandToInclude ( rect ) ;
}
List < Directionality > _memberAncestors ;
public static void sortWithDirectionality ( List < _ReadingOrderDirectionalGroupData > list , TextDirection directionality ) {
/ * public static void sortWithDirectionality ( List < _ReadingOrderDirectionalGroupData > list , TextDirection directionality ) {
return a . rect . left . compareTo ( b . rect . left ) ;
return a . rect . left . CompareTo ( b . rect . left ) ;
return b . rect . right . compareTo ( a . rect . right ) ;
return b . rect . right . CompareTo ( a . rect . right ) ;
}
public override void debugFillProperties ( TextTreeRenderer . DiagnosticPropertiesBuilder properties ) {
} * /
public override void debugFillProperties ( DiagnosticPropertiesBuilder properties ) {
properties . add ( DiagnosticsProperty < TextDirection > ( "directionality" , directionality ) ) ;
properties . add ( DiagnosticsProperty < Rect > ( "rect" , rect ) ) ;
properties . add ( IterableProperty < String > ( "members" , members . map < String > ( ( _ReadingOrderSortData member ) {
return "" $ { member . node . debugLabel } "(${member.rect})" ;
} ) ) ) ;
properties . add ( new DiagnosticsProperty < TextDirection > ( "directionality" , directionality ) ) ;
properties . add ( new DiagnosticsProperty < Rect > ( "rect" , rect ) ) ;
//properties.add(new IterableProperty<string>("members", members.map<String>((_ReadingOrderSortData member) {
// return ""${member.node.debugLabel}"(${member.rect})";
//})));
public class ReadingOrderTraversalPolicy : FocusTraversalPolicy , DirectionalFocusTraversalPolicyMixin {
public class ReadingOrderTraversalPolicy : FocusTraversalPolicy , DirectionalFocusTraversalPolicyMixin
{
public List < _ReadingOrderDirectionalGroupData > _collectDirectionalityGroups ( IEnumerable < _ReadingOrderSortData > candidates ) {
TextDirection currentDirection = candidates . First ( ) . directionality ;
List < _ReadingOrderSortData > currentGroup = new List < _ReadingOrderSortData > ( ) ;
continue ;
}
currentDirection = candidate . directionality ;
result . Add ( _ReadingOrderDirectionalGroupData ( currentGroup ) ) ;
result . Add ( new _ReadingOrderDirectionalGroupData ( currentGroup ) ) ;
result . Add ( _ReadingOrderDirectionalGroupData ( currentGroup ) ) ;
result . Add ( new _ReadingOrderDirectionalGroupData ( currentGroup ) ) ;
if ( bandGroup . members . length = = 1 ) {
if ( bandGroup . members . Count = = 1 ) {
_ReadingOrderSortData . sortWithDirectionality ( bandGroup . members , bandGroup . directionality ) ;
// _ReadingOrderSortData.sortWithDirectionality(bandGroup.members, bandGroup.directionality);
public _ReadingOrderSortData _pickNext ( List < _ReadingOrderSortData > candidates ) {
/ * public _ReadingOrderSortData _pickNext ( List < _ReadingOrderSortData > candidates ) {
mergeSort < _ReadingOrderSortData > ( candidates , compare : ( _ReadingOrderSortData a , _ReadingOrderSortData b ) = > a . rect . top . c ompareTo( b . rect . top ) ) ;
MERGESORT < _ReadingOrderSortData > ( candidates , compare : ( _ReadingOrderSortData a , _ReadingOrderSortData b ) = > a . rect . top . C ompareTo( b . rect . top ) ) ;
Rect band = Rect . fromLTRB ( double . n egativeInfinity, current . rect . top , double . i nfinity, current . rect . bottom ) ;
Rect band = Rect . fromLTRB ( float . N egativeInfinity, current . rect . top , float . PositiveI nfinity, current . rect . bottom ) ;
D . assert ( topmost . rect . isEmpty | | inBandOfTop . isNotEmpty ) ;
D . assert ( topmost . rect . isEmpty | | inBandOfTop . isNotEmpty ( ) ) ;
if ( inBandOfTop . Count < = 1 ) {
return topmost ;
}
if ( bandGroups . Count = = 1 ) {
return bandGroups . First ( ) . members . first ;
return bandGroups . First ( ) . members . First ( ) ;
return bandGroups . First ( ) . members . first ;
}
return bandGroups . First ( ) . members . First ( ) ;
} * /
public override IEnumerable < FocusNode > sortDescendants ( IEnumerable < FocusNode > descendants ) {
/ * public override IEnumerable < FocusNode > sortDescendants ( IEnumerable < FocusNode > descendants ) {
List < _ReadingOrderSortData > data = new List < _ReadingOrderSortData > ( ) {
foreach ( FocusNode node in descendants )
_ReadingOrderSortData ( node ) ,
} ;
List < _ReadingOrderSortData > data = new List < _ReadingOrderSortData > ( ) ;
foreach ( FocusNode node in descendants )
data . Add ( new _ReadingOrderSortData ( node ) ) ;
List < FocusNode > sortedList = new List < FocusNode > ( ) ;
List < _ReadingOrderSortData > unplaced = data ;
_ReadingOrderSortData current = _pickNext ( unplaced ) ;
unplaced . Remove ( current ) ;
}
return sortedList ;
}
} * /
} * /
}
}