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 AdjustableParameters { get { return (Dictionary)GetValue(AdjustableParametersProperty); } set { SetValue(AdjustableParametersProperty, value); } } public static readonly DependencyProperty AdjustableParametersProperty = DependencyProperty.Register("AdjustableParameters", typeof(Dictionary), typeof(AdjustableParameterSection), new PropertyMetadata(new Dictionary(), new PropertyChangedCallback(AdjustableParametersChanged))); private static void AdjustableParametersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(d is AdjustableParameterSection _me)) return; _me.UpdateAdjustableParameters(); } #endregion public Dictionary ParameterValues { get; set; } = new Dictionary(); #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 } }