Skip to content

Commit 6f388fb

Browse files
authored
Merge pull request #1502 from dbindley/master
AccountSwitcher drag-and-drop reordering
2 parents b14e0d3 + 7a2b9fb commit 6f388fb

File tree

2 files changed

+88
-3
lines changed

2 files changed

+88
-3
lines changed

src/XIVLauncher/Windows/AccountSwitcher.xaml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717
<Grid Margin="0,0,0,0">
1818
<materialDesign:Card Background="{DynamicResource MaterialDesignPaper}" Height="390" Margin="0,0,10,0">
1919
<StackPanel Margin="16,16,10,0">
20-
<ListView x:Name="AccountListView" MouseUp="AccountListView_OnMouseUp" MaxHeight="370">
20+
<ListView x:Name="AccountListView"
21+
MaxHeight="370"
22+
AllowDrop="True"
23+
MouseUp="AccountListView_OnMouseUp"
24+
PreviewMouseLeftButtonDown="AccountListView_OnPreviewMouseLeftButtonDown"
25+
PreviewMouseMove="AccountListView_OnPreviewMouseMove"
26+
Drop="AccountListView_OnDrop">
2127
<ListView.ContextMenu>
2228
<ContextMenu Opened="AccountListViewContext_Opened" StaysOpen="true">
2329
<MenuItem Header="{Binding AccountSwitcherSetProfilePicLoc}" Click="SetProfilePicture_OnClick" Foreground="{DynamicResource MaterialDesignBody}"/>
@@ -92,4 +98,4 @@
9298
</StackPanel>
9399
</materialDesign:Card>
94100
</Grid>
95-
</Window>
101+
</Window>

src/XIVLauncher/Windows/AccountSwitcher.xaml.cs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using System.Linq;
77
using System.Threading.Tasks;
88
using System.Windows;
9+
using System.Windows.Controls;
910
using System.Windows.Input;
11+
using System.Windows.Media;
1012
using System.Windows.Media.Imaging;
1113
using IWshRuntimeLibrary;
1214
using XIVLauncher.Accounts;
@@ -22,6 +24,9 @@ public partial class AccountSwitcher : Window
2224
{
2325
private readonly AccountManager _accountManager;
2426

27+
private System.Windows.Point startPoint;
28+
private ListViewItem draggedItem;
29+
2530
public EventHandler<XivAccount> OnAccountSwitchedEventHandler;
2631

2732
public AccountSwitcher(AccountManager accountManager)
@@ -225,5 +230,79 @@ private void DontSavePassword_OnUnchecked(object sender, RoutedEventArgs e)
225230
account.SavePassword = true;
226231
_accountManager.Save();
227232
}
233+
234+
private void AccountListView_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
235+
{
236+
this.startPoint = e.GetPosition(null);
237+
this.draggedItem = FindAncestor<ListViewItem>((DependencyObject)e.OriginalSource);
238+
239+
if (this.draggedItem == null)
240+
return;
241+
242+
this.draggedItem.IsSelected = true;
243+
}
244+
245+
private void AccountListView_OnPreviewMouseMove(object sender, MouseEventArgs e)
246+
{
247+
var mousePos = e.GetPosition(null);
248+
var diff = this.startPoint - mousePos;
249+
250+
if (sender is ListView listView &&
251+
FindAncestor<ListViewItem>((DependencyObject)e.OriginalSource) is ListViewItem listViewItem &&
252+
listView.ItemContainerGenerator.ItemFromContainer(listViewItem) is AccountSwitcherEntry accountEntry &&
253+
e.LeftButton == MouseButtonState.Pressed &&
254+
(this.draggedItem != null && (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)))
255+
{
256+
var data = new DataObject("AccountSwitcherEntry", accountEntry);
257+
DragDrop.DoDragDrop(listViewItem, data, DragDropEffects.Move);
258+
}
259+
}
260+
261+
private void AccountListView_OnDrop(object sender, DragEventArgs e)
262+
{
263+
if (this.draggedItem == null)
264+
return;
265+
266+
var targetItem = FindAncestor<ListViewItem>((DependencyObject)e.OriginalSource);
267+
268+
if (targetItem == null)
269+
return;
270+
271+
var targetIndex = AccountListView.ItemContainerGenerator.IndexFromContainer(targetItem);
272+
var draggedIndex = AccountListView.ItemContainerGenerator.IndexFromContainer(this.draggedItem);
273+
274+
if (targetIndex < 0 || draggedIndex < 0)
275+
return;
276+
277+
var accountEntries = AccountListView.ItemsSource as List<AccountSwitcherEntry>;
278+
279+
if (accountEntries == null)
280+
return;
281+
282+
var draggedEntry = accountEntries[draggedIndex];
283+
accountEntries.RemoveAt(draggedIndex);
284+
accountEntries.Insert(targetIndex, draggedEntry);
285+
286+
_accountManager.Accounts.Clear();
287+
foreach (var accountEntry in accountEntries)
288+
_accountManager.Accounts.Add(accountEntry.Account);
289+
290+
_accountManager.Save();
291+
RefreshEntries();
292+
}
293+
294+
private static T FindAncestor<T>(DependencyObject current) where T : DependencyObject
295+
{
296+
do
297+
{
298+
if (current is T ancestor)
299+
return ancestor;
300+
301+
current = VisualTreeHelper.GetParent(current);
302+
}
303+
while (current != null);
304+
305+
return null;
306+
}
228307
}
229-
}
308+
}

0 commit comments

Comments
 (0)