//
// Copyright (c) PlaceholderCompany. All rights reserved.
//
namespace SystemTrayMenu.Business
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security;
using System.Windows.Forms;
using SystemTrayMenu.DataClasses;
using SystemTrayMenu.Handler;
using SystemTrayMenu.Helper;
using SystemTrayMenu.Utilities;
using Menu = SystemTrayMenu.UserInterface.Menu;
using Timer = System.Windows.Forms.Timer;
internal class Menus : IDisposable
{
private readonly Menu[] menus = new Menu[MenuDefines.MenusMax];
private readonly BackgroundWorker workerMainMenu = new BackgroundWorker();
private readonly List workersSubMenu = new List();
private readonly DgvMouseRow dgvMouseRow = new DgvMouseRow();
private readonly WaitToLoadMenu waitToOpenMenu = new WaitToLoadMenu();
private readonly KeyboardInput keyboardInput;
private readonly Timer timerStillActiveCheck = new Timer();
private readonly WaitLeave waitLeave = new WaitLeave(MenuDefines.TimeUntilClose);
private DateTime deactivatedTime = DateTime.MinValue;
private OpenCloseState openCloseState = OpenCloseState.Default;
private RowData loadingRowData;
private bool showingMessageBox;
private TaskbarPosition taskbarPosition = new WindowsTaskbar().Position;
private bool searchTextChanging;
public Menus()
{
workerMainMenu.WorkerSupportsCancellation = true;
workerMainMenu.DoWork += LoadMenu;
static void LoadMenu(object senderDoWork, DoWorkEventArgs eDoWork)
{
string path = Config.Path;
int level = 0;
RowData rowData = eDoWork.Argument as RowData;
if (rowData != null)
{
path = rowData.TargetFilePath;
level = rowData.MenuLevel + 1;
}
MenuData menuData = GetData((BackgroundWorker)senderDoWork, path, level);
menuData.RowDataParent = rowData;
eDoWork.Result = menuData;
}
workerMainMenu.RunWorkerCompleted += LoadMainMenuCompleted;
void LoadMainMenuCompleted(object sender, RunWorkerCompletedEventArgs e)
{
keyboardInput.ResetSelectedByKey();
LoadStopped();
MenuData menuData = (MenuData)e.Result;
switch (menuData.Validity)
{
case MenuDataValidity.Valid:
DisposeMenu(menus[menuData.Level]);
menus[0] = Create(menuData, Path.GetFileName(Config.Path));
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
break;
case MenuDataValidity.Empty:
if (!showingMessageBox)
{
showingMessageBox = true;
MessageBox.Show(Translator.GetText(
"MessageRootFolderEmpty"));
OpenFolder();
showingMessageBox = false;
}
break;
case MenuDataValidity.NoAccess:
if (!showingMessageBox)
{
showingMessageBox = true;
MessageBox.Show(Translator.GetText(
"MessageRootFolderNoAccess"));
OpenFolder();
showingMessageBox = false;
}
break;
case MenuDataValidity.AbortedOrUnknown:
Log.Info("MenuDataValidity.AbortedOrUnknown");
break;
default:
break;
}
}
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 &&
loadingRowData != rowData &&
(menus[rowData.MenuLevel + 1] == null ||
menus[rowData.MenuLevel + 1].Tag as RowData != rowData))
{
loadingRowData = rowData;
LoadStarted();
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)
{
LoadStopped();
MenuData menuData = (MenuData)e.Result;
if (menus[0].IsUsable &&
menuData.Validity != MenuDataValidity.AbortedOrUnknown)
{
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);
}
}
loadingRowData = null;
}
}
waitToOpenMenu.CloseMenu += CloseMenu;
void CloseMenu(int level)
{
if (menus[level] != null)
{
menus[level - 1].FocusTextBox();
HideOldMenu(menus[level]);
}
}
waitToOpenMenu.MouseEnterOk += MouseEnterOk;
void MouseEnterOk(DataGridView dgv, int rowIndex)
{
if (menus[0].IsUsable)
{
if (keyboardInput.InUse)
{
keyboardInput.ClearIsSelectedByKey();
keyboardInput.InUse = false;
}
keyboardInput.Select(dgv, rowIndex, false);
}
}
dgvMouseRow.RowMouseEnter += waitToOpenMenu.MouseEnter;
dgvMouseRow.RowMouseLeave += waitToOpenMenu.MouseLeave;
keyboardInput = new KeyboardInput(menus);
keyboardInput.RegisterHotKey();
keyboardInput.HotKeyPressed += KeyboardInput_HotKeyPressed;
void KeyboardInput_HotKeyPressed()
{
SwitchOpenClose(false);
}
keyboardInput.ClosePressed += MenusFadeOut;
keyboardInput.RowDeselected += waitToOpenMenu.RowDeselected;
keyboardInput.RowSelected += waitToOpenMenu.RowSelected;
keyboardInput.EnterPressed += waitToOpenMenu.EnterOpensInstantly;
timerStillActiveCheck.Interval = 1000;
timerStillActiveCheck.Tick += StillActiveTick;
void StillActiveTick(object senderTimer, EventArgs eTimer)
{
if (!IsActive())
{
FadeHalfOrOutIfNeeded();
timerStillActiveCheck.Stop();
}
}
waitLeave.LeaveTriggered += LeaveTriggered;
void LeaveTriggered()
{
FadeHalfOrOutIfNeeded();
}
}
internal event EventHandlerEmpty LoadStarted;
internal event EventHandlerEmpty LoadStopped;
private enum OpenCloseState
{
Default,
Opening,
Closing,
}
private IEnumerable