private double Sort(FlexElementCollection elements, FlexDistributeDirection direction) { ArrayUtils.EnsureArrayLength(ref _sortedElements, elements.Count, false); ArrayUtils.EnsureArrayLength(ref _sortedIndex, elements.Count, false); _actualCount = 0; var fixedLength = 0.0; for (var index = elements.Count - 1; index >= 0; index--) { var item = elements[index]; if (item.CanDistribute(direction) == false) { fixedLength += item.ActualLength; continue; } _sortedElements[_actualCount] = item; _sortedIndex[_actualCount] = index; _actualCount++; } Array.Sort(_sortedElements, _sortedIndex, 0, _actualCount, FlexItemComparer.Default); _currentCount = _actualCount; return(fixedLength); }
public bool CanDistribute(FlexDistributeDirection direction) { if (StretchDirection == FlexStretchDirection.None && IsStar == false) { return(false); } if (direction == FlexDistributeDirection.Expand) { return(ActualLength < MaxLength && (CanExpand || IsStar)); } return(ActualLength > MinLength && (CanShrink || IsStar)); }
private void Distribute(FlexElementCollection elements, FlexDistributeDirection direction, double target) { ArrayUtils.EnsureArrayLength(ref _index, elements.Count, false); _priorityStack.Clear(); _priorityStack.Push(0); foreach (var flexItem in elements) { var priority = flexItem.GetPriority(direction); if (priority > _priorityStack.Peek()) { _priorityStack.Push(priority); } } while (_priorityStack.Count > 0) { var priority = _priorityStack.Pop(); _elementsCopy.EnsureCount(elements.Count); _elementsCopy.UseLayoutRounding = elements.UseLayoutRounding; var currentTarget = target; var j = 0; for (var i = 0; i < elements.Count; i++) { var flexItem = elements[i]; if (flexItem.GetPriority(direction) < priority) { currentTarget -= flexItem.ActualLength; continue; } _index[j] = i; _elementsCopy[j] = flexItem; j++; } _elementsCopy.EnsureCount(j); currentTarget = Math.Max(0, currentTarget); if (direction == FlexDistributeDirection.Expand) { ExpandAllImpl(_elementsCopy, currentTarget); } else { ShrinkAllImpl(_elementsCopy, currentTarget); } for (var i = 0; i < _elementsCopy.Count; i++) { var flexItem = _elementsCopy[i]; var index = _index[i]; elements[index] = flexItem; } if (elements.Actual.IsCloseTo(target)) { return; } } }