public void EstimateElementBounds( ElementType elementType, int elementIndex, EstimationReference headerReference, EstimationReference containerReference, Rect window, out Rect pReturnValue) { pReturnValue = default; int totalItems; global::System.Diagnostics.Debug.Assert(elementType == ElementType.ItemContainer); totalItems = GetLayoutDataInfoProviderNoRef.GetTotalItemCount(); global::System.Diagnostics.Debug.Assert(0 <= elementIndex && elementIndex < totalItems); int maxStackingLines; int virtualizingLine; int stackingLine; var visualIndex = m_indexCorrectionTable.ActualIndexToVisualIndex(elementIndex); DetermineLineInformation(visualIndex, out maxStackingLines, out virtualizingLine, out stackingLine); global::System.Diagnostics.Debug.Assert(maxStackingLines > 0); SetPointFromRectInVirtualizingDirection(ref pReturnValue, virtualizingLine * SizeInVirtualizingDirection(m_cellSize)); SetPointFromRectInNonVirtualizingDirection(ref pReturnValue, GetItemStackingPosition(stackingLine)); pReturnValue.Width = m_cellSize.Width; pReturnValue.Height = m_cellSize.Height; return; }
// Based on current element's index/type and action, return the next element index/type. public void GetTargetIndexFromNavigationAction( ElementType elementType, int elementIndex, KeyNavigationAction action, Rect windowConstraint, out ElementType pTargetElementType, out int pTargetElementIndex) { int totalItems; int totalGroups; totalItems = GetLayoutDataInfoProviderNoRef.GetTotalItemCount(); totalGroups = GetLayoutDataInfoProviderNoRef.GetTotalGroupCount(); global::System.Diagnostics.Debug.Assert(0 <= elementIndex && elementIndex < totalItems); global::System.Diagnostics.Debug.Assert(elementType == ElementType.ItemContainer); pTargetElementType = ElementType.ItemContainer; if (action != KeyNavigationAction.Left && action != KeyNavigationAction.Right && action != KeyNavigationAction.Up && action != KeyNavigationAction.Down) { throw new ArgumentException(nameof(action)); } int step = (action == KeyNavigationAction.Left || action == KeyNavigationAction.Up) ? -1 : 1; pTargetElementIndex = elementIndex; // Easy case: the action is along layout orientation, therefore handle it. if ((VirtualizationDirection == Orientation.Vertical && (action == KeyNavigationAction.Left || action == KeyNavigationAction.Right)) || (VirtualizationDirection == Orientation.Horizontal && (action == KeyNavigationAction.Up || action == KeyNavigationAction.Down))) { pTargetElementIndex = Math.Min(Math.Max(elementIndex + step, 0), totalItems - 1); } // The action is not in layout direction. We must jump to the next item in the same row/column. // We are not grouping, easy. else { // TODO: verify startAt int maxLineLength = DetermineMaxStackingLine(); int nextIndex = elementIndex + step * maxLineLength; if (0 <= nextIndex && nextIndex < totalItems) { pTargetElementIndex = nextIndex; } } global::System.Diagnostics.Debug.Assert(0 <= pTargetElementIndex && pTargetElementIndex < totalItems); return; }
EstimateElementIndex( ElementType elementType, EstimationReference headerReference, EstimationReference containerReference, Rect window, out Rect pTargetRect, out int pReturnValue) { pTargetRect = default; pReturnValue = -1; int totalItems = 0; global::System.Diagnostics.Debug.Assert(elementType == ElementType.ItemContainer); totalItems = GetLayoutDataInfoProviderNoRef.GetTotalItemCount(); int maxStackingLines = (totalItems > 0) ? DetermineMaxStackingLine() : 1; // We are non-grouped, this is an exact calculation global::System.Diagnostics.Debug.Assert(maxStackingLines > 0); // How many virtualizing lines does it take to get from the start to here? float virtualizingDistanceFromStart = Math.Max(0.0f, PointFromRectInVirtualizingDirection(window)); int virtualizingLineDistance = (int)(virtualizingDistanceFromStart / SizeInVirtualizingDirection(m_cellSize)); float stackingDistanceFromStart = Math.Max(0.0f, PointFromRectInNonVirtualizingDirection(window)); int stackingLineDistance = (int)(stackingDistanceFromStart / SizeInNonVirtualizingDirection(m_cellSize)); int targetVisualIndex = virtualizingLineDistance * maxStackingLines + stackingLineDistance; // clamp targetvisualIndex. int firstVisualIndex = m_indexCorrectionTable.ActualIndexToVisualIndex(0); int lastVisualIndex = m_indexCorrectionTable.ActualIndexToVisualIndex(totalItems - 1); targetVisualIndex = Math.Min(targetVisualIndex, lastVisualIndex); targetVisualIndex = Math.Max(targetVisualIndex, firstVisualIndex); // With the final index, calculate its position int ignored; int virtualizingLine; int stackingLine; DetermineLineInformation(targetVisualIndex, out ignored, out virtualizingLine, out stackingLine); pReturnValue = m_indexCorrectionTable.VisualIndexToActualIndex(targetVisualIndex); SetPointFromRectInVirtualizingDirection(ref pTargetRect, virtualizingLine * SizeInVirtualizingDirection(m_cellSize)); SetPointFromRectInNonVirtualizingDirection(ref pTargetRect, GetItemStackingPosition(stackingLine)); return; }
public void EstimatePanelExtent( EstimationReference lastHeaderReference, EstimationReference lastContainerReference, Rect windowConstraint, out Size pExtent) { pExtent = default; int totalItems = 0; totalItems = GetLayoutDataInfoProviderNoRef.GetTotalItemCount(); int maxStackingLine = DetermineMaxStackingLine(); global::System.Diagnostics.Debug.Assert(maxStackingLine > 0); //actual panel size SetSizeInVirtualizingDirection(ref pExtent, GetVirtualizedExtentOfItems(totalItems, maxStackingLine)); SetSizeInNonVirtualizingDirection(ref pExtent, GetItemStackingPosition(Math.Min(maxStackingLine, totalItems))); return; }