mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-10-03 10:36:30 +13:00
Improve window size and position calculations
Fix several warnings
This commit is contained in:
parent
b12d4ad656
commit
c9ce4d1d21
5 changed files with 189 additions and 157 deletions
|
@ -16,13 +16,13 @@ namespace SystemTrayMenu.Handler
|
|||
|
||||
internal class KeyboardInput : IDisposable
|
||||
{
|
||||
private readonly Menu[] menus;
|
||||
private readonly Menu?[] menus;
|
||||
private readonly KeyboardHook hook = new();
|
||||
|
||||
private int iRowKey = -1;
|
||||
private int iMenuKey;
|
||||
|
||||
public KeyboardInput(Menu[] menus)
|
||||
public KeyboardInput(Menu?[] menus)
|
||||
{
|
||||
this.menus = menus;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace SystemTrayMenu.Business
|
|||
internal class Menus : IDisposable
|
||||
{
|
||||
private readonly Dispatcher dispatchter = Dispatcher.CurrentDispatcher;
|
||||
private readonly Menu[] menus = new Menu[MenuDefines.MenusMax];
|
||||
private readonly Menu?[] menus = new Menu?[MenuDefines.MenusMax];
|
||||
private readonly BackgroundWorker workerMainMenu = new();
|
||||
private readonly List<BackgroundWorker> workersSubMenu = new();
|
||||
private readonly DgvMouseRow<ListView> dgvMouseRow = new();
|
||||
|
@ -43,18 +43,25 @@ namespace SystemTrayMenu.Business
|
|||
private OpenCloseState openCloseState = OpenCloseState.Default;
|
||||
private TaskbarPosition taskbarPosition = new WindowsTaskbar().Position;
|
||||
private bool searchTextChanging;
|
||||
private bool waitingForReactivate;
|
||||
private int lastMouseDownRowIndex = -1;
|
||||
private bool showMenuAfterMainPreload;
|
||||
#if TODO // TOUCH
|
||||
private int dragSwipeScrollingStartRowIndex = -1;
|
||||
#endif
|
||||
private bool isDraggingSwipeScrolling;
|
||||
#endif
|
||||
private bool isDragSwipeScrolled;
|
||||
private bool hideSubmenuDuringRefreshSearch;
|
||||
|
||||
public Menus()
|
||||
{
|
||||
keyboardInput = new(menus);
|
||||
keyboardInput.RegisterHotKey();
|
||||
keyboardInput.HotKeyPressed += () => SwitchOpenClose(false);
|
||||
keyboardInput.ClosePressed += MenusFadeOut;
|
||||
keyboardInput.RowDeselected += waitToOpenMenu.RowDeselected;
|
||||
keyboardInput.EnterPressed += waitToOpenMenu.EnterOpensInstantly;
|
||||
keyboardInput.RowSelected += waitToOpenMenu.RowSelected;
|
||||
|
||||
workerMainMenu.WorkerSupportsCancellation = true;
|
||||
workerMainMenu.DoWork += LoadMenu;
|
||||
workerMainMenu.RunWorkerCompleted += LoadMainMenuCompleted;
|
||||
|
@ -67,7 +74,7 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
// The main menu gets loaded again
|
||||
// Clean up menu status of previous one
|
||||
ListView? dgvMainMenu = menus[0].GetDataGridView();
|
||||
ListView? dgvMainMenu = menus[0]?.GetDataGridView();
|
||||
if (dgvMainMenu != null)
|
||||
{
|
||||
foreach (ListViewItemData item in dgvMainMenu.Items)
|
||||
|
@ -84,7 +91,11 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
if (Settings.Default.AppearAtMouseLocation)
|
||||
{
|
||||
menus[0].RowDataParent = null;
|
||||
Menu? menu = menus[0];
|
||||
if (menu != null)
|
||||
{
|
||||
menu.RowDataParent = null;
|
||||
}
|
||||
}
|
||||
|
||||
AsEnumerable.ToList().ForEach(m => { m.ShowWithFade(); });
|
||||
|
@ -151,9 +162,9 @@ namespace SystemTrayMenu.Business
|
|||
waitToOpenMenu.StartLoadMenu += StartLoadMenu;
|
||||
void StartLoadMenu(RowData rowData)
|
||||
{
|
||||
if (menus[0].IsUsable &&
|
||||
if (IsMainUsable && rowData.Path != null &&
|
||||
(menus[rowData.Level + 1] == null ||
|
||||
menus[rowData.Level + 1].RowDataParent != rowData))
|
||||
menus[rowData.Level + 1]?.RowDataParent != rowData))
|
||||
{
|
||||
Create(new(rowData.Level + 1, rowData), rowData.Path); // Level 1+ Sub Menu (loading)
|
||||
|
||||
|
@ -187,27 +198,31 @@ namespace SystemTrayMenu.Business
|
|||
return;
|
||||
}
|
||||
|
||||
if (menus[0].IsUsable)
|
||||
if (IsMainUsable)
|
||||
{
|
||||
if (menuData.DirectoryState != MenuDataDirectoryState.Undefined)
|
||||
{
|
||||
// Sub Menu (completed)
|
||||
menu.AddItemsToMenu(menuData.RowDatas);
|
||||
menu.SetSubMenuState(menuData.DirectoryState);
|
||||
AdjustMenusSizeAndLocation();
|
||||
AdjustMenusSizeAndLocation(menu.Level);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.HideWithFade();
|
||||
menus[menu.Level] = null;
|
||||
|
||||
menuData.RowDataParent.IsMenuOpen = false;
|
||||
menuData.RowDataParent.IsClicking = false;
|
||||
menuData.RowDataParent.IsSelected = false;
|
||||
Menu menuPrevious = menus[menuData.Level - 1];
|
||||
if (menuPrevious != null)
|
||||
if (menuData.RowDataParent != null)
|
||||
{
|
||||
RefreshSelection(menuPrevious.GetDataGridView());
|
||||
menuData.RowDataParent.IsMenuOpen = false;
|
||||
menuData.RowDataParent.IsClicking = false;
|
||||
menuData.RowDataParent.IsSelected = false;
|
||||
}
|
||||
|
||||
ListView? lv = menus[menuData.Level - 1]?.GetDataGridView();
|
||||
if (lv != null)
|
||||
{
|
||||
RefreshSelection(lv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,14 +232,18 @@ namespace SystemTrayMenu.Business
|
|||
waitToOpenMenu.CloseMenu += CloseMenu;
|
||||
void CloseMenu(int level)
|
||||
{
|
||||
if (level < menus.Length && menus[level] != null)
|
||||
if (level < menus.Length)
|
||||
{
|
||||
HideOldMenu(menus[level]);
|
||||
Menu? menu = menus[level];
|
||||
if (menu != null)
|
||||
{
|
||||
HideOldMenu(menu);
|
||||
}
|
||||
}
|
||||
|
||||
if (level - 1 < menus.Length && menus[level - 1] != null)
|
||||
{
|
||||
menus[level - 1].FocusTextBox();
|
||||
menus[level - 1]?.FocusTextBox();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,16 +254,8 @@ namespace SystemTrayMenu.Business
|
|||
dgvMouseRow.RowMouseLeave += Dgv_RowMouseLeave;
|
||||
#endif
|
||||
|
||||
keyboardInput = new(menus);
|
||||
keyboardInput.RegisterHotKey();
|
||||
keyboardInput.HotKeyPressed += () => SwitchOpenClose(false);
|
||||
keyboardInput.ClosePressed += MenusFadeOut;
|
||||
keyboardInput.RowDeselected += waitToOpenMenu.RowDeselected;
|
||||
keyboardInput.EnterPressed += waitToOpenMenu.EnterOpensInstantly;
|
||||
keyboardInput.RowSelected += waitToOpenMenu.RowSelected;
|
||||
|
||||
joystickHelper = new();
|
||||
joystickHelper.KeyPressed += (key, modifiers) => menus[0].Dispatcher.Invoke(keyboardInput.CmdKeyProcessed, new object[] { null!, key, modifiers });
|
||||
joystickHelper.KeyPressed += (key, modifiers) => menus[0]?.Dispatcher.Invoke(keyboardInput.CmdKeyProcessed, new object[] { null!, key, modifiers });
|
||||
|
||||
timerShowProcessStartedAsLoadingIcon.Interval = TimeSpan.FromMilliseconds(Settings.Default.TimeUntilClosesAfterEnterPressed);
|
||||
timerStillActiveCheck.Interval = TimeSpan.FromMilliseconds(Settings.Default.TimeUntilClosesAfterEnterPressed + 20);
|
||||
|
@ -313,7 +324,9 @@ namespace SystemTrayMenu.Business
|
|||
Closing,
|
||||
}
|
||||
|
||||
private IEnumerable<Menu> AsEnumerable => menus.Where(m => m != null && !m.IsDisposed);
|
||||
private bool IsMainUsable => menus[0]?.IsUsable ?? false;
|
||||
|
||||
private IEnumerable<Menu> AsEnumerable => menus.Where(m => m != null && !m.IsDisposed) !;
|
||||
|
||||
private List<Menu> AsList => AsEnumerable.ToList();
|
||||
|
||||
|
@ -387,22 +400,26 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
// Case when Folder Dialog open
|
||||
}
|
||||
else if (openCloseState == OpenCloseState.Opening ||
|
||||
(menus[0] != null && menus[0].Visibility == Visibility.Visible && openCloseState == OpenCloseState.Default))
|
||||
{
|
||||
openCloseState = OpenCloseState.Closing;
|
||||
MenusFadeOut();
|
||||
StopWorker();
|
||||
if (!AsEnumerable.Any(m => m.Visibility == Visibility.Visible))
|
||||
{
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
openCloseState = OpenCloseState.Opening;
|
||||
joystickHelper.Enable();
|
||||
StartWorker();
|
||||
Menu? menu = menus[0];
|
||||
if (openCloseState == OpenCloseState.Opening ||
|
||||
(menu != null && menu.Visibility == Visibility.Visible && openCloseState == OpenCloseState.Default))
|
||||
{
|
||||
openCloseState = OpenCloseState.Closing;
|
||||
MenusFadeOut();
|
||||
StopWorker();
|
||||
if (!AsEnumerable.Any(m => m.Visibility == Visibility.Visible))
|
||||
{
|
||||
openCloseState = OpenCloseState.Default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
openCloseState = OpenCloseState.Opening;
|
||||
joystickHelper.Enable();
|
||||
StartWorker();
|
||||
}
|
||||
}
|
||||
|
||||
deactivatedTime = DateTime.MinValue;
|
||||
|
@ -485,9 +502,9 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
bool IsShellContextMenuOpen()
|
||||
{
|
||||
foreach (Menu menu in menus.Where(m => m != null))
|
||||
foreach (Menu? menu in menus.Where(m => m != null))
|
||||
{
|
||||
ListView? dgv = menu.GetDataGridView();
|
||||
ListView? dgv = menu?.GetDataGridView();
|
||||
if (dgv != null)
|
||||
{
|
||||
foreach (ListViewItemData item in dgv.Items)
|
||||
|
@ -504,7 +521,7 @@ namespace SystemTrayMenu.Business
|
|||
return false;
|
||||
}
|
||||
|
||||
foreach (Menu menu in menus.Where(m => m != null && m.IsActive))
|
||||
foreach (Menu? menu in menus.Where(m => m != null && m.IsActive))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -516,7 +533,7 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
Menu menu = new(menuData, path);
|
||||
|
||||
menu.MenuScrolled += AdjustMenusSizeAndLocation; // TODO: Only update vertical location while scrolling?
|
||||
menu.MenuScrolled += () => AdjustMenusSizeAndLocation(menu.Level + 1); // TODO: Only update vertical location while scrolling?
|
||||
menu.MouseLeave += (_, _) =>
|
||||
{
|
||||
// Restart timer
|
||||
|
@ -529,15 +546,38 @@ namespace SystemTrayMenu.Business
|
|||
menu.KeyPressCheck += Menu_KeyPressCheck;
|
||||
#endif
|
||||
menu.SearchTextChanging += Menu_SearchTextChanging;
|
||||
#if TODO // SEARCH
|
||||
void Menu_SearchTextChanging()
|
||||
{
|
||||
searchTextChanging = true;
|
||||
keyboardInput.SearchTextChanging();
|
||||
waitToOpenMenu.MouseActive = false;
|
||||
}
|
||||
|
||||
menu.SearchTextChanged += Menu_SearchTextChanged;
|
||||
#endif
|
||||
void Menu_SearchTextChanged(Menu menu, bool isSearchStringEmpty)
|
||||
{
|
||||
keyboardInput.SearchTextChanged(menu, isSearchStringEmpty);
|
||||
AdjustMenusSizeAndLocation(menu.Level + 1);
|
||||
searchTextChanging = false;
|
||||
|
||||
// if any open menu close
|
||||
if (menu.Level + 1 < menus.Length)
|
||||
{
|
||||
Menu? menuToClose = menus[menu.Level + 1];
|
||||
if (menuToClose != null && hideSubmenuDuringRefreshSearch)
|
||||
{
|
||||
HideOldMenu(menuToClose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu.UserDragsMenu += Menu_UserDragsMenu;
|
||||
void Menu_UserDragsMenu()
|
||||
{
|
||||
if (menus[1] != null)
|
||||
Menu? menu = menus[1];
|
||||
if (menu != null)
|
||||
{
|
||||
HideOldMenu(menus[1]);
|
||||
HideOldMenu(menu);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,8 +588,7 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
Log.Info("Ignored Deactivate, because openCloseState == OpenCloseState.Opening");
|
||||
}
|
||||
else if (!Settings.Default.StaysOpenWhenFocusLostAfterEnterPressed ||
|
||||
!waitingForReactivate)
|
||||
else if (!Settings.Default.StaysOpenWhenFocusLostAfterEnterPressed)
|
||||
{
|
||||
FadeHalfOrOutIfNeeded();
|
||||
if (!IsActive())
|
||||
|
@ -562,7 +601,7 @@ namespace SystemTrayMenu.Business
|
|||
menu.Activated += (sender, e) => Activated();
|
||||
void Activated()
|
||||
{
|
||||
if (IsActive() && menus[0].IsUsable)
|
||||
if (IsActive() && IsMainUsable)
|
||||
{
|
||||
AsList.ForEach(m => m.ShowWithFade());
|
||||
timerStillActiveCheck.Stop();
|
||||
|
@ -606,12 +645,11 @@ namespace SystemTrayMenu.Business
|
|||
else
|
||||
{
|
||||
// Sub Menu (loading)
|
||||
if (menus[0].IsUsable)
|
||||
if (IsMainUsable)
|
||||
{
|
||||
HideOldMenu(menu, true);
|
||||
menus[menu.Level] = menu;
|
||||
AdjustMenusSizeAndLocation();
|
||||
menus[menu.Level]?.ShowWithFadeOrTransparent(IsActive());
|
||||
menu.ShowWithFadeOrTransparent(IsActive());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -622,7 +660,7 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
if (menu.IsUsable)
|
||||
{
|
||||
AdjustMenusSizeAndLocation();
|
||||
AdjustMenusSizeAndLocation(menu.Level);
|
||||
|
||||
if (menu.Level == 0)
|
||||
{
|
||||
|
@ -725,13 +763,17 @@ namespace SystemTrayMenu.Business
|
|||
private void Dgv_MouseUp(object sender, int index, MouseButtonEventArgs e)
|
||||
{
|
||||
lastMouseDownRowIndex = -1;
|
||||
#if TODO // TOUCH
|
||||
isDraggingSwipeScrolling = false;
|
||||
#endif
|
||||
isDragSwipeScrolled = false;
|
||||
}
|
||||
|
||||
private void Dgv_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
#if TODO // TOUCH
|
||||
isDraggingSwipeScrolling = false;
|
||||
#endif
|
||||
isDragSwipeScrolled = false;
|
||||
}
|
||||
|
||||
|
@ -742,7 +784,7 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
private void MouseEnterOk(ListView dgv, int rowIndex, bool refreshView)
|
||||
{
|
||||
if (menus[0].IsUsable)
|
||||
if (IsMainUsable)
|
||||
{
|
||||
if (keyboardInput.InUse)
|
||||
{
|
||||
|
@ -823,7 +865,7 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
// Case when filtering a previous menu
|
||||
}
|
||||
else if (!menus[0].IsUsable)
|
||||
else if (!IsMainUsable)
|
||||
{
|
||||
#if TODO // Colors
|
||||
row.DefaultCellStyle.SelectionBackColor = Color.White;
|
||||
|
@ -900,7 +942,6 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
if (rowData.ProcessStarted)
|
||||
{
|
||||
waitingForReactivate = true;
|
||||
rowData.ProcessStarted = false;
|
||||
row.Cells[0].Value = Resources.StaticResources.LoadingIcon;
|
||||
timerShowProcessStartedAsLoadingIcon.Tick += Tick;
|
||||
|
@ -909,7 +950,6 @@ namespace SystemTrayMenu.Business
|
|||
timerShowProcessStartedAsLoadingIcon.Tick -= Tick;
|
||||
timerShowProcessStartedAsLoadingIcon.Stop();
|
||||
row.Cells[0].Value = rowData.ReadIcon(false);
|
||||
waitingForReactivate = false;
|
||||
}
|
||||
|
||||
timerShowProcessStartedAsLoadingIcon.Stop();
|
||||
|
@ -925,16 +965,21 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
dispatchter.Invoke(() =>
|
||||
{
|
||||
if (menus[0].IsUsable)
|
||||
if (IsMainUsable)
|
||||
{
|
||||
menus[0].RowDataParent = null;
|
||||
Menu? menu = menus[0];
|
||||
if (menu != null)
|
||||
{
|
||||
// TODO: What does this do???
|
||||
menu.RowDataParent = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void HideOldMenu(Menu menuToShow, bool keepOrSetIsMenuOpen = false)
|
||||
{
|
||||
Menu menuPrevious = menus[menuToShow.Level - 1];
|
||||
Menu? menuPrevious = menus[menuToShow.Level - 1];
|
||||
if (menuPrevious != null)
|
||||
{
|
||||
// Clean up menu status IsMenuOpen for previous one
|
||||
|
@ -958,10 +1003,10 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
|
||||
// Hide old menu
|
||||
foreach (Menu menuToClose in menus.Where(
|
||||
foreach (Menu? menuToClose in menus.Where(
|
||||
m => m != null && m.Level > menuPrevious.Level))
|
||||
{
|
||||
menuToClose.HideWithFade();
|
||||
menuToClose!.HideWithFade();
|
||||
menus[menuToClose.Level] = null;
|
||||
}
|
||||
}
|
||||
|
@ -969,7 +1014,7 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
private void FadeHalfOrOutIfNeeded()
|
||||
{
|
||||
if (menus[0] != null && menus[0].IsUsable)
|
||||
if (IsMainUsable)
|
||||
{
|
||||
if (!IsActive())
|
||||
{
|
||||
|
@ -1010,27 +1055,26 @@ namespace SystemTrayMenu.Business
|
|||
joystickHelper.Disable();
|
||||
}
|
||||
|
||||
private void AdjustMenusSizeAndLocation()
|
||||
private void GetScreenBounds(out Rect screenBounds, out bool useCustomLocation, out Menu.StartLocation startLocation)
|
||||
{
|
||||
Rect screenBounds;
|
||||
bool isCustomLocationOutsideOfScreen = false;
|
||||
|
||||
if (Settings.Default.AppearAtMouseLocation)
|
||||
{
|
||||
screenBounds = NativeMethods.Screen.FromPoint(NativeMethods.Screen.CursorPosition);
|
||||
useCustomLocation = false;
|
||||
}
|
||||
else if (Settings.Default.UseCustomLocation)
|
||||
{
|
||||
screenBounds = NativeMethods.Screen.FromPoint(new (
|
||||
screenBounds = NativeMethods.Screen.FromPoint(new(
|
||||
Settings.Default.CustomLocationX,
|
||||
Settings.Default.CustomLocationY));
|
||||
|
||||
isCustomLocationOutsideOfScreen = !screenBounds.Contains(
|
||||
useCustomLocation = !screenBounds.Contains(
|
||||
new Point(Settings.Default.CustomLocationX, Settings.Default.CustomLocationY));
|
||||
}
|
||||
else
|
||||
{
|
||||
screenBounds = NativeMethods.Screen.PrimaryScreen;
|
||||
useCustomLocation = false;
|
||||
}
|
||||
|
||||
// Only apply taskbar position change when no menu is currently open
|
||||
|
@ -1042,7 +1086,6 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
|
||||
// Shrink the usable space depending on taskbar location
|
||||
Menu.StartLocation startLocation;
|
||||
switch (taskbarPosition)
|
||||
{
|
||||
case TaskbarPosition.Left:
|
||||
|
@ -1066,19 +1109,32 @@ namespace SystemTrayMenu.Business
|
|||
break;
|
||||
}
|
||||
|
||||
if (Settings.Default.AppearAtTheBottomLeft ||
|
||||
isCustomLocationOutsideOfScreen)
|
||||
if (Settings.Default.AppearAtTheBottomLeft)
|
||||
{
|
||||
startLocation = Menu.StartLocation.BottomLeft;
|
||||
}
|
||||
}
|
||||
|
||||
private void AdjustMenusSizeAndLocation(int startLevel)
|
||||
{
|
||||
GetScreenBounds(out Rect screenBounds, out bool useCustomLocation, out Menu.StartLocation startLocation);
|
||||
|
||||
Menu menu;
|
||||
Menu? menuPredecessor = null;
|
||||
List<Menu> list = AsList;
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
menu = list[i];
|
||||
|
||||
menu.AdjustSizeAndLocation(screenBounds, menuPredecessor, startLocation, isCustomLocationOutsideOfScreen);
|
||||
if (startLevel <= i)
|
||||
{
|
||||
menu.AdjustSizeAndLocation(screenBounds, menuPredecessor, startLocation, useCustomLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure further calculations of this menu access updated values (later used as predecessor)
|
||||
menu.UpdateLayout();
|
||||
}
|
||||
|
||||
if (!Settings.Default.AppearAtTheBottomLeft &&
|
||||
!Settings.Default.AppearAtMouseLocation &&
|
||||
|
@ -1110,31 +1166,6 @@ namespace SystemTrayMenu.Business
|
|||
}
|
||||
#endif
|
||||
|
||||
private void Menu_SearchTextChanging()
|
||||
{
|
||||
searchTextChanging = true;
|
||||
keyboardInput.SearchTextChanging();
|
||||
waitToOpenMenu.MouseActive = false;
|
||||
}
|
||||
|
||||
private void Menu_SearchTextChanged(object sender, bool isSearchStringEmpty)
|
||||
{
|
||||
Menu menu = (Menu)sender;
|
||||
keyboardInput.SearchTextChanged(menu, isSearchStringEmpty);
|
||||
AdjustMenusSizeAndLocation();
|
||||
searchTextChanging = false;
|
||||
|
||||
// if any open menu close
|
||||
if (menu.Level + 1 < menus.Length)
|
||||
{
|
||||
Menu menuToClose = menus[menu.Level + 1];
|
||||
if (menuToClose != null && hideSubmenuDuringRefreshSearch)
|
||||
{
|
||||
HideOldMenu(menuToClose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteWatcherHistory()
|
||||
{
|
||||
foreach (var fileSystemEventArgs in watcherHistory)
|
||||
|
@ -1147,14 +1178,15 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
private void WatcherProcessItem(object sender, EventArgs e)
|
||||
{
|
||||
Menu? menu = menus[0];
|
||||
bool useHistory = false;
|
||||
if (menus[0] == null)
|
||||
if (menu == null)
|
||||
{
|
||||
useHistory = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
menus[0].Dispatcher.Invoke(() => useHistory = !menus[0].IsLoaded);
|
||||
menu.Dispatcher.Invoke(() => useHistory = !menu.IsLoaded);
|
||||
}
|
||||
|
||||
if (useHistory)
|
||||
|
@ -1165,17 +1197,17 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
if (e is RenamedEventArgs renamedEventArgs)
|
||||
{
|
||||
menus[0].Dispatcher.Invoke(() => RenameItem(renamedEventArgs));
|
||||
menus[0]?.Dispatcher.Invoke(() => RenameItem(renamedEventArgs));
|
||||
}
|
||||
else if (e is FileSystemEventArgs fileSystemEventArgs)
|
||||
{
|
||||
if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Deleted)
|
||||
{
|
||||
menus[0].Dispatcher.Invoke(() => DeleteItem(fileSystemEventArgs));
|
||||
menus[0]?.Dispatcher.Invoke(() => DeleteItem(fileSystemEventArgs));
|
||||
}
|
||||
else if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Created)
|
||||
{
|
||||
menus[0].Dispatcher.Invoke(() => CreateItem(fileSystemEventArgs));
|
||||
menus[0]?.Dispatcher.Invoke(() => CreateItem(fileSystemEventArgs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1185,23 +1217,27 @@ namespace SystemTrayMenu.Business
|
|||
try
|
||||
{
|
||||
List<RowData> rowDatas = new();
|
||||
ListView? dgv = menus[0].GetDataGridView();
|
||||
ListView? dgv = menus[0]?.GetDataGridView();
|
||||
if (dgv != null)
|
||||
{
|
||||
foreach (ListViewItemData item in dgv.Items)
|
||||
{
|
||||
RowData rowData = item.data;
|
||||
if (rowData.Path.StartsWith($"{e.OldFullPath}"))
|
||||
if (rowData.Path?.StartsWith($"{e.OldFullPath}") ?? false)
|
||||
{
|
||||
string path = rowData.Path.Replace(e.OldFullPath, e.FullPath);
|
||||
string? path = rowData.Path.Replace(e.OldFullPath, e.FullPath);
|
||||
FileAttributes attr = File.GetAttributes(path);
|
||||
bool isFolder = (attr & FileAttributes.Directory) == FileAttributes.Directory;
|
||||
if (isFolder)
|
||||
{
|
||||
path = Path.GetDirectoryName(path);
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
RowData rowDataRenamed = new(isFolder, rowData.IsAddionalItem, false, 0, path);
|
||||
RowData rowDataRenamed = new(isFolder, rowData.IsAdditionalItem, false, 0, path);
|
||||
if (FolderOptions.IsHidden(rowDataRenamed))
|
||||
{
|
||||
continue;
|
||||
|
@ -1220,13 +1256,13 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
rowDatas = DirectoryHelpers.SortItems(rowDatas);
|
||||
keyboardInput.ClearIsSelectedByKey();
|
||||
menus[0].AddItemsToMenu(rowDatas);
|
||||
menus[0]?.AddItemsToMenu(rowDatas);
|
||||
|
||||
hideSubmenuDuringRefreshSearch = false;
|
||||
menus[0].RefreshSearchText();
|
||||
menus[0]?.RefreshSearchText();
|
||||
hideSubmenuDuringRefreshSearch = true;
|
||||
|
||||
menus[0].TimerUpdateIconsStart();
|
||||
menus[0]?.TimerUpdateIconsStart();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -1238,7 +1274,7 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
try
|
||||
{
|
||||
ListView? dgv = menus[0].GetDataGridView();
|
||||
ListView? dgv = menus[0]?.GetDataGridView();
|
||||
if (dgv != null)
|
||||
{
|
||||
List<ListViewItemData> rowsToRemove = new();
|
||||
|
@ -1247,7 +1283,7 @@ namespace SystemTrayMenu.Business
|
|||
{
|
||||
RowData rowData = item.data;
|
||||
if (rowData.Path == e.FullPath ||
|
||||
rowData.Path.StartsWith($"{e.FullPath}\\"))
|
||||
(rowData.Path?.StartsWith($"{e.FullPath}\\") ?? false))
|
||||
{
|
||||
IconReader.RemoveIconFromCache(rowData.Path);
|
||||
rowsToRemove.Add(item);
|
||||
|
@ -1263,7 +1299,7 @@ namespace SystemTrayMenu.Business
|
|||
keyboardInput.ClearIsSelectedByKey();
|
||||
|
||||
hideSubmenuDuringRefreshSearch = false;
|
||||
menus[0].RefreshSearchText();
|
||||
menus[0]?.RefreshSearchText();
|
||||
hideSubmenuDuringRefreshSearch = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -1292,7 +1328,7 @@ namespace SystemTrayMenu.Business
|
|||
rowData,
|
||||
};
|
||||
|
||||
ListView? dgv = menus[0].GetDataGridView();
|
||||
ListView? dgv = menus[0]?.GetDataGridView();
|
||||
if (dgv != null)
|
||||
{
|
||||
foreach (ListViewItemData item in dgv.Items)
|
||||
|
@ -1303,13 +1339,13 @@ namespace SystemTrayMenu.Business
|
|||
|
||||
rowDatas = DirectoryHelpers.SortItems(rowDatas);
|
||||
keyboardInput.ClearIsSelectedByKey();
|
||||
menus[0].AddItemsToMenu(rowDatas);
|
||||
menus[0]?.AddItemsToMenu(rowDatas);
|
||||
|
||||
hideSubmenuDuringRefreshSearch = false;
|
||||
menus[0].RefreshSearchText();
|
||||
menus[0]?.RefreshSearchText();
|
||||
hideSubmenuDuringRefreshSearch = true;
|
||||
|
||||
menus[0].TimerUpdateIconsStart();
|
||||
menus[0]?.TimerUpdateIconsStart();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -31,14 +31,14 @@ namespace SystemTrayMenu.DataClasses
|
|||
/// (Related replace "\x00" see #171.)
|
||||
/// </summary>
|
||||
/// <param name="isFolder">Flag if file or folder.</param>
|
||||
/// <param name="isAddionalItem">Flag if addional item, from other folder than root folder.</param>
|
||||
/// <param name="isAdditionalItem">Flag if additional item, from other folder than root folder.</param>
|
||||
/// <param name="isNetworkRoot">Flag if resolved from network root folder.</param>
|
||||
/// <param name="level">The number of the menu level.</param>
|
||||
/// <param name="path">Path to item.</param>
|
||||
internal RowData(bool isFolder, bool isAddionalItem, bool isNetworkRoot, int level, string path)
|
||||
internal RowData(bool isFolder, bool isAdditionalItem, bool isNetworkRoot, int level, string path)
|
||||
{
|
||||
IsFolder = isFolder;
|
||||
IsAddionalItem = isAddionalItem;
|
||||
IsAdditionalItem = isAdditionalItem;
|
||||
IsNetworkRoot = isNetworkRoot;
|
||||
Level = level;
|
||||
|
||||
|
@ -106,7 +106,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
|
||||
internal bool IsFolder { get; }
|
||||
|
||||
internal bool IsAddionalItem { get; }
|
||||
internal bool IsAdditionalItem { get; }
|
||||
|
||||
internal bool IsNetworkRoot { get; }
|
||||
|
||||
|
@ -182,6 +182,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
if (e != null &&
|
||||
e.RightButton == MouseButtonState.Pressed &&
|
||||
FileInfo != null &&
|
||||
Path != null &&
|
||||
dgv != null &&
|
||||
dgv.Items.Count > RowIndex &&
|
||||
(DateTime.Now - contextMenuClosed).TotalMilliseconds > 200)
|
||||
|
@ -235,7 +236,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
OpenItem(e, ref toCloseByDoubleClick);
|
||||
}
|
||||
|
||||
if (Properties.Settings.Default.OpenDirectoryWithOneClick &&
|
||||
if (Properties.Settings.Default.OpenDirectoryWithOneClick && Path != null &&
|
||||
ContainsMenu && (e == null || e.LeftButton == MouseButtonState.Pressed))
|
||||
{
|
||||
Log.ProcessStart(Path);
|
||||
|
@ -255,7 +256,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
OpenItem(e, ref toCloseByDoubleClick);
|
||||
}
|
||||
|
||||
if (!Properties.Settings.Default.OpenDirectoryWithOneClick &&
|
||||
if (!Properties.Settings.Default.OpenDirectoryWithOneClick && Path != null &&
|
||||
ContainsMenu && (e == null || e.LeftButton == MouseButtonState.Pressed))
|
||||
{
|
||||
Log.ProcessStart(Path);
|
||||
|
@ -268,7 +269,7 @@ namespace SystemTrayMenu.DataClasses
|
|||
|
||||
private void OpenItem(MouseEventArgs e, ref bool toCloseByOpenItem)
|
||||
{
|
||||
if (!ContainsMenu &&
|
||||
if (!ContainsMenu && Path != null && ResolvedPath != null &&
|
||||
(e == null || e.LeftButton == MouseButtonState.Pressed))
|
||||
{
|
||||
ProcessStarted = true;
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
<DockPanel x:Name="searchPanel" DockPanel.Dock="Top" Margin="6,0">
|
||||
<Separator x:Name="panelLine" Height="1" Margin="0,1" DockPanel.Dock="Bottom"/>
|
||||
<Image x:Name="pictureBoxSearch" Width="16" Height="16" Margin="1" DockPanel.Dock="Left" Source="{StaticResource ic_fluent_search_48_regularDrawingImage}"/>
|
||||
<TextBox x:Name="textBoxSearch" BorderBrush="{x:Null}" TextInput="TextBoxSearch_TextInput" Background="{x:Null}" SelectionTextBrush="Red" SelectionBrush="#FFDAFF00" />
|
||||
<TextBox x:Name="textBoxSearch" BorderBrush="{x:Null}" Background="{x:Null}" SelectionTextBrush="Red" SelectionBrush="#FFDAFF00" />
|
||||
</DockPanel>
|
||||
|
||||
<DockPanel x:Name="tableLayoutPanelBottom" DockPanel.Dock="Bottom" Margin="12,4">
|
||||
|
|
|
@ -296,9 +296,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
internal event Action? SearchTextChanging;
|
||||
|
||||
#if TODO // SEARCH
|
||||
internal event EventHandler<bool> SearchTextChanged;
|
||||
#endif
|
||||
internal event Action<Menu, bool>? SearchTextChanged;
|
||||
|
||||
internal event Action? UserDragsMenu;
|
||||
|
||||
|
@ -447,7 +445,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
foreach (RowData rowData in data)
|
||||
{
|
||||
if (!(rowData.IsAddionalItem && Settings.Default.ShowOnlyAsSearchResult))
|
||||
if (!(rowData.IsAdditionalItem && Settings.Default.ShowOnlyAsSearchResult))
|
||||
{
|
||||
if (rowData.ContainsMenu)
|
||||
{
|
||||
|
@ -464,7 +462,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
(rowData.HiddenEntry ? IconReader.AddIconOverlay(rowData.Icon, Properties.Resources.White50Percentage) : rowData.Icon)?.ToImageSource(),
|
||||
rowData.Text ?? "?",
|
||||
rowData,
|
||||
rowData.IsAddionalItem && Settings.Default.ShowOnlyAsSearchResult ? 99 : 0));
|
||||
rowData.IsAdditionalItem && Settings.Default.ShowOnlyAsSearchResult ? 99 : 0));
|
||||
}
|
||||
|
||||
dgv.ItemsSource = items;
|
||||
|
@ -550,26 +548,25 @@ namespace SystemTrayMenu.UserInterface
|
|||
/// <param name="bounds">Screen coordinates where the menu is allowed to be drawn in.</param>
|
||||
/// <param name="menuPredecessor">Predecessor menu (when available).</param>
|
||||
/// <param name="startLocation">Defines where the first menu is drawn (when no predecessor is set).</param>
|
||||
/// <param name="isCustomLocationOutsideOfScreen">isCustomLocationOutsideOfScreen.</param>
|
||||
/// <param name="useCustomLocation">Use CustomLocation as start position.</param>
|
||||
internal void AdjustSizeAndLocation(
|
||||
Rect bounds,
|
||||
Menu? menuPredecessor,
|
||||
StartLocation startLocation,
|
||||
bool isCustomLocationOutsideOfScreen)
|
||||
bool useCustomLocation)
|
||||
{
|
||||
// Update the height and width
|
||||
AdjustDataGridViewHeight(menuPredecessor, bounds.Height);
|
||||
AdjustDataGridViewWidth();
|
||||
|
||||
bool useCustomLocation = Settings.Default.UseCustomLocation || lastLocation.X > 0;
|
||||
bool changeDirectionWhenOutOfBounds = true;
|
||||
|
||||
if (menuPredecessor != null)
|
||||
if (Level > 0)
|
||||
{
|
||||
// Ignore start as we use predecessor
|
||||
// Sub Menu location depends on the location of its predecessor
|
||||
startLocation = StartLocation.Predecessor;
|
||||
}
|
||||
else if (useCustomLocation && !isCustomLocationOutsideOfScreen)
|
||||
else if (useCustomLocation)
|
||||
{
|
||||
// Do not adjust location again because Cursor.Postion changed
|
||||
if (RowDataParent != null)
|
||||
|
@ -607,17 +604,20 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
if (IsLoaded)
|
||||
{
|
||||
AdjustSizeAndLocationInternal();
|
||||
AdjustWindowPositionInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Layout cannot be calculated during loading, postpone this event
|
||||
// TODO: Make sure lampa capture is registered only once
|
||||
Loaded += (_, _) => AdjustSizeAndLocationInternal();
|
||||
Loaded += (_, _) => AdjustWindowPositionInternal();
|
||||
}
|
||||
|
||||
void AdjustSizeAndLocationInternal()
|
||||
void AdjustWindowPositionInternal()
|
||||
{
|
||||
// Make sure we have latest values of own window size
|
||||
UpdateLayout();
|
||||
|
||||
// Calculate X position
|
||||
double x;
|
||||
switch (startLocation)
|
||||
|
@ -715,12 +715,12 @@ namespace SystemTrayMenu.UserInterface
|
|||
{
|
||||
case StartLocation.Predecessor:
|
||||
|
||||
RowData trigger = RowDataParent;
|
||||
RowData? trigger = RowDataParent;
|
||||
ListView dgv = menuPredecessor!.GetDataGridView() !;
|
||||
|
||||
// Set position on same height as the selected row from predecessor
|
||||
y = menuPredecessor.Location.Y;
|
||||
if (dgv.Items.Count > trigger.RowIndex)
|
||||
if (trigger != null && dgv.Items.Count > trigger.RowIndex)
|
||||
{
|
||||
// When item is not found, it might be invalidated due to resizing or moving
|
||||
// After updating the layout the location should be available again.
|
||||
|
@ -1071,9 +1071,9 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
|
||||
SetCounts(foldersCount, filesCount);
|
||||
|
||||
SearchTextChanged.Invoke(this, string.IsNullOrEmpty(userPattern));
|
||||
|
||||
#endif
|
||||
SearchTextChanged?.Invoke(this, string.IsNullOrEmpty(userPattern));
|
||||
#if TODO // SEARCH
|
||||
if (anyIconNotUpdated)
|
||||
{
|
||||
timerUpdateIcons.Start();
|
||||
|
@ -1258,7 +1258,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
/// </summary>
|
||||
internal class ListViewItemData
|
||||
{
|
||||
public ListViewItemData(ImageSource columnIcon, string columnText, RowData rowData, int sortIndex)
|
||||
public ListViewItemData(ImageSource? columnIcon, string columnText, RowData rowData, int sortIndex)
|
||||
{
|
||||
ColumnIcon = columnIcon;
|
||||
ColumnText = columnText;
|
||||
|
@ -1266,7 +1266,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
SortIndex = sortIndex;
|
||||
}
|
||||
|
||||
public ImageSource ColumnIcon { get; set; }
|
||||
public ImageSource? ColumnIcon { get; set; }
|
||||
|
||||
public string ColumnText { get; set; }
|
||||
|
||||
|
@ -1276,10 +1276,5 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
public int SortIndex { get; set; }
|
||||
}
|
||||
|
||||
private void TextBoxSearch_TextInput(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
// TODO WPF
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue