public override IEnumerable <FocusNode> sortDescendants(IEnumerable <FocusNode> descendants) { D.assert(descendants != null); if (descendants.Count() <= 1) { return(descendants); } 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); sortedList.Add(current.node); unplaced.Remove(current); while (unplaced.isNotEmpty()) { _ReadingOrderSortData next = _pickNext(unplaced); current = next; sortedList.Add(current.node); unplaced.Remove(current); } return(sortedList); }
public _ReadingOrderSortData _pickNext(List <_ReadingOrderSortData> candidates) { FocusTravesalUtils.mergeSort <_ReadingOrderSortData>(candidates, compare: (_ReadingOrderSortData a, _ReadingOrderSortData b) => a.rect.top.CompareTo(b.rect.top)); _ReadingOrderSortData topmost = candidates.First(); List <_ReadingOrderSortData> inBand(_ReadingOrderSortData current, IEnumerable <_ReadingOrderSortData> _candidates) { Rect band = Rect.fromLTRB(float.NegativeInfinity, current.rect.top, float.PositiveInfinity, current.rect.bottom); return(LinqUtils <_ReadingOrderSortData> .WhereList(_candidates, ((_ReadingOrderSortData item) => { return !item.rect.intersect(band).isEmpty; }))); } List <_ReadingOrderSortData> inBandOfTop = inBand(topmost, candidates); D.assert(topmost.rect.isEmpty || inBandOfTop.isNotEmpty()); if (inBandOfTop.Count <= 1) { return(topmost); } TextDirection nearestCommonDirectionality = _ReadingOrderSortData.commonDirectionalityOf(inBandOfTop); _ReadingOrderSortData.sortWithDirectionality(inBandOfTop, nearestCommonDirectionality); List <_ReadingOrderDirectionalGroupData> bandGroups = _collectDirectionalityGroups(inBandOfTop); if (bandGroups.Count == 1) { return(bandGroups.First().members.First()); } _ReadingOrderDirectionalGroupData.sortWithDirectionality(bandGroups, nearestCommonDirectionality); return(bandGroups.First().members.First()); }