Files
2025-11-11 11:03:42 +01:00

231 lines
7.8 KiB
C#

using FasdDesktopUi.Basics.CustomEvents;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UiActions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.UserControls
{
public partial class CustomMenu : UserControl
{
#region Properties
#region MenuDataList DependencyPoperty
private static void MenuDataListChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is CustomMenu _me))
return;
_me.ClearControl();
_me.AddCustomMenuItems();
_me.UpdateCornerRadius();
if (_me.IsKeyboardNavigatable)
_me.IndexOfSelectedMenuItem = 0;
}
public static readonly DependencyProperty MenuDataListProperty =
DependencyProperty.Register("MenuDataList", typeof(List<cMenuDataBase>), typeof(CustomMenu), new PropertyMetadata(new List<cMenuDataBase>(), new PropertyChangedCallback(MenuDataListChangedCallback)));
public List<cMenuDataBase> MenuDataList
{
get { return (List<cMenuDataBase>)GetValue(MenuDataListProperty); }
set { SetValue(MenuDataListProperty, value); }
}
#endregion
#region IndexOfSelectedMenuItem DependencyProperty
private static void IndexOfSelectedMenuItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is CustomMenu _me && e.NewValue is int index))
return;
if (!_me.IsKeyboardNavigatable)
return;
foreach (CustomMenuItem menuItem in _me.MainStackPanel.Children)
{
menuItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory");
if (index < 0 || index > _me.MainStackPanel.Children.Count)
continue;
if (_me.MainStackPanel.Children.IndexOf(menuItem) == index)
menuItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory.Hover");
}
}
public static readonly DependencyProperty IndexOfSelectedMenuItemProperty =
DependencyProperty.Register("IndexOfSelectedMenuItem", typeof(int), typeof(CustomMenu), new PropertyMetadata(-1, new PropertyChangedCallback(IndexOfSelectedMenuItemChanged)));
public int IndexOfSelectedMenuItem
{
get { return (int)GetValue(IndexOfSelectedMenuItemProperty); }
set { SetValue(IndexOfSelectedMenuItemProperty, value); }
}
#endregion
#region IsKeyboardNavigatable
public static readonly DependencyProperty IsKeyboardNavigatableProperty =
DependencyProperty.Register("IsKeyboardNavigatable", typeof(bool), typeof(CustomMenuItem), new PropertyMetadata(false));
public bool IsKeyboardNavigatable
{
get { return (bool)GetValue(IsKeyboardNavigatableProperty); }
set { SetValue(IsKeyboardNavigatableProperty, value); }
}
#endregion
#endregion
public CustomMenu()
{
InitializeComponent();
}
public CustomMenu(bool drawWithBorder = false)
{
InitializeComponent();
if (drawWithBorder)
DrawControlWithBorder();
}
private void DrawControlWithBorder()
{
var tempBorder = new Border() { Padding = new Thickness(10), CornerRadius = new CornerRadius(10) };
tempBorder.SetResourceReference(BackgroundProperty, "BackgroundColor.Menu.Categories");
var tempControl = MainScrollViewer;
MainGrid.Children.Remove(tempControl);
MainGrid.Children.Add(tempBorder);
tempBorder.Child = tempControl;
}
private void ClearControl()
{
MainStackPanel.Children.Clear();
IndexOfSelectedMenuItem = -1;
}
private void AddCustomMenuItems()
{
if (MenuDataList == null)
return;
foreach (var menuItemData in MenuDataList)
{
var menuItem = new CustomMenuItem(false) { MenuData = menuItemData };
menuItem.MouseEnter += MenuItem_MouseEnter;
MainStackPanel.Children.Add(menuItem);
}
}
private void UpdateCornerRadius()
{
const double cornerRadius = 10;
if (MainStackPanel.Children.Count <= 0)
return;
if (MainStackPanel.Children[0] is CustomMenuItem menuItemFirst)
{
var tempCornerRadius = menuItemFirst.MenuItemBorder.CornerRadius;
tempCornerRadius.TopLeft = cornerRadius;
tempCornerRadius.TopRight = cornerRadius;
menuItemFirst.MenuItemBorder.CornerRadius = tempCornerRadius;
}
if (MainStackPanel.Children[MainStackPanel.Children.Count - 1] is CustomMenuItem menuItemLast)
{
var tempCornerRadiusLast = menuItemLast.MenuItemBorder.CornerRadius;
tempCornerRadiusLast.BottomLeft = cornerRadius;
tempCornerRadiusLast.BottomRight = cornerRadius;
menuItemLast.MenuItemBorder.CornerRadius = tempCornerRadiusLast;
}
}
private void MenuItem_MouseEnter(object sender, MouseEventArgs e)
{
if (!(sender is CustomMenuItem menuItem))
return;
CustomEventManager.RaiseIndexChangedEvent(this, -1, MainStackPanel.Children.IndexOf(menuItem));
}
internal void ShowDetailHeading(bool showDetailHeadings)
{
try
{
foreach (var resultItem in MainStackPanel.Children.OfType<CustomMenuItem>())
{
resultItem.ShowDetailHeadings(showDetailHeadings);
}
}
catch (Exception ex)
{
LogException(ex);
}
}
internal void HightlightItemAt(int index)
{
try
{
foreach (CustomMenuItem resultItem in MainStackPanel.Children)
{
if (MainStackPanel.Children.IndexOf(resultItem) == index)
{
resultItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory.Hover");
CustomEventManager.RaiseMenuDataChangedEvent(this, resultItem.MenuData);
}
else
resultItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory");
}
}
catch (Exception ex)
{
LogException(ex);
}
}
internal void SelectItemAt(int index)
{
try
{
if (MenuDataList is null)
return;
if (index < 0)
return;
if (MenuDataList.Count == 0 || MenuDataList.Count <= index)
return;
cUiActionBase uiAction = MenuDataList[index].UiAction;
if (uiAction is null || uiAction.DisplayType == Enums.enumActionDisplayType.disabled)
return;
cUiActionBase.RaiseEvent(uiAction, this, this);
}
catch (Exception E)
{
LogException(E);
}
}
}
}