using F4SD_AdaptableIcon.Enums; using FasdDesktopUi.Basics.Enums; using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics.UiActions; using FasdDesktopUi.Basics.UserControls; using FasdDesktopUi.Pages.DetailsPage.Models; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using static C4IT.Logging.cLogManager; namespace FasdDesktopUi.Pages.DetailsPage.UserControls { public partial class DetailsPageWidget : UserControl { #region Properties #region WidgetGeometry DependencyProperty private static bool DidGeometryDataChange(DependencyPropertyChangedEventArgs e) { bool didGeometryChange = false; if (e.OldValue != null && e.NewValue != null) { var oldGeometry = e.OldValue as DetailsPageWidgetGeometryModel; var newGeometry = e.NewValue as DetailsPageWidgetGeometryModel; didGeometryChange = newGeometry.WidgetTitleCount != oldGeometry.WidgetTitleCount || didGeometryChange; didGeometryChange = newGeometry.WidgetDetailCount != oldGeometry.WidgetDetailCount || didGeometryChange; } else { didGeometryChange = true; } return didGeometryChange; } private static void GeometryChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (DidGeometryDataChange(e) is false) return; var _me = d as DetailsPageWidget; _me.ClearControls(); _me.InitializeWidgetGeometry(); } public static readonly DependencyProperty WidgetGeometryProperty = DependencyProperty.Register("WidgetGeometry", typeof(DetailsPageWidgetGeometryModel), typeof(DetailsPageWidget), new PropertyMetadata(new DetailsPageWidgetGeometryModel(), new PropertyChangedCallback(GeometryChangedCallback))); public DetailsPageWidgetGeometryModel WidgetGeometry { get { return (DetailsPageWidgetGeometryModel)GetValue(WidgetGeometryProperty); } set { SetValue(WidgetGeometryProperty, value); } } #endregion #region WidgetData DependencyProperty private static void RefreshDataCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is DetailsPageWidget _me) { _me.UpdateWidgetControls(); _me.RefreshData(); } } public static readonly DependencyProperty WidgetDataProperty = DependencyProperty.Register("WidgetData", typeof(List), typeof(DetailsPageWidget), new PropertyMetadata(new List(), new PropertyChangedCallback(RefreshDataCallback))); public List WidgetData { get { return (List)GetValue(WidgetDataProperty); } set { SetValue(WidgetDataProperty, value); } } #endregion #region WidgetHeight DependencyProperty public static readonly DependencyProperty WidgetHeightProperty = DependencyProperty.Register("WidgetHeight", typeof(double), typeof(DetailsPageWidget), new PropertyMetadata(50.0, new PropertyChangedCallback(RefreshWidgetHeightCallback))); public double WidgetHeight { get { return (double)GetValue(WidgetHeightProperty); } set { SetValue(WidgetHeightProperty, value); } } #endregion #endregion public DetailsPageWidget() { InitializeComponent(); } #region SetUpControls #region Control Lists private readonly List TitleControls = new List(); private readonly List TitleFunctionMarkerControls = new List(); private readonly List ValueControls = new List(); private readonly List ValueFunctionMarkerControls = new List(); private readonly List EditControls = new List(); #endregion #region Clear Controls and ControlLists private void ClearControls() { TitleControls.Clear(); TitleFunctionMarkerControls.Clear(); ValueControls.Clear(); ValueFunctionMarkerControls.Clear(); EditControls.Clear(); WidgetGrid.RowDefinitions.Clear(); } #endregion #region SetUp Functions private void InitializeWidgetGeometry() { try { SetUpTitleRows(WidgetGeometry.WidgetTitleCount); SetUpValueRows(WidgetGeometry.WidgetDetailCount); } catch (Exception E) { LogException(E); } } private void SetUpTitleRows(int rowsToAdd) { try { if (TitleControls.Count == 0) WidgetGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); for (int i = 0; i < rowsToAdd; i++) { WidgetGrid.RowDefinitions.Insert(TitleControls.Count, new RowDefinition { Height = GridLength.Auto }); StackPanel titleStackPanel = new StackPanel() { Orientation = Orientation.Horizontal }; TitleFunctionMarkerControls.Add(FunctionMarker.SetUpFunctionMarker(titleStackPanel, new FunctionMarker.FunctionMarkerClick(WidgetDetailsTitleFunctionMarker_Click))); TextBlock title = new TextBlock() { Style = widgetTitleStyle }; title.Margin = new Thickness(0, 0, 0, 0); titleStackPanel.Children.Add(title); TitleControls.Add(title); Grid.SetRow(titleStackPanel, TitleControls.Count - 1); Grid.SetColumn(titleStackPanel, 0); WidgetGrid.Children.Add(titleStackPanel); } } catch (Exception E) { LogException(E); } } private void SetUpValueRows(int rowsToAdd) { try { for (int i = 0; i < rowsToAdd; i++) { StackPanel valueDockPanel = new StackPanel() { Orientation = Orientation.Horizontal }; var valueFunctionMarker = FunctionMarker.SetUpFunctionMarker(valueDockPanel, new FunctionMarker.FunctionMarkerClick(WidgetDetailsValueFunctionMarker_Click)); ValueFunctionMarkerControls.Add(valueFunctionMarker); valueFunctionMarker.Margin = new Thickness(-8, 0, -15, 0); TextBlock valueTextBlock = new TextBlock() { Style = widgetValueStyle }; ValueControls.Add(valueTextBlock); valueDockPanel.Children.Add(valueTextBlock); Grid.SetRow(valueDockPanel, ValueControls.Count - 1); Grid.SetColumn(valueDockPanel, 1); WidgetGrid.Children.Add(valueDockPanel); EditWidgetValueControl editControl = new EditWidgetValueControl() { Visibility = Visibility.Collapsed, Margin = new Thickness(10, 0, 10, 0), ParentElement = WidgetGrid }; var maxWidthValue = FindResource("DetailsPage.Widget.Value.MaxWidth"); if (maxWidthValue != null && maxWidthValue is double maxWidth) editControl.MaxWidth = maxWidth - 7.5 - 7.5; EditControls.Add(editControl); Grid.SetRow(editControl, EditControls.Count - 1); Grid.SetColumn(editControl, 1); WidgetGrid.Children.Add(editControl); } } catch (Exception E) { LogException(E); } } #endregion #region Update Controls Functions private void UpdateWidgetControls() { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { if (WidgetData == null) return; UpdateWidgetTitleControls(); UpdateWidgetValueControls(); UpdateEditControls(); } catch (Exception E) { LogException(E); } finally { LogMethodEnd(CM); } } private void UpdateWidgetTitleControls() { try { if (TitleControls.Count < WidgetData.Count) { SetUpTitleRows(WidgetData.Count - TitleControls.Count); } foreach (var titleControl in TitleControls) { if (titleControl.Parent is FrameworkElement titleControlParent) { titleControlParent.Margin = new Thickness(0, 0, 10, 0); } } if (TitleControls.First().Parent is FrameworkElement firstTitleControlParent) { firstTitleControlParent.Margin = new Thickness(0, 15, 10, 0); } } catch (Exception E) { LogException(E); } } private void UpdateWidgetValueControls() { try { if (ValueControls.Count < WidgetData.Count) { SetUpValueRows(WidgetData.Count - ValueControls.Count); } if (ValueControls.First().Parent is FrameworkElement firstControlParent) { firstControlParent.Margin = new Thickness(0, 15, 10, 0); } } catch (Exception E) { LogException(E); } } private void UpdateEditControls() { try { for (int i = 0; i < EditControls.Count; i++) { var currentEditControl = EditControls[i]; if (WidgetData.Count <= i) continue; if (i == 0) currentEditControl.Margin = new Thickness(10, 15, 10, 0); else currentEditControl.Margin = new Thickness(10, 0, 10, 0); var currentWidgetData = WidgetData[i]; currentEditControl.Visibility = Visibility.Collapsed; if (currentWidgetData.EditValueInformation is null) continue; currentEditControl.EditableValueInformation = currentWidgetData.EditValueInformation; } } catch (Exception E) { LogException(E); } } #endregion #endregion #region Refresh Data private delegate void RefreshDelegate(); private void RefreshData() { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { if (WidgetData == null) return; RefreshWidgetTitles(); RefreshWidgetTitleFunctionMarkers(); RefreshWidgetValues(); RefreshWidgetValueFunctionMarkers(); } catch (Exception E) { LogException(E); } finally { LogMethodEnd(CM); } } private void RefreshWidgetTitles() { try { var widgetTitleEnumerator = WidgetData.GetEnumerator(); for (int i = 0; i < TitleControls.Count; i++) { if (widgetTitleEnumerator.MoveNext()) { var Data = widgetTitleEnumerator.Current; if (TitleControls[i] is TextBlock titleEntry) { titleEntry.Text = Data.Title; titleEntry.Visibility = Visibility.Visible; } } else { if (TitleControls[i] is TextBlock titleEntry) { titleEntry.Text = null; titleEntry.Visibility = Visibility.Collapsed; } } } } catch (Exception E) { LogException(E); } } private void RefreshWidgetTitleFunctionMarkers() { try { var titleFunctionMarkerEnumerator = WidgetData.GetEnumerator(); for (int i = 0; i < TitleFunctionMarkerControls.Count; i++) { if (titleFunctionMarkerEnumerator.MoveNext()) { var Data = titleFunctionMarkerEnumerator.Current; var functionMarkerEntry = TitleFunctionMarkerControls[i]; if (Data.UiActionTitle != null && Data.UiActionTitle.DisplayType == enumActionDisplayType.enabled) { functionMarkerEntry.Tag = Data; var tempToolTip = Data.UiActionTitle.Name; if (!string.IsNullOrEmpty(Data.UiActionTitle.Description)) tempToolTip += ": \n" + Data.UiActionTitle.Description; functionMarkerEntry.ToolTip = tempToolTip; functionMarkerEntry.Visibility = Visibility.Visible; if (Data.UiActionTitle is cShowDetailedDataAction) functionMarkerEntry.SelectedIcon = enumInternIcons.misc_dot; else if (Data.UiActionTitle is cUiQuickAction || Data.UiActionTitle is cSubMenuAction) functionMarkerEntry.SelectedIcon = enumInternIcons.misc_functionBolt; } else { functionMarkerEntry.Tag = null; functionMarkerEntry.ToolTip = null; functionMarkerEntry.Visibility = Visibility.Hidden; } } else { var functionMarkerEntry = TitleFunctionMarkerControls[i]; functionMarkerEntry.Tag = null; functionMarkerEntry.ToolTip = null; functionMarkerEntry.Visibility = Visibility.Collapsed; } } } catch (Exception E) { LogException(E); } } private void RefreshWidgetValueFunctionMarkers() { try { var valueFunctionMarkerEnumerator = WidgetData.GetEnumerator(); for (int i = 0; i < ValueFunctionMarkerControls.Count; i++) { if (valueFunctionMarkerEnumerator.MoveNext()) { var Data = valueFunctionMarkerEnumerator.Current; var functionMarkerEntry = ValueFunctionMarkerControls[i]; if (Data.UiActionValue != null && Data.UiActionValue.DisplayType == enumActionDisplayType.enabled && !string.IsNullOrEmpty(Data.Value)) { functionMarkerEntry.Visibility = Visibility.Visible; functionMarkerEntry.Tag = Data; var tempToolTip = Data.UiActionValue.Name; if (!string.IsNullOrEmpty(Data.UiActionValue.Description)) tempToolTip += ": \n" + Data.UiActionValue.Description; functionMarkerEntry.ToolTip = tempToolTip; } else { functionMarkerEntry.Tag = null; functionMarkerEntry.ToolTip = null; functionMarkerEntry.Visibility = Visibility.Hidden; } } else { var functionMarkerEntry = ValueFunctionMarkerControls[i]; functionMarkerEntry.Tag = null; functionMarkerEntry.ToolTip = null; functionMarkerEntry.Visibility = Visibility.Collapsed; } } } catch (Exception E) { LogException(E); } } private void RefreshWidgetValues() { try { var widgetDataEnumerator = WidgetData.GetEnumerator(); for (int i = 0; i < ValueControls.Count; i++) { if (widgetDataEnumerator.MoveNext()) { var Data = widgetDataEnumerator.Current; if (ValueControls[i] is TextBlock valueEntry) { valueEntry.Text = Data.IsLoading ? "..." : Data.Value; valueEntry.Visibility = Visibility.Visible; valueEntry.IsHitTestVisible = !string.IsNullOrWhiteSpace(Data.Value); switch (Data.HighlightIn) { case enumHighlightColor.none: valueEntry.ClearValue(ForegroundProperty); break; case enumHighlightColor.blue: valueEntry.Foreground = (SolidColorBrush)FindResource("Color.Blue"); break; case enumHighlightColor.green: valueEntry.Foreground = (SolidColorBrush)FindResource("Color.Green"); break; case enumHighlightColor.orange: valueEntry.Foreground = (SolidColorBrush)FindResource("Color.Orange"); break; case enumHighlightColor.red: valueEntry.Foreground = (SolidColorBrush)FindResource("Color.Red"); break; default: valueEntry.ClearValue(ForegroundProperty); break; } } } else { if (ValueControls[i] is TextBlock valueEntry) { valueEntry.Text = null; valueEntry.Visibility = Visibility.Collapsed; valueEntry.Foreground = null; } } } } catch (Exception E) { LogException(E); } } #endregion #region Refresh Widget Height static void RefreshWidgetHeightCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is DetailsPageWidget _me) _me.WidgetHeight = (double)e.NewValue; } #endregion #region Style Definitions private Style widgetTitleStyle; private Style widgetValueStyle; private void SetStyles() { widgetTitleStyle = (Style)FindResource("DetailsPage.Widget.Title"); widgetValueStyle = (Style)FindResource("DetailsPage.Widget.Value"); } #endregion #region Event Methods #region UserControl private void UserControl_Initialized(object sender, EventArgs e) { SetStyles(); } #endregion #region FunctionMarker private void WidgetDetailsTitleFunctionMarker_Click(object sender) { if (!(sender is FrameworkElement FE)) return; if (!(FE.Tag is cWidgetValueModel widgetData)) return; if (widgetData.UiActionTitle == null) return; cUiActionBase.RaiseEvent(widgetData.UiActionTitle, this, this); } private void WidgetDetailsValueFunctionMarker_Click(object sender) { if (!(sender is FrameworkElement FE)) return; if (!(FE.Tag is cWidgetValueModel widgetData)) return; if (widgetData.UiActionValue == null) return; cUiActionBase.RaiseEvent(widgetData.UiActionValue, this, this); } #endregion #endregion public void SetEditMode(bool isActive) { try { if (WidgetData is null) return; for (int i = 0; i < WidgetData.Count; i++) { var currentWidgetData = WidgetData[i]; if (currentWidgetData.EditValueInformation is null) continue; if (EditControls.Count > i) EditControls[i].Visibility = isActive ? Visibility.Visible : Visibility.Collapsed; if (ValueControls.Count > i) ValueControls[i].Visibility = isActive ? Visibility.Collapsed : Visibility.Visible; } } catch (Exception E) { LogException(E); } } } }