From acfa8329672d23db92b8e9f6e7afc54cdbc77ad9 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 25 Jun 2019 13:34:28 +0200 Subject: [PATCH] Try up code. Remove unused code and implement some focus stuff. --- .../Repeaters/FlowLayoutAlgorithm.cs | 8 -- .../Repeaters/ITrackerHandleManager.cs | 10 --- .../Repeaters/ItemsRepeater.cs | 13 --- .../Repeaters/NonVirtualizingLayout.cs | 21 +---- .../Repeaters/StackLayout.cs | 1 - .../Repeaters/UniformGridLayout.cs | 2 - .../Repeaters/UniqueIdElementPool.cs | 5 -- .../Repeaters/ViewManager.cs | 79 +++---------------- .../Repeaters/ViewportManager.cs | 49 ------------ .../Repeaters/VirtualizationInfo.cs | 8 -- 10 files changed, 14 insertions(+), 182 deletions(-) delete mode 100644 src/Avalonia.Controls/Repeaters/ITrackerHandleManager.cs diff --git a/src/Avalonia.Controls/Repeaters/FlowLayoutAlgorithm.cs b/src/Avalonia.Controls/Repeaters/FlowLayoutAlgorithm.cs index 6aaad0bdb5..f605bf72c8 100644 --- a/src/Avalonia.Controls/Repeaters/FlowLayoutAlgorithm.cs +++ b/src/Avalonia.Controls/Repeaters/FlowLayoutAlgorithm.cs @@ -407,7 +407,6 @@ namespace Avalonia.Controls.Repeaters _elementManager.ClearRealizedRange(); // FlowLayout requires that the anchor is the first element in the row. var internalAnchor = _algorithmCallbacks.Algorithm_GetAnchorForTargetElement(index, availableSize, context); - //MUX_ASSERT(internalAnchor.Index <= index); // No need to set the position of the anchor. // (0,0) is fine for now since the extent can @@ -505,7 +504,6 @@ namespace Avalonia.Controls.Repeaters int realizedElementCount = _elementManager.GetRealizedElementCount(); if (realizedElementCount > 0) { - //MUX_ASSERT(_firstRealizedDataIndexInsideRealizationWindow != -1 && _lastRealizedDataIndexInsideRealizationWindow != -1); int countInLine = 0; var previousElementBounds = _elementManager.GetLayoutBoundsForDataIndex(_firstRealizedDataIndexInsideRealizationWindow); var currentLineOffset = _orientation.MajorStart(previousElementBounds); @@ -662,12 +660,6 @@ namespace Avalonia.Controls.Repeaters { _context.LayoutOrigin = new Point(_lastExtent.X, _lastExtent.Y); } - else - { - // Should have 0 origin for non-virtualizing layout since we always start from - // the first item - //MUX_ASSERT(m_lastExtent.X == 0 && m_lastExtent.Y == 0); - } } public IControl GetElementIfRealized(int dataIndex) diff --git a/src/Avalonia.Controls/Repeaters/ITrackerHandleManager.cs b/src/Avalonia.Controls/Repeaters/ITrackerHandleManager.cs deleted file mode 100644 index 55ce6c28ca..0000000000 --- a/src/Avalonia.Controls/Repeaters/ITrackerHandleManager.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Avalonia.Controls.Repeaters -{ - internal interface ITrackerHandleManager - { - } -} diff --git a/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs b/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs index 9d71685b11..b0e9842d57 100644 --- a/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs +++ b/src/Avalonia.Controls/Repeaters/ItemsRepeater.cs @@ -243,19 +243,11 @@ namespace Avalonia.Controls.Repeaters else { var newBounds = element.Bounds; - - //if (virtInfo.ArrangeBounds != ItemsRepeater.InvalidRect && - // newBounds != virtInfo.ArrangeBounds) - //{ - // _animationManager.OnElementBoundsChanged(element, virtInfo.ArrangeBounds, newBounds); - //} - virtInfo.ArrangeBounds = newBounds; } } _viewportManager.OnOwnerArranged(); - //_animationManager.OnOwnerArranged(); return arrangeSize; } @@ -299,10 +291,6 @@ namespace Avalonia.Controls.Repeaters { OnLayoutChanged((Layout)args.OldValue, (Layout)args.NewValue); } - //else if (property == AnimatorProperty) - //{ - // OnAnimatorChanged((ElementAnimator)args.OldValue, (ElementAnimator)args.NewValue); - //} else if (property == HorizontalCacheLengthProperty) { _viewportManager.HorizontalCacheLength = (double)args.NewValue; @@ -592,7 +580,6 @@ namespace Avalonia.Controls.Repeaters try { - //_animationManager.OnItemsSourceChanged(sender, args); _viewManager.OnItemsSourceChanged(sender, args); if (Layout != null) diff --git a/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs b/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs index c5ab27fabb..fb8d329d7f 100644 --- a/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs +++ b/src/Avalonia.Controls/Repeaters/NonVirtualizingLayout.cs @@ -4,26 +4,7 @@ using System.Text; namespace Avalonia.Controls.Repeaters { - public class NonVirtualizingLayout : Layout + public abstract class NonVirtualizingLayout : Layout { - public override Size Arrange(LayoutContext context, Size finalSize) - { - throw new NotImplementedException(); - } - - public override void InitializeForContext(LayoutContext context) - { - throw new NotImplementedException(); - } - - public override Size Measure(LayoutContext context, Size availableSize) - { - throw new NotImplementedException(); - } - - public override void UninitializeForContext(LayoutContext context) - { - throw new NotImplementedException(); - } } } diff --git a/src/Avalonia.Controls/Repeaters/StackLayout.cs b/src/Avalonia.Controls/Repeaters/StackLayout.cs index db1900d03b..66b0be5b92 100644 --- a/src/Avalonia.Controls/Repeaters/StackLayout.cs +++ b/src/Avalonia.Controls/Repeaters/StackLayout.cs @@ -53,7 +53,6 @@ namespace Avalonia.Controls.Repeaters { if (firstRealized != null) { - //MUX_ASSERT(lastRealized); _orientation.SetMajorStart( ref extent, _orientation.MajorStart(firstRealizedLayoutBounds) - firstRealizedItemIndex * averageElementSize); diff --git a/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs b/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs index 4d062e23ab..624e477354 100644 --- a/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs +++ b/src/Avalonia.Controls/Repeaters/UniformGridLayout.cs @@ -217,8 +217,6 @@ namespace Avalonia.Controls.Repeaters if (firstRealized != null) { - ////MUX_ASSERT(lastRealized); - _orientation.SetMajorStart( ref extent, _orientation.MajorStart(firstRealizedLayoutBounds) - (firstRealizedItemIndex / itemsPerLine) * lineSize); diff --git a/src/Avalonia.Controls/Repeaters/UniqueIdElementPool.cs b/src/Avalonia.Controls/Repeaters/UniqueIdElementPool.cs index 4b3922b9c3..3ad883c04b 100644 --- a/src/Avalonia.Controls/Repeaters/UniqueIdElementPool.cs +++ b/src/Avalonia.Controls/Repeaters/UniqueIdElementPool.cs @@ -14,8 +14,6 @@ namespace Avalonia.Controls.Repeaters public void Add(IControl element) { - //MUX_ASSERT(_owner.ItemsSourceView.HasKeyIndexMapping); - var virtInfo = ItemsRepeater.GetVirtualizationInfo(element); var key = virtInfo.UniqueId; @@ -29,8 +27,6 @@ namespace Avalonia.Controls.Repeaters public IControl Remove(int index) { - //MUX_ASSERT(_owner.ItemsSourceView.HasKeyIndexMapping); - // Check if there is already a element in the mapping and if so, use it. string key = _owner.ItemsSourceView.KeyFromIndex(index); @@ -44,7 +40,6 @@ namespace Avalonia.Controls.Repeaters public void Clear() { - //MUX_ASSERT(_owner.ItemsSourceView.HasKeyIndexMapping); _elementMap.Clear(); } diff --git a/src/Avalonia.Controls/Repeaters/ViewManager.cs b/src/Avalonia.Controls/Repeaters/ViewManager.cs index 5fccba5412..1167705b5b 100644 --- a/src/Avalonia.Controls/Repeaters/ViewManager.cs +++ b/src/Avalonia.Controls/Repeaters/ViewManager.cs @@ -108,7 +108,7 @@ namespace Avalonia.Controls.Repeaters _owner.ItemTemplateShim.RecycleElement(_owner, element); virtInfo.MoveOwnershipToElementFactory(); - //_phaser.StopPhasing(element, virtInfo); + if (_lastFocusedElement == element) { // Focused element is going away. Remove the tracked last focused element @@ -125,13 +125,9 @@ namespace Avalonia.Controls.Repeaters var focusCandidate = FindFocusCandidate(clearedIndex, focusedChild); if (focusCandidate != null) { - //var focusState = _lastFocusedElement?.FocusState ?? FocusState.Programmatic; - - // If the last focused element has focus, use its focus state, if not use programmatic. - //focusState = focusState == FocusState.Unfocused ? FocusState.Programmatic : focusState; focusCandidate.Focus(); - _lastFocusedElement = focusedChild; + // Add pin to hold the focused element. UpdatePin(focusedChild, true /* addPin */); } @@ -186,12 +182,12 @@ namespace Avalonia.Controls.Repeaters focusCandidate = nextElement as IControl; if (focusCandidate != null) { - ////var firstFocus = FocusManager.FindFirstFocusableElement(nextElement); + var firstFocus = KeyboardNavigationHandler.GetNext(nextElement, NavigationDirection.First); - ////if (firstFocus != null) - ////{ - //// focusCandidate = firstFocus as IControl; - ////} + if (firstFocus != null) + { + focusCandidate = firstFocus as IControl; + } } } @@ -200,12 +196,12 @@ namespace Avalonia.Controls.Repeaters focusCandidate = previousElement as IControl; if (previousElement != null) { - ////var lastFocus = FocusManager.FindLastFocusableElement(previousElement); + var lastFocus = KeyboardNavigationHandler.GetNext(previousElement, NavigationDirection.Last); - ////if (lastFocus != null) - ////{ - //// focusCandidate = lastFocus as IControl; - ////} + if (lastFocus != null) + { + focusCandidate = lastFocus as IControl; + } } } @@ -233,8 +229,6 @@ namespace Avalonia.Controls.Repeaters var elementInfo = _pinnedPool[i]; var virtInfo = elementInfo.VirtualizationInfo; - //MUX_ASSERT(virtInfo.Owner() == ElementOwner.PinnedPool); - if (!virtInfo.IsPinned) { _pinnedPool.RemoveAt(i); @@ -471,16 +465,10 @@ namespace Avalonia.Controls.Repeaters IControl element = null; bool cachedFirstLastIndicesInvalid = _firstRealizedElementIndexHeldByLayout == FirstRealizedElementIndexDefault; - //MUX_ASSERT(!cachedFirstLastIndicesInvalid || m_lastRealizedElementIndexHeldByLayout == LastRealizedElementIndexDefault); - bool isRequestedIndexInRealizedRange = (_firstRealizedElementIndexHeldByLayout <= index && index <= _lastRealizedElementIndexHeldByLayout); if (cachedFirstLastIndicesInvalid || isRequestedIndexInRealizedRange) { - // Both First and Last indices need to be valid or default. - //MUX_ASSERT((m_firstRealizedElementIndexHeldByLayout == FirstRealizedElementIndexDefault && m_lastRealizedElementIndexHeldByLayout == LastRealizedElementIndexDefault) || - // (m_firstRealizedElementIndexHeldByLayout != FirstRealizedElementIndexDefault && m_lastRealizedElementIndexHeldByLayout != LastRealizedElementIndexDefault)); - foreach (var child in _owner.Children) { var virtInfo = ItemsRepeater.TryGetVirtualizationInfo(child); @@ -572,27 +560,7 @@ namespace Avalonia.Controls.Repeaters } // Prepare the element - // If we are phasing, run phase 0 before setting DataContext. If phase 0 is not - // run before setting DataContext, when setting DataContext all the phases will be - // run in the OnDataContextChanged handler in code generated by the xaml compiler (code-gen). - var extension = false; ////CachedVisualTreeHelpers.GetDataTemplateComponent(element); - if (extension) - { - ////// Clear out old data. - ////extension.Recycle(); - ////int nextPhase = VirtualizationInfo.PhaseReachedEnd; - ////// Run Phase 0 - ////extension.ProcessBindings(data, index, 0 /* currentPhase */, nextPhase); - - ////// Setup phasing information, so that Phaser can pick up any pending phases left. - ////// Update phase on virtInfo. Set data and templateComponent only if x:Phase was used. - ////virtInfo.UpdatePhasingInfo(nextPhase, nextPhase > 0 ? data : null, nextPhase > 0 ? extension : null); - } - else - { - // Set data context only if no x:Bind was used. ie. No data template component on the root. - element.DataContext = data; - } + element.DataContext = data; virtInfo.MoveOwnershipToLayoutFromElementFactory( index, @@ -613,9 +581,7 @@ namespace Avalonia.Controls.Repeaters children.Add(element); } - ////repeater.AnimationManager.OnElementPrepared(element); repeater.OnElementPrepared(element, index); - ////_phaser.PhaseElement(element, virtInfo); // Update realized indices _firstRealizedElementIndexHeldByLayout = Math.Min(_firstRealizedElementIndexHeldByLayout, index); @@ -635,25 +601,6 @@ namespace Avalonia.Controls.Repeaters return _isDataSourceStableResetPending; } - private bool ClearElementToAnimator(IControl element, VirtualizationInfo virtInfo) - { - return false; - ////bool cleared = _owner.AnimationManager.ClearElement(element); - ////if (cleared) - ////{ - //// int clearedIndex = virtInfo.Index; - //// virtInfo.MoveOwnershipToAnimator(); - //// if (_lastFocusedElement == element) - //// { - //// // Focused element is going away. Remove the tracked last focused element - //// // and pick a reasonable next focus if we can find one within the layout - //// // realized elements. - //// MoveFocusFromClearedIndex(clearedIndex); - //// } - ////} - ////return cleared; - } - private bool ClearElementToPinnedPool(IControl element, VirtualizationInfo virtInfo, bool isClearedDueToCollectionChange) { if (_isDataSourceStableResetPending) diff --git a/src/Avalonia.Controls/Repeaters/ViewportManager.cs b/src/Avalonia.Controls/Repeaters/ViewportManager.cs index cf69f9beb6..238870644f 100644 --- a/src/Avalonia.Controls/Repeaters/ViewportManager.cs +++ b/src/Avalonia.Controls/Repeaters/ViewportManager.cs @@ -62,7 +62,6 @@ namespace Avalonia.Controls.Repeaters { ValidateCacheLength(value); _maximumHorizontalCacheLength = value; - ResetCacheBuffer(); } } } @@ -76,7 +75,6 @@ namespace Avalonia.Controls.Repeaters { ValidateCacheLength(value); _maximumVerticalCacheLength = value; - ResetCacheBuffer(); } } } @@ -182,7 +180,6 @@ namespace Avalonia.Controls.Repeaters _expectedViewportShift = default; _pendingViewportShift = default; _unshiftableShift = default; - ResetCacheBuffer(); _effectiveViewportChangedRevoker?.Dispose(); @@ -250,10 +247,6 @@ namespace Avalonia.Controls.Repeaters _horizontalCacheBufferPerSide = Math.Min(_horizontalCacheBufferPerSide, maximumHorizontalCacheBufferPerSide); _verticalCacheBufferPerSide = Math.Min(_verticalCacheBufferPerSide, maximumVerticalCacheBufferPerSide); - - // Since we grow the cache buffer at the end of the arrange pass, - // we need to register work even if we just reached cache potential. - RegisterCacheBuildWork(); } } } @@ -294,14 +287,6 @@ namespace Avalonia.Controls.Repeaters { if (!_managingViewportDisabled) { - // We do not animate bring-into-view operations where the anchor is disconnected because - // it doesn't look good (the blank space is obvious because the layout can't keep track - // of two realized ranges while the animation is going on). - if (_isAnchorOutsideRealizedRange) - { - ////args.AnimationDesired(false); - } - // During the time between a bring into view request and the element coming into view we do not // want the anchor provider to pick some anchor and jump to it. Instead we want to anchor on the // element that is being brought into view. We can do this by making just that element as a potential @@ -389,8 +374,6 @@ namespace Avalonia.Controls.Repeaters private void UpdateViewport(Rect viewport) { - //assert(!m_managingViewportDisabled); - var previousVisibleWindow = _visibleWindow; var currentVisibleWindow = viewport; if (-currentVisibleWindow.X <= ItemsRepeater.ClearedElementsArrangePosition.X && @@ -407,18 +390,6 @@ namespace Avalonia.Controls.Repeaters TryInvalidateMeasure(); } - private void ResetCacheBuffer() - { - _horizontalCacheBufferPerSide = 0.0; - _verticalCacheBufferPerSide = 0.0; - - if (!_managingViewportDisabled) - { - // We need to start building the realization buffer again. - RegisterCacheBuildWork(); - } - } - private static void ValidateCacheLength(double cacheLength) { if (cacheLength < 0.0 || double.IsInfinity(cacheLength) || double.IsNaN(cacheLength)) @@ -427,26 +398,6 @@ namespace Avalonia.Controls.Repeaters } } - private void RegisterCacheBuildWork() - { - ////assert(!m_managingViewportDisabled); - if (_owner.Layout != null && - _cacheBuildAction == null) - { - // We capture 'owner' (a strong refernce on ItemsRepeater) to make sure ItemsRepeater is still around - // when the async action completes. By protecting ItemsRepeater, we also ensure that this instance - // of ViewportManager (referenced by 'this' pointer) is valid because the lifetime of ItemsRepeater - // and ViewportManager is the same (see ItemsRepeater::m_viewportManager). - // We can't simply hold a strong reference on ViewportManager because it's not a COM object. - ////auto strongOwner = m_owner->get_strong(); - ////m_cacheBuildAction.set( - //// m_owner->Dispatcher().RunIdleAsync([this, strongOwner](const winrt::IdleDispatchedHandlerArgs&) - ////{ - //// OnCacheBuildActionCompleted(); - ////})); - } - } - private void TryInvalidateMeasure() { // Don't invalidate measure if we have an invalid window. diff --git a/src/Avalonia.Controls/Repeaters/VirtualizationInfo.cs b/src/Avalonia.Controls/Repeaters/VirtualizationInfo.cs index 5c6554be81..dddf00efd0 100644 --- a/src/Avalonia.Controls/Repeaters/VirtualizationInfo.cs +++ b/src/Avalonia.Controls/Repeaters/VirtualizationInfo.cs @@ -37,7 +37,6 @@ namespace Avalonia.Controls.Repeaters public void MoveOwnershipToLayoutFromElementFactory(int index, string uniqueId) { - //MUX_ASSERT(_owner == ElementOwner.ElementFactory); Owner = ElementOwner.Layout; Index = index; UniqueId = uniqueId; @@ -45,20 +44,16 @@ namespace Avalonia.Controls.Repeaters public void MoveOwnershipToLayoutFromUniqueIdResetPool() { - //MUX_ASSERT(_owner == ElementOwner.UniqueIdResetPool); Owner = ElementOwner.Layout; } public void MoveOwnershipToLayoutFromPinnedPool() { - //MUX_ASSERT(_owner == ElementOwner.PinnedPool); - //MUX_ASSERT(IsPinned()); Owner = ElementOwner.Layout; } public void MoveOwnershipToElementFactory() { - //MUX_ASSERT(_owner != ElementOwner.ElementFactory); Owner = ElementOwner.ElementFactory; _pinCounter = 0; Index = -1; @@ -68,7 +63,6 @@ namespace Avalonia.Controls.Repeaters public void MoveOwnershipToUniqueIdResetPoolFromLayout() { - //MUX_ASSERT(_owner == ElementOwner.Layout); Owner = ElementOwner.UniqueIdResetPool; // Keep the pinCounter the same. If the container survives the reset // it can go on being pinned as if nothing happened. @@ -79,7 +73,6 @@ namespace Avalonia.Controls.Repeaters // During a unique id reset, some elements might get removed. // Their ownership will go from the UniqueIdResetPool to the Animator. // The common path though is for ownership to go from Layout to Animator. - //MUX_ASSERT(_owner == ElementOwner.Layout || _owner == ElementOwner.UniqueIdResetPool); Owner = ElementOwner.Animator; Index = -1; _pinCounter = 0; @@ -87,7 +80,6 @@ namespace Avalonia.Controls.Repeaters public void MoveOwnershipToPinnedPool() { - //MUX_ASSERT(_owner == ElementOwner.Layout); Owner = ElementOwner.PinnedPool; }