/Odyssey/Odyssey/Controls/Primitives/QuickJumpWrapPanel.cs
# · C# · 271 lines · 217 code · 43 blank · 11 comment · 41 complexity · aaaa33c5f763509c399f51750c28b1ca MD5 · raw file
- using System;
- using System.Net;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Ink;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Shapes;
- using Odyssey.Controls.Internals;
- using System.Windows.Threading;
- using System.Collections.Generic;
- using Odyssey.Effects;
-
- namespace Odyssey.Controls.Primitives
- {
- /// <summary>
- /// Panel used with OdcListBox to display the alphabetic quick jump list.
- /// </summary>
- public class QuickJumpWrapPanel : OdcVirtualizingPanel
- {
- public QuickJumpWrapPanel()
- : base()
- {
- for (int i = 0; i < 28; i++)
- {
- quickJumpItems.Add(new QuickJumpListBoxItem());
- }
- for (int i = 0; i < 7; i++)
- {
- QuickJumpRowPanel panel = new QuickJumpRowPanel { ItemWidth = 112d, ItemHeight = 112d };
- QuickJumpSwivelEffect.SetIsElement(panel, true);
- panel.CacheMode = new BitmapCache();
- Children.Add(panel);
- rowPanels.Add(panel);
- }
- }
-
- private List<QuickJumpListBoxItem> quickJumpItems = new List<QuickJumpListBoxItem>();
- private int maxItems = 40;
-
- private DispatcherTimer timer;
-
- public double ItemWidth
- {
- get { return (double)GetValue(ItemWidthProperty); }
- set { SetValue(ItemWidthProperty, value); }
- }
-
- public static readonly DependencyProperty ItemWidthProperty =
- DependencyProperty.Register("ItemWidth", typeof(double), typeof(QuickJumpWrapPanel), new PropertyMetadata(112.0));
-
-
- public static readonly DependencyProperty ColumnCountProperty =
- DependencyProperty.Register("ColumnCount", typeof(int), typeof(QuickJumpWrapPanel), new PropertyMetadata(4));
-
-
- protected override void OnUnloaded(object sender, RoutedEventArgs e)
- {
- base.OnUnloaded(sender, e);
- StopTimer();
- }
-
- protected override Size MeasureOverride(Size availableSize)
- {
- double totalHeight = availableSize.Height;
- double totalWidth = availableSize.Width;
-
- IItemsControl itemsControl = ItemsControl;
- int count = itemsControl.ItemsSource != null ? itemsControl.ItemsSource.Count : 0;
- if (double.IsInfinity(totalHeight)) totalHeight = itemsControl.ItemHeight * count;
- if (double.IsInfinity(totalWidth)) totalWidth = 800d;
-
- if (IsInvalidated) Balance();
-
- totalHeight = totalHeight > 480d ? 800d : 480d;
- totalWidth = totalWidth > 480d ? 800d : 480d;
- return new Size(totalWidth, totalHeight);
- }
-
- protected override Size ArrangeOverride(Size finalSize)
- {
- int n = ItemsControl.ItemsSource.Count;
- double w = ItemWidth;
- double h = ItemsControl.ItemHeight;
-
- double h0 = finalSize.Height > 480d ? 800d : 480d;
- double w0 = finalSize.Width > 480d ? 800d : 480d;
-
- int numColumns = (int)Math.Floor(w0 / w);
- int numRows = (int)Math.Ceiling((double)n / numColumns);
-
- double left = (w0 - numColumns * w) / 2.0;
- double top = (h0 - numRows * h) / 2.0;
-
- int columnIndex = 0;
-
- n = elements.Count;
-
- int rowCount = 0;
-
- Rect rect = new Rect(left, top, w, h);
-
-
- if (n > 0)
- {
- QuickJumpRowPanel rowPanel = NextRowPanel(rowCount, ref rect, finalSize.Width);
- for (int i = 0; i < n; i++)
- {
- var child = elements[i];
- if (rowPanel != child.Parent)
- {
- if (child.Parent != null)
- {
- (child.Parent as Panel).Children.Remove(child);
- }
- rowPanel.Children.Add(child);
- }
- if (++columnIndex < numColumns)
- {
- rect.X += w;
- }
- else
- {
- rowCount++;
- columnIndex = 0;
- rect.X = left;
- rect.Y += h;
- if (i < n - 1)
- {
- rowPanel = NextRowPanel(rowCount, ref rect, finalSize.Width);
- }
- }
- }
- }
-
- rect = new Rect(left, top, w, h);
-
- foreach (var child in Children)
- {
- if (rect.Y <= finalSize.Height)
- {
- child.Arrange(rect);
- rect.Y = rect.Bottom;
- }
- else child.Arrange(new Rect());
- }
-
-
- return finalSize;
- }
-
-
- private QuickJumpRowPanel NextRowPanel(int rowCount, ref Rect rect, double width)
- {
- if (rowPanels.Count <= rowCount)
- {
- throw new ArgumentNullException("NextRowPanel");
- }
- else
- {
- QuickJumpRowPanel panel = rowPanels[rowCount];
- return panel;
- }
- }
-
- private List<QuickJumpRowPanel> rowPanels = new List<QuickJumpRowPanel>();
- private List<FrameworkElement> elements = new List<FrameworkElement>();
-
-
- private void Balance()
- {
- var itemsControl = ItemsControl;
- IsInvalidated = false;
- var items = itemsControl.ItemsSource;
- if (items != null)
- {
- int n = items.Count;
-
- if (maxItems > n) maxItems = n;
- else if (maxItems < n)
- {
- StartTimer();
- }
- OdcListBox lb = itemsControl as OdcListBox;
- for (int i = 0; i < maxItems; i++)
- {
- QuickJumpListBoxItem item = quickJumpItems[i];
- item.Content = item.DataContext = items[i];
- item.ListBox = lb;
- if (item.Parent == null) elements.Add(item);
-
- //bool isNew;
- //FrameworkElement item = itemsControl.GetItemContainer(i, out isNew);
- //if (isNew)
- //{
- // elements.Insert(i, item);
- // itemsControl.ItemContainerAttached(i, item);
- //}
- }
- }
- }
-
- private void StartTimer()
- {
- if (timer == null || !timer.IsEnabled)
- {
- if (timer == null)
- {
- timer = new DispatcherTimer
- {
- Interval = TimeSpan.FromMilliseconds(1.0)
- };
- timer.Tick += delegate
- {
- var itemsControl = ItemsControl;
- int n = ItemsControl != null && itemsControl.ItemsSource != null ? itemsControl.ItemsSource.Count : 0;
- int nextItems = maxItems + 4;
- if (nextItems >= n)
- {
- nextItems = n;
- StopTimer();
- }
- bool isNew;
- for (int i = maxItems; i < nextItems; i++)
- {
- FrameworkElement item = itemsControl.GetItemContainer(i, out isNew);
- this.Children.Add(item);
- }
- maxItems = nextItems;
-
- };
- }
- else StopTimer();
- timer.Start();
- }
- }
-
- private void StopTimer()
- {
- if (timer != null && timer.IsEnabled) timer.Stop();
- }
-
- protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
- {
- Invalidate();
- }
-
- private void SetLoadState(UIElement item)
- {
- Control ctrl = item as Control;
- if (ctrl != null)
- {
- VisualStateManager.GoToState(ctrl, VisualStates.LoadedState, true);
- }
- }
-
-
- public override void ScrollIntoView(int itemIndex)
- {
- }
-
-
- protected internal override void Reset()
- {
- // Children.Clear();
- base.Reset();
- }
- }
- }