Enhance result panel update

The last commit f132cb54baa000a245feb5da87149960f6dbd9f5 only fix UI
flickering for different icon. This commit also fix the commit for same
icon. e.g. in web search plugin, although the title is different, but
the icon is not changes.
part of #350
This commit is contained in:
bao-qian
2015-11-08 01:44:28 +00:00
parent 9627272b57
commit 2b27e84956
2 changed files with 58 additions and 16 deletions

View File

@@ -9,7 +9,7 @@ using Wox.Plugin;
namespace Wox.Helper
{
class ListBoxItems : ObservableCollection<Result>
// todo implement custom moveItem,removeItem,insertItem
// todo implement custom moveItem,removeItem,insertItem for better performance
{
public void RemoveAll(Predicate<Result> predicate)
{
@@ -18,6 +18,7 @@ namespace Wox.Helper
List<Result> itemsToRemove = Items.Where(x => predicate(x)).ToList();
if (itemsToRemove.Count > 0)
{
itemsToRemove.ForEach(item => Items.Remove(item));
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
@@ -29,5 +30,38 @@ namespace Wox.Helper
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
public void Update(List<Result> newItems)
{
int newCount = newItems.Count;
int oldCount = Items.Count;
int location = newCount > oldCount ? oldCount : newCount;
for (int i = 0; i < location; i++)
{
Result oldItem = Items[i];
Result newItem = newItems[i];
if (!Equals(oldItem, newItem))
{
this[i] = newItem;
}
}
if (newCount > oldCount)
{
for (int i = oldCount; i < newCount; i++)
{
Add(newItems[i]);
}
}
else
{
int removeIndex = newCount;
for (int i = newCount; i < oldCount; i++)
{
RemoveAt(removeIndex);
}
}
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
@@ -21,7 +22,7 @@ namespace Wox
public event Action<Result> LeftMouseClickEvent;
public event Action<Result> RightMouseClickEvent;
public event Action<Result, IDataObject, DragEventArgs> ItemDropEvent;
private readonly ListBoxItems _results; //todo, for better performance, override the default linear search
private readonly ListBoxItems _results;
private readonly object _resultsUpdateLock = new object();
protected virtual void OnRightMouseClick(Result result)
@@ -57,15 +58,16 @@ namespace Wox
public void AddResults(List<Result> newResults, string resultId)
{
var oldResults = _results.Where(r => r.PluginID == resultId).ToList();
// intersection of A (old results) and B (new newResults)
var intersection = oldResults.Intersect(newResults).ToList();
lock (_resultsUpdateLock)
{
var resultCopy = _results.ToList();
var oldResults = resultCopy.Where(r => r.PluginID == resultId).ToList();
// intersection of A (old results) and B (new newResults)
var intersection = oldResults.Intersect(newResults).ToList();
// remove result of relative complement of B in A
foreach (var result in oldResults.Except(intersection))
{
_results.Remove(result);
resultCopy.Remove(result);
}
// update scores
@@ -80,14 +82,16 @@ namespace Wox
// update index for result in intersection of A and B
foreach (var result in intersection)
{
int oldIndex = _results.IndexOf(result);
int oldScore = _results[oldIndex].Score;
int oldIndex = resultCopy.IndexOf(result);
int oldScore = resultCopy[oldIndex].Score;
if (result.Score != oldScore)
{
int newIndex = InsertIndexOf(result.Score);
int newIndex = InsertIndexOf(result.Score, resultCopy);
if (newIndex != oldIndex)
{
_results.Move(oldIndex, newIndex);
var item = resultCopy[oldIndex];
resultCopy.RemoveAt(oldIndex);
resultCopy.Insert(newIndex, item);
}
}
}
@@ -95,9 +99,13 @@ namespace Wox
// insert result in relative complement of A in B
foreach (var result in newResults.Except(intersection))
{
int newIndex = InsertIndexOf(result.Score);
_results.Insert(newIndex, result);
int newIndex = InsertIndexOf(result.Score, resultCopy);
resultCopy.Insert(newIndex, result);
}
// update UI in one run, so it can avoid UI flickering
_results.Update(resultCopy);
lbResults.Margin = lbResults.Items.Count > 0 ? new Thickness { Top = 8 } : new Thickness { Top = 0 };
SelectFirst();
}
@@ -108,13 +116,13 @@ namespace Wox
return TopMostRecordStorage.Instance.IsTopMost(result);
}
private int InsertIndexOf(int newScore)
private int InsertIndexOf(int newScore, IList<Result> list)
{
int index = 0;
for (; index < lbResults.Items.Count; index++)
for (; index < list.Count; index++)
{
Result result = lbResults.Items[index] as Result;
if (newScore > result?.Score)
var result = list[index];
if (newScore > result.Score)
{
break;
}