using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Data; using System.Windows.Input; using System.Windows.Media; using FontAwesome.Sharp; using static System.Runtime.InteropServices.JavaScript.JSType; using static LinqToDB.Sql; using Color = System.Windows.Media.Color; namespace Pf2eDataScrapper.WPF.EntityViewer.EntityViewStructure; internal class StructureRow : INotifyPropertyChanged { /// /// Отображаемая строка поля сущности. /// public StructureField Field { get; } /// /// Список типов лестницы. /// public List Ladder { get; set; } = []; /// /// Флаг наличия кнопки. /// public bool HasButton => Field.FieldType == StructureFieldType.Complex && ((StructureFieldComplex)Field).Collapsable; /// /// Флаг, указывающий, отображается ли строка. /// public bool Visible => Field.Visible; /// /// Флаг, указывающий, отображается ли строка. /// public Visibility ItemVisibility => Visible ? Visibility.Visible : Visibility.Collapsed; /// /// Флаг, указывающий, отображается ли строка. /// public Visibility ButtonVisibility => HasButton ? Visibility.Visible : Visibility.Collapsed; /// /// Иконка кнопки. /// public string ButtonIcon => HasButton && !((StructureFieldComplex)Field).Collapsed ? IconChar.PlusSquare.ToChar() : IconChar.MinusSquare.ToChar(); /// /// Глубина отображения поля. /// public int Depth => Field.Depth; /// /// Строковое представление названия поля. /// public string Name => Field.Name; /// /// Строковое представление типа поля. /// public string Type { get { string result = Field.GetTypeString(); if (result != "") { result = $@"({result})"; } return result; } } /// /// Строковое представление значения поля. /// public string Value => Field.GetValueString().Replace("\r", "").Replace("\n", ""); /// /// Цвет значения /// public Color? AccentColor => Field switch { StructureFieldPrimitive primitive => System.Type.GetTypeCode(primitive.Type) switch { TypeCode.Boolean => Colors.DarkGoldenrod, TypeCode.Int32 => Colors.Blue, TypeCode.Double => Colors.Aqua, TypeCode.String => Colors.Green, _ => null, }, StructureFieldEnum => Colors.Red, StructureFieldNull => Colors.Transparent, _ => null, }; /// /// Команда переключения. /// public ICommand CollapseCommand { get; } /// /// Кониструктор класса . /// /// Поле. public StructureRow(StructureField field) { Field = field; CollapseCommand = new CollapseCommand(this); Field.PropertyChanged += Field_PropertyChanged; } /// /// /// /// private void Field_PropertyChanged(object? sender, PropertyChangedEventArgs e) { OnPropertyChanged(nameof(Field)); OnPropertyChanged(nameof(Visible)); OnPropertyChanged(nameof(ItemVisibility)); OnPropertyChanged(nameof(ButtonVisibility)); OnPropertyChanged(nameof(ButtonIcon)); } /// /// Событие изменения поля. /// public event Action? OnChange; /// /// Изменение поля. /// public event PropertyChangedEventHandler? PropertyChanged; /// /// При изменении поля. /// /// Название поля. protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new(propertyName)); } } internal class CollapseCommand(StructureRow structureRow) : ICommand { private StructureRow StructureRow { get; } = structureRow; public event EventHandler? CanExecuteChanged; public bool CanExecute(object? parameter) { return true; } public void Execute(object? parameter) { var field = (StructureFieldComplex)StructureRow.Field; field.Collapsed = !field.Collapsed; } } public class ColorAdapterConverter : IMultiValueConverter { private byte Mix(byte a, byte b, double rate) => System.Convert.ToByte(Math.Round(a * rate + b * (1 - rate))); public object? Convert(object[] value, Type targetType, object parameter, CultureInfo culture) { Color textColor = System.Windows.SystemColors.WindowTextColor; double a = textColor.A; double r = textColor.R; double g = textColor.G; double b = textColor.B; int n = 1 + value.Length; foreach (var item in value) { if (item == null || item is not Color) { n--; continue; } Color color = (Color)item; a += color.A; r += color.R; g += color.G; b += color.B; } Color resultColor = Color.FromArgb( System.Convert.ToByte(Math.Round(a / n)), System.Convert.ToByte(Math.Round(r / n)), System.Convert.ToByte(Math.Round(g / n)), System.Convert.ToByte(Math.Round(b / n)) ); var @switch = new Dictionary> { { typeof(System.Windows.Media.Brush), () => new SolidColorBrush(resultColor) }, }; return @switch.TryGetValue(targetType, out var action) ? action() : null; } public object[] ConvertBack( object value, Type[] targetType, object parameter, CultureInfo culture ) { throw new NotImplementedException(); } }