[Feature] Show menu faster (load icons in background and update UI later) #196, 1.0.18.2

This commit is contained in:
Markus Hofknecht 2021-09-23 22:53:46 +02:00
parent 7c77c235c4
commit cc70299972
11 changed files with 108 additions and 7 deletions

View file

@ -538,6 +538,11 @@ namespace SystemTrayMenu.Business
Path.GetFileName(Config.Path));
AdjustMenusSizeAndLocation();
DisposeMenu(menus[0]);
if (FileUrl.GetDefaultBrowserPath(out string browserPath))
{
IconReader.GetFileIconWithCache(browserPath, true, true, out bool loading);
}
}
internal void StartWorker()

View file

@ -23,6 +23,7 @@ namespace SystemTrayMenu.DataClasses
internal class RowData : IDisposable
{
private static readonly Icon White50PercentageIcon = Properties.Resources.White50Percentage;
private static readonly Icon NotFoundIcon = Properties.Resources.NotFound;
private static DateTime contextMenuClosed;
private string workingDirectory;
private string arguments;
@ -59,6 +60,10 @@ namespace SystemTrayMenu.DataClasses
internal int MenuLevel { get; set; }
internal Icon Icon => icon;
internal bool IconLoading { get; set; }
public void Dispose()
{
Dispose(true);
@ -79,7 +84,7 @@ namespace SystemTrayMenu.DataClasses
if (icon == null)
{
icon = White50PercentageIcon;
icon = NotFoundIcon;
}
if (HiddenEntry)
@ -150,7 +155,10 @@ namespace SystemTrayMenu.DataClasses
{
icon = IconReader.GetFileIconWithCache(
TargetFilePath,
showOverlay);
showOverlay,
true,
out bool loading);
IconLoading = loading;
diposeIcon = false;
}
catch (Exception ex)
@ -334,7 +342,8 @@ namespace SystemTrayMenu.DataClasses
{
if (FileUrl.GetDefaultBrowserPath(out string browserPath))
{
icon = IconReader.GetFileIconWithCache(browserPath, true);
icon = IconReader.GetFileIconWithCache(browserPath, true, true, out bool loading);
IconLoading = loading;
diposeIcon = false;
handled = true;
}

View file

@ -39,5 +39,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.18.1")]
[assembly: AssemblyFileVersion("1.0.18.1")]
[assembly: AssemblyVersion("1.0.18.2")]
[assembly: AssemblyFileVersion("1.0.18.2")]

View file

@ -300,6 +300,26 @@ namespace SystemTrayMenu.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
public static System.Drawing.Icon Loading {
get {
object obj = ResourceManager.GetObject("Loading", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
public static System.Drawing.Icon NotFound {
get {
object obj = ResourceManager.GetObject("NotFound", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>

View file

@ -199,4 +199,10 @@
<data name="ic_fluent_folder_arrow_right_48_regular" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ic_fluent_folder_arrow_right_48_regular.svg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="Loading" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Loading.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="NotFound" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\NotFound.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

BIN
Resources/Loading.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
Resources/NotFound.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -17,6 +17,9 @@
{
components.Dispose();
}
timerUpdateIcons.Stop();
timerUpdateIcons.Dispose();
fading.Dispose();
customScrollbar.Dispose();
base.Dispose(disposing);
@ -30,6 +33,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
this.tableLayoutPanelDgvAndScrollbar = new System.Windows.Forms.TableLayoutPanel();
this.dgv = new System.Windows.Forms.DataGridView();
@ -44,6 +48,7 @@
this.tableLayoutPanelTitle = new System.Windows.Forms.TableLayoutPanel();
this.pictureBoxOpenFolder = new System.Windows.Forms.PictureBox();
this.pictureBoxMenuAlwaysOpen = new System.Windows.Forms.PictureBox();
this.timerUpdateIcons = new System.Windows.Forms.Timer(this.components);
this.tableLayoutPanelDgvAndScrollbar.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dgv)).BeginInit();
this.tableLayoutPanelSearch.SuspendLayout();
@ -288,6 +293,11 @@
//
InitializeComponentControlsTheDesignerRemoves();
//
// timerUpdateIcons
//
this.timerUpdateIcons.Interval = 300;
this.timerUpdateIcons.Tick += new System.EventHandler(this.TimerUpdateIcons_Tick);
//
// Menu
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
@ -340,5 +350,6 @@
private System.Windows.Forms.PictureBox pictureBoxFilesCount;
private System.Windows.Forms.PictureBox pictureBoxFoldersCount;
private System.Windows.Forms.Label labelFoldersCount;
private System.Windows.Forms.Timer timerUpdateIcons;
}
}

View file

@ -43,6 +43,7 @@ namespace SystemTrayMenu.UserInterface
isShowing = true;
Visible = true;
isShowing = false;
timerUpdateIcons.Start();
}
catch (ObjectDisposedException)
{
@ -702,6 +703,13 @@ namespace SystemTrayMenu.UserInterface
else
{
filesCount++;
if (rowData.IconLoading)
{
string resolvedLnkPath = string.Empty;
rowData.ReadIcon(rowData.ContainsMenu, ref resolvedLnkPath);
row.Cells[0].Value = rowData.Icon;
}
}
}
@ -795,5 +803,29 @@ namespace SystemTrayMenu.UserInterface
UserClickedOpenFolder?.Invoke();
}
}
private void TimerUpdateIcons_Tick(object sender, EventArgs e)
{
int iconsToUpdate = 0;
foreach (DataGridViewRow row in dgv.Rows)
{
RowData rowData = (RowData)row.Cells[2].Value;
rowData.RowIndex = row.Index;
if (rowData.IconLoading)
{
iconsToUpdate++;
string resolvedLnkPath = string.Empty;
rowData.ReadIcon(rowData.ContainsMenu, ref resolvedLnkPath);
row.Cells[0].Value = rowData.Icon;
}
}
if (iconsToUpdate < 1)
{
timerUpdateIcons.Stop();
}
}
}
}

View file

@ -57,4 +57,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="timerUpdateIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -11,6 +11,7 @@ namespace SystemTrayMenu.Utilities
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
// from https://www.codeproject.com/Articles/2532/Obtaining-and-managing-file-and-folder-icons-using
@ -47,9 +48,10 @@ namespace SystemTrayMenu.Utilities
}
}
public static Icon GetFileIconWithCache(string filePath, bool linkOverlay)
public static Icon GetFileIconWithCache(string filePath, bool linkOverlay, bool updateIconInBackground, out bool loading)
{
Icon icon = null;
loading = false;
string extension = Path.GetExtension(filePath);
IconSize size = IconSize.Small;
if (Scaling.Factor > 1)
@ -63,7 +65,20 @@ namespace SystemTrayMenu.Utilities
}
else
{
icon = DictIconCache.GetOrAdd(filePath, GetIcon);
if (!DictIconCache.TryGetValue(filePath, out icon))
{
icon = Properties.Resources.Loading;
loading = true;
if (updateIconInBackground)
{
new Thread(UpdateIconInBackground).Start();
void UpdateIconInBackground()
{
DictIconCache.GetOrAdd(filePath, GetIcon);
}
}
}
}
Icon GetIcon(string keyExtension)