WPF Cover Flow Tutorial : Part 7

15 篇文章 0 订阅
After some improvements in the Cover class, let's describe how virtualization works.

We do not keep all covers in memory. Remember the drawing in Part 2. At a given time, we only keep a few covers on both sides of the current cover (at position index). This means that every time we browse through the covers, we create and destroy one or more covers. If we do not keep all covers in memory, we have to keep enough information to rebuild covers : image file path and position. We also need to remember which covers are currently built.
  1. public const int HalfRealizedCount = 6;  
  2. public const int PageSize = HalfRealizedCount;  
  3. private readonly ICoverFactory coverFactory;  
  4. private readonly Dictionary<int, ImageInfo> imageList = new Dictionary<int, ImageInfo>();  
  5. private readonly Dictionary<int, ICover> coverList = new Dictionary<int, ICover>();  
  6. private int index;  
  7. private int firstRealized = -1;  
  8. private int lastRealized = -1;  
  • HalfRealizedCount is the number of covers created before and after current cover
  • I use the same value for the PageSize (we could choose a different value) when we will move by more than one cover at a time
  • imageList will map cover positions to image paths
  • coverList will be used as an array to keep realized covers
  • firstRealized and lastRealized are the positions of respectively first and last realized covers
There will be two ways to browse covers : by less than a page with animation or jumping by more than a page without animation.
  1. private void RotateCover(int pos, bool animate)  
  2. {  
  3.     if (coverList.ContainsKey(pos))  
  4.         coverList[pos].Animate(index, animate);  
  5. }  
  6. private void UpdateIndex(int newIndex)  
  7. {  
  8.     if (index != newIndex)  
  9.     {  
  10.         bool animate = Math.Abs(newIndex - index) < PageSize;  
  11.         UpdateRange(newIndex);  
  12.         int oldIndex = index;  
  13.         index = newIndex;  
  14.         if (index > oldIndex)  
  15.         {  
  16.             if (oldIndex < firstRealized)  
  17.                 oldIndex = firstRealized;  
  18.             for (int i = oldIndex; i <= index; i++)  
  19.                 RotateCover(i, animate);  
  20.         }  
  21.         else  
  22.         {  
  23.             if (oldIndex > lastRealized)  
  24.                 oldIndex = lastRealized;  
  25.             for (int i = oldIndex; i >= index; i--)  
  26.                 RotateCover(i, animate);  
  27.         }  
  28.         camera.Position = new Point3D(Cover.CoverStep * index, camera.Position.Y, camera.Position.Z);  
  29.     }  
  30. }  
I'm not sure if the test in RotateCover is still needed. Here is how the new UpdateIndex function. We compute the animation boolean like described before. The UpdateRange function deals with cover realization : it will create and destroy covers as necessary and updates both realized indexes. Then, for all realized covers between old and new index, we rotate the covers. Finally, like before, we update camera positions.
  1. private void RemoveCover(int pos)  
  2. {  
  3.     if (!coverList.ContainsKey(pos))  
  4.         return;  
  5.     coverList[pos].Destroy();  
  6.     coverList.Remove(pos);  
  7. }  
  8. private void UpdateRange(int newIndex)  
  9. {  
  10.     int newFirstRealized = Math.Max(newIndex - HalfRealizedCount, 0);  
  11.     int newLastRealized = Math.Min(newIndex + HalfRealizedCount, imageList.Count - 1);  
  12.     if (lastRealized < newFirstRealized || firstRealized > newLastRealized)  
  13.     {  
  14.         visualModel.Children.Clear();  
  15.         coverList.Clear();  
  16.     }  
  17.     else if (firstRealized < newFirstRealized)  
  18.     {  
  19.         for (int i = firstRealized; i < newFirstRealized; i++)  
  20.             RemoveCover(i);  
  21.     }  
  22.     else if (newLastRealized < lastRealized)  
  23.     {  
  24.         for (int i = lastRealized; i > newLastRealized; i--)  
  25.             RemoveCover(i);  
  26.     }  
  27.     for (int i = newFirstRealized; i <= newLastRealized; i++)  
  28.     {  
  29.         if (!coverList.ContainsKey(i))  
  30.         {  
  31.             ICover cover = coverFactory.NewCover(imageList[i].Host, imageList[i].Path, i, newIndex);  
  32.             coverList.Add(i, cover);  
  33.         }  
  34.     }  
  35.     firstRealized = newFirstRealized;  
  36.     lastRealized = newLastRealized;  
  37. }  
In the UpdateRange method, we first compute realized indexes. Then, we remove necessary covers (might need all covers if we move by more than HalfRealizedCount. Finally, we create missing covers.
  1. public void GoToNext()  
  2. {  
  3.     UpdateIndex(Math.Min(index + 1, imageList.Count - 1));  
  4. }  
  5. public void GoToPrevious()  
  6. {  
  7.     UpdateIndex(Math.Max(index - 1, 0));  
  8. }  
  9. public void GoToNextPage()  
  10. {  
  11.     UpdateIndex(Math.Min(index + PageSize, imageList.Count - 1));  
  12. }  
  13. public void GoToPreviousPage()  
  14. {  
  15.     UpdateIndex(Math.Max(index - PageSize, 0));  
  16. }  
Navigation methods are self explanatory.

Possible improvements :
  • Slider
  • Events
  • Tags (e.g. album names to jump to covers)

Source is available in next post.

转载自:http://d3dal3.blogspot.com/2009/04/wpf-cover-flow-tutorial-part-7.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值