Skip to content

Commit

Permalink
Fix file list drag & drop oddity
Browse files Browse the repository at this point in the history
There's a weird interaction where, if you left-click on an item in
the file list, then right-click to open the context menu, then left-
click on another entry, the application thinks you just tried to
drag the first item onto the second one.

This seems to be fixed by doing three things:
(1) Explicitly clear the drag start point when the context menu is
  opened.  This is required because the file list doesn't get any
  mouse events while the context menu is open, so the click that
  closes the menu looks like an instantaneous drag if the start
  point is set.
(2) Explicitly clear the drag start point if we see mouse movement
  in the file list and the left button isn't being held down.  This
  shouldn't be necessary with #1 in place, and it doesn't solve the
  problem on its own, but it might help with some other edge case.
(3) Pass "this" instead of "null" to e.GetPosition(), which was
  making things more complicated by occasionally choosing a different
  object to use as the top-left corner after the context menu closed.

Yay WPF.

(issue #20)
  • Loading branch information
fadden committed Jun 15, 2024
1 parent 32f0adb commit 3a8c4ff
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
5 changes: 4 additions & 1 deletion FileConv/Gfx/GSFinderIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private class IconFile {

public string BlkNameStr { get; private set; } = string.Empty;

private const int BASE_LENGTH = 26;
public const int BASE_LENGTH = 26;

public bool Load(byte[] buf, ref int offset, Notes notes) {
if (offset + BASE_LENGTH > buf.Length) {
Expand Down Expand Up @@ -239,6 +239,9 @@ protected override Applicability TestApplicability() {
if (DataStream == null) {
return Applicability.Not;
}
if (DataStream.Length < IconFile.BASE_LENGTH) {
return Applicability.Not;
}
if (FileAttrs.FileType == FileAttribs.FILE_TYPE_ICN) {
return Applicability.Yes;
}
Expand Down
25 changes: 19 additions & 6 deletions cp2_wpf/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,7 @@ private void FileListContextMenu_ContextMenuOpening(object sender, ContextMenuEv
mFileListRefocusNeeded + ")");
fileListDataGrid.Focus();
}
mDragStartPosn = NO_POINT; // see issue #20
}

#endregion Center Panel
Expand Down Expand Up @@ -1402,11 +1403,13 @@ private void LaunchPanel_Drop(object sender, DragEventArgs e) {
}
}

private static readonly Point NO_POINT = new Point(-1, -1);

// True if we're in the middle of a drag operation that started in the file list.
private bool mIsDraggingFileList;

// Screen position of drag start.
private Point mDragStartPosn;
private Point mDragStartPosn = NO_POINT;

// Hack to make multi-file drag easier for the user.
// https://stackoverflow.com/a/25123410/294248
Expand All @@ -1422,7 +1425,7 @@ private void LaunchPanel_Drop(object sender, DragEventArgs e) {
private void FileListDataGrid_PreviewMouseLeftButtonDown(object sender,
MouseButtonEventArgs e) {
DataGrid grid = (DataGrid)sender;
mDragStartPosn = new Point(-1, -1);
mDragStartPosn = NO_POINT;

// Identify the row that was clicked on.
DataGridRow? row = FindVisualParent<DataGridRow>(e.OriginalSource as FrameworkElement);
Expand All @@ -1431,7 +1434,9 @@ private void FileListDataGrid_PreviewMouseLeftButtonDown(object sender,
// this allows the scroll bar to work.
return;
}
mDragStartPosn = e.GetPosition(null);
mDragStartPosn = e.GetPosition(this);
//Debug.WriteLine("CLICK: posn=" + mDragStartPosn + " left=" + e.LeftButton +
// " right=" + e.RightButton + " st=" + e.ButtonState + " src=" + e.OriginalSource);
mPreSelection.Clear();
if (row != null && row.IsSelected) {
// The user clicked on an entry that is already selected. Capture the selection
Expand All @@ -1456,15 +1461,23 @@ private void FileListDataGrid_PreviewMouseLeftButtonDown(object sender,
/// Handles mouse movement in the file list, watching for the start of a drag.
/// </summary>
private void FileListDataGrid_PreviewMouseMove(object sender, MouseEventArgs e) {
if (e.LeftButton != MouseButtonState.Pressed || mIsDraggingFileList) {
// Mouse button isn't being held down, or we're already in a drag op.
//Debug.WriteLine("MOVE to " + e.GetPosition(this));
if (e.LeftButton != MouseButtonState.Pressed) {
// Mouse button isn't being held down. Clear the start position. (Without this
// we get weird behavior when a right-click context menu is cleared by left-
// clicking on a different element; see issue #20.)
mDragStartPosn = NO_POINT;
return;
}
if (mIsDraggingFileList) {
// We're already in a drag op.
return;
}
if (mDragStartPosn.X < 0) {
// Initial click wasn't on an item in the file list.
return;
}
Point posn = e.GetPosition(null);
Point posn = e.GetPosition(this);
if (Math.Abs(mDragStartPosn.X - posn.X) >
SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(mDragStartPosn.Y - posn.Y) >
Expand Down

0 comments on commit 3a8c4ff

Please sign in to comment.