Decouple thumb generation for ListView control
- Issue MatterHackers/MCCentral#3357 ListView ActiveContainer_Changed fires far more than expected - Issue MatterHackers/MCCentral#3363 Start page -> Part icon -> Click does not load workspace
This commit is contained in:
parent
ad62450575
commit
7d8bb2d964
6 changed files with 76 additions and 51 deletions
|
|
@ -277,7 +277,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
public override async void OnLoad(EventArgs args)
|
||||
{
|
||||
base.OnLoad(args);
|
||||
await this.LoadItemThumbnail(listViewItem.ListView.ActiveContainer);
|
||||
await this.LoadItemThumbnail();
|
||||
}
|
||||
|
||||
public override Color BackgroundColor
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
// Folder items
|
||||
foreach (var childContainer in this.SortItems(containerItems))
|
||||
{
|
||||
var listViewItem = new ListViewItem(childContainer, this);
|
||||
var listViewItem = new ListViewItem(childContainer, this.ActiveContainer);
|
||||
listViewItem.DoubleClick += listViewItem_DoubleClick;
|
||||
items.Add(listViewItem);
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
|
||||
foreach (var item in this.SortItems(filteredResults))
|
||||
{
|
||||
var listViewItem = new ListViewItem(item, this);
|
||||
var listViewItem = new ListViewItem(item, this.ActiveContainer, this);
|
||||
listViewItem.DoubleClick += listViewItem_DoubleClick;
|
||||
items.Add(listViewItem);
|
||||
|
||||
|
|
@ -280,10 +280,9 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
|
||||
private void WritableContainer_ItemContentChanged(object sender, ItemChangedEventArgs e)
|
||||
{
|
||||
var firstItem = items.Where(i => i.Model.ID == e.LibraryItem.ID).FirstOrDefault();
|
||||
if (firstItem != null)
|
||||
if (items.Where(i => i.Model.ID == e.LibraryItem.ID).FirstOrDefault() is ListViewItem listViewItem)
|
||||
{
|
||||
firstItem.ViewWidget.LoadItemThumbnail(firstItem.ListView.ActiveContainer).ConfigureAwait(false);
|
||||
listViewItem.ViewWidget.LoadItemThumbnail().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -326,16 +325,16 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
}
|
||||
}
|
||||
|
||||
internal static ImageBuffer LoadCachedImage(ListViewItem listViewItem, int width, int height)
|
||||
internal static ImageBuffer LoadCachedImage(ILibraryItem libraryItem, int width, int height)
|
||||
{
|
||||
ImageBuffer cachedItem = LoadImage(ApplicationController.Instance.ThumbnailCachePath(listViewItem.Model, width, height));
|
||||
ImageBuffer cachedItem = LoadImage(ApplicationController.Instance.ThumbnailCachePath(libraryItem, width, height));
|
||||
if (cachedItem != null)
|
||||
{
|
||||
return cachedItem;
|
||||
}
|
||||
|
||||
// Check for big render, resize, cache and return
|
||||
var bigRender = LoadImage(ApplicationController.Instance.ThumbnailCachePath(listViewItem.Model));
|
||||
var bigRender = LoadImage(ApplicationController.Instance.ThumbnailCachePath(libraryItem));
|
||||
if (bigRender != null)
|
||||
{
|
||||
try
|
||||
|
|
@ -344,7 +343,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
|
||||
// Cache at requested size
|
||||
AggContext.ImageIO.SaveImageData(
|
||||
ApplicationController.Instance.ThumbnailCachePath(listViewItem.Model, width, height),
|
||||
ApplicationController.Instance.ThumbnailCachePath(libraryItem, width, height),
|
||||
thumbnail);
|
||||
|
||||
return thumbnail;
|
||||
|
|
@ -378,7 +377,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
}
|
||||
|
||||
// TODO: ResizeCanvas is also colorizing thumbnails as a proof of concept
|
||||
public ImageBuffer ResizeCanvas(ImageBuffer originalImage, int width, int height)
|
||||
public static ImageBuffer ResizeCanvas(ImageBuffer originalImage, int width, int height)
|
||||
{
|
||||
var destImage = new ImageBuffer(width, height, 32, originalImage.GetRecieveBlender());
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,15 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
|
||||
public ListViewItemBase ViewWidget { get; set; }
|
||||
|
||||
public ListViewItem(ILibraryItem libraryItem, ListView listView)
|
||||
public ListViewItem(ILibraryItem libraryItem, ILibraryContainer container, ListView listView = null)
|
||||
{
|
||||
this.Container = container;
|
||||
this.ListView = listView;
|
||||
this.Model = libraryItem;
|
||||
}
|
||||
|
||||
public ILibraryContainer Container { get; }
|
||||
|
||||
internal void OnDoubleClick()
|
||||
{
|
||||
DoubleClick?.Invoke(this, null);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using MatterHackers.Agg;
|
||||
|
|
@ -64,6 +65,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
this.thumbHeight = height;
|
||||
}
|
||||
|
||||
// TODO: Why is this static?
|
||||
private static bool WidgetOnScreen(GuiWidget widget, RectangleDouble bounds)
|
||||
{
|
||||
if (!widget.Visible)
|
||||
|
|
@ -89,33 +91,42 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
return true;
|
||||
}
|
||||
|
||||
public async Task LoadItemThumbnail(ILibraryContainer libraryContainer)
|
||||
public Task LoadItemThumbnail()
|
||||
{
|
||||
var thumbnail = ListView.LoadCachedImage(listViewItem, thumbWidth, thumbHeight);
|
||||
return LoadItemThumbnail(
|
||||
listViewItem.Model,
|
||||
listViewItem.Container,
|
||||
this.thumbWidth,
|
||||
this.thumbHeight,
|
||||
this.SetItemThumbnail,
|
||||
() => ListViewItemBase.WidgetOnScreen(this, this.LocalBounds));
|
||||
}
|
||||
|
||||
private static async Task LoadItemThumbnail(ILibraryItem libraryItem, ILibraryContainer libraryContainer, int thumbWidth, int thumbHeight, Action<ImageBuffer, bool> thumbnailSetter, Func<bool> shouldGenerateThumbnail)
|
||||
{
|
||||
var thumbnail = ListView.LoadCachedImage(libraryItem, thumbWidth, thumbHeight);
|
||||
if (thumbnail != null)
|
||||
{
|
||||
SetItemThumbnail(thumbnail);
|
||||
thumbnailSetter(thumbnail, false);
|
||||
return;
|
||||
}
|
||||
|
||||
var itemModel = listViewItem.Model;
|
||||
|
||||
if (thumbnail == null)
|
||||
{
|
||||
// Ask the container - allows the container to provide its own interpretation of the item thumbnail
|
||||
thumbnail = await libraryContainer.GetThumbnail(itemModel, thumbWidth, thumbHeight);
|
||||
thumbnail = await libraryContainer.GetThumbnail(libraryItem, thumbWidth, thumbHeight);
|
||||
}
|
||||
|
||||
if (thumbnail == null && itemModel is IThumbnail)
|
||||
if (thumbnail == null && libraryItem is IThumbnail)
|
||||
{
|
||||
// If the item provides its own thumbnail, try to collect it
|
||||
thumbnail = await (itemModel as IThumbnail).GetThumbnail(thumbWidth, thumbHeight);
|
||||
thumbnail = await (libraryItem as IThumbnail).GetThumbnail(thumbWidth, thumbHeight);
|
||||
}
|
||||
|
||||
if (thumbnail == null)
|
||||
{
|
||||
// Ask content provider - allows type specific thumbnail creation
|
||||
var contentProvider = ApplicationController.Instance.Library.GetContentProvider(itemModel);
|
||||
var contentProvider = ApplicationController.Instance.Library.GetContentProvider(libraryItem);
|
||||
if (contentProvider is MeshContentProvider)
|
||||
{
|
||||
// Before we have a thumbnail set to the content specific thumbnail
|
||||
|
|
@ -124,19 +135,19 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
ApplicationController.Instance.QueueForGeneration(async () =>
|
||||
{
|
||||
// When this widget is dequeued for generation, validate before processing. Off-screen widgets should be skipped and will requeue next time they become visible
|
||||
if (ListViewItemBase.WidgetOnScreen(this, this.LocalBounds))
|
||||
if (shouldGenerateThumbnail?.Invoke() == true)
|
||||
{
|
||||
SetItemThumbnail(generatingThumbnailIcon);
|
||||
thumbnailSetter(generatingThumbnailIcon, false);
|
||||
|
||||
// Then try to load a content specific thumbnail
|
||||
await contentProvider.GetThumbnail(
|
||||
itemModel,
|
||||
libraryItem,
|
||||
thumbWidth,
|
||||
thumbHeight,
|
||||
(image) =>
|
||||
{
|
||||
// Use the content providers default image if an image failed to load
|
||||
SetItemThumbnail(image ?? contentProvider.DefaultImage, true);
|
||||
thumbnailSetter(image ?? contentProvider.DefaultImage, true);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -145,7 +156,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
{
|
||||
// Then try to load a content specific thumbnail
|
||||
await contentProvider.GetThumbnail(
|
||||
itemModel,
|
||||
libraryItem,
|
||||
thumbWidth,
|
||||
thumbHeight,
|
||||
(image) => thumbnail = image);
|
||||
|
|
@ -155,10 +166,10 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
if (thumbnail == null)
|
||||
{
|
||||
// Use the listview defaults
|
||||
thumbnail = ((itemModel is ILibraryContainerLink) ? defaultFolderIcon : defaultItemIcon).AlphaToPrimaryAccent();
|
||||
thumbnail = ((libraryItem is ILibraryContainerLink) ? defaultFolderIcon : defaultItemIcon).AlphaToPrimaryAccent();
|
||||
}
|
||||
|
||||
SetItemThumbnail(thumbnail);
|
||||
thumbnailSetter(thumbnail, false);
|
||||
}
|
||||
|
||||
internal void EnsureSelection()
|
||||
|
|
@ -168,13 +179,13 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
// Existing selection only survives with ctrl->click
|
||||
if (!Keyboard.IsKeyDown(Keys.ControlKey))
|
||||
{
|
||||
listViewItem.ListView.SelectedItems.Clear();
|
||||
listViewItem.ListView?.SelectedItems.Clear();
|
||||
}
|
||||
|
||||
// Any mouse down ensures selection - mouse up will evaluate if DragDrop occurred and toggle selection if not
|
||||
if (!listViewItem.ListView.SelectedItems.Contains(listViewItem))
|
||||
if (!listViewItem.ListView?.SelectedItems.Contains(listViewItem) == true)
|
||||
{
|
||||
listViewItem.ListView.SelectedItems.Add(listViewItem);
|
||||
listViewItem.ListView?.SelectedItems.Add(listViewItem);
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
|
|
@ -188,7 +199,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
{
|
||||
if (wasSelected)
|
||||
{
|
||||
listViewItem.ListView.SelectedItems.Remove(listViewItem);
|
||||
listViewItem.ListView?.SelectedItems.Remove(listViewItem);
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
|
|
@ -218,7 +229,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
// Resize canvas to target as fallback
|
||||
if (thumbnail.Width < thumbWidth || thumbnail.Height < thumbHeight)
|
||||
{
|
||||
thumbnail = listViewItem.ListView.ResizeCanvas(thumbnail, thumbWidth, thumbHeight);
|
||||
thumbnail = ListView.ResizeCanvas(thumbnail, thumbWidth, thumbHeight);
|
||||
}
|
||||
else if (thumbnail.Width > thumbWidth || thumbnail.Height > thumbHeight)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
public override async void OnLoad(EventArgs args)
|
||||
{
|
||||
base.OnLoad(args);
|
||||
await this.LoadItemThumbnail(listViewItem.ListView.ActiveContainer);
|
||||
await this.LoadItemThumbnail();
|
||||
}
|
||||
|
||||
private bool isHoverItem = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue