mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-05-08 14:32:38 +12:00
Not enough memory resources are available to process this command. (#442), version 1.3.1.9
This commit is contained in:
parent
87dbd64c73
commit
1d4820c946
|
@ -24,27 +24,20 @@ namespace SystemTrayMenu
|
|||
public App()
|
||||
{
|
||||
AppRestart.BeforeRestarting += Dispose;
|
||||
SystemEvents.DisplaySettingsChanged += (s, e) => SystemEvents_DisplaySettingsChanged();
|
||||
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
|
||||
menus.LoadStarted += menuNotifyIcon.LoadingStart;
|
||||
menus.LoadStopped += menuNotifyIcon.LoadingStop;
|
||||
menuNotifyIcon.Click += () => menus.SwitchOpenClose(true);
|
||||
menuNotifyIcon.Click += MenuNotifyIcon_Click;
|
||||
menuNotifyIcon.OpenLog += Log.OpenLogFile;
|
||||
menus.MainPreload();
|
||||
|
||||
if (Properties.Settings.Default.ShowInTaskbar)
|
||||
{
|
||||
taskbarForm = new TaskbarForm();
|
||||
taskbarForm.FormClosed += (s, e) => Application.Exit();
|
||||
taskbarForm.Deactivate += (s, e) => SetStateNormal();
|
||||
taskbarForm.Resize += (s, e) => SetStateNormal();
|
||||
taskbarForm.FormClosed += TaskbarForm_FormClosed;
|
||||
taskbarForm.Deactivate += SetStateNormal;
|
||||
taskbarForm.Resize += SetStateNormal;
|
||||
taskbarForm.Activated += TasbkarItemActivated;
|
||||
void TasbkarItemActivated(object sender, EventArgs e)
|
||||
{
|
||||
SetStateNormal();
|
||||
taskbarForm.Activate();
|
||||
taskbarForm.Focus();
|
||||
menus.SwitchOpenCloseByTaskbarItem();
|
||||
}
|
||||
}
|
||||
|
||||
DllImports.NativeMethods.User32ShowInactiveTopmost(taskbarForm);
|
||||
|
@ -65,27 +58,57 @@ namespace SystemTrayMenu
|
|||
}
|
||||
else
|
||||
{
|
||||
taskbarForm?.Dispose();
|
||||
SystemEvents.DisplaySettingsChanged -= (s, e) => SystemEvents_DisplaySettingsChanged();
|
||||
AppRestart.BeforeRestarting -= Dispose;
|
||||
SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
|
||||
menus.LoadStarted -= menuNotifyIcon.LoadingStart;
|
||||
menus.LoadStopped -= menuNotifyIcon.LoadingStop;
|
||||
menus.Dispose();
|
||||
menuNotifyIcon.Click -= MenuNotifyIcon_Click;
|
||||
menuNotifyIcon.OpenLog -= Log.OpenLogFile;
|
||||
menuNotifyIcon.Dispose();
|
||||
if (taskbarForm != null)
|
||||
{
|
||||
taskbarForm.FormClosed -= TaskbarForm_FormClosed;
|
||||
taskbarForm.Deactivate -= SetStateNormal;
|
||||
taskbarForm.Resize -= SetStateNormal;
|
||||
taskbarForm.Activated -= TasbkarItemActivated;
|
||||
taskbarForm.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SystemEvents_DisplaySettingsChanged()
|
||||
private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
menus.ReAdjustSizeAndLocation();
|
||||
}
|
||||
|
||||
private void MenuNotifyIcon_Click()
|
||||
{
|
||||
menus.SwitchOpenClose(true);
|
||||
}
|
||||
|
||||
private void TaskbarForm_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This ensures that next click on taskbaritem works as activate event/click event.
|
||||
/// </summary>
|
||||
private void SetStateNormal()
|
||||
private void SetStateNormal(object sender, EventArgs e)
|
||||
{
|
||||
if (Form.ActiveForm == taskbarForm)
|
||||
{
|
||||
taskbarForm.WindowState = FormWindowState.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
private void TasbkarItemActivated(object sender, EventArgs e)
|
||||
{
|
||||
SetStateNormal(sender, e);
|
||||
taskbarForm.Activate();
|
||||
taskbarForm.Focus();
|
||||
menus.SwitchOpenCloseByTaskbarItem();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,33 +27,34 @@ namespace SystemTrayMenu.Handler
|
|||
this.menus = menus;
|
||||
}
|
||||
|
||||
internal event EventHandlerEmpty HotKeyPressed;
|
||||
public event Action HotKeyPressed;
|
||||
|
||||
internal event EventHandlerEmpty ClosePressed;
|
||||
public event Action ClosePressed;
|
||||
|
||||
internal event Action<DataGridView, int> RowSelected;
|
||||
public event Action<DataGridView, int> RowSelected;
|
||||
|
||||
internal event Action<int, DataGridView> RowDeselected;
|
||||
public event Action<DataGridView, int> RowDeselected;
|
||||
|
||||
internal event Action<DataGridView, int> EnterPressed;
|
||||
public event Action<DataGridView, int> EnterPressed;
|
||||
|
||||
internal event EventHandlerEmpty Cleared;
|
||||
public event Action Cleared;
|
||||
|
||||
internal bool InUse { get; set; }
|
||||
public bool InUse { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
hook.KeyPressed -= Hook_KeyPressed;
|
||||
hook.Dispose();
|
||||
}
|
||||
|
||||
internal void RegisterHotKey()
|
||||
public void RegisterHotKey()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Properties.Settings.Default.HotKey))
|
||||
{
|
||||
try
|
||||
{
|
||||
hook.RegisterHotKey();
|
||||
hook.KeyPressed += (sender, e) => HotKeyPressed?.Invoke();
|
||||
hook.KeyPressed += Hook_KeyPressed;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
|
@ -64,13 +65,13 @@ namespace SystemTrayMenu.Handler
|
|||
}
|
||||
}
|
||||
|
||||
internal void ResetSelectedByKey()
|
||||
public void ResetSelectedByKey()
|
||||
{
|
||||
iRowKey = -1;
|
||||
iMenuKey = 0;
|
||||
}
|
||||
|
||||
internal void CmdKeyProcessed(object sender, Keys keys)
|
||||
public void CmdKeyProcessed(object sender, Keys keys)
|
||||
{
|
||||
sender ??= menus[iMenuKey];
|
||||
|
||||
|
@ -171,12 +172,12 @@ namespace SystemTrayMenu.Handler
|
|||
}
|
||||
}
|
||||
|
||||
internal void SearchTextChanging()
|
||||
public void SearchTextChanging()
|
||||
{
|
||||
ClearIsSelectedByKey();
|
||||
}
|
||||
|
||||
internal void SearchTextChanged(Menu menu, bool isSearchStringEmpty)
|
||||
public void SearchTextChanged(Menu menu, bool isSearchStringEmpty)
|
||||
{
|
||||
DataGridView dgv = menu.GetDataGridView();
|
||||
if (isSearchStringEmpty)
|
||||
|
@ -189,12 +190,12 @@ namespace SystemTrayMenu.Handler
|
|||
}
|
||||
}
|
||||
|
||||
internal void ClearIsSelectedByKey()
|
||||
public void ClearIsSelectedByKey()
|
||||
{
|
||||
ClearIsSelectedByKey(iMenuKey, iRowKey);
|
||||
}
|
||||
|
||||
internal void Select(DataGridView dgv, int i, bool refreshview)
|
||||
public void Select(DataGridView dgv, int i, bool refreshview)
|
||||
{
|
||||
int newiMenuKey = ((Menu)dgv.TopLevelControl).Level;
|
||||
if (i != iRowKey || newiMenuKey != iMenuKey)
|
||||
|
@ -222,6 +223,11 @@ namespace SystemTrayMenu.Handler
|
|||
}
|
||||
}
|
||||
|
||||
private void Hook_KeyPressed(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
HotKeyPressed?.Invoke();
|
||||
}
|
||||
|
||||
private bool IsAnyMenuSelectedByKey(
|
||||
ref DataGridView dgv,
|
||||
ref Menu menuFromSelected,
|
||||
|
@ -307,7 +313,7 @@ namespace SystemTrayMenu.Handler
|
|||
}
|
||||
else
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
EnterPressed.Invoke(dgv, iRowKey);
|
||||
}
|
||||
|
@ -318,7 +324,7 @@ namespace SystemTrayMenu.Handler
|
|||
if (SelectMatchedReverse(dgv, iRowKey) ||
|
||||
SelectMatchedReverse(dgv, dgv.Rows.Count - 1))
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
@ -328,7 +334,7 @@ namespace SystemTrayMenu.Handler
|
|||
if (SelectMatched(dgv, iRowKey) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
@ -337,7 +343,7 @@ namespace SystemTrayMenu.Handler
|
|||
case Keys.Home:
|
||||
if (SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
@ -346,7 +352,7 @@ namespace SystemTrayMenu.Handler
|
|||
case Keys.End:
|
||||
if (SelectMatchedReverse(dgv, dgv.Rows.Count - 1))
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
@ -380,7 +386,7 @@ namespace SystemTrayMenu.Handler
|
|||
break;
|
||||
case Keys.Escape:
|
||||
case Keys.Alt | Keys.F4:
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
iMenuKey = 0;
|
||||
iRowKey = -1;
|
||||
toClear = true;
|
||||
|
@ -392,7 +398,7 @@ namespace SystemTrayMenu.Handler
|
|||
if (SelectMatched(dgv, iRowKey, keyInput) ||
|
||||
SelectMatched(dgv, 0, keyInput))
|
||||
{
|
||||
RowDeselected(iRowBefore, null);
|
||||
RowDeselected(null, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
@ -402,7 +408,7 @@ namespace SystemTrayMenu.Handler
|
|||
if (SelectMatched(dgv, iRowKey, keyInput) ||
|
||||
SelectMatched(dgv, 0, keyInput))
|
||||
{
|
||||
RowDeselected(iRowBefore, null);
|
||||
RowDeselected(null, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
}
|
||||
else
|
||||
|
@ -434,7 +440,7 @@ namespace SystemTrayMenu.Handler
|
|||
if (SelectMatched(dgv, dgv.SelectedRows[0].Index) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
@ -442,7 +448,7 @@ namespace SystemTrayMenu.Handler
|
|||
}
|
||||
else
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
iMenuKey = 0;
|
||||
iRowKey = -1;
|
||||
toClear = true;
|
||||
|
@ -466,7 +472,7 @@ namespace SystemTrayMenu.Handler
|
|||
if (SelectMatched(dgv, iRowKey) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
@ -483,7 +489,7 @@ namespace SystemTrayMenu.Handler
|
|||
if (SelectMatched(dgv, iRowKey) ||
|
||||
SelectMatched(dgv, 0))
|
||||
{
|
||||
RowDeselected(iRowBefore, dgvBefore);
|
||||
RowDeselected(dgvBefore, iRowBefore);
|
||||
SelectRow(dgv, iRowKey);
|
||||
toClear = true;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace SystemTrayMenu.Business
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using SharpDX.DirectInput;
|
||||
using SystemTrayMenu.DataClasses;
|
||||
using SystemTrayMenu.DllImports;
|
||||
using SystemTrayMenu.Handler;
|
||||
|
@ -19,6 +20,7 @@ namespace SystemTrayMenu.Business
|
|||
using SystemTrayMenu.Helpers;
|
||||
using SystemTrayMenu.UserInterface;
|
||||
using SystemTrayMenu.Utilities;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||||
using Menu = SystemTrayMenu.UserInterface.Menu;
|
||||
using Timer = System.Windows.Forms.Timer;
|
||||
|
||||
|
@ -53,275 +55,33 @@ namespace SystemTrayMenu.Business
|
|||
workerMainMenu.WorkerSupportsCancellation = true;
|
||||
workerMainMenu.DoWork += LoadMenu;
|
||||
workerMainMenu.RunWorkerCompleted += LoadMainMenuCompleted;
|
||||
void LoadMainMenuCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
keyboardInput.ResetSelectedByKey();
|
||||
LoadStopped();
|
||||
|
||||
if (e.Result == null)
|
||||
{
|
||||
// Clean up menu status IsMenuOpen for previous one
|
||||
DataGridView dgvMainMenu = menus[0].GetDataGridView();
|
||||
foreach (DataRow row in ((DataTable)dgvMainMenu.DataSource).Rows)
|
||||
{
|
||||
RowData rowDataToClear = (RowData)row[2];
|
||||
rowDataToClear.IsMenuOpen = false;
|
||||
rowDataToClear.IsClicking = false;
|
||||
rowDataToClear.IsSelected = false;
|
||||
rowDataToClear.IsContextMenuOpen = false;
|
||||
}
|
||||
|
||||
RefreshSelection(dgvMainMenu);
|
||||
|
||||
if (Properties.Settings.Default.AppearAtMouseLocation)
|
||||
{
|
||||
menus[0].Tag = null;
|
||||
}
|
||||
|
||||
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuData menuData = (MenuData)e.Result;
|
||||
switch (menuData.Validity)
|
||||
{
|
||||
case MenuDataValidity.Valid:
|
||||
if (IconReader.MainPreload)
|
||||
{
|
||||
workerMainMenu.DoWork -= LoadMenu;
|
||||
menus[0] = Create(menuData, new DirectoryInfo(Config.Path).Name);
|
||||
menus[0].HandleCreated += (s, e) => ExecuteWatcherHistory();
|
||||
Scaling.CalculateFactorByDpi(menus[0].GetDataGridView().CreateGraphics());
|
||||
IconReader.MainPreload = false;
|
||||
if (showMenuAfterMainPreload)
|
||||
{
|
||||
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
}
|
||||
|
||||
break;
|
||||
case MenuDataValidity.Empty:
|
||||
MessageBox.Show(Translator.GetText("Your root directory for the app does not exist or is empty! Change the root directory or put some files, directories or shortcuts into the root directory."));
|
||||
OpenFolder();
|
||||
Config.SetFolderByUser();
|
||||
AppRestart.ByConfigChange();
|
||||
break;
|
||||
case MenuDataValidity.NoAccess:
|
||||
MessageBox.Show(Translator.GetText("You have no access to the root directory of the app. Grant access to the directory or change the root directory."));
|
||||
OpenFolder();
|
||||
Config.SetFolderByUser();
|
||||
AppRestart.ByConfigChange();
|
||||
break;
|
||||
case MenuDataValidity.Undefined:
|
||||
Log.Info($"{nameof(MenuDataValidity)}.{nameof(MenuDataValidity.Undefined)}");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
|
||||
waitToOpenMenu.StopLoadMenu += WaitToOpenMenu_StopLoadMenu;
|
||||
void WaitToOpenMenu_StopLoadMenu()
|
||||
{
|
||||
foreach (BackgroundWorker workerSubMenu in workersSubMenu.
|
||||
Where(w => w.IsBusy))
|
||||
{
|
||||
workerSubMenu.CancelAsync();
|
||||
}
|
||||
|
||||
LoadStopped();
|
||||
}
|
||||
|
||||
waitToOpenMenu.StartLoadMenu += StartLoadMenu;
|
||||
void StartLoadMenu(RowData rowData)
|
||||
{
|
||||
if (menus[0].IsUsable &&
|
||||
(menus[rowData.Level + 1] == null ||
|
||||
menus[rowData.Level + 1].Tag as RowData != rowData))
|
||||
{
|
||||
CreateAndShowLoadingMenu(rowData);
|
||||
void CreateAndShowLoadingMenu(RowData rowData)
|
||||
{
|
||||
MenuData menuDataLoading = new(rowData.Level + 1)
|
||||
{
|
||||
Validity = MenuDataValidity.Valid,
|
||||
};
|
||||
|
||||
Menu menuLoading = Create(menuDataLoading, new DirectoryInfo(rowData.Path).Name);
|
||||
menuLoading.IsLoadingMenu = true;
|
||||
AdjustMenusSizeAndLocation();
|
||||
menus[rowData.Level + 1] = menuLoading;
|
||||
menuLoading.Tag = menuDataLoading.RowDataParent = rowData;
|
||||
menuDataLoading.RowDataParent.SubMenu = menuLoading;
|
||||
menuLoading.SetTypeLoading();
|
||||
ShowSubMenu(menuLoading);
|
||||
}
|
||||
|
||||
BackgroundWorker workerSubMenu = workersSubMenu.
|
||||
Where(w => !w.IsBusy).FirstOrDefault();
|
||||
if (workerSubMenu == null)
|
||||
{
|
||||
workerSubMenu = new BackgroundWorker
|
||||
{
|
||||
WorkerSupportsCancellation = true,
|
||||
};
|
||||
workerSubMenu.DoWork += LoadMenu;
|
||||
workerSubMenu.RunWorkerCompleted += LoadSubMenuCompleted;
|
||||
workersSubMenu.Add(workerSubMenu);
|
||||
}
|
||||
|
||||
workerSubMenu.RunWorkerAsync(rowData);
|
||||
}
|
||||
|
||||
void LoadSubMenuCompleted(object senderCompleted, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
MenuData menuData = (MenuData)e.Result;
|
||||
|
||||
Menu menuLoading = menus[menuData.Level];
|
||||
string userSearchText = string.Empty;
|
||||
bool closedLoadingMenu = false;
|
||||
if (menuLoading != null && menuLoading.IsLoadingMenu)
|
||||
{
|
||||
menuLoading.HideWithFade();
|
||||
userSearchText = menuLoading.GetSearchText();
|
||||
menus[menuLoading.Level] = null;
|
||||
closedLoadingMenu = true;
|
||||
}
|
||||
|
||||
if (menuData.Validity != MenuDataValidity.Undefined &&
|
||||
menus[0].IsUsable)
|
||||
{
|
||||
Menu menu = Create(menuData);
|
||||
switch (menuData.Validity)
|
||||
{
|
||||
case MenuDataValidity.Valid:
|
||||
menu.SetTypeSub();
|
||||
break;
|
||||
case MenuDataValidity.Empty:
|
||||
menu.SetTypeEmpty();
|
||||
break;
|
||||
case MenuDataValidity.NoAccess:
|
||||
menu.SetTypeNoAccess();
|
||||
break;
|
||||
}
|
||||
|
||||
menu.Tag = menuData.RowDataParent;
|
||||
menuData.RowDataParent.SubMenu = menu;
|
||||
if (menus[0].IsUsable)
|
||||
{
|
||||
ShowSubMenu(menu);
|
||||
menu.SetSearchText(userSearchText);
|
||||
}
|
||||
}
|
||||
else if (closedLoadingMenu && menus[0].IsUsable)
|
||||
{
|
||||
menuData.RowDataParent.IsMenuOpen = false;
|
||||
menuData.RowDataParent.IsClicking = false;
|
||||
menuData.RowDataParent.IsSelected = false;
|
||||
Menu menuPrevious = menus[menuData.Level - 1];
|
||||
if (menuPrevious != null)
|
||||
{
|
||||
RefreshSelection(menuPrevious.GetDataGridView());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitToOpenMenu.CloseMenu += CloseMenu;
|
||||
void CloseMenu(int level)
|
||||
{
|
||||
if (level < menus.Length && menus[level] != null)
|
||||
{
|
||||
HideOldMenu(menus[level]);
|
||||
}
|
||||
|
||||
if (level - 1 < menus.Length && menus[level - 1] != null)
|
||||
{
|
||||
menus[level - 1].FocusTextBox();
|
||||
}
|
||||
}
|
||||
|
||||
waitToOpenMenu.MouseEnterOk += MouseEnterOk;
|
||||
dgvMouseRow.RowMouseEnter += waitToOpenMenu.MouseEnter;
|
||||
dgvMouseRow.RowMouseLeave += waitToOpenMenu.MouseLeave;
|
||||
dgvMouseRow.RowMouseLeave += Dgv_RowMouseLeave;
|
||||
|
||||
keyboardInput = new(menus);
|
||||
keyboardInput.RegisterHotKey();
|
||||
keyboardInput.HotKeyPressed += () => SwitchOpenClose(false);
|
||||
keyboardInput.HotKeyPressed += KeyboardInput_HotKeyPressed;
|
||||
keyboardInput.ClosePressed += MenusFadeOut;
|
||||
keyboardInput.RowDeselected += waitToOpenMenu.RowDeselected;
|
||||
keyboardInput.EnterPressed += waitToOpenMenu.EnterOpensInstantly;
|
||||
keyboardInput.RowSelected += waitToOpenMenu.RowSelected;
|
||||
keyboardInput.RowSelected += AdjustScrollbarToDisplayedRow;
|
||||
void AdjustScrollbarToDisplayedRow(DataGridView dgv, int index)
|
||||
{
|
||||
Menu menu = (Menu)dgv.FindForm();
|
||||
menu.AdjustScrollbar();
|
||||
}
|
||||
|
||||
joystickHelper = new();
|
||||
joystickHelper.KeyPressed += (key) => menus[0].Invoke(keyboardInput.CmdKeyProcessed, null, key);
|
||||
|
||||
joystickHelper.KeyPressed += JoystickHelper_KeyPressed;
|
||||
timerShowProcessStartedAsLoadingIcon.Interval = Properties.Settings.Default.TimeUntilClosesAfterEnterPressed;
|
||||
timerStillActiveCheck.Interval = Properties.Settings.Default.TimeUntilClosesAfterEnterPressed + 20;
|
||||
timerStillActiveCheck.Tick += (sender, e) => StillActiveTick();
|
||||
void StillActiveTick()
|
||||
{
|
||||
if (!IsActive())
|
||||
{
|
||||
FadeHalfOrOutIfNeeded();
|
||||
}
|
||||
|
||||
timerStillActiveCheck.Stop();
|
||||
}
|
||||
|
||||
timerStillActiveCheck.Tick += TimerStillActiveCheck_Tick;
|
||||
waitLeave.LeaveTriggered += FadeHalfOrOutIfNeeded;
|
||||
|
||||
CreateWatcher(Config.Path, false);
|
||||
foreach (var pathAndFlags in MenusHelpers.GetAddionalPathsForMainMenu())
|
||||
{
|
||||
CreateWatcher(pathAndFlags.Path, pathAndFlags.Recursive);
|
||||
}
|
||||
|
||||
void CreateWatcher(string path, bool recursiv)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileSystemWatcher watcher = new()
|
||||
{
|
||||
Path = path,
|
||||
NotifyFilter = NotifyFilters.Attributes |
|
||||
NotifyFilters.DirectoryName |
|
||||
NotifyFilters.FileName |
|
||||
NotifyFilters.LastWrite,
|
||||
Filter = "*.*",
|
||||
};
|
||||
watcher.Created += WatcherProcessItem;
|
||||
watcher.Deleted += WatcherProcessItem;
|
||||
watcher.Renamed += WatcherProcessItem;
|
||||
watcher.Changed += WatcherProcessItem;
|
||||
watcher.IncludeSubdirectories = recursiv;
|
||||
watcher.EnableRaisingEvents = true;
|
||||
watchers.Add(watcher);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"Failed to {nameof(CreateWatcher)}: {path}", ex);
|
||||
}
|
||||
}
|
||||
CreateWatchers();
|
||||
}
|
||||
|
||||
internal event EventHandlerEmpty LoadStarted;
|
||||
public event Action LoadStarted;
|
||||
|
||||
internal event EventHandlerEmpty LoadStopped;
|
||||
public event Action LoadStopped;
|
||||
|
||||
private enum OpenCloseState
|
||||
{
|
||||
|
@ -334,34 +94,7 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
private List<Menu> AsList => AsEnumerable.ToList();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
workerMainMenu.Dispose();
|
||||
foreach (BackgroundWorker worker in workersSubMenu)
|
||||
{
|
||||
worker.Dispose();
|
||||
}
|
||||
|
||||
waitToOpenMenu.Dispose();
|
||||
keyboardInput.Dispose();
|
||||
joystickHelper.Dispose();
|
||||
timerShowProcessStartedAsLoadingIcon.Dispose();
|
||||
timerStillActiveCheck.Dispose();
|
||||
waitLeave.Dispose();
|
||||
IconReader.Dispose();
|
||||
DisposeMenu(menus[0]);
|
||||
dgvMouseRow.Dispose();
|
||||
foreach (FileSystemWatcher watcher in watchers)
|
||||
{
|
||||
watcher.Created -= WatcherProcessItem;
|
||||
watcher.Deleted -= WatcherProcessItem;
|
||||
watcher.Renamed -= WatcherProcessItem;
|
||||
watcher.Changed -= WatcherProcessItem;
|
||||
watcher.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal static MenuData GetData(BackgroundWorker worker, string path, int level)
|
||||
public static MenuData GetData(BackgroundWorker worker, string path, int level)
|
||||
{
|
||||
MenuData menuData = new(level);
|
||||
if (worker?.CancellationPending == true || string.IsNullOrEmpty(path))
|
||||
|
@ -392,18 +125,65 @@ namespace SystemTrayMenu.Business
|
|||
return menuData;
|
||||
}
|
||||
|
||||
internal void SwitchOpenCloseByTaskbarItem()
|
||||
public void Dispose()
|
||||
{
|
||||
workerMainMenu.DoWork -= LoadMenu;
|
||||
workerMainMenu.RunWorkerCompleted -= LoadMainMenuCompleted;
|
||||
workerMainMenu.Dispose();
|
||||
dgvMouseRow.RowMouseEnter -= waitToOpenMenu.MouseEnter;
|
||||
dgvMouseRow.RowMouseLeave -= waitToOpenMenu.MouseLeave;
|
||||
dgvMouseRow.RowMouseLeave -= Dgv_RowMouseLeave;
|
||||
keyboardInput.HotKeyPressed -= KeyboardInput_HotKeyPressed;
|
||||
keyboardInput.ClosePressed -= MenusFadeOut;
|
||||
keyboardInput.RowDeselected -= waitToOpenMenu.RowDeselected;
|
||||
keyboardInput.EnterPressed -= waitToOpenMenu.EnterOpensInstantly;
|
||||
keyboardInput.RowSelected -= waitToOpenMenu.RowSelected;
|
||||
keyboardInput.RowSelected -= AdjustScrollbarToDisplayedRow;
|
||||
keyboardInput.Dispose();
|
||||
waitToOpenMenu.StopLoadMenu -= WaitToOpenMenu_StopLoadMenu;
|
||||
waitToOpenMenu.StartLoadMenu -= StartLoadMenu;
|
||||
waitToOpenMenu.CloseMenu -= CloseMenu;
|
||||
waitToOpenMenu.MouseEnterOk -= MouseEnterOk;
|
||||
waitToOpenMenu.Dispose();
|
||||
joystickHelper.KeyPressed -= JoystickHelper_KeyPressed;
|
||||
joystickHelper.Dispose();
|
||||
timerShowProcessStartedAsLoadingIcon.Dispose();
|
||||
timerStillActiveCheck.Tick -= TimerStillActiveCheck_Tick;
|
||||
timerStillActiveCheck.Dispose();
|
||||
waitLeave.LeaveTriggered -= FadeHalfOrOutIfNeeded;
|
||||
waitLeave.Dispose();
|
||||
foreach (BackgroundWorker workerSubMenu in workersSubMenu)
|
||||
{
|
||||
workerSubMenu.DoWork -= LoadMenu;
|
||||
workerSubMenu.RunWorkerCompleted -= LoadSubMenuCompleted;
|
||||
workerSubMenu.Dispose();
|
||||
}
|
||||
|
||||
IconReader.Dispose();
|
||||
dgvMouseRow.Dispose();
|
||||
DisposeMenu(menus[0]);
|
||||
foreach (FileSystemWatcher watcher in watchers)
|
||||
{
|
||||
watcher.Created -= WatcherProcessItem;
|
||||
watcher.Deleted -= WatcherProcessItem;
|
||||
watcher.Renamed -= WatcherProcessItem;
|
||||
watcher.Changed -= WatcherProcessItem;
|
||||
watcher.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void SwitchOpenCloseByTaskbarItem()
|
||||
{
|
||||
SwitchOpenClose(true);
|
||||
timerStillActiveCheck.Start();
|
||||
}
|
||||
|
||||
internal bool IsOpenCloseStateOpening()
|
||||
public bool IsOpenCloseStateOpening()
|
||||
{
|
||||
return openCloseState == OpenCloseState.Opening;
|
||||
}
|
||||
|
||||
internal void SwitchOpenClose(bool byClick, bool isMainPreload = false)
|
||||
public void SwitchOpenClose(bool byClick, bool isMainPreload = false)
|
||||
{
|
||||
// Ignore open close events during main preload #248
|
||||
if (IconReader.MainPreload && !isMainPreload)
|
||||
|
@ -448,13 +228,18 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
if (menuToDispose != null)
|
||||
{
|
||||
menuToDispose.UserClickedOpenFolder -= OpenFolder;
|
||||
menuToDispose.MouseWheel -= AdjustMenusSizeAndLocation;
|
||||
menuToDispose.MouseLeave -= waitLeave.Start;
|
||||
menuToDispose.MouseEnter -= waitLeave.Stop;
|
||||
menuToDispose.CmdKeyProcessed -= keyboardInput.CmdKeyProcessed;
|
||||
menuToDispose.SearchTextChanging -= keyboardInput.SearchTextChanging;
|
||||
menuToDispose.KeyPressCheck -= Menu_KeyPressCheck;
|
||||
menuToDispose.SearchTextChanging -= Menu_SearchTextChanging;
|
||||
menuToDispose.SearchTextChanged -= Menu_SearchTextChanged;
|
||||
menuToDispose.UserDragsMenu -= Menu_UserDragsMenu;
|
||||
menuToDispose.Activated -= Menu_Activated;
|
||||
menuToDispose.Deactivate -= Menu_Deactivate;
|
||||
menuToDispose.VisibleChanged -= MenuVisibleChanged;
|
||||
DataGridView dgv = menuToDispose.GetDataGridView();
|
||||
if (dgv != null)
|
||||
{
|
||||
|
@ -470,6 +255,7 @@ namespace SystemTrayMenu.Business
|
|||
dgv.MouseDoubleClick -= Dgv_MouseDoubleClick;
|
||||
dgv.SelectionChanged -= Dgv_SelectionChanged;
|
||||
dgv.RowPostPaint -= Dgv_RowPostPaint;
|
||||
dgv.DataError -= Dgv_DataError;
|
||||
dgv.ClearSelection();
|
||||
|
||||
foreach (DataGridViewRow row in dgv.Rows)
|
||||
|
@ -477,6 +263,9 @@ namespace SystemTrayMenu.Business
|
|||
RowData rowData = (RowData)row.Cells[2].Value;
|
||||
DisposeMenu(rowData.SubMenu);
|
||||
}
|
||||
|
||||
DataTable dataTable = (DataTable)dgv.DataSource;
|
||||
dataTable.Dispose();
|
||||
}
|
||||
|
||||
menuToDispose.Dispose();
|
||||
|
@ -620,6 +409,197 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
}
|
||||
|
||||
private void LoadMainMenuCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
keyboardInput.ResetSelectedByKey();
|
||||
LoadStopped();
|
||||
|
||||
if (e.Result == null)
|
||||
{
|
||||
// Clean up menu status IsMenuOpen for previous one
|
||||
DataGridView dgvMainMenu = menus[0].GetDataGridView();
|
||||
foreach (DataRow row in ((DataTable)dgvMainMenu.DataSource).Rows)
|
||||
{
|
||||
RowData rowDataToClear = (RowData)row[2];
|
||||
rowDataToClear.IsMenuOpen = false;
|
||||
rowDataToClear.IsClicking = false;
|
||||
rowDataToClear.IsSelected = false;
|
||||
rowDataToClear.IsContextMenuOpen = false;
|
||||
}
|
||||
|
||||
RefreshSelection(dgvMainMenu);
|
||||
|
||||
if (Properties.Settings.Default.AppearAtMouseLocation)
|
||||
{
|
||||
menus[0].Tag = null;
|
||||
}
|
||||
|
||||
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuData menuData = (MenuData)e.Result;
|
||||
switch (menuData.Validity)
|
||||
{
|
||||
case MenuDataValidity.Valid:
|
||||
if (IconReader.MainPreload)
|
||||
{
|
||||
workerMainMenu.DoWork -= LoadMenu;
|
||||
menus[0] = Create(menuData, new DirectoryInfo(Config.Path).Name);
|
||||
menus[0].HandleCreated += (s, e) => ExecuteWatcherHistory();
|
||||
Scaling.CalculateFactorByDpi(menus[0].GetDataGridView().CreateGraphics());
|
||||
IconReader.MainPreload = false;
|
||||
if (showMenuAfterMainPreload)
|
||||
{
|
||||
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
}
|
||||
|
||||
break;
|
||||
case MenuDataValidity.Empty:
|
||||
MessageBox.Show(Translator.GetText("Your root directory for the app does not exist or is empty! Change the root directory or put some files, directories or shortcuts into the root directory."));
|
||||
OpenFolder();
|
||||
Config.SetFolderByUser();
|
||||
AppRestart.ByConfigChange();
|
||||
break;
|
||||
case MenuDataValidity.NoAccess:
|
||||
MessageBox.Show(Translator.GetText("You have no access to the root directory of the app. Grant access to the directory or change the root directory."));
|
||||
OpenFolder();
|
||||
Config.SetFolderByUser();
|
||||
AppRestart.ByConfigChange();
|
||||
break;
|
||||
case MenuDataValidity.Undefined:
|
||||
Log.Info($"{nameof(MenuDataValidity)}.{nameof(MenuDataValidity.Undefined)}");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
|
||||
private void WaitToOpenMenu_StopLoadMenu()
|
||||
{
|
||||
foreach (BackgroundWorker workerSubMenu in workersSubMenu.Where(w => w.IsBusy))
|
||||
{
|
||||
workerSubMenu.CancelAsync();
|
||||
}
|
||||
|
||||
LoadStopped();
|
||||
}
|
||||
|
||||
private void StartLoadMenu(RowData rowData)
|
||||
{
|
||||
if (menus[0].IsUsable &&
|
||||
(menus[rowData.Level + 1] == null ||
|
||||
menus[rowData.Level + 1].Tag as RowData != rowData))
|
||||
{
|
||||
CreateAndShowLoadingMenu(rowData);
|
||||
void CreateAndShowLoadingMenu(RowData rowData)
|
||||
{
|
||||
MenuData menuDataLoading = new(rowData.Level + 1)
|
||||
{
|
||||
Validity = MenuDataValidity.Valid,
|
||||
};
|
||||
|
||||
Menu menuLoading = Create(menuDataLoading, new DirectoryInfo(rowData.Path).Name);
|
||||
menuLoading.IsLoadingMenu = true;
|
||||
AdjustMenusSizeAndLocation();
|
||||
menus[rowData.Level + 1] = menuLoading;
|
||||
menuLoading.Tag = menuDataLoading.RowDataParent = rowData;
|
||||
menuDataLoading.RowDataParent.SubMenu = menuLoading;
|
||||
menuLoading.SetTypeLoading();
|
||||
ShowSubMenu(menuLoading);
|
||||
}
|
||||
|
||||
BackgroundWorker workerSubMenu = workersSubMenu.
|
||||
Where(w => !w.IsBusy).FirstOrDefault();
|
||||
if (workerSubMenu == null)
|
||||
{
|
||||
workerSubMenu = new BackgroundWorker()
|
||||
{
|
||||
WorkerSupportsCancellation = true,
|
||||
};
|
||||
workerSubMenu.DoWork += LoadMenu;
|
||||
workerSubMenu.RunWorkerCompleted += LoadSubMenuCompleted;
|
||||
workersSubMenu.Add(workerSubMenu);
|
||||
}
|
||||
|
||||
workerSubMenu.RunWorkerAsync(rowData);
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseMenu(int level)
|
||||
{
|
||||
if (level < menus.Length && menus[level] != null)
|
||||
{
|
||||
HideOldMenu(menus[level]);
|
||||
}
|
||||
|
||||
if (level - 1 < menus.Length && menus[level - 1] != null)
|
||||
{
|
||||
menus[level - 1].FocusTextBox();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSubMenuCompleted(object senderCompleted, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
MenuData menuData = (MenuData)e.Result;
|
||||
|
||||
Menu menuLoading = menus[menuData.Level];
|
||||
string userSearchText = string.Empty;
|
||||
bool closedLoadingMenu = false;
|
||||
if (menuLoading != null && menuLoading.IsLoadingMenu)
|
||||
{
|
||||
menuLoading.HideWithFade();
|
||||
userSearchText = menuLoading.GetSearchText();
|
||||
menus[menuLoading.Level] = null;
|
||||
closedLoadingMenu = true;
|
||||
}
|
||||
|
||||
if (menuData.Validity != MenuDataValidity.Undefined &&
|
||||
menus[0].IsUsable)
|
||||
{
|
||||
Menu menu = Create(menuData);
|
||||
switch (menuData.Validity)
|
||||
{
|
||||
case MenuDataValidity.Valid:
|
||||
menu.SetTypeSub();
|
||||
break;
|
||||
case MenuDataValidity.Empty:
|
||||
menu.SetTypeEmpty();
|
||||
break;
|
||||
case MenuDataValidity.NoAccess:
|
||||
menu.SetTypeNoAccess();
|
||||
break;
|
||||
}
|
||||
|
||||
menu.Tag = menuData.RowDataParent;
|
||||
menuData.RowDataParent.SubMenu = menu;
|
||||
if (menus[0].IsUsable)
|
||||
{
|
||||
ShowSubMenu(menu);
|
||||
menu.SetSearchText(userSearchText);
|
||||
}
|
||||
}
|
||||
else if (closedLoadingMenu && menus[0].IsUsable)
|
||||
{
|
||||
menuData.RowDataParent.IsMenuOpen = false;
|
||||
menuData.RowDataParent.IsClicking = false;
|
||||
menuData.RowDataParent.IsSelected = false;
|
||||
Menu menuPrevious = menus[menuData.Level - 1];
|
||||
if (menuPrevious != null)
|
||||
{
|
||||
RefreshSelection(menuPrevious.GetDataGridView());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsActive()
|
||||
{
|
||||
bool IsShellContextMenuOpen()
|
||||
|
@ -653,22 +633,21 @@ namespace SystemTrayMenu.Business
|
|||
private Menu Create(MenuData menuData, string title = null)
|
||||
{
|
||||
Menu menu = new();
|
||||
|
||||
string path = Config.Path;
|
||||
menu.Level = menuData.Level;
|
||||
menu.Path = Config.Path;
|
||||
if (title == null)
|
||||
{
|
||||
title = new DirectoryInfo(menuData.RowDataParent.ResolvedPath).Name;
|
||||
path = menuData.RowDataParent.ResolvedPath;
|
||||
menu.Path = menuData.RowDataParent.ResolvedPath;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(title))
|
||||
{
|
||||
title = Path.GetPathRoot(path);
|
||||
title = Path.GetPathRoot(menu.Path);
|
||||
}
|
||||
|
||||
menu.AdjustControls(title, menuData.Validity);
|
||||
menu.UserClickedOpenFolder += () => OpenFolder(path);
|
||||
menu.Level = menuData.Level;
|
||||
menu.UserClickedOpenFolder += OpenFolder;
|
||||
menu.MouseWheel += AdjustMenusSizeAndLocation;
|
||||
menu.MouseLeave += waitLeave.Start;
|
||||
menu.MouseEnter += waitLeave.Stop;
|
||||
|
@ -677,43 +656,8 @@ namespace SystemTrayMenu.Business
|
|||
menu.SearchTextChanging += Menu_SearchTextChanging;
|
||||
menu.SearchTextChanged += Menu_SearchTextChanged;
|
||||
menu.UserDragsMenu += Menu_UserDragsMenu;
|
||||
void Menu_UserDragsMenu()
|
||||
{
|
||||
if (menus[1] != null)
|
||||
{
|
||||
HideOldMenu(menus[1]);
|
||||
}
|
||||
}
|
||||
|
||||
menu.Deactivate += Deactivate;
|
||||
void Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
if (IsOpenCloseStateOpening())
|
||||
{
|
||||
Log.Info("Ignored Deactivate, because openCloseState == OpenCloseState.Opening");
|
||||
}
|
||||
else if (!Properties.Settings.Default.StaysOpenWhenFocusLostAfterEnterPressed ||
|
||||
!waitingForReactivate)
|
||||
{
|
||||
FadeHalfOrOutIfNeeded();
|
||||
if (!IsActive())
|
||||
{
|
||||
deactivatedTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu.Activated += (sender, e) => Activated();
|
||||
void Activated()
|
||||
{
|
||||
if (IsActive() && menus[0].IsUsable)
|
||||
{
|
||||
AsList.ForEach(m => m.ShowWithFade());
|
||||
timerStillActiveCheck.Stop();
|
||||
timerStillActiveCheck.Start();
|
||||
}
|
||||
}
|
||||
|
||||
menu.Activated += Menu_Activated;
|
||||
menu.Deactivate += Menu_Deactivate;
|
||||
menu.VisibleChanged += MenuVisibleChanged;
|
||||
AddItemsToMenu(menuData.RowDatas, menu, out int foldersCount, out int filesCount);
|
||||
|
||||
|
@ -731,18 +675,47 @@ namespace SystemTrayMenu.Business
|
|||
dgv.SelectionChanged += Dgv_SelectionChanged;
|
||||
dgv.RowPostPaint += Dgv_RowPostPaint;
|
||||
dgv.DataError += Dgv_DataError;
|
||||
void Dgv_DataError(object sender, DataGridViewDataErrorEventArgs e)
|
||||
{
|
||||
// WARN Dgv_DataError occured System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Icon'
|
||||
// => Rare times occured (e.g. when focused an close other application => closed and activated at same time)
|
||||
Log.Warn("Dgv_DataError occured", e.Exception);
|
||||
}
|
||||
|
||||
menu.SetCounts(foldersCount, filesCount);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private void Menu_UserDragsMenu()
|
||||
{
|
||||
if (menus[1] != null)
|
||||
{
|
||||
HideOldMenu(menus[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private void Menu_Activated(object sender, EventArgs e)
|
||||
{
|
||||
if (IsActive() && menus[0].IsUsable)
|
||||
{
|
||||
AsList.ForEach(m => m.ShowWithFade());
|
||||
timerStillActiveCheck.Stop();
|
||||
timerStillActiveCheck.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void Menu_Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
if (IsOpenCloseStateOpening())
|
||||
{
|
||||
Log.Info("Ignored Deactivate, because openCloseState == OpenCloseState.Opening");
|
||||
}
|
||||
else if (!Properties.Settings.Default.StaysOpenWhenFocusLostAfterEnterPressed ||
|
||||
!waitingForReactivate)
|
||||
{
|
||||
FadeHalfOrOutIfNeeded();
|
||||
if (!IsActive())
|
||||
{
|
||||
deactivatedTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuVisibleChanged(object sender, EventArgs e)
|
||||
{
|
||||
Menu menu = (Menu)sender;
|
||||
|
@ -1058,6 +1031,13 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
}
|
||||
|
||||
private void Dgv_DataError(object sender, DataGridViewDataErrorEventArgs e)
|
||||
{
|
||||
// WARN Dgv_DataError occured System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Icon'
|
||||
// => Rare times occured (e.g. when focused an close other application => closed and activated at same time)
|
||||
Log.Warn("Dgv_DataError occured", e.Exception);
|
||||
}
|
||||
|
||||
private void ShowSubMenu(Menu menuToShow)
|
||||
{
|
||||
HideOldMenu(menuToShow, true);
|
||||
|
@ -1142,6 +1122,68 @@ namespace SystemTrayMenu.Business
|
|||
joystickHelper.Disable();
|
||||
}
|
||||
|
||||
private void CreateWatchers()
|
||||
{
|
||||
CreateWatcher(Config.Path, false);
|
||||
foreach (var pathAndFlags in MenusHelpers.GetAddionalPathsForMainMenu())
|
||||
{
|
||||
CreateWatcher(pathAndFlags.Path, pathAndFlags.Recursive);
|
||||
}
|
||||
|
||||
void CreateWatcher(string path, bool recursiv)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileSystemWatcher watcher = new()
|
||||
{
|
||||
Path = path,
|
||||
NotifyFilter = NotifyFilters.Attributes |
|
||||
NotifyFilters.DirectoryName |
|
||||
NotifyFilters.FileName |
|
||||
NotifyFilters.LastWrite,
|
||||
Filter = "*.*",
|
||||
};
|
||||
watcher.Created += WatcherProcessItem;
|
||||
watcher.Deleted += WatcherProcessItem;
|
||||
watcher.Renamed += WatcherProcessItem;
|
||||
watcher.Changed += WatcherProcessItem;
|
||||
watcher.IncludeSubdirectories = recursiv;
|
||||
watcher.EnableRaisingEvents = true;
|
||||
watchers.Add(watcher);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Warn($"Failed to {nameof(CreateWatcher)}: {path}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustScrollbarToDisplayedRow(DataGridView dgv, int index)
|
||||
{
|
||||
Menu menu = (Menu)dgv.FindForm();
|
||||
menu.AdjustScrollbar();
|
||||
}
|
||||
|
||||
private void JoystickHelper_KeyPressed(Keys keys)
|
||||
{
|
||||
menus[0].Invoke(keyboardInput.CmdKeyProcessed, null, keys);
|
||||
}
|
||||
|
||||
private void TimerStillActiveCheck_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (!IsActive())
|
||||
{
|
||||
FadeHalfOrOutIfNeeded();
|
||||
}
|
||||
|
||||
timerStillActiveCheck.Stop();
|
||||
}
|
||||
|
||||
private void KeyboardInput_HotKeyPressed()
|
||||
{
|
||||
SwitchOpenClose(false);
|
||||
}
|
||||
|
||||
private void AdjustMenusSizeAndLocation()
|
||||
{
|
||||
Rectangle screenBounds;
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace SystemTrayMenu
|
|||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.ThreadException += (sender, e) => AskUserSendError(e.Exception);
|
||||
Application.ThreadException += Application_ThreadException;
|
||||
Scaling.Initialize();
|
||||
FolderOptions.Initialize();
|
||||
|
||||
|
@ -40,6 +40,7 @@ namespace SystemTrayMenu
|
|||
}
|
||||
}
|
||||
|
||||
Application.ThreadException -= Application_ThreadException;
|
||||
Config.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -50,32 +51,37 @@ namespace SystemTrayMenu
|
|||
{
|
||||
Log.Close();
|
||||
}
|
||||
}
|
||||
|
||||
static void AskUserSendError(Exception ex)
|
||||
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
|
||||
{
|
||||
AskUserSendError(e.Exception);
|
||||
}
|
||||
|
||||
private static void AskUserSendError(Exception ex)
|
||||
{
|
||||
Log.Error("Application Crashed", ex);
|
||||
|
||||
DialogResult dialogResult = MessageBox.Show(
|
||||
"A problem has been encountered and the application needs to restart. " +
|
||||
"Reporting this error will help us make our product better. " +
|
||||
"Press 'Yes' to open your standard email app (emailto: Markus@Hofknecht.eu). " + Environment.NewLine +
|
||||
@"You can also create an issue manually here https://github.com/Hofknecht/SystemTrayMenu/issues" + Environment.NewLine +
|
||||
"Press 'Cancel' to quit SystemTrayMenu.",
|
||||
"SystemTrayMenu Crashed",
|
||||
MessageBoxButtons.YesNoCancel);
|
||||
|
||||
if (dialogResult == DialogResult.Yes)
|
||||
{
|
||||
Log.Error("Application Crashed", ex);
|
||||
Log.ProcessStart("mailto:" + "markus@hofknecht.eu" +
|
||||
"?subject=SystemTrayMenu Bug reported " +
|
||||
Assembly.GetEntryAssembly().GetName().Version +
|
||||
"&body=" + ex.ToString());
|
||||
}
|
||||
|
||||
DialogResult dialogResult = MessageBox.Show(
|
||||
"A problem has been encountered and the application needs to restart. " +
|
||||
"Reporting this error will help us make our product better. " +
|
||||
"Press 'Yes' to open your standard email app (emailto: Markus@Hofknecht.eu). " + Environment.NewLine +
|
||||
@"You can also create an issue manually here https://github.com/Hofknecht/SystemTrayMenu/issues" + Environment.NewLine +
|
||||
"Press 'Cancel' to quit SystemTrayMenu.",
|
||||
"SystemTrayMenu Crashed",
|
||||
MessageBoxButtons.YesNoCancel);
|
||||
|
||||
if (dialogResult == DialogResult.Yes)
|
||||
{
|
||||
Log.ProcessStart("mailto:" + "markus@hofknecht.eu" +
|
||||
"?subject=SystemTrayMenu Bug reported " +
|
||||
Assembly.GetEntryAssembly().GetName().Version +
|
||||
"&body=" + ex.ToString());
|
||||
}
|
||||
|
||||
if (!isStartup && dialogResult != DialogResult.Cancel)
|
||||
{
|
||||
AppRestart.ByThreadException();
|
||||
}
|
||||
if (!isStartup && dialogResult != DialogResult.Cancel)
|
||||
{
|
||||
AppRestart.ByThreadException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,11 @@ namespace SystemTrayMenu.Handler
|
|||
timerLeaveCheck.Tick += TimerLeaveCheckTick;
|
||||
}
|
||||
|
||||
public event EventHandlerEmpty LeaveTriggered;
|
||||
public event Action LeaveTriggered;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
timerLeaveCheck.Tick -= TimerLeaveCheckTick;
|
||||
timerLeaveCheck.Dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
internal event Action<int> CloseMenu;
|
||||
|
||||
internal event EventHandlerEmpty StopLoadMenu;
|
||||
internal event Action StopLoadMenu;
|
||||
|
||||
internal event Action<DataGridView, int> MouseEnterOk;
|
||||
|
||||
|
@ -41,6 +41,7 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
timerStartLoad.Tick -= WaitStartLoad_Tick;
|
||||
timerStartLoad.Stop();
|
||||
timerStartLoad.Dispose();
|
||||
dgv?.Dispose();
|
||||
|
@ -92,7 +93,7 @@ namespace SystemTrayMenu.Handler
|
|||
}
|
||||
}
|
||||
|
||||
internal void RowDeselected(int rowIndex, DataGridView dgv)
|
||||
internal void RowDeselected(DataGridView dgv, int rowIndex)
|
||||
{
|
||||
timerStartLoad.Stop();
|
||||
StopLoadMenu?.Invoke();
|
||||
|
|
|
@ -16,12 +16,12 @@ namespace SystemTrayMenu.Helper
|
|||
internal DgvMouseRow()
|
||||
{
|
||||
timerRaiseRowMouseLeave.Interval = 200;
|
||||
timerRaiseRowMouseLeave.Tick += Elapsed;
|
||||
void Elapsed(object sender, EventArgs e)
|
||||
{
|
||||
timerRaiseRowMouseLeave.Stop();
|
||||
TriggerRowMouseLeave();
|
||||
}
|
||||
timerRaiseRowMouseLeave.Tick += TimerRaiseRowMouseLeave_Tick;
|
||||
}
|
||||
|
||||
~DgvMouseRow() // the finalizer
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
internal event Action<object, DataGridViewCellEventArgs> RowMouseEnter;
|
||||
|
@ -75,11 +75,18 @@ namespace SystemTrayMenu.Helper
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
timerRaiseRowMouseLeave.Tick -= TimerRaiseRowMouseLeave_Tick;
|
||||
timerRaiseRowMouseLeave.Dispose();
|
||||
dgv?.Dispose();
|
||||
dgv = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void TimerRaiseRowMouseLeave_Tick(object sender, EventArgs e)
|
||||
{
|
||||
timerRaiseRowMouseLeave.Stop();
|
||||
TriggerRowMouseLeave();
|
||||
}
|
||||
|
||||
private void TriggerRowMouseLeave()
|
||||
{
|
||||
if (dgv != null)
|
||||
|
|
|
@ -28,14 +28,19 @@ namespace SystemTrayMenu.Helper
|
|||
internal Fading()
|
||||
{
|
||||
timer.Interval = Interval100FPS;
|
||||
timer.Tick += (sender, e) => FadeStep();
|
||||
timer.Tick += Timer_Tick;
|
||||
}
|
||||
|
||||
internal event EventHandlerEmpty Hide;
|
||||
~Fading() // the finalizer
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
internal event EventHandlerEmpty Show;
|
||||
internal event Action Hide;
|
||||
|
||||
internal event EventHandler<double> ChangeOpacity;
|
||||
internal event Action Show;
|
||||
|
||||
internal event Action<double> ChangeOpacity;
|
||||
|
||||
internal enum FadingState
|
||||
{
|
||||
|
@ -62,6 +67,7 @@ namespace SystemTrayMenu.Helper
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
timer.Tick -= Timer_Tick;
|
||||
timer.Dispose();
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +86,11 @@ namespace SystemTrayMenu.Helper
|
|||
}
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
FadeStep();
|
||||
}
|
||||
|
||||
private void FadeStep()
|
||||
{
|
||||
switch (state)
|
||||
|
@ -90,13 +101,13 @@ namespace SystemTrayMenu.Helper
|
|||
visible = true;
|
||||
Show?.Invoke();
|
||||
opacity = 0;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
}
|
||||
else if (Properties.Settings.Default.UseFading &&
|
||||
opacity < ShownMinus)
|
||||
{
|
||||
opacity += StepIn;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -104,11 +115,11 @@ namespace SystemTrayMenu.Helper
|
|||
{
|
||||
// #393 provoke a redraw for the CS_DROPSHADOW to work
|
||||
opacity = ShownMinus;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
}
|
||||
|
||||
opacity = Shown;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
StartStopTimer(FadingState.Idle);
|
||||
}
|
||||
|
||||
|
@ -119,24 +130,24 @@ namespace SystemTrayMenu.Helper
|
|||
visible = true;
|
||||
Show?.Invoke();
|
||||
opacity = 0;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
}
|
||||
else if (Properties.Settings.Default.UseFading &&
|
||||
opacity < TransparentMinus)
|
||||
{
|
||||
opacity += StepIn;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
}
|
||||
else if (Properties.Settings.Default.UseFading &&
|
||||
opacity > TransparentPlus)
|
||||
{
|
||||
opacity -= StepOut;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
}
|
||||
else
|
||||
{
|
||||
opacity = Transparent;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
StartStopTimer(FadingState.Idle);
|
||||
}
|
||||
|
||||
|
@ -146,12 +157,12 @@ namespace SystemTrayMenu.Helper
|
|||
opacity > StepOut)
|
||||
{
|
||||
opacity -= StepOut;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
}
|
||||
else if (visible)
|
||||
{
|
||||
opacity = 0;
|
||||
ChangeOpacity?.Invoke(this, opacity);
|
||||
ChangeOpacity?.Invoke(opacity);
|
||||
visible = false;
|
||||
Hide?.Invoke();
|
||||
StartStopTimer(FadingState.Idle);
|
||||
|
|
|
@ -32,6 +32,11 @@ namespace SystemTrayMenu.Helpers
|
|||
}
|
||||
}
|
||||
|
||||
~JoystickHelper() // the finalizer
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public event Action<Keys> KeyPressed;
|
||||
|
||||
public void Enable()
|
||||
|
@ -54,6 +59,7 @@ namespace SystemTrayMenu.Helpers
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
timerReadJoystick.Elapsed -= ReadJoystickLoop;
|
||||
timerReadJoystick?.Dispose();
|
||||
joystick?.Dispose();
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace SystemTrayMenu.Helper
|
|||
/// The enumeration of possible modifiers.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
internal enum KeyboardHookModifierKeys : uint
|
||||
public enum KeyboardHookModifierKeys : uint
|
||||
{
|
||||
None = 0,
|
||||
Alt = 1,
|
||||
|
@ -30,7 +30,7 @@ namespace SystemTrayMenu.Helper
|
|||
public KeyboardHook()
|
||||
{
|
||||
// register the event of the inner native window.
|
||||
window.KeyPressed += (sender, e) => KeyPressed?.Invoke(this, e);
|
||||
window.KeyPressed += Window_KeyPressed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -47,6 +47,7 @@ namespace SystemTrayMenu.Helper
|
|||
}
|
||||
|
||||
// dispose the inner native window.
|
||||
window.KeyPressed -= Window_KeyPressed;
|
||||
window.Dispose();
|
||||
}
|
||||
|
||||
|
@ -104,6 +105,11 @@ namespace SystemTrayMenu.Helper
|
|||
RegisterHotKey((uint)modifier, key);
|
||||
}
|
||||
|
||||
private void Window_KeyPressed(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
KeyPressed?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void RegisterHotKey(uint modifier, Keys key)
|
||||
{
|
||||
currentId += 1;
|
||||
|
|
|
@ -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.3.1.7")]
|
||||
[assembly: AssemblyFileVersion("1.3.1.7")]
|
||||
[assembly: AssemblyVersion("1.3.1.9")]
|
||||
[assembly: AssemblyFileVersion("1.3.1.9")]
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace SystemTrayMenu.Helper
|
|||
|
||||
internal class AppContextMenu
|
||||
{
|
||||
public event EventHandlerEmpty ClickedOpenLog;
|
||||
public event Action ClickedOpenLog;
|
||||
|
||||
public ContextMenuStrip Create()
|
||||
{
|
||||
|
|
|
@ -41,9 +41,9 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
}
|
||||
|
||||
public event EventHandlerEmpty Click;
|
||||
public event Action Click;
|
||||
|
||||
public event EventHandlerEmpty OpenLog;
|
||||
public event Action OpenLog;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
@ -204,6 +204,11 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
MouseDown -= CustomScrollbar_MouseDown;
|
||||
MouseMove -= CustomScrollbar_MouseMove;
|
||||
MouseUp -= CustomScrollbar_MouseUp;
|
||||
MouseLeave -= CustomScrollbar_MouseLeave;
|
||||
timerMouseStillClicked.Tick -= TimerMouseStillClicked_Tick;
|
||||
timerMouseStillClicked.Dispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@ namespace SystemTrayMenu.UserInterface.FolderBrowseDialog
|
|||
{
|
||||
private bool isDisposed;
|
||||
|
||||
~FolderDialog() // the finalizer
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets /sets folder in which dialog will be open.
|
||||
/// </summary>
|
||||
|
|
41
UserInterface/Menu.Designer.cs
generated
41
UserInterface/Menu.Designer.cs
generated
|
@ -1,4 +1,7 @@
|
|||
namespace SystemTrayMenu.UserInterface
|
||||
using System.Windows.Forms;
|
||||
using SystemTrayMenu.Helper;
|
||||
|
||||
namespace SystemTrayMenu.UserInterface
|
||||
{
|
||||
partial class Menu
|
||||
{
|
||||
|
@ -19,9 +22,45 @@
|
|||
}
|
||||
|
||||
timerUpdateIcons.Stop();
|
||||
timerUpdateIcons.Tick -= TimerUpdateIcons_Tick;
|
||||
timerUpdateIcons.Tick += TimerUpdateIcons_Tick_Loading;
|
||||
timerUpdateIcons.Dispose();
|
||||
fading.ChangeOpacity -= Fading_ChangeOpacity;
|
||||
fading.Show -= Fading_Show;
|
||||
fading.Hide -= Hide;
|
||||
fading.Dispose();
|
||||
dgv.GotFocus -= Dgv_GotFocus;
|
||||
dgv.MouseEnter -= ControlsMouseEnter;
|
||||
dgv.MouseLeave -= ControlsMouseLeave;
|
||||
customScrollbar.GotFocus -= CustomScrollbar_GotFocus;
|
||||
customScrollbar.Scroll -= CustomScrollbar_Scroll;
|
||||
customScrollbar.MouseEnter -= ControlsMouseEnter;
|
||||
customScrollbar.MouseLeave -= ControlsMouseLeave;
|
||||
customScrollbar.Dispose();
|
||||
labelTitle.MouseEnter -= ControlsMouseEnter;
|
||||
labelTitle.MouseLeave -= ControlsMouseLeave;
|
||||
textBoxSearch.MouseEnter -= ControlsMouseEnter;
|
||||
textBoxSearch.MouseLeave -= ControlsMouseLeave;
|
||||
pictureBoxOpenFolder.MouseEnter -= ControlsMouseEnter;
|
||||
pictureBoxOpenFolder.MouseLeave -= ControlsMouseLeave;
|
||||
pictureBoxMenuAlwaysOpen.MouseEnter -= ControlsMouseEnter;
|
||||
pictureBoxMenuAlwaysOpen.MouseLeave -= ControlsMouseLeave;
|
||||
pictureBoxMenuAlwaysOpen.Paint -= PictureBoxMenuAlwaysOpen_Paint;
|
||||
pictureBoxMenuAlwaysOpen.Paint -= LoadingMenu_Paint;
|
||||
pictureBoxSettings.MouseEnter -= ControlsMouseEnter;
|
||||
pictureBoxSettings.MouseLeave -= ControlsMouseLeave;
|
||||
pictureBoxRestart.MouseEnter -= ControlsMouseEnter;
|
||||
pictureBoxRestart.MouseLeave -= ControlsMouseLeave;
|
||||
pictureBoxSearch.MouseEnter -= ControlsMouseEnter;
|
||||
pictureBoxSearch.MouseLeave -= ControlsMouseLeave;
|
||||
tableLayoutPanelMenu.MouseEnter -= ControlsMouseEnter;
|
||||
tableLayoutPanelMenu.MouseLeave -= ControlsMouseLeave;
|
||||
tableLayoutPanelDgvAndScrollbar.MouseEnter -= ControlsMouseEnter;
|
||||
tableLayoutPanelDgvAndScrollbar.MouseLeave -= ControlsMouseLeave;
|
||||
tableLayoutPanelBottom.MouseEnter -= ControlsMouseEnter;
|
||||
tableLayoutPanelBottom.MouseLeave -= ControlsMouseLeave;
|
||||
labelItems.MouseEnter -= ControlsMouseEnter;
|
||||
labelItems.MouseLeave -= ControlsMouseLeave;
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,144 +32,41 @@ namespace SystemTrayMenu.UserInterface
|
|||
internal Menu()
|
||||
{
|
||||
fading.ChangeOpacity += Fading_ChangeOpacity;
|
||||
void Fading_ChangeOpacity(object sender, double newOpacity)
|
||||
{
|
||||
if (newOpacity != Opacity && !IsDisposed && !Disposing)
|
||||
{
|
||||
Opacity = newOpacity;
|
||||
}
|
||||
}
|
||||
|
||||
fading.Show += Fading_Show;
|
||||
void Fading_Show()
|
||||
{
|
||||
try
|
||||
{
|
||||
isShowing = true;
|
||||
Visible = true;
|
||||
isShowing = false;
|
||||
timerUpdateIcons.Start();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
Visible = false;
|
||||
isShowing = false;
|
||||
Log.Info($"Could not open menu, old menu was disposing," +
|
||||
$" IsDisposed={IsDisposed}");
|
||||
}
|
||||
|
||||
if (Visible)
|
||||
{
|
||||
if (Level == 0)
|
||||
{
|
||||
Activate();
|
||||
NativeMethods.User32ShowInactiveTopmost(this);
|
||||
NativeMethods.ForceForegroundWindow(Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeMethods.User32ShowInactiveTopmost(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fading.Hide += Hide;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
SetDoubleBuffer(dgv, true);
|
||||
|
||||
Color foreColor = Color.Black;
|
||||
Color backColor = AppColors.Background;
|
||||
Color backColorSearch = AppColors.SearchField;
|
||||
Color backgroundBorder = AppColors.BackgroundBorder;
|
||||
|
||||
if (Config.IsDarkMode())
|
||||
{
|
||||
foreColor = Color.White;
|
||||
labelTitle.ForeColor = foreColor;
|
||||
textBoxSearch.ForeColor = foreColor;
|
||||
backColor = AppColors.DarkModeBackground;
|
||||
backColorSearch = AppColors.DarkModeSearchField;
|
||||
backgroundBorder = AppColors.DarkModeBackgroundBorder;
|
||||
}
|
||||
|
||||
ColorConverter colorConverter = new();
|
||||
labelItems.ForeColor = MenuDefines.ColorIcons;
|
||||
|
||||
if (backColor.R == 0)
|
||||
{
|
||||
backColor = Color.White;
|
||||
}
|
||||
|
||||
BackColor = backgroundBorder;
|
||||
labelTitle.BackColor = backColor;
|
||||
tableLayoutPanelDgvAndScrollbar.BackColor = backColor;
|
||||
tableLayoutPanelBottom.BackColor = backColor;
|
||||
tableLayoutPanelMenu.BackColor = backColor;
|
||||
dgv.BackgroundColor = backColor;
|
||||
textBoxSearch.BackColor = backColorSearch;
|
||||
panelLine.BackColor = AppColors.Icons;
|
||||
pictureBoxSearch.BackColor = backColorSearch;
|
||||
tableLayoutPanelSearch.BackColor = backColorSearch;
|
||||
dgv.DefaultCellStyle = new DataGridViewCellStyle
|
||||
{
|
||||
SelectionForeColor = foreColor,
|
||||
ForeColor = foreColor,
|
||||
BackColor = backColor,
|
||||
};
|
||||
|
||||
dgv.GotFocus += (sender, e) => FocusTextBox();
|
||||
customScrollbar.GotFocus += (sender, e) => FocusTextBox();
|
||||
|
||||
customScrollbar.Margin = new Padding(0);
|
||||
customScrollbar.Scroll += CustomScrollbar_Scroll;
|
||||
void CustomScrollbar_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
decimal firstIndex = customScrollbar.Value * dgv.Rows.Count / (decimal)customScrollbar.Maximum;
|
||||
int firstIndexRounded = (int)Math.Ceiling(firstIndex);
|
||||
if (firstIndexRounded > -1 && firstIndexRounded < dgv.RowCount)
|
||||
{
|
||||
dgv.FirstDisplayedScrollingRowIndex = firstIndexRounded;
|
||||
}
|
||||
}
|
||||
|
||||
customScrollbar.MouseEnter += ControlsMouseEnter;
|
||||
AdjustColors();
|
||||
dgv.GotFocus += Dgv_GotFocus;
|
||||
dgv.MouseEnter += ControlsMouseEnter;
|
||||
labelTitle.MouseEnter += ControlsMouseEnter;
|
||||
textBoxSearch.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxOpenFolder.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxMenuAlwaysOpen.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxSettings.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxRestart.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxSearch.MouseEnter += ControlsMouseEnter;
|
||||
tableLayoutPanelMenu.MouseEnter += ControlsMouseEnter;
|
||||
tableLayoutPanelDgvAndScrollbar.MouseEnter += ControlsMouseEnter;
|
||||
tableLayoutPanelBottom.MouseEnter += ControlsMouseEnter;
|
||||
labelItems.MouseEnter += ControlsMouseEnter;
|
||||
void ControlsMouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
MouseEnter?.Invoke();
|
||||
}
|
||||
|
||||
customScrollbar.MouseLeave += ControlsMouseLeave;
|
||||
dgv.MouseLeave += ControlsMouseLeave;
|
||||
customScrollbar.Margin = new Padding(0);
|
||||
customScrollbar.GotFocus += CustomScrollbar_GotFocus;
|
||||
customScrollbar.Scroll += CustomScrollbar_Scroll;
|
||||
customScrollbar.MouseEnter += ControlsMouseEnter;
|
||||
customScrollbar.MouseLeave += ControlsMouseLeave;
|
||||
labelTitle.MouseEnter += ControlsMouseEnter;
|
||||
labelTitle.MouseLeave += ControlsMouseLeave;
|
||||
textBoxSearch.MouseEnter += ControlsMouseEnter;
|
||||
textBoxSearch.MouseLeave += ControlsMouseLeave;
|
||||
pictureBoxMenuAlwaysOpen.MouseLeave += ControlsMouseLeave;
|
||||
pictureBoxOpenFolder.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxOpenFolder.MouseLeave += ControlsMouseLeave;
|
||||
pictureBoxMenuAlwaysOpen.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxMenuAlwaysOpen.MouseLeave += ControlsMouseLeave;
|
||||
pictureBoxSettings.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxSettings.MouseLeave += ControlsMouseLeave;
|
||||
pictureBoxRestart.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxRestart.MouseLeave += ControlsMouseLeave;
|
||||
pictureBoxSearch.MouseEnter += ControlsMouseEnter;
|
||||
pictureBoxSearch.MouseLeave += ControlsMouseLeave;
|
||||
tableLayoutPanelMenu.MouseEnter += ControlsMouseEnter;
|
||||
tableLayoutPanelMenu.MouseLeave += ControlsMouseLeave;
|
||||
tableLayoutPanelDgvAndScrollbar.MouseEnter += ControlsMouseEnter;
|
||||
tableLayoutPanelDgvAndScrollbar.MouseLeave += ControlsMouseLeave;
|
||||
tableLayoutPanelBottom.MouseEnter += ControlsMouseEnter;
|
||||
tableLayoutPanelBottom.MouseLeave += ControlsMouseLeave;
|
||||
labelItems.MouseEnter += ControlsMouseEnter;
|
||||
labelItems.MouseLeave += ControlsMouseLeave;
|
||||
void ControlsMouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
MouseLeave?.Invoke();
|
||||
}
|
||||
|
||||
bool isTouchEnabled = NativeMethods.IsTouchEnabled();
|
||||
if ((isTouchEnabled && Properties.Settings.Default.DragDropItemsEnabledTouch) ||
|
||||
(!isTouchEnabled && Properties.Settings.Default.DragDropItemsEnabled))
|
||||
|
@ -180,23 +77,23 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
}
|
||||
|
||||
internal new event EventHandlerEmpty MouseWheel;
|
||||
internal new event Action MouseWheel;
|
||||
|
||||
internal new event EventHandlerEmpty MouseEnter;
|
||||
internal new event Action MouseEnter;
|
||||
|
||||
internal new event EventHandlerEmpty MouseLeave;
|
||||
internal new event Action MouseLeave;
|
||||
|
||||
internal event EventHandlerEmpty UserClickedOpenFolder;
|
||||
internal event Action<string> UserClickedOpenFolder;
|
||||
|
||||
internal event EventHandler<Keys> CmdKeyProcessed;
|
||||
|
||||
internal event EventHandler<KeyPressEventArgs> KeyPressCheck;
|
||||
|
||||
internal event EventHandlerEmpty SearchTextChanging;
|
||||
internal event Action SearchTextChanging;
|
||||
|
||||
internal event EventHandler<bool> SearchTextChanged;
|
||||
|
||||
internal event EventHandlerEmpty UserDragsMenu;
|
||||
internal event Action UserDragsMenu;
|
||||
|
||||
internal enum MenuType
|
||||
{
|
||||
|
@ -218,6 +115,8 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
internal int Level { get; set; }
|
||||
|
||||
internal string Path { get; set; }
|
||||
|
||||
internal bool IsUsable => Visible && !fading.IsHiding && !IsDisposed && !Disposing;
|
||||
|
||||
internal bool ScrollbarVisible { get; private set; }
|
||||
|
@ -324,7 +223,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
pictureBoxMenuAlwaysOpen.Paint -= PictureBoxMenuAlwaysOpen_Paint;
|
||||
pictureBoxMenuAlwaysOpen.Paint += LoadingMenu_Paint;
|
||||
timerUpdateIcons.Tick -= TimerUpdateIcons_Tick;
|
||||
timerUpdateIcons.Tick += (sender, e) => pictureBoxMenuAlwaysOpen.Invalidate();
|
||||
timerUpdateIcons.Tick += TimerUpdateIcons_Tick_Loading;
|
||||
timerUpdateIcons.Interval = 15;
|
||||
break;
|
||||
default:
|
||||
|
@ -718,6 +617,117 @@ namespace SystemTrayMenu.UserInterface
|
|||
CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private void Fading_ChangeOpacity(double newOpacity)
|
||||
{
|
||||
if (newOpacity != Opacity && !IsDisposed && !Disposing)
|
||||
{
|
||||
Opacity = newOpacity;
|
||||
}
|
||||
}
|
||||
|
||||
private void Fading_Show()
|
||||
{
|
||||
try
|
||||
{
|
||||
isShowing = true;
|
||||
Visible = true;
|
||||
isShowing = false;
|
||||
timerUpdateIcons.Start();
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
Visible = false;
|
||||
isShowing = false;
|
||||
Log.Info($"Could not open menu, old menu was disposing," +
|
||||
$" IsDisposed={IsDisposed}");
|
||||
}
|
||||
|
||||
if (Visible)
|
||||
{
|
||||
if (Level == 0)
|
||||
{
|
||||
Activate();
|
||||
NativeMethods.User32ShowInactiveTopmost(this);
|
||||
NativeMethods.ForceForegroundWindow(Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeMethods.User32ShowInactiveTopmost(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustColors()
|
||||
{
|
||||
Color foreColor = Color.Black;
|
||||
Color backColor = AppColors.Background;
|
||||
Color backColorSearch = AppColors.SearchField;
|
||||
Color backgroundBorder = AppColors.BackgroundBorder;
|
||||
if (Config.IsDarkMode())
|
||||
{
|
||||
foreColor = Color.White;
|
||||
labelTitle.ForeColor = foreColor;
|
||||
textBoxSearch.ForeColor = foreColor;
|
||||
backColor = AppColors.DarkModeBackground;
|
||||
backColorSearch = AppColors.DarkModeSearchField;
|
||||
backgroundBorder = AppColors.DarkModeBackgroundBorder;
|
||||
}
|
||||
|
||||
ColorConverter colorConverter = new();
|
||||
labelItems.ForeColor = MenuDefines.ColorIcons;
|
||||
if (backColor.R == 0)
|
||||
{
|
||||
backColor = Color.White;
|
||||
}
|
||||
|
||||
BackColor = backgroundBorder;
|
||||
labelTitle.BackColor = backColor;
|
||||
tableLayoutPanelDgvAndScrollbar.BackColor = backColor;
|
||||
tableLayoutPanelBottom.BackColor = backColor;
|
||||
tableLayoutPanelMenu.BackColor = backColor;
|
||||
dgv.BackgroundColor = backColor;
|
||||
textBoxSearch.BackColor = backColorSearch;
|
||||
panelLine.BackColor = AppColors.Icons;
|
||||
pictureBoxSearch.BackColor = backColorSearch;
|
||||
tableLayoutPanelSearch.BackColor = backColorSearch;
|
||||
dgv.DefaultCellStyle = new DataGridViewCellStyle
|
||||
{
|
||||
SelectionForeColor = foreColor,
|
||||
ForeColor = foreColor,
|
||||
BackColor = backColor,
|
||||
};
|
||||
}
|
||||
|
||||
private void Dgv_GotFocus(object sender, EventArgs e)
|
||||
{
|
||||
FocusTextBox();
|
||||
}
|
||||
|
||||
private void CustomScrollbar_GotFocus(object sender, EventArgs e)
|
||||
{
|
||||
FocusTextBox();
|
||||
}
|
||||
|
||||
private void CustomScrollbar_Scroll(object sender, EventArgs e)
|
||||
{
|
||||
decimal firstIndex = customScrollbar.Value * dgv.Rows.Count / (decimal)customScrollbar.Maximum;
|
||||
int firstIndexRounded = (int)Math.Ceiling(firstIndex);
|
||||
if (firstIndexRounded > -1 && firstIndexRounded < dgv.RowCount)
|
||||
{
|
||||
dgv.FirstDisplayedScrollingRowIndex = firstIndexRounded;
|
||||
}
|
||||
}
|
||||
|
||||
private void ControlsMouseEnter(object sender, EventArgs e)
|
||||
{
|
||||
MouseEnter?.Invoke();
|
||||
}
|
||||
|
||||
private void ControlsMouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
MouseLeave?.Invoke();
|
||||
}
|
||||
|
||||
private void AdjustDataGridViewHeight(Menu menuPredecessor, int screenHeightMax)
|
||||
{
|
||||
double factor = Properties.Settings.Default.RowHeighteInPercentage / 100f;
|
||||
|
@ -753,12 +763,12 @@ namespace SystemTrayMenu.UserInterface
|
|||
row.Height = dgv.RowTemplate.Height;
|
||||
}
|
||||
|
||||
int dgvHeightByItems = dgv.Rows.GetRowsHeight(DataGridViewElementStates.None);
|
||||
int dgvHeightByItems = Math.Max(dgv.Rows.GetRowsHeight(DataGridViewElementStates.None), 1);
|
||||
int dgvHeightMaxByScreen = screenHeightMax - (Height - dgv.Height);
|
||||
int dgvHeightMaxByOptions = (int)(Scaling.Factor * Scaling.FactorByDpi *
|
||||
450f * (Properties.Settings.Default.HeightMaxInPercent / 100f));
|
||||
int dgvHeightMax = Math.Min(dgvHeightMaxByScreen, dgvHeightMaxByOptions);
|
||||
if (!dgvHeightSet && dgvHeightByItems > 0 && dgvHeightMax > 0)
|
||||
if (!dgvHeightSet)
|
||||
{
|
||||
dgv.Height = Math.Min(dgvHeightByItems, dgvHeightMax);
|
||||
dgvHeightSet = true;
|
||||
|
@ -1035,7 +1045,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
UserClickedOpenFolder?.Invoke();
|
||||
UserClickedOpenFolder?.Invoke(Path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1145,6 +1155,11 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
}
|
||||
|
||||
private void TimerUpdateIcons_Tick_Loading(object sender, EventArgs e)
|
||||
{
|
||||
pictureBoxMenuAlwaysOpen.Invalidate();
|
||||
}
|
||||
|
||||
private void Menu_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (Level == 0)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace SystemTrayMenu.Utilities
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
@ -11,7 +12,7 @@ namespace SystemTrayMenu.Utilities
|
|||
|
||||
internal class AppRestart
|
||||
{
|
||||
public static event EventHandlerEmpty BeforeRestarting;
|
||||
public static event Action BeforeRestarting;
|
||||
|
||||
internal static void ByThreadException()
|
||||
{
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
// <copyright file="EventHandlerEmpty.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace SystemTrayMenu.Utilities
|
||||
{
|
||||
public delegate void EventHandlerEmpty();
|
||||
}
|
Loading…
Reference in a new issue