/// <summary> /// Handles control's DragOver event. /// </summary> public void DragOver(DragEventArgs e) { if (mImageListView.AllowDrop || (mImageListView.AllowDrag && selfDragging)) { if (mImageListView.Items.Count == 0) { if (selfDragging) { e.Effect = DragDropEffects.None; } else { e.Effect = DragDropEffects.Copy; } } else { // Calculate the location of the insertion cursor Point pt = new Point(e.X, e.Y); pt = mImageListView.PointToClient(pt); // Do we need to scroll the view? if (mImageListView.ScrollOrientation == ScrollOrientation.VerticalScroll && pt.Y > mImageListView.ClientRectangle.Bottom - 20) { scrollTimer.Tag = -120; scrollTimer.Enabled = true; } else if (mImageListView.ScrollOrientation == ScrollOrientation.VerticalScroll && pt.Y < mImageListView.ClientRectangle.Top + 20) { scrollTimer.Tag = 120; scrollTimer.Enabled = true; } else if (mImageListView.ScrollOrientation == ScrollOrientation.HorizontalScroll && pt.X > mImageListView.ClientRectangle.Right - 20) { scrollTimer.Tag = -120; scrollTimer.Enabled = true; } else if (mImageListView.ScrollOrientation == ScrollOrientation.HorizontalScroll && pt.X < mImageListView.ClientRectangle.Left + 20) { scrollTimer.Tag = 120; scrollTimer.Enabled = true; } else { scrollTimer.Enabled = false; } // Normalize to item area coordinates pt.X -= mImageListView.layoutManager.ItemAreaBounds.Left; pt.Y -= mImageListView.layoutManager.ItemAreaBounds.Top; // Row and column mouse is over bool dragCaretOnRight = false; int index = 0; if (mImageListView.ScrollOrientation == ScrollOrientation.HorizontalScroll) { index = (pt.X + mImageListView.ViewOffset.X) / mImageListView.layoutManager.ItemSizeWithMargin.Width; } else { int col = pt.X / mImageListView.layoutManager.ItemSizeWithMargin.Width; int row = (pt.Y + mImageListView.ViewOffset.Y) / mImageListView.layoutManager.ItemSizeWithMargin.Height; if (col > mImageListView.layoutManager.Cols - 1) { col = mImageListView.layoutManager.Cols - 1; dragCaretOnRight = true; } index = row * mImageListView.layoutManager.Cols + col; } if (index < 0) { index = 0; } if (index > mImageListView.Items.Count - 1) { index = mImageListView.Items.Count - 1; dragCaretOnRight = true; } ImageListViewItem dragDropTarget = mImageListView.Items[index]; if (selfDragging && (dragDropTarget.Selected || (!dragCaretOnRight && index > 0 && mImageListView.Items[index - 1].Selected) || (dragCaretOnRight && index < mImageListView.Items.Count - 1 && mImageListView.Items[index + 1].Selected))) { e.Effect = DragDropEffects.None; dragDropTarget = null; } else if (selfDragging) { e.Effect = DragDropEffects.Copy; } else { e.Effect = DragDropEffects.Copy; } if (!ReferenceEquals(dragDropTarget, DropTarget) || dragCaretOnRight != DropToRight) { DropTarget = dragDropTarget; DropToRight = dragCaretOnRight; mImageListView.Refresh(true); } } } else { e.Effect = DragDropEffects.None; } }
/// <summary> /// Handles control's MouseMove event. /// </summary> public void MouseMove(MouseEventArgs e) { ImageListViewItem oldHoveredItem = HoveredItem; ImageListView.ImageListViewColumnHeader oldHoveredColumn = HoveredColumn; ImageListView.ImageListViewColumnHeader oldHoveredSeparator = HoveredSeparator; DoHitTest(e.Location); mImageListView.mRenderer.SuspendPaint(); // Do we need to scroll the view? if (MouseSelecting && mImageListView.ScrollOrientation == ScrollOrientation.VerticalScroll && !scrollTimer.Enabled) { if (e.Y > mImageListView.ClientRectangle.Bottom) { scrollTimer.Tag = -120; scrollTimer.Enabled = true; } else if (e.Y < mImageListView.ClientRectangle.Top) { scrollTimer.Tag = 120; scrollTimer.Enabled = true; } } else if (MouseSelecting && mImageListView.ScrollOrientation == ScrollOrientation.HorizontalScroll && !scrollTimer.Enabled) { if (e.X > mImageListView.ClientRectangle.Right) { scrollTimer.Tag = -120; scrollTimer.Enabled = true; } else if (e.X < mImageListView.ClientRectangle.Left) { scrollTimer.Tag = 120; scrollTimer.Enabled = true; } } else if (scrollTimer.Enabled && mImageListView.ClientRectangle.Contains(e.Location)) { scrollTimer.Enabled = false; } if (DraggingSeperator) { int delta = e.Location.X - lastSeparatorDragLocation.X; int colwidth = SelectedSeperator.Width + delta; if (colwidth > 16) { lastSeparatorDragLocation = e.Location; } else { lastSeparatorDragLocation = new Point(e.Location.X - colwidth + 16, e.Location.Y); colwidth = 16; } SelectedSeperator.Width = colwidth; HoveredItem = null; HoveredColumn = SelectedSeperator; HoveredSeparator = SelectedSeperator; mImageListView.Refresh(); } else if (ResizingPane) { int delta = e.Location.X - lastPaneResizeLocation.X; int width = mImageListView.mPaneWidth + delta; if (width > 2) { lastPaneResizeLocation = e.Location; } else { lastPaneResizeLocation = new Point(e.Location.X - width + 2, e.Location.Y); width = 2; } mImageListView.mPaneWidth = width; HoveredItem = null; HoveredColumn = null; HoveredSeparator = null; mImageListView.Refresh(); } else if (MouseSelecting) { if (!ShiftKey && !ControlKey) { mImageListView.SelectedItems.Clear(false); } // Create the selection rectangle Point viewOffset = mImageListView.ViewOffset; Point pt1 = new Point(lastMouseDownLocation.X - (viewOffset.X - lastViewOffset.X), lastMouseDownLocation.Y - (viewOffset.Y - lastViewOffset.Y)); Point pt2 = new Point(e.Location.X, e.Location.Y); SelectionRectangle = new Rectangle(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y), Math.Abs(pt1.X - pt2.X), Math.Abs(pt1.Y - pt2.Y)); // Normalize to item area coordinates pt1 = new Point(SelectionRectangle.Left, SelectionRectangle.Top); pt2 = new Point(SelectionRectangle.Right, SelectionRectangle.Bottom); Point itemAreaOffset = new Point(-mImageListView.layoutManager.ItemAreaBounds.Left, -mImageListView.layoutManager.ItemAreaBounds.Top); pt1.Offset(itemAreaOffset); pt2.Offset(itemAreaOffset); // Determine which items are highlighted highlightedItems.Clear(); int startRow = (int)Math.Floor((float)(Math.Min(pt1.Y, pt2.Y) + viewOffset.Y) / (float)mImageListView.layoutManager.ItemSizeWithMargin.Height); int endRow = (int)Math.Floor((float)(Math.Max(pt1.Y, pt2.Y) + viewOffset.Y) / (float)mImageListView.layoutManager.ItemSizeWithMargin.Height); int startCol = (int)Math.Floor((float)(Math.Min(pt1.X, pt2.X) + viewOffset.X) / (float)mImageListView.layoutManager.ItemSizeWithMargin.Width); int endCol = (int)Math.Floor((float)(Math.Max(pt1.X, pt2.X) + viewOffset.X) / (float)mImageListView.layoutManager.ItemSizeWithMargin.Width); if (mImageListView.ScrollOrientation == ScrollOrientation.HorizontalScroll && (startRow >= 0 || endRow >= 0)) { for (int i = startCol; i <= endCol; i++) { for (int col = startCol; col <= endCol; col++) { if (i >= 0 && i <= mImageListView.Items.Count - 1 && !highlightedItems.ContainsKey(mImageListView.Items[i])) { highlightedItems.Add(mImageListView.Items[i], (ControlKey ? !mImageListView.Items[i].Selected : true)); } } } } else if (mImageListView.ScrollOrientation == ScrollOrientation.VerticalScroll && (startCol >= 0 || endCol >= 0) && (startRow >= 0 || endRow >= 0) && (startCol <= mImageListView.layoutManager.Cols - 1 || endCol <= mImageListView.layoutManager.Cols - 1)) { startCol = Math.Min(mImageListView.layoutManager.Cols - 1, Math.Max(0, startCol)); endCol = Math.Min(mImageListView.layoutManager.Cols - 1, Math.Max(0, endCol)); for (int row = startRow; row <= endRow; row++) { for (int col = startCol; col <= endCol; col++) { int i = row * mImageListView.layoutManager.Cols + col; if (i >= 0 && i <= mImageListView.Items.Count - 1 && !highlightedItems.ContainsKey(mImageListView.Items[i])) { highlightedItems.Add(mImageListView.Items[i], (ControlKey ? !mImageListView.Items[i].Selected : true)); } } } } HoveredColumn = null; HoveredSeparator = null; SelectedSeperator = null; mImageListView.Refresh(); } else if (!MouseSelecting && !DraggingSeperator && !ResizingPane && inItemArea && lastMouseDownInItemArea && (LeftButton || RightButton) && ((Math.Abs(e.Location.X - lastMouseDownLocation.X) > SelectionTolerance || Math.Abs(e.Location.Y - lastMouseDownLocation.Y) > SelectionTolerance))) { if (!lastMouseDownOverItem && HoveredItem == null) { // Start mouse selection MouseSelecting = true; SelectionRectangle = new Rectangle(lastMouseDownLocation, new Size(0, 0)); mImageListView.Refresh(); } else if (lastMouseDownOverItem && HoveredItem != null && mImageListView.AllowDrag) { // Start drag&drop if (!HoveredItem.Selected) { mImageListView.SelectedItems.Clear(false); HoveredItem.mSelected = true; mImageListView.OnSelectionChangedInternal(); DropTarget = null; mImageListView.Refresh(true); } // Set drag data List <string> filenames = new List <string>(); foreach (ImageListViewItem item in mImageListView.SelectedItems) { if (item.isVirtualItem) { // Get the virtual item source image VirtualItemImageEventArgs ve = new VirtualItemImageEventArgs(item.mVirtualItemKey); mImageListView.RetrieveVirtualItemImageInternal(ve); if (!string.IsNullOrEmpty(ve.FileName)) { filenames.Add(ve.FileName); } } else { filenames.Add(item.FileName); } } DataObject data = new DataObject(DataFormats.FileDrop, filenames.ToArray()); DropTarget = null; selfDragging = true; mImageListView.DoDragDrop(data, DragDropEffects.Copy); selfDragging = false; // Since the MouseUp event will be eaten by DoDragDrop we will not receive // the MouseUp event. We need to manually update mouse button flags after // the drop. if ((Control.MouseButtons & MouseButtons.Left) == MouseButtons.None) { LeftButton = false; } if ((Control.MouseButtons & MouseButtons.Right) == MouseButtons.None) { RightButton = false; } } } else if (!MouseSelecting && !DraggingSeperator && !ResizingPane && inHeaderArea && lastMouseDownInColumnHeaderArea && lastMouseDownOverSeparator && LeftButton && mImageListView.AllowColumnResize && HoveredSeparator != null) { // Start dragging a separator DraggingSeperator = true; SelectedSeperator = HoveredSeparator; lastSeparatorDragLocation = e.Location; } else if (!MouseSelecting && !DraggingSeperator && !ResizingPane && inPaneArea && lastMouseDownInPaneArea && lastMouseDownOverPaneBorder && LeftButton && mImageListView.AllowPaneResize && HoveredPaneBorder != false) { // Start dragging the pane ResizingPane = true; lastPaneResizeLocation = e.Location; } else if (!ReferenceEquals(HoveredItem, oldHoveredItem) || !ReferenceEquals(HoveredColumn, oldHoveredColumn) || !ReferenceEquals(HoveredSeparator, oldHoveredSeparator)) { // Hovered item changed if (!ReferenceEquals(HoveredItem, oldHoveredItem)) { mImageListView.OnItemHover(new ItemHoverEventArgs(HoveredItem, oldHoveredItem)); } if (!ReferenceEquals(HoveredColumn, oldHoveredColumn)) { mImageListView.OnColumnHover(new ColumnHoverEventArgs(HoveredColumn, oldHoveredColumn)); } mImageListView.Refresh(); } mImageListView.mRenderer.ResumePaint(); // Change to size cursor if mouse is over a column separator or pane border if (mImageListView.Cursor != Cursors.VSplit && mImageListView.Focused && !MouseSelecting) { if ((mImageListView.AllowColumnResize && HoveredSeparator != null) || (mImageListView.AllowPaneResize && HoveredPaneBorder != false)) { mImageListView.Cursor = Cursors.VSplit; } } else if (mImageListView.Cursor == Cursors.VSplit) { if (!((inHeaderArea && (DraggingSeperator || HoveredSeparator != null)) || (inPaneArea && (ResizingPane || HoveredPaneBorder != false)))) { mImageListView.Cursor = Cursors.Default; } } lastMouseMoveLocation = e.Location; }