Browse Source

WIP: More work on primitive virtualization.

Steven Kirk 9 years ago
parent
commit
03e37f8f69

+ 1 - 0
src/Avalonia.Controls/Avalonia.Controls.csproj

@@ -69,6 +69,7 @@
     <Compile Include="Presenters\IContentPresenterHost.cs" />
     <Compile Include="Presenters\IItemsPresenterHost.cs" />
     <Compile Include="Presenters\ItemsPresenterBase.cs" />
+    <Compile Include="Presenters\ThingamybobPresenter.cs" />
     <Compile Include="Primitives\HeaderedSelectingControl.cs" />
     <Compile Include="Primitives\IScrollable.cs" />
     <Compile Include="Primitives\TabStripItem.cs" />

+ 104 - 0
src/Avalonia.Controls/Presenters/ThingamybobPresenter.cs

@@ -0,0 +1,104 @@
+using System;
+using Avalonia.Controls.Primitives;
+using Avalonia.Media;
+
+namespace Avalonia.Controls.Presenters
+{
+    public class ThingamybobPresenter : Decorator, IItemsPresenter, IScrollable
+    {
+        private IVirtualizingPanel _panel;
+        private int _firstIndex;
+        private int _lastIndex;
+
+        public override void ApplyTemplate()
+        {
+            if (_panel == null)
+            {
+                _panel = new VirtualizingStackPanel();
+                _panel.ArrangeCompleted = CheckPanel;
+                Child = _panel;
+            }
+        }
+
+        public IPanel Panel => _panel;
+
+        Action IScrollable.InvalidateScroll { get; set; }
+
+        Size IScrollable.Extent => new Size(1, 100);
+
+        Vector IScrollable.Offset
+        {
+            get
+            {
+                return new Vector(0, _firstIndex);
+            }
+
+            set
+            {
+                var count = _lastIndex - _firstIndex;
+                _firstIndex = (int)Math.Round(value.Y);
+                _lastIndex = _firstIndex + count;
+                Renumber();
+            }
+        }
+
+        Size IScrollable.Viewport => new Size(1, _lastIndex - _firstIndex);
+        Size IScrollable.ScrollSize => new Size(0, 1);
+        Size IScrollable.PageScrollSize => new Size(0, 1);
+
+        protected override Size ArrangeOverride(Size finalSize)
+        {
+            var result = base.ArrangeOverride(finalSize);
+            CreateItems();
+            ((IScrollable)this).InvalidateScroll();
+            return result;
+        }
+
+        private void CreateItems()
+        {
+            var randomColor = Color.FromUInt32(
+                (uint)(0xff000000 + new Random().Next(0xffffff)));
+
+            while (!_panel.IsFull)
+            {
+                _panel.Children.Add(new TextBlock
+                {
+                    Text = "Item " + ++_lastIndex,
+                    Background = new SolidColorBrush(randomColor),
+                });
+            }
+        }
+
+        private void RemoveItems()
+        {
+            var remove = _panel.OverflowCount;
+
+            _panel.Children.RemoveRange(
+                _panel.Children.Count - remove,
+                _panel.OverflowCount);
+            _lastIndex -= remove;
+        }
+
+        private void Renumber()
+        {
+            var index = _firstIndex;
+
+            foreach (TextBlock child in _panel.Children)
+            {
+                child.Text = "Item " + ++index;
+            }
+        }
+
+        private void CheckPanel()
+        {
+            if (!_panel.IsFull)
+            {
+                CreateItems();
+            }
+            else if (_panel.OverflowCount > 0)
+            {
+                RemoveItems();
+            }
+        }
+    }
+}

+ 8 - 50
src/Avalonia.Controls/Thingamybob.cs

@@ -1,66 +1,24 @@
 using Avalonia.Media;
 using System;
+using Avalonia.Controls.Primitives;
+using Avalonia.Controls.Presenters;
 
 namespace Avalonia.Controls
 {
     public class Thingamybob : Decorator
     {
-        private int _lastIndex;
+        private ScrollViewer _scrollViewer;
+        private ThingamybobPresenter _presenter;
 
         public override void ApplyTemplate()
         {
             if (Child == null)
             {
-                Child = new VirtualizingStackPanel();
-                ((IVirtualizingPanel)Child).ArrangeCompleted = CheckPanel;
-            }
-        }
-
-        protected override Size ArrangeOverride(Size finalSize)
-        {
-            var result = base.ArrangeOverride(finalSize);
-            CreateItems();
-            return result;
-        }
-
-        private void CreateItems()
-        {
-            var panel = Child as IVirtualizingPanel;
-            var randomColor = Color.FromUInt32(
-                (uint)(0xff000000 + new Random().Next(0xffffff)));
-
-            while (!panel.IsFull)
-            {
-                panel.Children.Add(new TextBlock
-                {
-                    Text = "Item " + ++_lastIndex,
-                    Background = new SolidColorBrush(randomColor),
-                });
-            }
-        }
-
-        private void RemoveItems()
-        {
-            var panel = Child as IVirtualizingPanel;
-            var remove = panel.OverflowCount;
-
-            panel.Children.RemoveRange(
-                panel.Children.Count - remove,
-                panel.OverflowCount);
-            _lastIndex -= remove;
-        }
+                _scrollViewer = new ScrollViewer();
+                _presenter = new ThingamybobPresenter();
+                _scrollViewer.Content = _presenter;
 
-        private void CheckPanel()
-        {
-            var panel = Child as IVirtualizingPanel;
-
-            if (!panel.IsFull)
-            {
-                CreateItems();
-            }
-            else if (panel.OverflowCount > 0)
-            {
-                RemoveItems();
+                Child = _scrollViewer;
             }
         }
     }