/// <summary> /// Occurs when the mouse pointer is moving over the control. /// Manages the display of mouse on/off visual effects. /// </summary> public void MouseMove(float x, float y, MouseButtonType button) { //Console.WriteLine("SongGridViewControl - MouseMove - x: {0} y: {1}", x, y); bool controlNeedsToBeFullyInvalidated = false; bool controlNeedsToBePartiallyInvalidated = false; var partialRect = new BasicRectangle(); if (_columns == null || _songCache == null) return; // Calculate album cover art width int albumArtCoverWidth = _columns[0].Visible ? _columns[0].Width : 0; // Check if the user is currently resizing a column (loop through columns) foreach (var column in _songCache.ActiveColumns) { // Check if the user is currently resizing this column if (column.IsUserResizingColumn && column.Visible) { // Calculate the new column width int newWidth = _dragOriginalColumnWidth - (_dragStartX - (int)x); // Make sure the width isn't lower than the minimum width if (newWidth < MinimumColumnWidth) newWidth = MinimumColumnWidth; // Set column width column.Width = newWidth; // Refresh control (invalidate whole control) controlNeedsToBeFullyInvalidated = true; InvalidateSongCache(); // Auto adjust horizontal scrollbar value if it exceeds the value range (i.e. do not show empty column) if (HorizontalScrollBar.Value > HorizontalScrollBar.Maximum - HorizontalScrollBar.LargeChange) { // Set new value int tempValue = HorizontalScrollBar.Maximum - HorizontalScrollBar.LargeChange; if (tempValue < 0) tempValue = 0; HorizontalScrollBar.Value = tempValue; } } // Check if the user is moving the column if (column.IsMouseOverColumnHeader && column.CanBeMoved && CanMoveColumns && _isUserHoldingLeftMouseButton && !IsColumnResizing) { // Check if the X position has changed by at least 2 pixels (i.e. dragging) if (_dragStartX >= x + 2 || _dragStartX <= x - 2) { // Set resizing column flag column.IsUserMovingColumn = true; } } // Check if the user is currently moving this column if (column.IsUserMovingColumn) { // Loop through columns int currentX = 0; foreach (SongGridViewColumn columnOver in _songCache.ActiveColumns) { // Check if column is visible if (columnOver.Visible) { // Check if the cursor is over the left part of the column if (x >= currentX - HorizontalScrollBar.Value && x <= currentX + (columnOver.Width / 2) - HorizontalScrollBar.Value) _columnMoveMarkerX = (int)x; // Check if the cursor is over the right part of the column else if (x >= currentX + (columnOver.Width / 2) - HorizontalScrollBar.Value && x <= currentX + columnOver.Width - HorizontalScrollBar.Value) _columnMoveMarkerX = (int)x + columnOver.Width; x += columnOver.Width; } } controlNeedsToBeFullyInvalidated = true; } } if (!IsColumnMoving) { // Check if the cursor needs to be changed int offsetX = 0; bool mousePointerIsOverColumnLimit = false; foreach (var column in _songCache.ActiveColumns) { if (column.Visible) { // Increment offset by the column width offsetX += column.Width; if (column.CanBeResized) { // Check if the mouse pointer is over a column (add 1 pixel so it's easier to select) if (x >= offsetX - HorizontalScrollBar.Value && x <= offsetX + 1 - HorizontalScrollBar.Value) { mousePointerIsOverColumnLimit = true; column.IsMouseCursorOverColumnLimit = true; OnChangeMouseCursorType(MouseCursorType.VSplit); } else { column.IsMouseCursorOverColumnLimit = false; } } } } // Check if the default cursor needs to be restored if (!mousePointerIsOverColumnLimit) OnChangeMouseCursorType(MouseCursorType.Default); int columnOffsetX2 = 0; for (int b = 0; b < _songCache.ActiveColumns.Count; b++) { var column = _songCache.ActiveColumns[b]; if (column.Visible) { // Was mouse over this column header? if (column.IsMouseOverColumnHeader) { // Invalidate region column.IsMouseOverColumnHeader = false; var newPartialRect = new BasicRectangle(columnOffsetX2 - HorizontalScrollBar.Value, 0, column.Width, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } // Increment offset columnOffsetX2 += column.Width; } } // Check if the mouse pointer is over the header if (y >= 0 && y <= _songCache.LineHeight) { // Check on what column the user has clicked int columnOffsetX = 0; for (int a = 0; a < _songCache.ActiveColumns.Count; a++) { var column = _songCache.ActiveColumns[a]; if (column.Visible) { // Check if the mouse pointer is over this column if (x >= columnOffsetX - HorizontalScrollBar.Value && x <= columnOffsetX + column.Width - HorizontalScrollBar.Value) { // Invalidate region column.IsMouseOverColumnHeader = true; var newPartialRect = new BasicRectangle(columnOffsetX - HorizontalScrollBar.Value, 0, column.Width, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; break; } columnOffsetX += column.Width; } } } // Check if the mouse cursor is over a line (loop through lines) int offsetY = 0; //int scrollbarOffsetY = (_startLineNumber * _songCache.LineHeight) - VerticalScrollBar.Value; // Check if there's at least one item if (_items.Count > 0) { // Reset mouse over item flags for (int b = _startLineNumber; b < _startLineNumber + _numberOfLinesToDraw; b++) { //Console.WriteLine("SongGridViewControl - MouseMove - Checking for resetting mouse over flag for line {0}", b); // Check if the mouse was over this item if (_items[b].IsMouseOverItem) { // Reset flag and invalidate region //Console.WriteLine("SongGridViewControl - MouseMove - Resetting mouse over flag for line {0}", b); _items[b].IsMouseOverItem = false; //OnInvalidateVisualInRect(new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, ((b - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, _songCache.LineHeight)); break; } } // Put new mouse over flag for (int a = _startLineNumber; a < _startLineNumber + _numberOfLinesToDraw; a++) { // Calculate offset offsetY = (a * _songCache.LineHeight) - VerticalScrollBar.Value + _songCache.LineHeight; //Console.WriteLine("SongGridViewControl - MouseMove - Checking for setting mouse over flag for line {0} - offsetY: {1}", a, offsetY); // Check if the mouse cursor is over this line (and not already mouse over) if (x >= albumArtCoverWidth - HorizontalScrollBar.Value && y >= offsetY && y <= offsetY + _songCache.LineHeight && !_items[a].IsEmptyRow && !_items[a].IsMouseOverItem) { // Set item as mouse over //Console.WriteLine("SongGridViewControl - MouseMove - Mouse is over item {0} {1}/{2}/{3}", a, _items[a].AudioFile.ArtistName, _items[a].AudioFile.AlbumTitle, _items[a].AudioFile.Title); _items[a].IsMouseOverItem = true; // Invalidate region and update control //OnInvalidateVisualInRect(new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, offsetY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, _songCache.LineHeight)); //controlNeedsToBeFullyInvalidated = true; break; } } } } if (controlNeedsToBeFullyInvalidated) OnInvalidateVisual(); else if (controlNeedsToBePartiallyInvalidated) OnInvalidateVisualInRect(partialRect); }
public void MouseClick(float x, float y, MouseButtonType button, KeysHeld keysHeld) { bool controlNeedsToBeFullyInvalidated = false; bool controlNeedsToBePartiallyInvalidated = false; var partialRect = new BasicRectangle(); if (_columns == null || _songCache == null) return; // Show context menu strip if the button click is right and not the album art column if (button == MouseButtonType.Right && x > _columns[0].Width && y > _songCache.LineHeight) OnDisplayContextMenu(ContextMenuType.Item, x, y); int albumArtCoverWidth = _columns[0].Visible ? _columns[0].Width : 0; var columnResizing = _columns.FirstOrDefault(col => col.IsUserResizingColumn == true); int scrollbarOffsetY = (_startLineNumber * _songCache.LineHeight) - VerticalScrollBar.Value; // Check if the user has clicked on the header (for orderBy) if (y >= 0 && y <= _songCache.LineHeight && columnResizing == null && !IsColumnMoving) { // Check on what column the user has clicked int offsetX = 0; for (int a = 0; a < _songCache.ActiveColumns.Count; a++) { var column = _songCache.ActiveColumns[a]; if (column.Visible) { // Check if the mouse pointer is over this column if (x >= offsetX - HorizontalScrollBar.Value && x <= offsetX + column.Width - HorizontalScrollBar.Value) { if (button == MouseButtonType.Left && CanChangeOrderBy) { // Check if the column order was already set if (_orderByFieldName == column.FieldName) { // Reverse ascending/descending _orderByAscending = !_orderByAscending; } else { // Set order by field name _orderByFieldName = column.FieldName; _orderByAscending = true; } //_items = null; _songCache = null; // Raise column click event (if an event is subscribed) if (OnColumnClick != null) { var data = new SongGridViewColumnClickData(); data.ColumnIndex = a; OnColumnClick(data); } OnInvalidateVisual(); return; } else if (button == MouseButtonType.Right) { //// Refresh column visibility in menu before opening //foreach (ToolStripMenuItem menuItem in _menuColumns.Items) //{ // SongGridViewColumn menuItemColumn = _columns.FirstOrDefault(x => x.Title == menuItem.Tag.ToString()); // if (menuItemColumn != null) // menuItem.Checked = menuItemColumn.Visible; //} OnDisplayContextMenu(ContextMenuType.Header, x, y); } } offsetX += column.Width; } } } // Loop through visible lines to find the original selected items var tuple = GetStartIndexAndEndIndexOfSelectedRows(); int startIndex = tuple.Item1; int endIndex = tuple.Item2; // Make sure the indexes are set if (startIndex > -1 && endIndex > -1) { // Invalidate the original selected lines int startY = ((startIndex - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY; int endY = ((endIndex - _startLineNumber + 2) * _songCache.LineHeight) + scrollbarOffsetY; var newPartialRect = new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, startY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, endY - startY); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } // Reset selection (make sure SHIFT or CTRL isn't held down) if (!keysHeld.IsShiftKeyHeld && !keysHeld.IsCtrlKeyHeld) { // Make sure the mouse is over at least one item var mouseOverItem = _items.FirstOrDefault(item => item.IsMouseOverItem == true); if (mouseOverItem != null) ResetSelection(); } // Loop through visible lines to update the new selected items bool invalidatedNewSelection = false; for (int a = _startLineNumber; a < _startLineNumber + _numberOfLinesToDraw; a++) { // Check if mouse is over this item if (_items[a].IsMouseOverItem) { invalidatedNewSelection = true; // Check if SHIFT is held if (keysHeld.IsShiftKeyHeld) { // Find the start index of the selection int startIndexSelection = _lastItemIndexClicked; if (a < startIndexSelection) startIndexSelection = a; if (startIndexSelection < 0) startIndexSelection = 0; // Find the end index of the selection int endIndexSelection = _lastItemIndexClicked; if (a > endIndexSelection) endIndexSelection = a + 1; // Loop through items to selected for (int b = startIndexSelection; b < endIndexSelection; b++) _items [b].IsSelected = true; controlNeedsToBeFullyInvalidated = true; } // Check if CTRL is held else if(keysHeld.IsCtrlKeyHeld) { // Invert selection _items[a].IsSelected = !_items[a].IsSelected; var newPartialRect = new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, ((a - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } else { // Set this item as the new selected item _items[a].IsSelected = true; var newPartialRect = new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, ((a - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } // Set the last item clicked index _lastItemIndexClicked = a; break; } } // Raise selected item changed event (if an event is subscribed) if (invalidatedNewSelection && OnSelectedIndexChanged != null) { var data = new SongGridViewSelectedIndexChangedData(); OnSelectedIndexChanged(data); } if (controlNeedsToBeFullyInvalidated) OnInvalidateVisual(); else if (controlNeedsToBePartiallyInvalidated) OnInvalidateVisualInRect(partialRect); }
/// <summary> /// Occurs when the user double-clicks on the control. /// Starts the playback of a new song. /// </summary> /// <param name="e">Event arguments</param> public void MouseDoubleClick(float x, float y, MouseButtonType button, KeysHeld keysHeld) { if (_columns == null || _songCache == null) return; var partialRect = new BasicRectangle(); bool controlNeedsToBePartiallyInvalidated = false; int albumArtCoverWidth = _columns[0].Visible ? _columns[0].Width : 0; int scrollbarOffsetY = (_startLineNumber * _songCache.LineHeight) - VerticalScrollBar.Value; // Keep original songId in case the now playing value is set before invalidating the older value Guid originalId = Guid.Empty; // Set original id if (_mode == SongGridViewMode.AudioFile) originalId = _nowPlayingAudioFileId; else if (_mode == SongGridViewMode.Playlist) originalId = _nowPlayingPlaylistItemId; // Loop through visible lines for (int a = _startLineNumber; a < _startLineNumber + _numberOfLinesToDraw; a++) { if (_items[a].IsMouseOverItem) { // Set this item as the new now playing _nowPlayingAudioFileId = _items[a].AudioFile.Id; _nowPlayingPlaylistItemId = _items[a].PlaylistItemId; OnItemDoubleClick(_nowPlayingAudioFileId, a); var newPartialRect = new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, ((a - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } else if (_mode == SongGridViewMode.AudioFile && _items[a].AudioFile != null && _items[a].AudioFile.Id == originalId) { var newPartialRect = new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, ((a - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } else if (_mode == SongGridViewMode.Playlist && _items[a].PlaylistItemId == originalId) { var newPartialRect = new BasicRectangle(albumArtCoverWidth - HorizontalScrollBar.Value, ((a - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY, Frame.Width - albumArtCoverWidth + HorizontalScrollBar.Value, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } } if (controlNeedsToBePartiallyInvalidated) OnInvalidateVisualInRect(partialRect); }
/// <summary> /// Occurs when the mouse cursor leaves the control. /// </summary> public void MouseLeave() { bool controlNeedsToBePartiallyInvalidated = false; var partialRect = new BasicRectangle(); _isMouseOverControl = false; if (_columns == null || _songCache == null) return; int scrollbarOffsetY = (_startLineNumber * _songCache.LineHeight) - VerticalScrollBar.Value; if (_items.Count > 0) { for (int b = _startLineNumber; b < _startLineNumber + _numberOfLinesToDraw; b++) { if (_items[b].IsMouseOverItem) { _items[b].IsMouseOverItem = false; var newPartialRect = new BasicRectangle(_columns[0].Width - HorizontalScrollBar.Value, ((b - _startLineNumber + 1) * _songCache.LineHeight) + scrollbarOffsetY, Frame.Width - _columns[0].Width + HorizontalScrollBar.Value, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; break; } } } // Reset column flags int columnOffsetX2 = 0; for (int b = 0; b < _songCache.ActiveColumns.Count; b++) { if (_songCache.ActiveColumns[b].Visible) { if (_songCache.ActiveColumns[b].IsMouseOverColumnHeader) { _songCache.ActiveColumns[b].IsMouseOverColumnHeader = false; var newPartialRect = new BasicRectangle(columnOffsetX2 - HorizontalScrollBar.Value, 0, _songCache.ActiveColumns[b].Width, _songCache.LineHeight); partialRect.Merge(newPartialRect); controlNeedsToBePartiallyInvalidated = true; } columnOffsetX2 += _songCache.ActiveColumns[b].Width; } } if (controlNeedsToBePartiallyInvalidated) OnInvalidateVisualInRect(partialRect); }