Files
C4IT-F4SD-Client/FasdDesktopUi/Basics/UserControls/DataCanvas/AdjustableParameterSection.xaml.cs
2025-11-11 11:03:42 +01:00

377 lines
15 KiB
C#

using C4IT.FASD.Base;
using C4IT.Logging;
using FasdDesktopUi.Basics.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.UserControls
{
public partial class AdjustableParameterSection : UserControl, IFocusInvoker
{
#region Variables & Properties
private double parameterBorderHeight = 0.0;
public int? ParentIndex { get; private set; }
public UIElement ParentElement { get; private set; }
#region Parameters
public Dictionary<string, cAdjustableParameter> AdjustableParameters
{
get { return (Dictionary<string, cAdjustableParameter>)GetValue(AdjustableParametersProperty); }
set { SetValue(AdjustableParametersProperty, value); }
}
public static readonly DependencyProperty AdjustableParametersProperty =
DependencyProperty.Register("AdjustableParameters", typeof(Dictionary<string, cAdjustableParameter>), typeof(AdjustableParameterSection), new PropertyMetadata(new Dictionary<string, cAdjustableParameter>(), new PropertyChangedCallback(AdjustableParametersChanged)));
private static void AdjustableParametersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is AdjustableParameterSection _me))
return;
_me.UpdateAdjustableParameters();
}
#endregion
public Dictionary<cAdjustableParameter, object> ParameterValues { get; set; } = new Dictionary<cAdjustableParameter, object>();
#endregion
public AdjustableParameterSection()
{
InitializeComponent();
}
private void UpdateIFocusInvokerValues()
{
try
{
if (Parent is UIElement parentElement)
{
ParentElement = parentElement;
if (parentElement is Panel panel)
ParentIndex = panel.Children.IndexOf(this);
}
}
catch (Exception E)
{
LogException(E);
}
}
private void UpdateAdjustableParameters()
{
try
{
ParameterStack.Children.Clear();
ParameterValues.Clear();
ParameterBorder.BeginAnimation(HeightProperty, null);
ParameterBorder.Height = double.NaN;
if (AdjustableParameters is null)
return;
foreach (var parameter in AdjustableParameters)
{
try
{
if (!(ParameterValues.ContainsKey(parameter.Value)))
ParameterValues.Add(parameter.Value, null);
var parameterValue = parameter.Value;
switch (parameterValue)
{
case cAdjustableParameterBoolean booleanParameter:
AddBooleanParameter(parameter.Key, booleanParameter);
break;
case cAdjustableParameterNumerical numericalParameter:
AddNumericalParameter(parameter.Key, numericalParameter);
break;
case cAdjustableParameterDropDown dropDownParameter:
AddDropDownParameter(parameter.Key, dropDownParameter);
break;
default:
break;
}
}
catch (Exception E)
{
LogException(E);
}
}
ParameterBorder.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
parameterBorderHeight = ParameterBorder.DesiredSize.Height;
ParameterBorder.Height = parameterBorderHeight;
UpdateIFocusInvokerValues();
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
}
#region Helper
private void AddBooleanParameter(string parameterKey, cAdjustableParameterBoolean booleanParameter)
{
try
{
DockPanel outerPanel = new DockPanel() { Margin = new Thickness(2.5) };
ParameterValues[booleanParameter] = booleanParameter.Default ? $"-{booleanParameter.ParameterName}" : string.Empty;
CheckBox valueCheckBox = new CheckBox() { IsChecked = booleanParameter.Default };
valueCheckBox.Checked += new RoutedEventHandler((sender, e) => ParameterValues[booleanParameter] = $"-{booleanParameter.ParameterName}");
valueCheckBox.Unchecked += new RoutedEventHandler((sender, e) => ParameterValues[booleanParameter] = string.Empty);
DockPanel.SetDock(valueCheckBox, Dock.Right);
valueCheckBox.SetResourceReference(StyleProperty, "ToggleSwitch");
outerPanel.Children.Add(valueCheckBox);
TextBlock parameterNameTextBlock = new TextBlock() { Text = booleanParameter.Names.GetValue(), Margin = new Thickness(0, 0, 7.5, 0) };
if(!string.IsNullOrEmpty(booleanParameter.Descriptions.GetValue()))
{
parameterNameTextBlock.ToolTip = booleanParameter.Descriptions.GetValue();
}
parameterNameTextBlock.SetResourceReference(ForegroundProperty, "FontColor.DetailsPage.DataHistory.Value");
outerPanel.Children.Add(parameterNameTextBlock);
ParameterStack.Children.Add(outerPanel);
}
catch (Exception E)
{
LogException(E);
}
}
private void AddNumericalParameter(string parameterKey, cAdjustableParameterNumerical numericalParameter)
{
try
{
DockPanel outerPanel = new DockPanel() { Margin = new Thickness(2.5) };
ParameterValues[numericalParameter] = numericalParameter.Default;
TextBox valueTextBox = new TextBox() { Text = numericalParameter.Default.ToString(), Width = 35, TextAlignment = TextAlignment.Center };
valueTextBox.SetResourceReference(ForegroundProperty, "FontColor.DetailsPage.DataHistory.Value");
valueTextBox.SetResourceReference(BackgroundProperty, "BackgroundColor.DetailsPage.DataHistory.TitleColumn");
valueTextBox.SetResourceReference(BorderBrushProperty, "BackgroundColor.DetailsPage.DataHistory.ValueColumn");
valueTextBox.PreviewKeyDown += ((sender, e) =>
{
if (double.TryParse(valueTextBox.Text, out var parsedValue))
ParameterValues[numericalParameter] = parsedValue;
});
valueTextBox.PreviewTextInput += new TextCompositionEventHandler((sender, e) =>
{
var plannedValue = valueTextBox.Text.Insert(valueTextBox.CaretIndex, e.Text);
if (double.TryParse(plannedValue, out var parsedValue))
ParameterValues[numericalParameter] = parsedValue;
else
e.Handled = true;
});
DockPanel.SetDock(valueTextBox, Dock.Right);
outerPanel.Children.Add(valueTextBox);
TextBlock parameterNameTextBlock = new TextBlock() { Text = numericalParameter.Names.GetValue(), Margin = new Thickness(0, 0, 7.5, 0) };
if (!string.IsNullOrEmpty(numericalParameter.Descriptions.GetValue()))
{
parameterNameTextBlock.ToolTip = numericalParameter.Descriptions.GetValue();
}
parameterNameTextBlock.SetResourceReference(ForegroundProperty, "FontColor.DetailsPage.DataHistory.Value");
outerPanel.Children.Add(parameterNameTextBlock);
ParameterStack.Children.Add(outerPanel);
}
catch (Exception E)
{
LogException(E);
}
}
private void AddDropDownParameter(string parameterKey, cAdjustableParameterDropDown dropDownParameter)
{
try
{
DockPanel outerPanel = new DockPanel() { Margin = new Thickness(2.5) };
ParameterValues[dropDownParameter] = dropDownParameter.Default;
ComboBox valueComboBox = new ComboBox() { SelectedItem = dropDownParameter.Default, MinWidth = 125 };
valueComboBox.Style = (Style)FindResource("DarkComboBox");
valueComboBox.DropDownOpened += (sender, e) => cFocusInvoker.InvokeGotFocus(this, e);
valueComboBox.DropDownClosed += (sender, e) => cFocusInvoker.InvokeLostFocus(this, e);
foreach (var dropDownValue in dropDownParameter.DropdownValues)
{
try
{
var tempComboBoxItem = new ComboBoxItem() { Content = dropDownValue.DisplayValues.GetValue(), Tag = dropDownValue.Value };
if (dropDownParameter.DropdownValues?.First() == dropDownValue && dropDownParameter.DropdownValues?.Last() == dropDownValue)
tempComboBoxItem.SetResourceReference(StyleProperty, "ComboBoxSingleItem");
else if (dropDownParameter.DropdownValues?.First() == dropDownValue)
tempComboBoxItem.SetResourceReference(StyleProperty, "ComboBoxFirstItem");
else if (dropDownParameter.DropdownValues?.Last() == dropDownValue)
tempComboBoxItem.SetResourceReference(StyleProperty, "ComboBoxLastItem");
valueComboBox.Items.Add(tempComboBoxItem);
}
catch (Exception E)
{
LogException(E);
}
}
var selectedIndex = -1;
var defaultValue = dropDownParameter.DropdownValues.FirstOrDefault(value => value.Value == dropDownParameter.Default);
if (defaultValue != null)
selectedIndex = dropDownParameter.DropdownValues.IndexOf(defaultValue);
valueComboBox.SelectionChanged += ((sender, e) =>
{
try
{
if (!(sender is ComboBox senderComboBox))
return;
if (!(senderComboBox.SelectedItem is FrameworkElement selectedElement))
return;
ParameterValues[dropDownParameter] = selectedElement.Tag;
}
catch (Exception E)
{
LogException(E);
}
});
valueComboBox.SelectedIndex = selectedIndex;
DockPanel.SetDock(valueComboBox, Dock.Right);
outerPanel.Children.Add(valueComboBox);
TextBlock parameterNameTextBlock = new TextBlock() { VerticalAlignment = VerticalAlignment.Center, Text = dropDownParameter.Names.GetValue(), Margin = new Thickness(0, 0, 7.5, 0) };
if (!string.IsNullOrEmpty(dropDownParameter.Descriptions.GetValue()))
{
parameterNameTextBlock.ToolTip = dropDownParameter.Descriptions.GetValue();
}
parameterNameTextBlock.SetResourceReference(ForegroundProperty, "FontColor.DetailsPage.DataHistory.Value");
outerPanel.Children.Add(parameterNameTextBlock);
ParameterStack.Children.Add(outerPanel);
}
catch (Exception E)
{
LogException(E);
}
}
#endregion
private void ToggleCollapse(bool shouldCollapse)
{
try
{
const double animatinDurationInSeconds = 0.2;
if (shouldCollapse)
ParameterBorder.BeginAnimation(HeightProperty, new DoubleAnimation(0, TimeSpan.FromSeconds(animatinDurationInSeconds)));
else
ParameterBorder.BeginAnimation(HeightProperty, new DoubleAnimation(parameterBorderHeight, TimeSpan.FromSeconds(animatinDurationInSeconds)));
CollapseButton.SelectedMaterialIcon = shouldCollapse ? MaterialIcons.MaterialIconType.ic_add : MaterialIcons.MaterialIconType.ic_remove;
}
catch (Exception E)
{
LogException(E);
}
}
public void ToggleIsActive(bool isActive)
{
try
{
if (isActive)
{
UpdateAdjustableParameters();
foreach (UIElement element in ParameterStack.Children)
{
element.IsEnabled = true;
}
}
else
{
ToggleCollapse(true);
foreach (UIElement element in ParameterStack.Children)
{
element.IsEnabled = false;
}
}
}
catch (Exception E)
{
LogException(E);
}
}
#region CollapseButton_Click
private void CollapseButton_Click()
{
try
{
bool shouldCollapse = ParameterBorder.ActualHeight - ParameterBorder.Padding.Top - ParameterBorder.Padding.Bottom != 0;
ToggleCollapse(shouldCollapse);
}
catch (Exception E)
{
LogException(E);
}
}
private void CollapseButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
CollapseButton_Click();
}
private void CollapseButton_TouchDown(object sender, TouchEventArgs e)
{
CollapseButton_Click();
}
#endregion
}
}