diff --git a/NAPS2.Lib.Gtk/EtoForms/Gtk/GtkListView.cs b/NAPS2.Lib.Gtk/EtoForms/Gtk/GtkListView.cs index d7ef94be33..67e28f95d9 100644 --- a/NAPS2.Lib.Gtk/EtoForms/Gtk/GtkListView.cs +++ b/NAPS2.Lib.Gtk/EtoForms/Gtk/GtkListView.cs @@ -181,6 +181,10 @@ public void RegenerateImages() { throw new InvalidOperationException(); } + if (_entries.Count == 0) + { + return; + } _refreshing = true; foreach (var entry in _entries) { diff --git a/NAPS2.Lib.Mac/EtoForms/Mac/MacListView.cs b/NAPS2.Lib.Mac/EtoForms/Mac/MacListView.cs index da0b097ce5..9bdded177c 100644 --- a/NAPS2.Lib.Mac/EtoForms/Mac/MacListView.cs +++ b/NAPS2.Lib.Mac/EtoForms/Mac/MacListView.cs @@ -106,6 +106,10 @@ public void SetItems(IEnumerable items) // TODO: Do we need this method? Clean up the name/doc at least public void RegenerateImages() { + if (_dataSource.Items.Count == 0) + { + return; + } _view.ReloadData(); } diff --git a/NAPS2.Lib.WinForms/EtoForms/WinForms/WinFormsListView.cs b/NAPS2.Lib.WinForms/EtoForms/WinForms/WinFormsListView.cs index e1776210c0..6d5c2cb317 100644 --- a/NAPS2.Lib.WinForms/EtoForms/WinForms/WinFormsListView.cs +++ b/NAPS2.Lib.WinForms/EtoForms/WinForms/WinFormsListView.cs @@ -278,6 +278,10 @@ public void RegenerateImages() { throw new InvalidOperationException(); } + if (Items.Count == 0) + { + return; + } _refreshing = true; _view.BeginUpdate(); ImageList.Clear(); diff --git a/NAPS2.Lib/EtoForms/DefaultIconProvider.cs b/NAPS2.Lib/EtoForms/DefaultIconProvider.cs index 5edcd3a38f..8fc5bebe0d 100644 --- a/NAPS2.Lib/EtoForms/DefaultIconProvider.cs +++ b/NAPS2.Lib/EtoForms/DefaultIconProvider.cs @@ -8,6 +8,7 @@ public class DefaultIconProvider : IIconProvider { if (scale > 1) { + // TODO: Maybe generalize everything with a numeric pixel size suffix? if (name.EndsWith("_small")) { var norm = (byte[]?) Icons.ResourceManager.GetObject(name.Substring(0, name.Length - 6)); @@ -16,6 +17,14 @@ public class DefaultIconProvider : IIconProvider return new Bitmap(norm).ResizeTo((int) (16 * scale)); } } + else if (name.EndsWith("_48")) + { + var hires = (byte[]?) Icons.ResourceManager.GetObject(name.Substring(0, name.Length - 3) + "_96"); + if (hires != null) + { + return new Bitmap(hires).ResizeTo((int) (48 * scale)); + } + } else { var hires = (byte[]?) Icons.ResourceManager.GetObject(name + "_hires"); diff --git a/NAPS2.Lib/EtoForms/Ui/ProfilesForm.cs b/NAPS2.Lib/EtoForms/Ui/ProfilesForm.cs index ba974a658c..2cdbdece12 100644 --- a/NAPS2.Lib/EtoForms/Ui/ProfilesForm.cs +++ b/NAPS2.Lib/EtoForms/Ui/ProfilesForm.cs @@ -98,7 +98,11 @@ public ProfilesForm(Naps2Config config, IScanPerformer scanPerformer, ProfileNam profilesKsm.Assign("Mod+V", _pasteCommand); EtoPlatform.Current.HandleKeyDown(_listView.Control, profilesKsm.Perform); - _listView.ImageSize = new Size(48, 48); + EtoPlatform.Current.AttachDpiDependency(this, scale => + { + _listView.ImageSize = Size.Round(new SizeF(48, 48) * scale); + _listView.RegenerateImages(); + }); _listView.ItemClicked += ItemClicked; _listView.SelectionChanged += SelectionChanged; _listView.Drop += Drop; diff --git a/NAPS2.Lib/EtoForms/Ui/ScannerSharingForm.cs b/NAPS2.Lib/EtoForms/Ui/ScannerSharingForm.cs index b10aae7e83..cb80dc2f63 100644 --- a/NAPS2.Lib/EtoForms/Ui/ScannerSharingForm.cs +++ b/NAPS2.Lib/EtoForms/Ui/ScannerSharingForm.cs @@ -58,7 +58,11 @@ public ScannerSharingForm(Naps2Config config, SharedDevicesListViewBehavior list // TODO: Enable // _shareAsService.Checked = _osServiceManager.IsRegistered; // _shareAsService.CheckedChanged += ShareAsServiceCheckedChanged; - _listView.ImageSize = new Size(48, 48); + EtoPlatform.Current.AttachDpiDependency(this, scale => + { + _listView.ImageSize = Size.Round(new SizeF(48, 48) * scale); + _listView.RegenerateImages(); + }); _listView.SelectionChanged += SelectionChanged; _addCommand.Enabled = true; diff --git a/NAPS2.Lib/EtoForms/Widgets/ProfileListViewBehavior.cs b/NAPS2.Lib/EtoForms/Widgets/ProfileListViewBehavior.cs index 821846863b..82c4bb8fcf 100644 --- a/NAPS2.Lib/EtoForms/Widgets/ProfileListViewBehavior.cs +++ b/NAPS2.Lib/EtoForms/Widgets/ProfileListViewBehavior.cs @@ -22,19 +22,15 @@ public ProfileListViewBehavior(ColorScheme colorScheme) : base(colorScheme) public override Image GetImage(ScanProfile item, Size imageSize) { - if (item.IsDefault && item.IsLocked) + var iconName = (item.IsDefault, item.IsLocked) switch { - return Icons.scanner_lock_default.ToEtoImage(); - } - if (item.IsDefault) - { - return Icons.scanner_default.ToEtoImage(); - } - if (item.IsLocked) - { - return Icons.scanner_lock.ToEtoImage(); - } - return Icons.scanner_48.ToEtoImage(); + (true, true) => "scanner_lock_default_48", + (true, false) => "scanner_default_48", + (false, true) => "scanner_lock_48", + (false, false) => "scanner_48" + }; + var scale = imageSize.Height / 48f; + return EtoPlatform.Current.IconProvider.GetIcon(iconName, scale)!; } public override bool AllowDragDrop => true; diff --git a/NAPS2.Lib/EtoForms/Widgets/SharedDevicesListViewBehavior.cs b/NAPS2.Lib/EtoForms/Widgets/SharedDevicesListViewBehavior.cs index 5907db5880..8da24a0a09 100644 --- a/NAPS2.Lib/EtoForms/Widgets/SharedDevicesListViewBehavior.cs +++ b/NAPS2.Lib/EtoForms/Widgets/SharedDevicesListViewBehavior.cs @@ -14,5 +14,9 @@ public SharedDevicesListViewBehavior(ColorScheme colorScheme) : base(colorScheme public override string GetLabel(SharedDevice item) => item.Name; - public override Image GetImage(SharedDevice item, Size imageSize) => Icons.scanner_wireless.ToEtoImage(); + public override Image GetImage(SharedDevice item, Size imageSize) + { + var scale = imageSize.Height / 48f; + return EtoPlatform.Current.IconProvider.GetIcon("scanner_wireless_48", scale)!; + } } \ No newline at end of file diff --git a/NAPS2.Lib/Icons.Designer.cs b/NAPS2.Lib/Icons.Designer.cs index cfc627b6a8..db2770b5e9 100644 --- a/NAPS2.Lib/Icons.Designer.cs +++ b/NAPS2.Lib/Icons.Designer.cs @@ -1292,9 +1292,9 @@ internal static byte[] scanner_64 { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] scanner_default { + internal static byte[] scanner_96 { get { - object obj = ResourceManager.GetObject("scanner_default", resourceCulture); + object obj = ResourceManager.GetObject("scanner_96", resourceCulture); return ((byte[])(obj)); } } @@ -1302,9 +1302,9 @@ internal static byte[] scanner_default { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] scanner_lock { + internal static byte[] scanner_default_48 { get { - object obj = ResourceManager.GetObject("scanner_lock", resourceCulture); + object obj = ResourceManager.GetObject("scanner_default_48", resourceCulture); return ((byte[])(obj)); } } @@ -1312,9 +1312,9 @@ internal static byte[] scanner_lock { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] scanner_lock_default { + internal static byte[] scanner_default_96 { get { - object obj = ResourceManager.GetObject("scanner_lock_default", resourceCulture); + object obj = ResourceManager.GetObject("scanner_default_96", resourceCulture); return ((byte[])(obj)); } } @@ -1322,9 +1322,59 @@ internal static byte[] scanner_lock_default { /// /// Looks up a localized resource of type System.Byte[]. /// - internal static byte[] scanner_wireless { + internal static byte[] scanner_lock_48 { get { - object obj = ResourceManager.GetObject("scanner_wireless", resourceCulture); + object obj = ResourceManager.GetObject("scanner_lock_48", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] scanner_lock_96 { + get { + object obj = ResourceManager.GetObject("scanner_lock_96", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] scanner_lock_default_48 { + get { + object obj = ResourceManager.GetObject("scanner_lock_default_48", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] scanner_lock_default_96 { + get { + object obj = ResourceManager.GetObject("scanner_lock_default_96", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] scanner_wireless_48 { + get { + object obj = ResourceManager.GetObject("scanner_wireless_48", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] scanner_wireless_96 { + get { + object obj = ResourceManager.GetObject("scanner_wireless_96", resourceCulture); return ((byte[])(obj)); } } diff --git a/NAPS2.Lib/Icons.resx b/NAPS2.Lib/Icons.resx index fa64a6e5e8..b1a1fafb70 100644 --- a/NAPS2.Lib/Icons.resx +++ b/NAPS2.Lib/Icons.resx @@ -238,21 +238,36 @@ Icons\scanner-64-rev2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Icons\scanner-96.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + Icons\scanner-128.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + Icons\scanner-default-rev2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + Icons\scanner-default-hires.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Icons\scanner-lock-default-rev2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + Icons\scanner-lock-default-hires.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Icons\scanner-lock-rev2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + + Icons\scanner-lock-hires.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Icons\scanner-wireless-rev2.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Icons\scanner-wireless-hires.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + Icons\device.png;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/NAPS2.Lib/Icons/scanner-96.png b/NAPS2.Lib/Icons/scanner-96.png new file mode 100644 index 0000000000..3da732d0d9 Binary files /dev/null and b/NAPS2.Lib/Icons/scanner-96.png differ diff --git a/NAPS2.Lib/Icons/scanner-default-hires.png b/NAPS2.Lib/Icons/scanner-default-hires.png new file mode 100644 index 0000000000..b78962e03b Binary files /dev/null and b/NAPS2.Lib/Icons/scanner-default-hires.png differ diff --git a/NAPS2.Lib/Icons/scanner-lock-default-hires.png b/NAPS2.Lib/Icons/scanner-lock-default-hires.png new file mode 100644 index 0000000000..7a31c38bba Binary files /dev/null and b/NAPS2.Lib/Icons/scanner-lock-default-hires.png differ diff --git a/NAPS2.Lib/Icons/scanner-lock-hires.png b/NAPS2.Lib/Icons/scanner-lock-hires.png new file mode 100644 index 0000000000..499bad5dbc Binary files /dev/null and b/NAPS2.Lib/Icons/scanner-lock-hires.png differ diff --git a/NAPS2.Lib/Icons/scanner-wireless-hires.png b/NAPS2.Lib/Icons/scanner-wireless-hires.png new file mode 100644 index 0000000000..4babc3c981 Binary files /dev/null and b/NAPS2.Lib/Icons/scanner-wireless-hires.png differ diff --git a/NAPS2.Lib/Icons/wireless_filled.png b/NAPS2.Lib/Icons/wireless_filled.png new file mode 100644 index 0000000000..99ae9940a0 Binary files /dev/null and b/NAPS2.Lib/Icons/wireless_filled.png differ