mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-05-19 20:03:25 +12:00
parent
b887c25bb3
commit
b13eb62f52
|
@ -8,7 +8,6 @@ using System.Linq;
|
|||
using System.Security;
|
||||
using System.Windows.Forms;
|
||||
using SystemTrayMenu.DataClasses;
|
||||
using SystemTrayMenu.DllImports;
|
||||
using SystemTrayMenu.Handler;
|
||||
using SystemTrayMenu.Helper;
|
||||
using SystemTrayMenu.UserInterface;
|
||||
|
@ -27,7 +26,8 @@ namespace SystemTrayMenu
|
|||
private readonly Screen screen = Screen.PrimaryScreen;
|
||||
private readonly WaitLeave waitLeave = new WaitLeave(MenuDefines.TimeUntilClose);
|
||||
private readonly KeyboardInput keyboardInput;
|
||||
private int clicksInQueue = 0;
|
||||
private readonly Timer timerStillActiveCheck = new Timer();
|
||||
private DateTime deactivatedTime = DateTime.Now;
|
||||
|
||||
public SystemTrayMenu()
|
||||
{
|
||||
|
@ -53,9 +53,10 @@ namespace SystemTrayMenu
|
|||
menuNotifyIcon.HandleClick += SwitchOpenClose;
|
||||
void SwitchOpenClose()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Config.Path))
|
||||
if (string.IsNullOrEmpty(Config.Path) ||
|
||||
(DateTime.Now - deactivatedTime).TotalMilliseconds < 300)
|
||||
{
|
||||
//Case when Folder Dialog open
|
||||
//Case when Folder Dialog open or restarts to fast
|
||||
}
|
||||
else if (openCloseState == OpenCloseState.Opening ||
|
||||
menus[0].Visible && openCloseState == OpenCloseState.Default)
|
||||
|
@ -71,27 +72,10 @@ namespace SystemTrayMenu
|
|||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
}
|
||||
else if (worker.IsBusy)
|
||||
{
|
||||
if (clicksInQueue < MenuDefines.MaxClicksInQueue)
|
||||
{
|
||||
clicksInQueue++;
|
||||
while (worker.IsBusy)
|
||||
{
|
||||
Application.DoEvents();
|
||||
}
|
||||
clicksInQueue--;
|
||||
SwitchOpenClose();
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Info("User is clicking too often => throw event away");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
openCloseState = OpenCloseState.Opening;
|
||||
menuNotifyIcon.LoadingStart();
|
||||
menuNotifyIcon.LoadingStart(true);
|
||||
worker.RunWorkerAsync();
|
||||
}
|
||||
}
|
||||
|
@ -114,15 +98,8 @@ namespace SystemTrayMenu
|
|||
DisposeMenu(menus[0]);
|
||||
menus[0] = CreateMenu(menuData, Path.GetFileName(Config.Path));
|
||||
menus[0].AdjustLocationAndSize(screen);
|
||||
menus[0].Visible = false; // resets activated
|
||||
menus[0].Visible = true; // resets activated
|
||||
Menus().ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
menus[0].Activate();
|
||||
menus[0].SetTitleColorActive();
|
||||
NativeMethods.ForceForegroundWindow(menus[0].Handle);
|
||||
}
|
||||
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
|
||||
menuNotifyIcon.OpenLog += Log.OpenLogFile;
|
||||
|
@ -147,6 +124,7 @@ namespace SystemTrayMenu
|
|||
keyboardInput.Dispose();
|
||||
menuNotifyIcon.Dispose();
|
||||
waitLeave.Dispose();
|
||||
timerStillActiveCheck.Dispose();
|
||||
DisposeMenu(menus[0]);
|
||||
IconReader.Dispose();
|
||||
}
|
||||
|
@ -422,20 +400,36 @@ namespace SystemTrayMenu
|
|||
menu.Deactivate += Deactivate;
|
||||
void Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
if (!(Form.ActiveForm is Menu))
|
||||
if (!FadeHalfOrOutIfNeeded())
|
||||
{
|
||||
FadeHalfOrOutIfNeeded();
|
||||
menus[0].SetTitleColorDeactive();
|
||||
deactivatedTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
menu.Activated += Activated;
|
||||
void Activated(object sender, EventArgs e)
|
||||
{
|
||||
if (Form.ActiveForm is Menu)
|
||||
if (Form.ActiveForm is Menu &&
|
||||
menus[0].IsUsable)
|
||||
{
|
||||
FadeInIfNeeded();
|
||||
menus[0].SetTitleColorActive();
|
||||
Menus().ToList().ForEach(m => m.ShowWithFade());
|
||||
}
|
||||
|
||||
CheckIfWindowsStartStoleFocusNoDeactivateInRareCase();
|
||||
void CheckIfWindowsStartStoleFocusNoDeactivateInRareCase()
|
||||
{
|
||||
timerStillActiveCheck.Interval = 1000;
|
||||
timerStillActiveCheck.Tick += StillActiveTick;
|
||||
void StillActiveTick(object senderTimer, EventArgs eTimer)
|
||||
{
|
||||
if (!waitLeave.IsRunning &&
|
||||
!FadeHalfOrOutIfNeeded())
|
||||
{
|
||||
timerStillActiveCheck.Stop();
|
||||
}
|
||||
}
|
||||
timerStillActiveCheck.Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,7 +543,6 @@ namespace SystemTrayMenu
|
|||
{
|
||||
int level = (int)eDoWork.Argument;
|
||||
BackgroundWorker worker = (BackgroundWorker)senderDoWork;
|
||||
rowData.RestartLoading = false;
|
||||
eDoWork.Result = ReadMenu(worker, rowData.TargetFilePath, level);
|
||||
}
|
||||
|
||||
|
@ -560,12 +553,12 @@ namespace SystemTrayMenu
|
|||
MenuData menuData = (MenuData)e.Result;
|
||||
if (rowData.RestartLoading)
|
||||
{
|
||||
rowData.RestartLoading = false;
|
||||
rowData.Reading.RunWorkerAsync(menuData.Level);
|
||||
}
|
||||
else
|
||||
{
|
||||
menuNotifyIcon.LoadingStop();
|
||||
menuNotifyIcon.LoadWait();
|
||||
if (menuData.Validity != MenuDataValidity.Invalid)
|
||||
{
|
||||
menu = CreateMenu(menuData);
|
||||
|
@ -585,7 +578,6 @@ namespace SystemTrayMenu
|
|||
rowData.SubMenu = menu;
|
||||
rowData.MenuLoaded();
|
||||
}
|
||||
menuNotifyIcon.LoadStop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -620,46 +612,35 @@ namespace SystemTrayMenu
|
|||
DisposeMenu(menus[menuTriggered.Level]);
|
||||
menus[menuTriggered.Level] = menuTriggered;
|
||||
AdjustSubMenusLocationAndSize();
|
||||
|
||||
#warning wrap into showorshowtransparent or find way without asking active form
|
||||
if (Form.ActiveForm is Menu)
|
||||
{
|
||||
menus[menuTriggered.Level].ShowWithFade();
|
||||
}
|
||||
else
|
||||
{
|
||||
menus[menuTriggered.Level].ShowTransparent();
|
||||
}
|
||||
menus[menuTriggered.Level].ShowWithFadeOrTransparent(
|
||||
Form.ActiveForm is Menu);
|
||||
}
|
||||
|
||||
private void FadeInIfNeeded()
|
||||
{
|
||||
if (menus[0].IsUsable)
|
||||
{
|
||||
if (Form.ActiveForm is Menu)
|
||||
{
|
||||
Menus().ToList().ForEach(menu => menu.ShowWithFade());
|
||||
}
|
||||
else
|
||||
{
|
||||
Menus().ToList().ForEach(menu => menu.ShowTransparent());
|
||||
}
|
||||
bool isActive = Form.ActiveForm is Menu;
|
||||
Menus().ToList().ForEach(
|
||||
menu => menu.ShowWithFadeOrTransparent(isActive));
|
||||
}
|
||||
}
|
||||
|
||||
private void FadeHalfOrOutIfNeeded()
|
||||
private bool FadeHalfOrOutIfNeeded()
|
||||
{
|
||||
bool menuActive = false;
|
||||
if (menus[0].IsUsable)
|
||||
{
|
||||
if (!(Form.ActiveForm is Menu))
|
||||
menuActive = Form.ActiveForm is Menu;
|
||||
if (!menuActive)
|
||||
{
|
||||
Point position = Control.MousePosition;
|
||||
if (Menus().Any(m => m.IsMouseOn(position)))
|
||||
{
|
||||
if (!keyboardInput.InUse)
|
||||
{
|
||||
Menus().ToList().ForEach(menu =>
|
||||
menu.ShowTransparent());
|
||||
Menus().ToList().ForEach(
|
||||
menu => menu.ShowTransparent());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -668,10 +649,13 @@ namespace SystemTrayMenu
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return menuActive;
|
||||
}
|
||||
|
||||
private void MenusFadeOut()
|
||||
{
|
||||
openCloseState = OpenCloseState.Closing;
|
||||
Menus().ToList().ForEach(menu =>
|
||||
{
|
||||
if (menu.Level > 0)
|
||||
|
|
|
@ -10,10 +10,12 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
private readonly Timer timerLeaveCheck = new Timer();
|
||||
|
||||
public bool IsRunning => timerLeaveCheck.Enabled;
|
||||
|
||||
public WaitLeave(int timeUntilTriggered)
|
||||
{
|
||||
timerLeaveCheck.Interval = timeUntilTriggered;
|
||||
timerLeaveCheck.Tick += Leave;
|
||||
timerLeaveCheck.Tick += TimerLeaveCheckTick;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
|
@ -27,7 +29,7 @@ namespace SystemTrayMenu.Handler
|
|||
timerLeaveCheck.Stop();
|
||||
}
|
||||
|
||||
private void Leave(object sender, EventArgs e)
|
||||
private void TimerLeaveCheckTick(object sender, EventArgs e)
|
||||
{
|
||||
timerLeaveCheck.Stop();
|
||||
LeaveTriggered.Invoke();
|
||||
|
|
|
@ -22,7 +22,6 @@ namespace SystemTrayMenu
|
|||
internal const int Scrollspeed = 4;
|
||||
internal const int WaitMenuOpen = 200;
|
||||
internal const int MenusMax = 50;
|
||||
internal const int MaxClicksInQueue = 1;
|
||||
internal const int TimeUntilClose = 1000;
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
Log.Error($"iconLocation:'{iconLocation}'", ex);
|
||||
Log.Warn($"iconLocation:'{iconLocation}'", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,28 +43,16 @@ namespace SystemTrayMenu.UserInterface
|
|||
StartStopTimer(state);
|
||||
}
|
||||
|
||||
private void StartStopTimer(FadingState state)
|
||||
private void StartStopTimer(FadingState newState)
|
||||
{
|
||||
#warning if too many threads throw some away? win32 exception if too fast here
|
||||
if (state == FadingState.Idle)
|
||||
if (newState == FadingState.Idle)
|
||||
{
|
||||
this.state = state;
|
||||
state = newState;
|
||||
timer.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowAtLeastTransparentBeforeHideItAgain();
|
||||
void ShowAtLeastTransparentBeforeHideItAgain()
|
||||
{
|
||||
if (state == FadingState.Hide)
|
||||
{
|
||||
while (opacity < TransparentMinus)
|
||||
{
|
||||
Application.DoEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
this.state = state;
|
||||
state = newState;
|
||||
timer.Start();
|
||||
FadeStep();
|
||||
}
|
||||
|
|
|
@ -35,5 +35,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("0.9.2.21")]
|
||||
[assembly: AssemblyFileVersion("0.9.2.21")]
|
||||
[assembly: AssemblyVersion("0.9.2.22")]
|
||||
[assembly: AssemblyFileVersion("0.9.2.22")]
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<Optimize>true</Optimize>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'x64|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -351,6 +352,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>taskkill /f /fi "imagename eq $(TargetFileName)"</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -67,19 +67,21 @@ namespace SystemTrayMenu.UserInterface
|
|||
notifyIcon.MouseClick += NotifyIcon_MouseClick;
|
||||
void NotifyIcon_MouseClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
HandleClick.Invoke();
|
||||
}
|
||||
VerifyClick(e);
|
||||
}
|
||||
|
||||
notifyIcon.MouseDoubleClick += NotifyIcon_MouseDoubleClick;
|
||||
void NotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
HandleClick.Invoke();
|
||||
}
|
||||
VerifyClick(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void VerifyClick(MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Left)
|
||||
{
|
||||
HandleClick.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,8 +92,13 @@ namespace SystemTrayMenu.UserInterface
|
|||
load.Dispose();
|
||||
}
|
||||
|
||||
public void LoadingStart()
|
||||
public void LoadingStart(bool reset = false)
|
||||
{
|
||||
if (reset)
|
||||
{
|
||||
threadsLoading = 0;
|
||||
}
|
||||
|
||||
timeLoadingStart = DateTime.Now;
|
||||
threadsLoading++;
|
||||
load.Start();
|
||||
|
@ -101,14 +108,16 @@ namespace SystemTrayMenu.UserInterface
|
|||
{
|
||||
threadsLoading--;
|
||||
}
|
||||
public void LoadWait()
|
||||
{
|
||||
notifyIcon.Icon = bitmapsLoading[loadCount++ % indexLoad];
|
||||
}
|
||||
public void LoadStop()
|
||||
{
|
||||
notifyIcon.Icon = R.SystemTrayMenu;
|
||||
}
|
||||
|
||||
// Show a static icon when mainthread blocked
|
||||
//public void LoadingStaticWait()
|
||||
//{
|
||||
// notifyIcon.Icon = bitmapsLoading[loadCount++ % indexLoad];
|
||||
//}
|
||||
//public void LoadingStaticStop()
|
||||
//{
|
||||
// notifyIcon.Icon = R.SystemTrayMenu;
|
||||
//}
|
||||
|
||||
private void Load_Tick(object sender, EventArgs e)
|
||||
{
|
||||
|
|
|
@ -16,10 +16,11 @@ namespace SystemTrayMenu.UserInterface
|
|||
internal new event EventHandlerEmpty MouseEnter;
|
||||
internal new event EventHandlerEmpty MouseLeave;
|
||||
internal event EventHandlerEmpty UserClickedOpenFolder;
|
||||
#warning use event not action
|
||||
internal event Action<Keys> CmdKeyProcessed;
|
||||
#warning #68 => use event and not a action here?
|
||||
|
||||
internal bool IsUsable => Visible && !fading.IsHiding;
|
||||
internal bool IsUsable => Visible && !fading.IsHiding &&
|
||||
!IsDisposed && !Disposing;
|
||||
|
||||
internal enum MenuType
|
||||
{
|
||||
|
@ -45,7 +46,30 @@ namespace SystemTrayMenu.UserInterface
|
|||
fading.Show += Fading_Show;
|
||||
void Fading_Show()
|
||||
{
|
||||
NativeMethods.User32ShowInactiveTopmost(this);
|
||||
if (Level == 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Visible = true;
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
Visible = false;
|
||||
Log.Info($"Could not open menu, menu already closed," +
|
||||
$" IsDisposed={IsDisposed}");
|
||||
}
|
||||
|
||||
if (Visible)
|
||||
{
|
||||
Activate();
|
||||
NativeMethods.ForceForegroundWindow(Handle);
|
||||
SetTitleColorActive();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeMethods.User32ShowInactiveTopmost(this);
|
||||
}
|
||||
}
|
||||
fading.Hide += Hide;
|
||||
|
||||
|
@ -89,10 +113,12 @@ namespace SystemTrayMenu.UserInterface
|
|||
{
|
||||
SetType(MenuType.Sub);
|
||||
}
|
||||
|
||||
internal void SetTypeEmpty()
|
||||
{
|
||||
SetType(MenuType.Empty);
|
||||
}
|
||||
|
||||
internal void SetTypeNoAccess()
|
||||
{
|
||||
SetType(MenuType.NoAccess);
|
||||
|
@ -127,17 +153,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
}
|
||||
|
||||
internal bool IsVisible()
|
||||
{
|
||||
return Visible;
|
||||
}
|
||||
|
||||
internal bool IsActive(Form activeForm)
|
||||
{
|
||||
bool isActive = (this == activeForm);
|
||||
return isActive;
|
||||
}
|
||||
|
||||
internal bool IsMouseOn(Point mousePosition)
|
||||
{
|
||||
bool isMouseOn = Visible && ClientRectangle.Contains(
|
||||
|
@ -149,10 +164,6 @@ namespace SystemTrayMenu.UserInterface
|
|||
{
|
||||
return dgv;
|
||||
}
|
||||
internal Label GetLabel()
|
||||
{
|
||||
return labelTitle;
|
||||
}
|
||||
|
||||
internal void SetTitle(string title)
|
||||
{
|
||||
|
@ -166,6 +177,18 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
}
|
||||
|
||||
internal void ShowWithFadeOrTransparent(bool formActiveFormIsMenu)
|
||||
{
|
||||
if (formActiveFormIsMenu)
|
||||
{
|
||||
ShowWithFade();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowTransparent();
|
||||
}
|
||||
}
|
||||
|
||||
internal void ShowWithFade()
|
||||
{
|
||||
fading.Fade(Fading.FadingState.Show);
|
||||
|
|
Loading…
Reference in a new issue