[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)); Path.GetFileName(Config.Path));
AdjustMenusSizeAndLocation(); AdjustMenusSizeAndLocation();
DisposeMenu(menus[0]); DisposeMenu(menus[0]);
if (FileUrl.GetDefaultBrowserPath(out string browserPath))
{
IconReader.GetFileIconWithCache(browserPath, true, true, out bool loading);
}
} }
internal void StartWorker() internal void StartWorker()

View file

@ -23,6 +23,7 @@ namespace SystemTrayMenu.DataClasses
internal class RowData : IDisposable internal class RowData : IDisposable
{ {
private static readonly Icon White50PercentageIcon = Properties.Resources.White50Percentage; private static readonly Icon White50PercentageIcon = Properties.Resources.White50Percentage;
private static readonly Icon NotFoundIcon = Properties.Resources.NotFound;
private static DateTime contextMenuClosed; private static DateTime contextMenuClosed;
private string workingDirectory; private string workingDirectory;
private string arguments; private string arguments;
@ -59,6 +60,10 @@ namespace SystemTrayMenu.DataClasses
internal int MenuLevel { get; set; } internal int MenuLevel { get; set; }
internal Icon Icon => icon;
internal bool IconLoading { get; set; }
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
@ -79,7 +84,7 @@ namespace SystemTrayMenu.DataClasses
if (icon == null) if (icon == null)
{ {
icon = White50PercentageIcon; icon = NotFoundIcon;
} }
if (HiddenEntry) if (HiddenEntry)
@ -150,7 +155,10 @@ namespace SystemTrayMenu.DataClasses
{ {
icon = IconReader.GetFileIconWithCache( icon = IconReader.GetFileIconWithCache(
TargetFilePath, TargetFilePath,
showOverlay); showOverlay,
true,
out bool loading);
IconLoading = loading;
diposeIcon = false; diposeIcon = false;
} }
catch (Exception ex) catch (Exception ex)
@ -334,7 +342,8 @@ namespace SystemTrayMenu.DataClasses
{ {
if (FileUrl.GetDefaultBrowserPath(out string browserPath)) if (FileUrl.GetDefaultBrowserPath(out string browserPath))
{ {
icon = IconReader.GetFileIconWithCache(browserPath, true); icon = IconReader.GetFileIconWithCache(browserPath, true, true, out bool loading);
IconLoading = loading;
diposeIcon = false; diposeIcon = false;
handled = true; 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 // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.18.1")] [assembly: AssemblyVersion("1.0.18.2")]
[assembly: AssemblyFileVersion("1.0.18.1")] [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> /// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary> /// </summary>

View file

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

View file

@ -43,6 +43,7 @@ namespace SystemTrayMenu.UserInterface
isShowing = true; isShowing = true;
Visible = true; Visible = true;
isShowing = false; isShowing = false;
timerUpdateIcons.Start();
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
{ {
@ -702,6 +703,13 @@ namespace SystemTrayMenu.UserInterface
else else
{ {
filesCount++; 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(); 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"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </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> </root>

View file

@ -11,6 +11,7 @@ namespace SystemTrayMenu.Utilities
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
// from https://www.codeproject.com/Articles/2532/Obtaining-and-managing-file-and-folder-icons-using // 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; Icon icon = null;
loading = false;
string extension = Path.GetExtension(filePath); string extension = Path.GetExtension(filePath);
IconSize size = IconSize.Small; IconSize size = IconSize.Small;
if (Scaling.Factor > 1) if (Scaling.Factor > 1)
@ -63,7 +65,20 @@ namespace SystemTrayMenu.Utilities
} }
else 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) Icon GetIcon(string keyExtension)