This commit is contained in:
Meik
2025-11-11 11:03:42 +01:00
commit dc3e8a2e4c
582 changed files with 191465 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
<UserControl x:Class="FasdDesktopUi.Pages.DetailsPage.UserControls.CustomizableSection"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FasdDesktopUi.Pages.DetailsPage.UserControls"
xmlns:uc="clr-namespace:FasdDesktopUi.Basics.UserControls"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800"
Name="_me">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibility" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Margin="0 10 0 0"
Height="13">
<uc:LoadingDataIndicator Visibility="{Binding ElementName=_me, Path=IsDataIncomplete, Converter={StaticResource BoolToVisibility}}" />
</Border>
<Grid x:Name="MainGrid"
Margin="0 5 0 0"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
</Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using FasdDesktopUi.Basics.Models;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Pages.DetailsPage.UserControls
{
public partial class CustomizableSection : UserControl
{
#region Properties
#region ContainerCollections
public List<cContainerCollectionData> ContainerCollections
{
get { return (List<cContainerCollectionData>)GetValue(ContainerCollectionsProperty); }
set { SetValue(ContainerCollectionsProperty, value); }
}
public static readonly DependencyProperty ContainerCollectionsProperty =
DependencyProperty.Register("ContainerCollections", typeof(List<cContainerCollectionData>), typeof(CustomizableSection), new PropertyMetadata(new List<cContainerCollectionData>(), new PropertyChangedCallback(ContainerCollectionsChanged)));
private static void ContainerCollectionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is CustomizableSection _me))
return;
_me.DrawContainerCollections();
}
#endregion
#region IsDataIncomplete DependencyProperty
public static readonly DependencyProperty IsDataIncompleteProperty =
DependencyProperty.Register("IsDataIncomplete", typeof(bool), typeof(CustomizableSection), new PropertyMetadata(true));
public bool IsDataIncomplete
{
get { return (bool)GetValue(IsDataIncompleteProperty); }
set { SetValue(IsDataIncompleteProperty, value); }
}
#endregion
#endregion
public CustomizableSection()
{
InitializeComponent();
}
public void UpdateContainerCollection(List<cContainerCollectionData> containerCollectionsData)
{
ContainerCollections = containerCollectionsData;
}
private void DrawContainerCollections()
{
MainGrid.Children.Clear();
foreach (var containerCollection in ContainerCollections)
{
var containerCollectionToAdd = new DetailsPageStateContainerCollection() { CollectionData = containerCollection };
Grid.SetColumnSpan(containerCollectionToAdd, containerCollection.ColumnSpan);
SetColumnIndex(containerCollectionToAdd, containerCollection.ColumnSpan);
MainGrid.Children.Add(containerCollectionToAdd);
}
}
private void SetColumnIndex(UIElement element, int columnSpan)
{
try
{
int columnCount = MainGrid.ColumnDefinitions.Count;
if (MainGrid.Children.Count <= 0)
{
Grid.SetColumn(element, 0);
Grid.SetRow(element, 0);
return;
}
var lastChild = MainGrid.Children.OfType<FrameworkElement>().Last();
int lastChildColumnIndex = Grid.GetColumn(lastChild);
int lastChildColumnSpan = Grid.GetColumnSpan(lastChild);
int lastChildRowIndex = Grid.GetRow(lastChild);
if (columnCount < lastChildColumnIndex + lastChildColumnSpan + columnSpan)
{
MainGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
Grid.SetRow(element, lastChildRowIndex + 1);
Grid.SetColumn(element, 0);
return;
}
Grid.SetRow(element, lastChildRowIndex);
Grid.SetColumn(element, lastChildColumnIndex + lastChildColumnSpan);
}
catch (Exception E)
{
LogException(E);
}
}
public void SetEditMode(bool isActive)
{
try
{
foreach (var child in MainGrid.Children)
{
if (!(child is DetailsPageStateContainerCollection stateContainerCollection))
continue;
stateContainerCollection.SetEditMode(isActive);
}
}
catch (Exception E)
{
LogException(E);
}
}
}
}

View File

@@ -0,0 +1,74 @@
<UserControl x:Class="FasdDesktopUi.Pages.DetailsPage.UserControls.DetailsPageStateContainer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FasdDesktopUi.Pages.DetailsPage.UserControls"
xmlns:ico="clr-namespace:FasdDesktopUi.Basics.UserControls.AdaptableIcon;assembly=F4SD-AdaptableIcon"
xmlns:vc="clr-namespace:FasdDesktopUi.Basics.Converter"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<UserControl.Resources>
<vc:LanguageDefinitionsConverter x:Key="LanguageConverter" />
</UserControl.Resources>
<Border Background="{DynamicResource BackgroundColor.DetailsPage.Widget.Value}"
CornerRadius="7.5"
Padding="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border x:Name="AddButton"
Grid.Row="0"
Panel.ZIndex="2"
CornerRadius="5"
Padding="5 2.5"
Background="{DynamicResource BackgroundColor.Menu.MainCategory}"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Cursor="Hand"
Visibility="Collapsed">
<TextBlock Text="{Binding Converter={StaticResource LanguageConverter}, ConverterParameter=Global.Done }">
<TextBlock.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize"
Value="11.5" />
<Setter Property="Foreground"
Value="{DynamicResource FontColor.Menu.Categories}" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorLevel=1, AncestorType=Border}, Path=IsMouseOver}"
Value="True">
<Setter Property="Foreground"
Value="{DynamicResource FontColor.Menu.Categories.Hover}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Resources>
</TextBlock>
</Border>
<StackPanel x:Name="MainStackPanel"
Grid.Row="1" />
<ico:AdaptableIcon x:Name="FullSizeButton"
Grid.Row="1"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Style="{DynamicResource SettingsPage.Close.Icon}"
Margin="0 -10 -10 0"
BorderPadding="7.5"
MouseLeftButtonUp="FullSizeButton_MouseLeftButtonUp"
TouchDown="FullSizeButton_TouchDown"
SelectedMaterialIcon="ic_zoom_out_map" />
</Grid>
</Border>
</UserControl>

View File

@@ -0,0 +1,434 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using FasdDesktopUi.Basics.Enums;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using static C4IT.Logging.cLogManager;
using F4SD_AdaptableIcon.Enums;
using MaterialIcons;
using FasdDesktopUi.Basics.Helper;
namespace FasdDesktopUi.Pages.DetailsPage.UserControls
{
public partial class DetailsPageStateContainer : UserControl
{
private readonly List<(FrameworkElement ValueControl, FrameworkElement EditControl)> EditableControls = new List<(FrameworkElement ValueControl, FrameworkElement EditControl)>();
#region Properties
public cContainerData ContainerData
{
get { return (cContainerData)GetValue(ContainerDataProperty); }
set { SetValue(ContainerDataProperty, value); }
}
public static readonly DependencyProperty ContainerDataProperty =
DependencyProperty.Register("ContainerData", typeof(cContainerData), typeof(DetailsPageStateContainer), new PropertyMetadata(null, new PropertyChangedCallback(ContainerDataChanged)));
private static void ContainerDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is DetailsPageStateContainer _me))
return;
_me.EditableControls.Clear();
_me.DrawContainerContent();
}
#endregion
public DetailsPageStateContainer()
{
InitializeComponent();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
SetStyles();
}
private void DrawContainerContent()
{
try
{
if (ContainerData.IsMaximizable)
FullSizeButton.Visibility = Visibility.Visible;
else
FullSizeButton.Visibility = Visibility.Collapsed;
if(ContainerData.IsAddable)
AddButton.Visibility = Visibility.Visible;
else
AddButton.Visibility = Visibility.Collapsed;
foreach (var containerElement in ContainerData)
{
cUiElementHelper.DrawCustomizableContainerComponent(containerElement, this, out var createdElement, EditableControls.Add);
MainStackPanel.Children.Add(createdElement);
}
}
catch (Exception E)
{
LogException(E);
}
}
private string GetHtmlString(string maximizeValue, double fontSize = 14.0)
{
var output = maximizeValue;
try
{
var backgroundColor = (SolidColorBrush)TryFindResource("BackgroundColor.DetailsPage.Widget.Title");
var backgroundColorString = string.Empty;
if (backgroundColor != null)
backgroundColorString = $"rgb({backgroundColor.Color.R}, {backgroundColor.Color.G}, {backgroundColor.Color.B} )";
var foreGroundColor = (SolidColorBrush)TryFindResource("FontColor.DetailsPage.Widget");
var foreGroundColorString = string.Empty;
if (foreGroundColor != null)
foreGroundColorString = $"rgb({foreGroundColor.Color.R}, {foreGroundColor.Color.G}, {foreGroundColor.Color.B} )";
string htmlPrefix = $"<html><head><meta charset=\"UTF-8\"></head><body style=\"background-color: {backgroundColorString}; color: {foreGroundColorString}; font-size: {fontSize}px; font-family: Calibri, sans-serif; overflow: auto\"><div>";
string htmlSuffix = "</div></body></html>";
output = htmlPrefix + maximizeValue + htmlSuffix;
}
catch (Exception E)
{
LogException(E);
}
return output;
}
private void DrawMaximizedControl(IContainerData containerDataEntry, FrameworkElement parentElement)
{
try
{
const double enlargementFactor = 1.5;
FrameworkElement createdControl = null;
switch (containerDataEntry)
{
case cContainerValue containerValueData:
{
if (string.IsNullOrEmpty(containerValueData?.MaximizeValue))
{
createdControl = new TextBlock()
{
Text = containerValueData.DisplayValue,
TextWrapping = TextWrapping.Wrap,
FontSize = containerValueData.FontSize * enlargementFactor,
FontWeight = containerValueData.FontWeight,
Margin = new Thickness(0, 0, 5, 0),
Style = textBlockStyle
};
if (!string.IsNullOrEmpty(containerValueData.Description))
createdControl.ToolTip = containerValueData.Description;
}
else
{
var webBrowser = new WebBrowser() { ClipToBounds = true };
webBrowser.SetValue(ScrollViewer.VerticalScrollBarVisibilityProperty, ScrollBarVisibility.Hidden);
string htmlControlString = GetHtmlString(containerValueData.MaximizeValue, containerValueData.FontSize * enlargementFactor);
webBrowser.NavigateToString(htmlControlString);
createdControl = new Border() { Child = webBrowser };
if (createdControl is Border createdBorder)
createdBorder.SetResourceReference(BackgroundProperty, "BackgroundColor.DetailsPage.Widget.Title");
}
break;
}
case cContainerIcon containerIconData:
{
enumInternIcons? internIcon = null;
enumInternGif? internGif = null;
MaterialIconType? materialIcon = null;
if (Enum.TryParse<enumInternIcons>(containerIconData.IconName, out var tempInternIcon))
internIcon = tempInternIcon;
if (Enum.TryParse<enumInternGif>(containerIconData.IconName, out var tempInternGif))
internGif = tempInternGif;
if (Enum.TryParse<MaterialIconType>(containerIconData.IconName, out var tempMaterialIcon))
materialIcon = tempMaterialIcon;
createdControl = new AdaptableIcon()
{
SelectedInternIcon = internIcon,
SelectedInternGif = internGif,
SelectedMaterialIcon = materialIcon,
ToolTip = containerIconData.ToolTipText,
BorderPadding = new Thickness(0),
IconHeight = 14 * enlargementFactor,
IconWidth = 14 * enlargementFactor,
Margin = new Thickness(0, 0, 5, 0)
};
string iconResourceName = "Color.Menu.Icon";
switch (containerIconData.HighlightColor)
{
case enumHighlightColor.blue:
iconResourceName = "Color.Blue";
break;
case enumHighlightColor.green:
iconResourceName = "Color.Green";
break;
case enumHighlightColor.orange:
iconResourceName = "Color.Orange";
break;
case enumHighlightColor.red:
iconResourceName = "Color.Red";
break;
}
if (createdControl is AdaptableIcon createdAdaptable)
createdAdaptable.SetResourceReference(AdaptableIcon.PrimaryIconColorProperty, iconResourceName);
break;
}
case cContainerPrimaryContent primaryContentData:
{
if (parentElement is Grid parentGrid)
parentGrid.RowDefinitions.Last().Height = new GridLength(1, GridUnitType.Star);
createdControl = new Border()
{
Padding = new Thickness(10),
Margin = new Thickness(0, 5, 0, 5),
CornerRadius = new CornerRadius(7.5)
};
if (createdControl is Border createdBorder)
createdBorder.SetResourceReference(BackgroundProperty, "BackgroundColor.DetailsPage.Widget.Title");
DrawMaximizedControl(primaryContentData.Value, createdControl);
break;
}
case cContainerStackPanel stackPanelData:
{
createdControl = new StackPanel() { Orientation = stackPanelData.Orientation };
foreach (var stackPanelElement in stackPanelData.StackPanelData)
{
DrawMaximizedControl(stackPanelElement, createdControl);
}
break;
}
}
if (createdControl is null)
return;
if (parentElement is Panel parentPanel)
{
if (parentPanel is Grid parentGrid)
Grid.SetRow(createdControl, parentGrid.RowDefinitions.Count - 1);
parentPanel.Children.Add(createdControl);
}
else if (parentElement is Decorator parentDecorator)
{
parentDecorator.Child = createdControl;
}
}
catch (Exception E)
{
LogException(E);
}
}
private Decorator GetMaximizedContainer()
{
Decorator output = null;
try
{
output = new Border()
{
CornerRadius = new CornerRadius(10),
Padding = new Thickness(22)
};
output.SetResourceReference(BackgroundProperty, "BackgroundColor.DetailsPage.Widget.Value");
Grid grid = new Grid();
output.Child = grid;
AdaptableIcon closeIcon = new AdaptableIcon()
{
HorizontalAlignment = HorizontalAlignment.Right,
SelectedInternIcon = enumInternIcons.window_close,
IconHeight = 35,
IconWidth = 35,
Margin = new Thickness(0, -10, 0, 0)
};
Panel.SetZIndex(closeIcon, 1);
closeIcon.SetResourceReference(StyleProperty, "SettingsPage.Close.Icon");
closeIcon.MouseLeftButtonUp += CloseIcon_MouseLeftButtonUp;
closeIcon.TouchDown += CloseIcon_TouchDown;
grid.Children.Add(closeIcon);
foreach (var containerDataEntry in ContainerData)
{
try
{
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
DrawMaximizedControl(containerDataEntry, grid);
}
catch (Exception E)
{
LogException(E);
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
return output;
}
#region FullSizeButton Click
private void FullSizeButton_Click()
{
try
{
var maximizedContainer = GetMaximizedContainer();
if (maximizedContainer != null)
RaiseEvent(new ContainerEventArgs(MaximizeContainerEvent, this, maximizedContainer));
}
catch (Exception E)
{
LogException(E);
}
}
private void FullSizeButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
FullSizeButton_Click();
}
private void FullSizeButton_TouchDown(object sender, TouchEventArgs e)
{
FullSizeButton_Click();
}
#endregion
#region Styles
Style textBlockStyle;
private void SetStyles()
{
textBlockStyle = (Style)FindResource("DetailsPage.Widget.Title");
}
public void SetEditMode(bool isActive)
{
try
{
foreach (var editablePair in EditableControls)
{
editablePair.ValueControl.Visibility = isActive ? Visibility.Collapsed : Visibility.Visible;
editablePair.EditControl.Visibility = isActive ? Visibility.Visible : Visibility.Collapsed;
}
}
catch (Exception E)
{
LogException(E);
}
}
#endregion
#region Events
#region Full Size Events
public class ContainerEventArgs : RoutedEventArgs
{
public Decorator MaximizedControl { get; private set; }
public ContainerEventArgs(RoutedEvent routedEvent, object source, Decorator maximizedControl) : base(routedEvent, source)
{
MaximizedControl = maximizedControl;
}
}
public delegate void ContainerEventHandlerDelegate(object sender, ContainerEventArgs args);
public static readonly RoutedEvent MaximizeContainerEvent = EventManager.RegisterRoutedEvent("MaximizeContainer", RoutingStrategy.Bubble, typeof(ContainerEventHandlerDelegate), typeof(DetailsPageStateContainer));
public event RoutedEventHandler MaximizeContainer
{
add { AddHandler(MaximizeContainerEvent, value); }
remove { RemoveHandler(MaximizeContainerEvent, value); }
}
#endregion
#region Close Full Size Events
public static readonly RoutedEvent CloseMaximizedContainerEvent = EventManager.RegisterRoutedEvent("CloseMaximizedContainer", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DetailsPageStateContainer));
public event RoutedEventHandler CloseMaximizedContainer
{
add { AddHandler(CloseMaximizedContainerEvent, value); }
remove { RemoveHandler(CloseMaximizedContainerEvent, value); }
}
private void CloseIcon_Click()
{
try
{
RaiseEvent(new RoutedEventArgs(CloseMaximizedContainerEvent));
}
catch (Exception E)
{
LogException(E);
}
}
private void CloseIcon_TouchDown(object sender, TouchEventArgs e)
{
CloseIcon_Click();
}
private void CloseIcon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
CloseIcon_Click();
}
#endregion
#endregion
}
}

View File

@@ -0,0 +1,17 @@
<UserControl x:Class="FasdDesktopUi.Pages.DetailsPage.UserControls.DetailsPageStateContainerCollection"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FasdDesktopUi.Pages.DetailsPage.UserControls"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800">
<ScrollViewer VerticalScrollBarVisibility="Auto"
Margin="0 0 20 20"
Padding="0 0 8 8">
<StackPanel x:Name="MainStack" />
</ScrollViewer>
</UserControl>

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Pages.DetailsPage.UserControls
{
public partial class DetailsPageStateContainerCollection : UserControl
{
#region Properties and Fields
private List<UIElement> editControls = new List<UIElement>();
public cContainerCollectionData CollectionData
{
get { return (cContainerCollectionData)GetValue(CollectionDataProperty); }
set { SetValue(CollectionDataProperty, value); }
}
public static readonly DependencyProperty CollectionDataProperty =
DependencyProperty.Register("CollectionData", typeof(cContainerCollectionData), typeof(DetailsPageStateContainerCollection), new PropertyMetadata(null, new PropertyChangedCallback(CollectionDataChanged)));
private static void CollectionDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is DetailsPageStateContainerCollection _me))
return;
_me.editControls.Clear();
_me.DrawStateContainers();
}
#endregion
public DetailsPageStateContainerCollection()
{
InitializeComponent();
}
private void DrawStateContainers()
{
try
{
MainStack.Children.Clear();
foreach (var containerData in CollectionData)
{
var containerToAdd = new DetailsPageStateContainer() { ContainerData = containerData, Margin = new Thickness(0, 0, 0, 10) };
MainStack.Children.Add(containerToAdd);
}
}
catch (Exception E)
{
LogException(E);
}
}
public void SetEditMode(bool isActive)
{
try
{
editControls.ForEach(x => x.Visibility = isActive ? Visibility.Visible : Visibility.Collapsed);
foreach (var child in MainStack.Children)
{
if (!(child is DetailsPageStateContainer stateContainer))
continue;
stateContainer.SetEditMode(isActive);
}
}
catch (Exception E)
{
LogException(E);
}
}
}
}