Improve window size and position calculations

Fix several warnings
This commit is contained in:
Peter Kirmeier 2023-04-16 20:17:24 +02:00
parent b12d4ad656
commit c9ce4d1d21
5 changed files with 189 additions and 157 deletions

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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;

View file

@ -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">

View file

@ -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
}
}
}