mirror of
https://github.com/cyanfish/naps2.git
synced 2024-09-17 10:47:11 +03:00
WinForms: Use an ImageList abstraction
This commit is contained in:
parent
82b3456ec8
commit
7542765d45
157
NAPS2.Lib.WinForms/EtoForms/WinForms/WinFormsImageList.cs
Normal file
157
NAPS2.Lib.WinForms/EtoForms/WinForms/WinFormsImageList.cs
Normal file
@ -0,0 +1,157 @@
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using Eto.WinForms;
|
||||
|
||||
namespace NAPS2.EtoForms.WinForms;
|
||||
|
||||
public abstract class WinFormsImageList<T> where T : notnull
|
||||
{
|
||||
private readonly WinFormsListView<T> _listView;
|
||||
private readonly ListViewBehavior<T> _behavior;
|
||||
|
||||
private WinFormsImageList(WinFormsListView<T> listView, ListViewBehavior<T> behavior)
|
||||
{
|
||||
_listView = listView;
|
||||
_behavior = behavior;
|
||||
}
|
||||
|
||||
private Image ItemToImage(T item)
|
||||
{
|
||||
return _behavior.GetImage(item, _listView.ImageSize).ToSD();
|
||||
}
|
||||
|
||||
public abstract void Clear();
|
||||
public abstract void Append(T item, ListViewItem listViewItem);
|
||||
public abstract void Replace(T item, int index);
|
||||
public abstract void DeleteFromEnd();
|
||||
public abstract Image Get(ListViewItem listViewItem);
|
||||
public abstract Image PartialAppend(T item);
|
||||
public abstract void FinishPartialAppends(List<Image> images);
|
||||
|
||||
public class Custom : WinFormsImageList<T>
|
||||
{
|
||||
private readonly List<Image> _images = new();
|
||||
|
||||
public Custom(WinFormsListView<T> listView, ListViewBehavior<T> behavior) : base(listView, behavior)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
foreach (var image in _images)
|
||||
{
|
||||
image.Dispose();
|
||||
}
|
||||
_images.Clear();
|
||||
}
|
||||
|
||||
public override void Append(T item, ListViewItem listViewItem)
|
||||
{
|
||||
_images.Add(ItemToImage(item));
|
||||
}
|
||||
|
||||
public override void Replace(T item, int index)
|
||||
{
|
||||
_images[index].Dispose();
|
||||
_images[index] = ItemToImage(item);
|
||||
}
|
||||
|
||||
public override void DeleteFromEnd()
|
||||
{
|
||||
_images[_images.Count - 1].Dispose();
|
||||
_images.RemoveAt(_images.Count - 1);
|
||||
}
|
||||
|
||||
public override Image Get(ListViewItem listViewItem)
|
||||
{
|
||||
return _images[listViewItem.Index];
|
||||
}
|
||||
|
||||
public override Image PartialAppend(T item)
|
||||
{
|
||||
return ItemToImage(item);
|
||||
}
|
||||
|
||||
public override void FinishPartialAppends(List<Image> images)
|
||||
{
|
||||
_images.AddRange(images);
|
||||
}
|
||||
}
|
||||
|
||||
public class Native : WinFormsImageList<T>
|
||||
{
|
||||
private readonly ImageList.ImageCollection _images;
|
||||
|
||||
public Native(WinFormsListView<T> listView, ListViewBehavior<T> behavior) : base(listView, behavior)
|
||||
{
|
||||
_images = _listView.NativeControl.LargeImageList.Images;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
_images.Clear();
|
||||
}
|
||||
|
||||
public override void Append(T item, ListViewItem listViewItem)
|
||||
{
|
||||
_images.Add(_behavior.GetImage(item, _listView.ImageSize).ToSD());
|
||||
listViewItem.ImageIndex = _images.Count - 1;
|
||||
}
|
||||
|
||||
public override void Replace(T item, int index)
|
||||
{
|
||||
_images[index] = ItemToImage(item);
|
||||
}
|
||||
|
||||
public override void DeleteFromEnd()
|
||||
{
|
||||
_images.RemoveAt(_images.Count - 1);
|
||||
}
|
||||
|
||||
public override Image Get(ListViewItem listViewItem) => throw new NotSupportedException();
|
||||
|
||||
public override Image PartialAppend(T item)
|
||||
{
|
||||
return ItemToImage(item);
|
||||
}
|
||||
|
||||
public override void FinishPartialAppends(List<Image> images)
|
||||
{
|
||||
_images.AddRange(images.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public class Stub : WinFormsImageList<T>
|
||||
{
|
||||
public Stub(WinFormsListView<T> listView, ListViewBehavior<T> behavior) : base(listView, behavior)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
}
|
||||
|
||||
public override void Append(T item, ListViewItem listViewItem)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Replace(T item, int index)
|
||||
{
|
||||
}
|
||||
|
||||
public override void DeleteFromEnd()
|
||||
{
|
||||
}
|
||||
|
||||
public override Image Get(ListViewItem listViewItem) => throw new NotSupportedException();
|
||||
|
||||
public override Image PartialAppend(T item)
|
||||
{
|
||||
return null!;
|
||||
}
|
||||
|
||||
public override void FinishPartialAppends(List<Image> images)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -50,14 +50,24 @@ public class WinFormsListView<T> : IListView<T> where T : notnull
|
||||
_view.MouseMove += OnMouseMove;
|
||||
_view.MouseLeave += OnMouseLeave;
|
||||
|
||||
_view.OwnerDraw = true;
|
||||
_view.DrawItem += ViewOnDrawItem;
|
||||
ImageList = UseCustomRendering
|
||||
? new WinFormsImageList<T>.Custom(this, _behavior)
|
||||
: !_behavior.Checkboxes
|
||||
? new WinFormsImageList<T>.Native(this, _behavior)
|
||||
: new WinFormsImageList<T>.Stub(this, _behavior);
|
||||
if (UseCustomRendering)
|
||||
{
|
||||
_view.OwnerDraw = true;
|
||||
_view.DrawItem += CustomRenderItem;
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewOnDrawItem(object sender, DrawListViewItemEventArgs e)
|
||||
private bool UseCustomRendering => !_behavior.ShowLabels && !_behavior.Checkboxes;
|
||||
|
||||
private void CustomRenderItem(object sender, DrawListViewItemEventArgs e)
|
||||
{
|
||||
int width, height;
|
||||
var image = ImageList[e.Item.Index];
|
||||
var image = ImageList.Get(e.Item);
|
||||
if (image.Width > image.Height)
|
||||
{
|
||||
width = ImageSize;
|
||||
@ -119,7 +129,7 @@ public class WinFormsListView<T> : IListView<T> where T : notnull
|
||||
|
||||
private ListView.ListViewItemCollection Items => _view.Items;
|
||||
|
||||
private List<Image> ImageList { get; } = new();
|
||||
private WinFormsImageList<T> ImageList { get; }
|
||||
|
||||
public void SetItems(IEnumerable<T> items)
|
||||
{
|
||||
@ -129,29 +139,17 @@ public class WinFormsListView<T> : IListView<T> where T : notnull
|
||||
}
|
||||
_refreshing = true;
|
||||
Items.Clear();
|
||||
ClearImageList();
|
||||
ImageList.Clear();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (!_behavior.Checkboxes)
|
||||
{
|
||||
ImageList.Add(_behavior.GetImage(item, ImageSize).ToSD());
|
||||
}
|
||||
var listViewItem = Items.Add(GetLabel(item));
|
||||
listViewItem.Tag = item;
|
||||
ImageList.Append(item, listViewItem);
|
||||
}
|
||||
SetSelectedItems();
|
||||
_refreshing = false;
|
||||
}
|
||||
|
||||
private void ClearImageList()
|
||||
{
|
||||
if (!_behavior.Checkboxes)
|
||||
{
|
||||
foreach (var image in ImageList) image.Dispose();
|
||||
ImageList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetSelectedItems()
|
||||
{
|
||||
for (int i = 0; i < Items.Count; i++)
|
||||
@ -176,17 +174,15 @@ public class WinFormsListView<T> : IListView<T> where T : notnull
|
||||
}
|
||||
_refreshing = true;
|
||||
_view.BeginUpdate();
|
||||
ClearImageList();
|
||||
ImageList.Clear();
|
||||
|
||||
foreach (var image in Items.OfType<ListViewItem>().Select(x => (T) x.Tag))
|
||||
var images = new List<Image>();
|
||||
foreach (ListViewItem listViewItem in Items)
|
||||
{
|
||||
ImageList.Add(_behavior.GetImage(image, ImageSize).ToSD());
|
||||
}
|
||||
|
||||
foreach (ListViewItem item in Items)
|
||||
{
|
||||
item.ImageIndex = item.Index;
|
||||
var item = (T) listViewItem.Tag;
|
||||
images.Add(ImageList.PartialAppend(item));
|
||||
}
|
||||
ImageList.FinishPartialAppends(images);
|
||||
|
||||
_view.EndUpdate();
|
||||
_refreshing = false;
|
||||
@ -208,7 +204,7 @@ public class WinFormsListView<T> : IListView<T> where T : notnull
|
||||
if (!diffs.AppendOperations.Any() && !diffs.ReplaceOperations.Any() &&
|
||||
diffs.TrimOperations.Any(x => x.Count == Items.Count))
|
||||
{
|
||||
ClearImageList();
|
||||
ImageList.Clear();
|
||||
Items.Clear();
|
||||
}
|
||||
else
|
||||
@ -219,32 +215,21 @@ public class WinFormsListView<T> : IListView<T> where T : notnull
|
||||
// TODO: Use AddRange instead?
|
||||
// TODO: Add this to the new ImageListViewBehavior
|
||||
// _thumbnailProvider.GetThumbnail(append.Image.Source, ThumbnailSize)
|
||||
var item = Items.Add(GetLabel(append.Item));
|
||||
item.Tag = append.Item;
|
||||
if (!_behavior.Checkboxes)
|
||||
{
|
||||
ImageList.Add(_behavior.GetImage(append.Item, ImageSize).ToSD());
|
||||
}
|
||||
var listViewItem = Items.Add(GetLabel(append.Item));
|
||||
listViewItem.Tag = append.Item;
|
||||
ImageList.Append(append.Item, listViewItem);
|
||||
}
|
||||
foreach (var replace in diffs.ReplaceOperations)
|
||||
{
|
||||
if (!_behavior.Checkboxes)
|
||||
{
|
||||
ImageList[replace.Index].Dispose();
|
||||
ImageList[replace.Index] = _behavior.GetImage(replace.Item, ImageSize).ToSD();
|
||||
}
|
||||
Items[replace.Index].Tag = replace.Item;
|
||||
ImageList.Replace(replace.Item, replace.Index);
|
||||
}
|
||||
foreach (var trim in diffs.TrimOperations)
|
||||
{
|
||||
for (int i = 0; i < trim.Count; i++)
|
||||
{
|
||||
if (!_behavior.Checkboxes)
|
||||
{
|
||||
ImageList[ImageList.Count - 1].Dispose();
|
||||
ImageList.RemoveAt(ImageList.Count - 1);
|
||||
}
|
||||
Items.RemoveAt(Items.Count - 1);
|
||||
ImageList.DeleteFromEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -398,6 +398,7 @@ public abstract class DesktopForm : EtoFormBase
|
||||
Commands.ReorderMenu.Enabled =
|
||||
Commands.EmailPdf.Enabled = Commands.Print.Enabled = ImageList.Images.Any();
|
||||
|
||||
// TODO: Changing the text on the command doesn't actually propagate to the widget
|
||||
// "All" dropdown items
|
||||
Commands.SaveAllPdf.MenuText = Commands.SaveAllImages.MenuText = Commands.EmailAllPdf.MenuText =
|
||||
Commands.ReverseAll.MenuText = string.Format(MiscResources.AllCount, ImageList.Images.Count);
|
||||
|
Loading…
Reference in New Issue
Block a user