using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using FasdDesktopUi.Pages.DetailsPage.Models; using C4IT.Logging; using static C4IT.Logging.cLogManager; using FasdDesktopUi.Basics.Models; using FasdDesktopUi.Basics; namespace FasdDesktopUi.Pages.DetailsPage.UserControls { public partial class DetailsPageWidgetCollection : UserControl { #region Properties private bool isNewCase = true; #region WidgetGeometryList DependencyProperty private static bool DidGeometryDataChanged(DependencyPropertyChangedEventArgs e) { bool didGeometryChange = false; try { if (e.NewValue != null && e.OldValue != null) { var oldValueEnumerator = (e.OldValue as List).GetEnumerator(); var newValues = e.NewValue as List; foreach (var value in newValues) { if (oldValueEnumerator.MoveNext()) { didGeometryChange = value.WidgetTitleCount != oldValueEnumerator.Current.WidgetTitleCount || didGeometryChange; didGeometryChange = value.WidgetDetailCount != oldValueEnumerator.Current.WidgetDetailCount || didGeometryChange; } else { didGeometryChange = true; } } } else { didGeometryChange = true; } } catch (Exception E) { LogException(E); } return didGeometryChange; } private static void GeometryChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (DidGeometryDataChanged(e) is false) return; var _me = d as DetailsPageWidgetCollection; _me.InitializeCollectionGeometry(); } public static readonly DependencyProperty WidgetGeometryListProperty = DependencyProperty.Register("WidgetGeometryList", typeof(List), typeof(DetailsPageWidgetCollection), new PropertyMetadata(new List(), new PropertyChangedCallback(GeometryChangedCallback))); public List WidgetGeometryList { get { return (List)GetValue(WidgetGeometryListProperty); } set { SetValue(WidgetGeometryListProperty, value); } } #endregion #region WidgetDataList DependencyProperty static void RefreshDataCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is DetailsPageWidgetCollection _me) { _me.UpdateWidgetBar(); _me.RefreshData(); } } public static readonly DependencyProperty WidgetDataListProperty = DependencyProperty.Register("WidgetDataList", typeof(List>), typeof(DetailsPageWidgetCollection), new PropertyMetadata(new List>(), new PropertyChangedCallback(RefreshDataCallback))); public List> WidgetDataList { get { return (List>)GetValue(WidgetDataListProperty); } set { SetValue(WidgetDataListProperty, value); } } #endregion #endregion public DetailsPageWidgetCollection() { InitializeComponent(); } protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); cSupportCaseDataProvider.CaseChanged += (sender, args) => isNewCase = true; } #region SetUp Controls #region Control Lists private readonly List WidgetControls = new List(); #endregion #region SetUpFunctions private void InitializeCollectionGeometry() { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { if (DesignerProperties.GetIsInDesignMode(this) || WidgetGeometryList == null) return; WidgetControls.Clear(); WidgetSectionStackPanel.Children.RemoveRange(0, WidgetSectionStackPanel.Children.Count - 1); for (int i = 0; i < WidgetGeometryList.Count; i++) { Border widgetBorder = new Border() { Background = Brushes.Transparent, AllowDrop = true, Padding = new Thickness(0, 0, 25, 0), Tag = "WidgetDataBorder" }; DetailsPageWidget widgetToCreate = new DetailsPageWidget() { WidgetGeometry = WidgetGeometryList[i] }; widgetBorder.Child = widgetToCreate; WidgetSectionStackPanel.Children.Add(widgetBorder); WidgetControls.Add(widgetToCreate); } } catch (Exception E) { LogException(E); } finally { LogMethodEnd(CM); } } #endregion #endregion #region Update Controls Function private void UpdateWidgetBar() { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { if (WidgetDataList == null) return; if (WidgetDataList.Count > WidgetControls.Count) { int missingWidgetData = WidgetDataList.Count - WidgetControls.Count; LogEntry($"WidgetCollection - {missingWidgetData} widgets were missing and had to be added."); //todo: remove for (int i = 0; i < missingWidgetData; i++) { Border widgetBorder = new Border() { Background = Brushes.Transparent, AllowDrop = true, Padding = new Thickness(0, 0, 25, 0), Tag = "WidgetDataBorder" }; DetailsPageWidget widgetToCreate = new DetailsPageWidget(); widgetBorder.Child = widgetToCreate; WidgetSectionStackPanel.Children.Add(widgetBorder); WidgetControls.Add(widgetToCreate); } } } catch (Exception E) { LogException(E); } finally { LogMethodEnd(CM); } } #endregion #region Refresh Data private void RefreshData() { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { if (WidgetDataList == null) return; var WidgetDataEnumerator = WidgetDataList.GetEnumerator(); foreach (var widgetControl in WidgetControls) { if (WidgetDataEnumerator.MoveNext()) { var widgetData = WidgetDataEnumerator.Current; widgetControl.WidgetHeight = GetWidgetHeight(); widgetControl.Visibility = widgetData?.Count > 0 ? Visibility.Visible : Visibility.Collapsed; widgetControl.WidgetData = widgetData; } else { widgetControl.WidgetData = null; widgetControl.Visibility = Visibility.Collapsed; } } } catch (Exception E) { LogException(E); } finally { LogMethodEnd(CM); } } #endregion #region Update Data public void UpdateWidgetData(List> widgetData) { try { if (WidgetDataList is null || WidgetDataList.Count == 0) return; var widgetDataEnumerator = WidgetDataList.GetEnumerator(); for (int i = 0; i < widgetData.Count; i++) { var widgetCategory = widgetData[i]; widgetDataEnumerator.MoveNext(); var currentHistoryData = widgetDataEnumerator.Current; var didWidgetCategoryChange = isNewCase || DidWidgetCategoryChange(currentHistoryData, widgetCategory); LogEntry($"WidgetCollection - WidgetData for Widget {i} did {(didWidgetCategoryChange ? "" : "NOT")} change."); //todo: remove if (didWidgetCategoryChange && WidgetControls[i] != null) WidgetControls[i].WidgetData = widgetCategory; } WidgetDataList = widgetData; isNewCase = false; } catch (Exception E) { LogException(E); } } private bool DidWidgetCategoryChange(List oldValue, List newValue) { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { if (oldValue is null || newValue is null) return true; if (oldValue.Count != newValue.Count) return true; var newValueRowEnumeator = newValue.GetEnumerator(); foreach (var oldValueRow in oldValue) { if (!newValueRowEnumeator.MoveNext()) continue; var currentNewValueRow = newValueRowEnumeator.Current; if (oldValueRow?.Value != currentNewValueRow?.Value) return true; } } catch (Exception E) { LogException(E); } finally { LogMethodEnd(CM); } return false; } #endregion #region Style Definitions private Style widgetTitleStyle; private void SetStyles() { widgetTitleStyle = (Style)FindResource("DetailsPage.Widget.Title"); } private static Size MeasureStringSize(string stringToMeasure, Control controlOfText) { var formattedText = new FormattedText( stringToMeasure, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(controlOfText.FontFamily, controlOfText.FontStyle, controlOfText.FontWeight, controlOfText.FontStretch), controlOfText.FontSize, Brushes.Black, new NumberSubstitution(), 1); return new Size(formattedText.Width, formattedText.Height); } private double GetWidgetHeight() { double widgetHeight = 150; foreach (var widgetData in WidgetDataList) { double tempWidgetHeight = 0; foreach (var widget in widgetData) { if (widget.Title == null) continue; tempWidgetHeight += MeasureStringSize(widget.Title, new Control { Style = widgetTitleStyle }).Height + 14; // 14 = FunctionMarkerBorderHeight - FontSize } tempWidgetHeight += 4; if (tempWidgetHeight > widgetHeight) widgetHeight = tempWidgetHeight; } return widgetHeight; } #endregion #region Event Methods private void DetailsPageWidgetCollection_Initialized(object sender, EventArgs e) { SetStyles(); } private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e) { if (!(sender is ScrollViewer scrollViewer)) return; var destination = scrollViewer.HorizontalOffset - e.Delta; scrollViewer.ScrollToHorizontalOffset(destination); } private void ScrollViewer_PreviewKeyDown(object sender, KeyEventArgs e) { e.Handled = true; } #region Click Events private void WidgetSectionStackPanel_Click(object originalSource) { try { if (!(originalSource is TextBlock clickedTextBlock)) return; System.Windows.Forms.Clipboard.SetText(clickedTextBlock.Text); } catch { } } private void WidgetSectionStackPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { WidgetSectionStackPanel_Click(e.OriginalSource); } private void WidgetSectionStackPanel_TouchDown(object sender, TouchEventArgs e) { WidgetSectionStackPanel_Click(e.OriginalSource); } #endregion #endregion public void SetEditMode(bool isActive) { try { foreach (var child in WidgetSectionStackPanel.Children) { if (!(child is Border widgetBorder && widgetBorder.Child is DetailsPageWidget widget)) continue; widget.SetEditMode(isActive); } } catch (Exception E) { LogException(E); } } } }