using System.IO; using System.Windows; using EmbyToolbox.Services; using EmbyToolbox.ViewModels; namespace EmbyToolbox.Behaviors; public static class TrackExtractionDropTargetBehavior { public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached( "IsEnabled", typeof(bool), typeof(TrackExtractionDropTargetBehavior), new PropertyMetadata(false, OnIsEnabledChanged)); public static void SetIsEnabled(DependencyObject d, bool value) => d.SetValue(IsEnabledProperty, value); public static bool GetIsEnabled(DependencyObject d) => (bool)d.GetValue(IsEnabledProperty); private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is not FrameworkElement fe) { return; } fe.AllowDrop = false; fe.PreviewDragOver -= OnPreviewDragOver; fe.PreviewDragLeave -= OnPreviewDragLeave; fe.PreviewDrop -= OnPreviewDrop; if (e.NewValue is true) { fe.AllowDrop = true; fe.PreviewDragOver += OnPreviewDragOver; fe.PreviewDragLeave += OnPreviewDragLeave; fe.PreviewDrop += OnPreviewDrop; } } private static void OnPreviewDragOver(object sender, DragEventArgs e) { if (sender is not FrameworkElement fe || fe.DataContext is not TrackExtractionViewModel vm) { return; } if (vm.IsBusy) { e.Effects = DragDropEffects.None; vm.IsDropHighlight = false; return; } if (!e.Data.GetDataPresent(DataFormats.FileDrop)) { e.Effects = DragDropEffects.None; vm.IsDropHighlight = false; return; } var paths = (string[])e.Data.GetData(DataFormats.FileDrop); if (!HasSupportedDrop(paths)) { e.Effects = DragDropEffects.None; vm.IsDropHighlight = false; return; } e.Effects = DragDropEffects.Copy; e.Handled = true; vm.IsDropHighlight = true; } private static bool HasSupportedDrop(string[] paths) { if (paths is null || paths.Length == 0) { return false; } foreach (var raw in paths) { try { var full = Path.GetFullPath(raw); if (File.Exists(full) && TrackExtractionFormats.IsSupportedPath(full)) { return true; } if (Directory.Exists(full)) { return true; } } catch { return false; } } return false; } private static void OnPreviewDragLeave(object sender, DragEventArgs e) { if (sender is not FrameworkElement fe || fe.DataContext is not TrackExtractionViewModel vm) { return; } vm.IsDropHighlight = false; } private static void OnPreviewDrop(object sender, DragEventArgs e) { if (sender is not FrameworkElement fe || fe.DataContext is not TrackExtractionViewModel vm) { return; } vm.IsDropHighlight = false; if (vm.IsBusy || e.Data.GetData(DataFormats.FileDrop) is not string[] paths || paths.Length == 0) { e.Handled = true; return; } vm.ApplyDroppedPaths(paths); e.Handled = true; } }