using System.Text; using System.Windows.Input; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Data; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Logging; using Avalonia.Platform.Storage; using Avalonia.Threading; using Irihi.Avalonia.Shared.Common; using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; [TemplatePart(Name = "PART_Button", Type = typeof(Button))] public class PathPicker : TemplatedControl { public static readonly StyledProperty SuggestedStartPathProperty = AvaloniaProperty.Register( nameof(SuggestedStartPath), string.Empty); public static readonly StyledProperty UsePickerTypeProperty = AvaloniaProperty.Register( nameof(UsePickerType)); public static readonly StyledProperty SuggestedFileNameProperty = AvaloniaProperty.Register( nameof(SuggestedFileName), string.Empty); public static readonly StyledProperty FileFilterProperty = AvaloniaProperty.Register( nameof(FileFilter), string.Empty); public static readonly StyledProperty TitleProperty = AvaloniaProperty.Register( nameof(Title), string.Empty); public static readonly StyledProperty DefaultFileExtensionProperty = AvaloniaProperty.Register( nameof(DefaultFileExtension), string.Empty); public static readonly DirectProperty> SelectedPathsProperty = AvaloniaProperty.RegisterDirect>( nameof(SelectedPaths), o => o.SelectedPaths, (o, v) => o.SelectedPaths = v); public static readonly StyledProperty CommandProperty = AvaloniaProperty.Register( nameof(Command)); public static readonly StyledProperty AllowMultipleProperty = AvaloniaProperty.Register( nameof(AllowMultiple)); public static readonly StyledProperty SelectedPathsTextProperty = AvaloniaProperty.Register( nameof(SelectedPathsText), defaultBindingMode: BindingMode.TwoWay); public static readonly StyledProperty IsCancelingPickerAlsoTriggersProperty = AvaloniaProperty.Register( nameof(IsCancelingPickerAlsoTriggers)); public bool IsCancelingPickerAlsoTriggers { get => GetValue(IsCancelingPickerAlsoTriggersProperty); set => SetValue(IsCancelingPickerAlsoTriggersProperty, value); } public string? SelectedPathsText { get => GetValue(SelectedPathsTextProperty); set => SetValue(SelectedPathsTextProperty, value); } private Button? _button; private IReadOnlyList _selectedPaths = []; public bool AllowMultiple { get => GetValue(AllowMultipleProperty); set => SetValue(AllowMultipleProperty, value); } public ICommand? Command { get => GetValue(CommandProperty); set => SetValue(CommandProperty, value); } public IReadOnlyList SelectedPaths { get => _selectedPaths; private set => SetAndRaise(SelectedPathsProperty, ref _selectedPaths, value); } public string SuggestedFileName { get => GetValue(SuggestedFileNameProperty); set => SetValue(SuggestedFileNameProperty, value); } public string DefaultFileExtension { get => GetValue(DefaultFileExtensionProperty); set => SetValue(DefaultFileExtensionProperty, value); } public string Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); } public string FileFilter { get => GetValue(FileFilterProperty); set => SetValue(FileFilterProperty, value); } public UsePickerTypes UsePickerType { get => GetValue(UsePickerTypeProperty); set => SetValue(UsePickerTypeProperty, value); } public string SuggestedStartPath { get => GetValue(SuggestedStartPathProperty); set => SetValue(SuggestedStartPathProperty, value); } private bool _twoConvertLock; protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { base.OnPropertyChanged(change); if (_twoConvertLock) return; if (change.Property == SelectedPathsProperty) { _twoConvertLock = true; var stringBuilder = new StringBuilder(); if (SelectedPaths.Count != 0) { stringBuilder.Append(SelectedPaths[0]); foreach (var item in SelectedPaths.Skip(1)) { stringBuilder.AppendLine(item); } } SelectedPathsText = stringBuilder.ToString(); _twoConvertLock = false; } if (change.Property == SelectedPathsTextProperty) { _twoConvertLock = true; string[] separatedStrings = ["\r", "\n", "\r\n"]; // var list = SelectedPathsText?.Split(separatedStrings, StringSplitOptions.RemoveEmptyEntries) // .Select(RemoveNewLine).ToArray() // ?? []; // if (list.Length == SelectedPaths.Count) // { // if (SelectedPaths.Select(x => list.Any(y => x == y)).All(x => x is false)) // } SelectedPaths = SelectedPathsText?.Split(separatedStrings, StringSplitOptions.RemoveEmptyEntries) .Select(RemoveNewLine).ToArray() ?? []; _twoConvertLock = false; } } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); Button.ClickEvent.RemoveHandler(LaunchPicker, _button); _button = e.NameScope.Find