mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-10-03 10:36:30 +13:00
Improve and fix location calculation of sub menus
This commit is contained in:
parent
ada694c611
commit
6b1c63b2dc
2 changed files with 67 additions and 32 deletions
|
@ -391,14 +391,12 @@ namespace SystemTrayMenu.UserInterface
|
||||||
buttonMenuAlwaysOpen.Visibility = Visibility.Collapsed;
|
buttonMenuAlwaysOpen.Visibility = Visibility.Collapsed;
|
||||||
break;
|
break;
|
||||||
case MenuType.Empty:
|
case MenuType.Empty:
|
||||||
// TODO? remove search bar when searching makes no sense (take care of calculating initial position)
|
searchPanel.Visibility = Visibility.Collapsed;
|
||||||
// searchPanel.Visibility = Visibility.Collapsed;
|
|
||||||
labelItems.Content = Translator.GetText("Directory empty");
|
labelItems.Content = Translator.GetText("Directory empty");
|
||||||
buttonMenuAlwaysOpen.Visibility = Visibility.Collapsed;
|
buttonMenuAlwaysOpen.Visibility = Visibility.Collapsed;
|
||||||
break;
|
break;
|
||||||
case MenuType.NoAccess:
|
case MenuType.NoAccess:
|
||||||
// TODO? remove search bar when searching makes no sense (take care of calculating initial position)
|
searchPanel.Visibility = Visibility.Collapsed;
|
||||||
// searchPanel.Visibility = Visibility.Collapsed;
|
|
||||||
labelItems.Content = Translator.GetText("Directory inaccessible");
|
labelItems.Content = Translator.GetText("Directory inaccessible");
|
||||||
buttonMenuAlwaysOpen.Visibility = Visibility.Collapsed;
|
buttonMenuAlwaysOpen.Visibility = Visibility.Collapsed;
|
||||||
break;
|
break;
|
||||||
|
@ -716,40 +714,65 @@ namespace SystemTrayMenu.UserInterface
|
||||||
y = menuPredecessor.Location.Y;
|
y = menuPredecessor.Location.Y;
|
||||||
if (dgv.Items.Count > trigger.RowIndex)
|
if (dgv.Items.Count > trigger.RowIndex)
|
||||||
{
|
{
|
||||||
// TODO: Optimize calculation and fix calculation for items that are listed "beyond" the initial window size
|
|
||||||
|
|
||||||
// When item is not found, it might be invalidated due to resizing or moving
|
// When item is not found, it might be invalidated due to resizing or moving
|
||||||
// After updating the layout the location should be available again.
|
// After updating the layout the location should be available again.
|
||||||
|
// It also makes sure all height and location information is up to date
|
||||||
menuPredecessor.UpdateLayout();
|
menuPredecessor.UpdateLayout();
|
||||||
|
|
||||||
ListViewItem? lvi = dgv.FindVisualChildOfType<ListViewItem>(trigger.RowIndex);
|
#if TODO // SCROLL: bounds within list using scrollviewer index while calculating size once
|
||||||
if (lvi != null)
|
// When scrolled, we have to reduce the index number as we calculate based on visual tree
|
||||||
|
int index = trigger.RowIndex;
|
||||||
|
ScrollViewer? scrollViewer = (VisualTreeHelper.GetChild(dgv, 0) as Decorator)?.Child as ScrollViewer;
|
||||||
|
if (scrollViewer != null)
|
||||||
{
|
{
|
||||||
double offset;
|
// Show mid height or at bottom
|
||||||
|
if (scrollViewer.VerticalOffset <= index)
|
||||||
ScrollViewer? scrollViewer = (VisualTreeHelper.GetChild(dgv, 0) as Decorator)?.Child as ScrollViewer;
|
|
||||||
if (scrollViewer != null)
|
|
||||||
{
|
{
|
||||||
if (scrollViewer.VerticalOffset > 0)
|
if ((int)(scrollViewer.VerticalOffset + scrollViewer.ViewportHeight) < index)
|
||||||
{
|
{
|
||||||
offset = 0D;
|
// Outside of visible list while index is even further below: place at bottom (last entry)
|
||||||
for (int i = 0; i < scrollViewer.VerticalOffset; i++)
|
index = (int)scrollViewer.ViewportHeight;
|
||||||
{
|
}
|
||||||
ListViewItem? item = dgv.FindVisualChildOfType<ListViewItem>(i);
|
else
|
||||||
if (item != null)
|
{
|
||||||
{
|
// Remove skipped entries from index when scrolled down
|
||||||
offset += item.ActualHeight;
|
index -= (int)scrollViewer.VerticalOffset;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
y -= (int)offset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Outside of visible list while index is even further above: place at top (first entry)
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
y += menuPredecessor.GetRelativeChildPositionTo(dgv).Y;
|
y += menuPredecessor.GetRelativeChildPositionTo(dgv.FindVisualChildOfType<ListViewItem>(index)).Y;
|
||||||
|
#else // TODO: SCROLL: Sum up offsets by calculating final offset based on each items' height
|
||||||
|
// When scrolled, we have to reduce the index number as we calculate based on visual tree
|
||||||
|
int startIndex = 0;
|
||||||
|
double offset = 0D;
|
||||||
|
ScrollViewer? scrollViewer = (VisualTreeHelper.GetChild(dgv, 0) as Decorator)?.Child as ScrollViewer;
|
||||||
|
if (scrollViewer != null)
|
||||||
|
{
|
||||||
|
startIndex = (int)scrollViewer.VerticalOffset;
|
||||||
|
if (trigger.RowIndex < startIndex)
|
||||||
|
{
|
||||||
|
// calculate position above starting point
|
||||||
|
for (int i = trigger.RowIndex; i < startIndex; i++)
|
||||||
|
{
|
||||||
|
ListViewItem? item = dgv.FindVisualChildOfType<ListViewItem>(i);
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
offset -= item.ActualHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
offset = 0D;
|
if (startIndex < trigger.RowIndex)
|
||||||
for (int i = 0; i < trigger.RowIndex; i++)
|
{
|
||||||
|
// calculate position below starting point
|
||||||
|
for (int i = startIndex; i < trigger.RowIndex; i++)
|
||||||
{
|
{
|
||||||
ListViewItem? item = dgv.FindVisualChildOfType<ListViewItem>(i);
|
ListViewItem? item = dgv.FindVisualChildOfType<ListViewItem>(i);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
|
@ -757,22 +780,34 @@ namespace SystemTrayMenu.UserInterface
|
||||||
offset += item.ActualHeight;
|
offset += item.ActualHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
y += (int)offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
y += menuPredecessor.GetRelativeChildPositionTo(dgv).Y + (int)offset;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TODO // SCROLL: Do we want this - Move upwards when there is no content? (Feels odd to me, topeterk)
|
||||||
|
// Maybe always move it up only the height of labelTitle?
|
||||||
// when warning is shown, the title should appear at same height as selected row
|
// when warning is shown, the title should appear at same height as selected row
|
||||||
if (searchPanel.Visibility != Visibility.Visible)
|
if (searchPanel.Visibility != Visibility.Visible)
|
||||||
{
|
{
|
||||||
y += labelTitle.ActualHeight;
|
// TODO: This seems to fail in version 1 as search bar is always visible, so no adjustement is made
|
||||||
|
// And even when adjustment is made, it moves the menu even further down rather up?
|
||||||
|
y -= this.GetRelativeChildPositionTo(labelItems).Y;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Move vertically when out of bounds
|
// Move vertically when out of bounds
|
||||||
if (bounds.Y + bounds.Height < y + Height)
|
if (bounds.Y + bounds.Height < y + Height)
|
||||||
{
|
{
|
||||||
y = bounds.Y + bounds.Height - Height;
|
y = bounds.Y + bounds.Height - Height;
|
||||||
}
|
}
|
||||||
|
#if !TODO // SCROLL: Upper screen bounds
|
||||||
|
else if (y < bounds.Y)
|
||||||
|
{
|
||||||
|
y = bounds.Y;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case StartLocation.TopRight:
|
case StartLocation.TopRight:
|
||||||
|
|
|
@ -81,9 +81,9 @@ namespace SystemTrayMenu.Utilities
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Point GetRelativeChildPositionTo(this Visual parent, Visual child)
|
internal static Point GetRelativeChildPositionTo(this Visual parent, Visual? child)
|
||||||
{
|
{
|
||||||
return child.TransformToAncestor(parent).Transform(new(0, 0));
|
return child == null ? new() : child.TransformToAncestor(parent).Transform(new ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Find and remove any unnecessary convertions
|
// TODO: Find and remove any unnecessary convertions
|
||||||
|
|
Loading…
Reference in a new issue