Reorganize main objects

Notify icon moved into Menus class (multiple instances would get multiple icons)
Taskbar logo moved into Menus class (multiple instances would get multiple icons)
joystickHelper moved into App class (Only one watcher for gamepad inputs even when multiple Menus exist)
Simplified event calling of these classes
This commit is contained in:
Peter Kirmeier 2023-05-18 21:25:03 +02:00
parent a1055ce31f
commit 13b2338b11
2 changed files with 63 additions and 59 deletions

View file

@ -8,9 +8,9 @@ namespace SystemTrayMenu
using System.Windows;
using System.Windows.Threading;
using SystemTrayMenu.Business;
using SystemTrayMenu.Helpers;
using SystemTrayMenu.Helpers.Updater;
using SystemTrayMenu.Properties;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
/// <summary>
@ -18,32 +18,24 @@ namespace SystemTrayMenu
/// </summary>
public partial class App : Application, IDisposable
{
private static TaskbarLogo? taskbarLogo;
private readonly AppNotifyIcon menuNotifyIcon = new();
private readonly Menus menus = new();
private JoystickHelper? joystickHelper;
private bool isDisposed;
public App()
{
AppRestart.BeforeRestarting += Dispose;
menus.LoadStarted += menuNotifyIcon.LoadingStart;
menus.LoadStopped += menuNotifyIcon.LoadingStop;
menuNotifyIcon.Click += () => menus.SwitchOpenClose(true, false);
Activated += (_, _) => IsActiveApp = true;
Deactivated += (_, _) => IsActiveApp = false;
Startup += (_, _) =>
{
if (Settings.Default.ShowInTaskbar)
menus.Startup();
if (Settings.Default.SupportGamepad)
{
taskbarLogo = new();
taskbarLogo.Activated += (_, _) => menus.SwitchOpenCloseByTaskbarItem();
taskbarLogo.Show();
}
else
{
menus.SwitchOpenClose(false, true);
joystickHelper = new();
joystickHelper.KeyPressed += menus.KeyPressed;
}
if (Settings.Default.CheckForUpdates)
@ -67,11 +59,13 @@ namespace SystemTrayMenu
{
if (!isDisposed)
{
taskbarLogo?.Close();
taskbarLogo = null;
if (joystickHelper != null)
{
joystickHelper.KeyPressed -= menus.KeyPressed;
joystickHelper.Dispose();
}
menus.Dispose();
menuNotifyIcon.Dispose();
isDisposed = true;
}

View file

@ -12,6 +12,7 @@ namespace SystemTrayMenu.Business
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Microsoft.Win32;
using SystemTrayMenu.DataClasses;
@ -19,17 +20,18 @@ namespace SystemTrayMenu.Business
using SystemTrayMenu.Handler;
using SystemTrayMenu.Helpers;
using SystemTrayMenu.Properties;
using SystemTrayMenu.UserInterface;
using SystemTrayMenu.Utilities;
using static SystemTrayMenu.UserInterface.Menu;
using Menu = SystemTrayMenu.UserInterface.Menu;
internal class Menus : IDisposable
{
private readonly AppNotifyIcon menuNotifyIcon = new();
private readonly BackgroundWorker workerMainMenu = new();
private readonly List<BackgroundWorker> workersSubMenu = new();
private readonly WaitToLoadMenu waitToOpenMenu = new();
private readonly KeyboardInput keyboardInput;
private readonly JoystickHelper? joystickHelper;
private readonly KeyboardInput keyboardInput = new();
private readonly List<FileSystemWatcher> watchers = new();
private readonly List<EventArgs> watcherHistory = new();
private readonly DispatcherTimer timerShowProcessStartedAsLoadingIcon = new();
@ -37,11 +39,13 @@ namespace SystemTrayMenu.Business
private readonly DispatcherTimer waitLeave = new();
private TaskbarPosition taskbarPosition = TaskbarPosition.Unknown;
private bool showMenuAfterMainPreload;
private TaskbarLogo? taskbarLogo;
private Menu? mainMenu;
public Menus()
{
keyboardInput = new();
menuNotifyIcon.Click += () => SwitchOpenClose(true, false);
if (!keyboardInput.RegisterHotKey(Settings.Default.HotKey))
{
Settings.Default.HotKey = string.Empty;
@ -65,35 +69,11 @@ namespace SystemTrayMenu.Business
workerSubMenu.CancelAsync();
}
LoadStopped?.Invoke();
menuNotifyIcon.LoadingStop();
}
waitToOpenMenu.MouseSelect += keyboardInput.SelectByMouse;
if (Settings.Default.SupportGamepad)
{
joystickHelper = new();
joystickHelper.KeyPressed += (key, modifiers) =>
{
if (mainMenu != null && mainMenu.Visibility == Visibility.Visible)
{
Menu? menu = mainMenu;
do
{
if (menu.IsActive || menu.IsKeyboardFocusWithin)
{
// Send the keys to the active menu
menu.Dispatcher.Invoke(keyboardInput.CmdKeyProcessed, new object[] { menu, key, modifiers });
return;
}
menu = menu.SubMenu;
}
while (menu != null);
}
};
}
// Timer to check after activation if the application lost focus and close/fadeout windows again
timerStillActiveCheck.Interval = TimeSpan.FromMilliseconds(Settings.Default.TimeUntilClosesAfterEnterPressed + 20);
timerStillActiveCheck.Tick += (sender, e) => StillActiveTick();
@ -146,10 +126,6 @@ namespace SystemTrayMenu.Business
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}
internal event Action? LoadStarted;
internal event Action? LoadStopped;
public void Dispose()
{
SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
@ -170,21 +146,34 @@ namespace SystemTrayMenu.Business
waitToOpenMenu.Dispose();
keyboardInput.Dispose();
joystickHelper?.Dispose();
timerShowProcessStartedAsLoadingIcon.Stop();
timerStillActiveCheck.Stop();
waitLeave.Stop();
mainMenu?.Close();
taskbarLogo?.Close();
menuNotifyIcon.Dispose();
}
internal static void OpenFolder(string path) => Log.ProcessStart(path);
internal void SwitchOpenCloseByTaskbarItem()
internal void Startup()
{
// User started with taskbar or clicked on taskbar: remember to open menu after preload has finished
showMenuAfterMainPreload = true;
SwitchOpenClose(true, true);
timerStillActiveCheck.Start();
if (Settings.Default.ShowInTaskbar)
{
taskbarLogo = new();
taskbarLogo.Activated += (_, _) =>
{
// User started with taskbar or clicked on taskbar: remember to open menu after preload has finished
showMenuAfterMainPreload = true;
SwitchOpenClose(true, true);
};
taskbarLogo.Show();
}
else
{
SwitchOpenClose(false, true);
}
}
internal void SwitchOpenClose(bool byClick, bool allowPreloading)
@ -203,7 +192,7 @@ namespace SystemTrayMenu.Business
{
// Stop current loading process of main menu
workerMainMenu.CancelAsync();
LoadStopped?.Invoke();
menuNotifyIcon.LoadingStop();
}
else if (mainMenu != null && mainMenu.Visibility == Visibility.Visible)
{
@ -218,11 +207,32 @@ namespace SystemTrayMenu.Business
GenerateDriveShortcuts.Start(); // TODO: Once or actually on every startup?
}
LoadStarted?.Invoke();
menuNotifyIcon.LoadingStart();
workerMainMenu.RunWorkerAsync(null);
}
}
internal void KeyPressed(Key key, ModifierKeys modifiers)
{
// Look for a valid menu that is visible, active and has focus
if (mainMenu != null && mainMenu.Visibility == Visibility.Visible)
{
Menu? menu = mainMenu;
do
{
if (menu.IsActive || menu.IsKeyboardFocusWithin)
{
// Send the keys to the active menu
menu.Dispatcher.Invoke(keyboardInput.CmdKeyProcessed, new object[] { menu, key, modifiers });
return;
}
menu = menu.SubMenu;
}
while (menu != null);
}
}
private static Menu? IsMouseOverAnyMenu(Menu? menu)
{
while (menu != null)
@ -259,7 +269,7 @@ namespace SystemTrayMenu.Business
private void LoadMainMenuCompleted(object? sender, RunWorkerCompletedEventArgs e)
{
keyboardInput.ResetSelectedByKey();
LoadStopped?.Invoke();
menuNotifyIcon.LoadingStop();
if (e.Result == null)
{