diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml index d1f48212b8b..152558e812b 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml @@ -52,6 +52,10 @@ MouseDoubleClick="MouseDoubleClickItem" SelectedItem="{Binding Settings.SelectedSearchSource}" SizeChanged="ListView_SizeChanged" + PreviewMouseLeftButtonDown="ListView_PreviewMouseLeftButtonDown" + PreviewMouseMove="ListView_PreviewMouseMove" + AllowDrop="True" + Drop="ListView_Drop" Style="{StaticResource {x:Static GridView.GridViewStyleKey}}"> diff --git a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs index 55fe9982470..6dc766fffd0 100644 --- a/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs +++ b/Plugins/Flow.Launcher.Plugin.WebSearch/SettingsControl.xaml.cs @@ -1,7 +1,10 @@ -using System.Windows; -using System.Windows.Controls; +using System; using System.ComponentModel; +using System.Windows; +using System.Windows.Controls; using System.Windows.Data; +using System.Windows.Input; +using System.Windows.Media; namespace Flow.Launcher.Plugin.WebSearch { @@ -12,6 +15,7 @@ public partial class SettingsControl : UserControl { private readonly Settings _settings; private readonly PluginInitContext _context; + private Point _dragStartPoint; public SettingsControl(PluginInitContext context, SettingsViewModel viewModel) { @@ -163,5 +167,78 @@ private void ListView_SizeChanged(object sender, SizeChangedEventArgs e) gView.Columns[3].Width = workingWidth * col4; gView.Columns[4].Width = workingWidth * col5; } + + private void ListView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + _dragStartPoint = e.GetPosition(null); + } + + private void ListView_PreviewMouseMove(object sender, MouseEventArgs e) + { + Point mousePos = e.GetPosition(null); + Vector diff = _dragStartPoint - mousePos; + + if (e.LeftButton == MouseButtonState.Pressed && + (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || + Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) + { + var listView = (ListView)sender; + ListViewItem listViewItem = FindAncestor((DependencyObject)e.OriginalSource); + + if (listViewItem == null) return; + + SearchSource item = (SearchSource)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); + if (item == null) return; + + DragDrop.DoDragDrop(listViewItem, item, DragDropEffects.Move); + } + } + + private void ListView_Drop(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(typeof(SearchSource))) + { + SearchSource droppedData = e.Data.GetData(typeof(SearchSource)) as SearchSource; + var listView = (ListView)sender; + var target = GetNearestContainer(e.OriginalSource); + + if (target == null) + return; + + SearchSource targetData = (SearchSource)listView.ItemContainerGenerator.ItemFromContainer(target); + + if (targetData == null) + return; + + var items = _settings.SearchSources; + int removedIdx = items.IndexOf(droppedData); + int targetIdx = items.IndexOf(targetData); + + if (removedIdx == targetIdx) + return; + + items.Move(removedIdx, targetIdx); + } + } + + private ListViewItem GetNearestContainer(object source) + { + var element = source as UIElement; + while (element != null && !(element is ListViewItem)) + element = VisualTreeHelper.GetParent(element) as UIElement; + + return element as ListViewItem; + } + + private static T FindAncestor(DependencyObject current) where T : DependencyObject + { + while (current != null) + { + if (current is T) + return (T)current; + current = VisualTreeHelper.GetParent(current); + } + return null; + } } }