diff --git a/Business/Menus.cs b/Business/Menus.cs index 72dd676..becfc39 100644 --- a/Business/Menus.cs +++ b/Business/Menus.cs @@ -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() diff --git a/DataClasses/RowData.cs b/DataClasses/RowData.cs index 3bf46b0..babe993 100644 --- a/DataClasses/RowData.cs +++ b/DataClasses/RowData.cs @@ -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; } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index f3c9e98..4be8395 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -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")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index ea58bcd..03c022a 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -300,6 +300,26 @@ namespace SystemTrayMenu.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + public static System.Drawing.Icon Loading { + get { + object obj = ResourceManager.GetObject("Loading", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + public static System.Drawing.Icon NotFound { + get { + object obj = ResourceManager.GetObject("NotFound", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index 64ecebe..7682f88 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -199,4 +199,10 @@ ..\Resources\ic_fluent_folder_arrow_right_48_regular.svg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\Loading.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\NotFound.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Resources/Loading.ico b/Resources/Loading.ico new file mode 100644 index 0000000..f8e5489 Binary files /dev/null and b/Resources/Loading.ico differ diff --git a/Resources/NotFound.ico b/Resources/NotFound.ico new file mode 100644 index 0000000..dcbfffa Binary files /dev/null and b/Resources/NotFound.ico differ diff --git a/UserInterface/Menu.Designer.cs b/UserInterface/Menu.Designer.cs index 07c5ce3..ec782e8 100644 --- a/UserInterface/Menu.Designer.cs +++ b/UserInterface/Menu.Designer.cs @@ -17,6 +17,9 @@ { components.Dispose(); } + + timerUpdateIcons.Stop(); + timerUpdateIcons.Dispose(); fading.Dispose(); customScrollbar.Dispose(); base.Dispose(disposing); @@ -30,6 +33,7 @@ /// 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; } } \ No newline at end of file diff --git a/UserInterface/Menu.cs b/UserInterface/Menu.cs index 5b3f879..7c42017 100644 --- a/UserInterface/Menu.cs +++ b/UserInterface/Menu.cs @@ -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(); + } + } } } \ No newline at end of file diff --git a/UserInterface/Menu.resx b/UserInterface/Menu.resx index f298a7b..0ef9e60 100644 --- a/UserInterface/Menu.resx +++ b/UserInterface/Menu.resx @@ -57,4 +57,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/Utilities/File/IconReader.cs b/Utilities/File/IconReader.cs index 3a7bdb0..7fa0147 100644 --- a/Utilities/File/IconReader.cs +++ b/Utilities/File/IconReader.cs @@ -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)