private void mnuPlayFile_Click(object sender, EventArgs e) { if (songListView1.SelectedItems.Count != 0) { SongListViewItem item = songListView1.SelectedItems[0]; this.Player.PlayFile(item.SongInfo.FileName); } }
private void Player_SongOpened(object sender, SongEventArgs e) { SongListViewItem item = FindItem(e.Song.FileName); if (item != null) { list.InvalidateItem(item); } }
internal void InvalidateItem(SongListViewItem item) { var r = new Rectangle(item.Rectangle.Location, item.Rectangle.Size); r.Offset(this.AutoScrollPosition); this.Invalidate(r); if (item.IsStartOfNewAlbum) { r = new Rectangle(item.AlbumRectangle.Location, item.AlbumRectangle.Size); r.Offset(this.AutoScrollPosition); this.Invalidate(r); } }
private void HandleControlMouseSelection(SongListViewItem item) { // If the user's holding down ctrl, add or remove this item but ignore the others if (_selectedItems.Contains(item)) { _selectedItems.Remove(item); } else { _selectedItems.Add(item); } _lastClickedIndex = item.Index; }
private void Library_LibraryUpdated(object sender, LibraryEntryEventArgs e) { if (e.LibraryEntry == null) { return; } SongListViewItem item = FindItem(e.LibraryEntry.FileName); if (item != null) { item.SongInfo = e.LibraryEntry; list.InvalidateItem(item); } }
/// <summary> /// Retrieves the item at the specified location. /// </summary> /// <param name="x">The x-coordinate of the location to search for an item (expressed in client coordinates).</param> /// <param name="y">The y-coordinate of the location to search for an item (expressed in client coordinates).</param> /// <returns> /// A SongListViewItem that represents the item at the specified position. If there is no item /// at the specified location, the method returns null. /// </returns> public SongListViewItem GetItemAt(int x, int y) { SongListViewItem result = null; for (int i = 0; i < _items.Count; i++) { SongListViewItem item = _items[i]; if (item.Rectangle.Top <= y && item.Rectangle.Bottom >= y && item.Rectangle.Left <= x) { result = item; break; } } return(result); }
protected override void OnMouseUp(MouseEventArgs e) { if (_mouseUpSelect) { int x = e.X - this.AutoScrollPosition.X; int y = e.Y - this.AutoScrollPosition.Y; SongListViewItem item = GetItemAt(x, y); if (item != null) { HandleMouseSelection(e, item); _mouseUpSelect = false; } } base.OnMouseUp(e); }
private void HandleNormalMouseSelection(bool rightButtonClicked, SongListViewItem item) { // If the user's not holding down a key, just select this item and deselect every other one // I lied a little just there. If the user is right-clicking on an already selected item, // we want to leave the selection as is if (rightButtonClicked && _selectedItems.Contains(item)) { // Pretty much don't do anything... } else { _selectedItems.Clear(); _selectedItems.Add(item); _lastClickedIndex = item.Index; } }
private void HandleMouseSelection(MouseEventArgs e, SongListViewItem item) { if (Control.ModifierKeys == Keys.Control) { HandleControlMouseSelection(item); } else if (Control.ModifierKeys == Keys.Shift && _lastClickedIndex != -1) { HandleShiftMouseSelection(item); } else { bool rightButtonClicked = (e.Button == MouseButtons.Right); HandleNormalMouseSelection(rightButtonClicked, item); } this.Invalidate(); }
private void HandleShiftMouseSelection(SongListViewItem clickedItem) { // If the user's holding down shift, add everything between this item and the last clicked item _selectedItems.Clear(); // Get the index of the selected item int selectedIndex = clickedItem.Index; _items.ForEach(delegate(SongListViewItem item) { if ((item.Index >= _lastClickedIndex && item.Index <= selectedIndex) || (item.Index <= _lastClickedIndex && item.Index >= selectedIndex)) { _selectedItems.Add(item); } }); }
private void list_DragOver(object sender, DragEventArgs e) { if (e.Effect == DragDropEffects.None) { return; } Point p = list.PointToClient(new Point(e.X, e.Y)); SongListViewItem item = list.GetItemAt(p.X - list.AutoScrollPosition.X, p.Y - list.AutoScrollPosition.Y); if (item != null) { list.DragIndex = item.Index; } else { list.DragIndex = -1; } list.Invalidate(); }
internal void ReCreateAndMeasure() { _creating = true; SongListViewItem prevItem = null; int i = 0; foreach (SongListViewItem item in _items) { if (prevItem != null) { prevItem.NextItem = item; } item.PreviousItem = prevItem; item.Index = i; prevItem = item; i++; } MeasureItems(); _creating = false; }
private void CreateOrAddItem(List <SongListViewItem> itemsToAdd, string file) { SongListViewItem myOld = FindItem(file); if (myOld == null) { var item = new SongListViewItem(list); SongInfo song = this.Library.GetSong(file); if (song == null) { song = new LibraryEntry(file); } item.SongInfo = song; item.AlbumDisplay = item.SongInfo.Album; itemsToAdd.Add(item); } else { list.Items.Remove(myOld); itemsToAdd.Add(myOld); } }
private void mnuQueueAlbum_Click(object sender, EventArgs e) { if (songListView1.SelectedItems.Count != 0) { // Just get the album of the first selected song SongListViewItem selectedItem = songListView1.SelectedItems[0]; string album = selectedItem.SongInfo.Album; LibraryEntry[] songs = this.Library.QueryLibrary("Album LIKE '" + album.Replace("'", "''") + "'"); foreach (LibraryEntry item in songs) { if (item.FileName.Equals(this.Player.CurrentSong.FileName) || this.Player.Playlist.Contains(item.FileName)) { // do nothing } else { this.Player.Playlist.AddToEnd(item); } } } }
protected override void OnMouseDown(MouseEventArgs e) { this.Focus(); int x = e.X - this.AutoScrollPosition.X; int y = e.Y - this.AutoScrollPosition.Y; SongListViewItem item = GetItemAt(x, y); if (item != null) { // If the user moused down on a selected item, wait until mouse up to change the selection // so that dragging works smoothly. This seems to be what the ListView does if (_selectedItems.Contains(item)) { _mouseUpSelect = true; } else { HandleMouseSelection(e, item); } if (e.Button == MouseButtons.Right) { if (_itemContextMenuStrip != null) { _itemContextMenuStrip.Show(this, e.Location); } } } else { _selectedItems.Clear(); _lastClickedIndex = -1; Invalidate(); } base.OnMouseDown(e); }
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (this.SelectedItems.Count > 0) { SongListViewItem oldItem = null; SongListViewItem newItem = null; switch (keyData) { case Keys.Up: { oldItem = this.SelectedItems[0]; newItem = oldItem.PreviousItem; break; } case Keys.Down: { oldItem = this.SelectedItems[0]; newItem = oldItem.NextItem; break; } } if (oldItem != null && newItem != null) { newItem.EnsureVisible(); this.SelectedItems.Clear(); this.SelectedItems.Add(newItem); _lastClickedIndex = newItem.Index; Invalidate(); return(true); } } return(base.ProcessCmdKey(ref msg, keyData)); }
private void SongListView_MouseDown(object sender, MouseEventArgs e) { if ((e.Button & MouseButtons.Left) == MouseButtons.Left) { // Get the index of the item the mouse is over SongListViewItem item = list.GetItemAt(e.X, e.Y); if (item != null) { // Remember the point where the mouse down occurred. The DragSize indicates // the size that the mouse can move before a drag event should be started Size dragSize = SystemInformation.DragSize; // Create a rectangle using the DragSize, with the mouse position being // at the center of the rectangle _dragBox = new Rectangle(new Point(e.X - (dragSize.Width / 2), e.Y - (dragSize.Height / 2)), dragSize); } else { // Reset the rectangle if the mouse is not over an item in the ListBox _dragBox = Rectangle.Empty; } } }
protected override void OnPaint(PaintEventArgs e) { if (_songListView == null) { return; } using (var foreColorBrush = new SolidBrush(this.ForeColor)) { using (Pen linePen = new Pen(_lineColor), linePenLight = new Pen(_lineColorLight)) { var rect = new RectangleF(this.XOffset, 0, _songListView.TitleColumnWidth, this.Height); if (!_songListView.FlatMode) { SongListViewItem.DrawColumn(e.Graphics, ref rect, "Album", _songListView.WidestAlbum, this.Font, foreColorBrush); } else { rect.X += _songListView.WidestAlbum; } rect.X += _songListView.StatusColumnWidth; SongListViewItem.DrawColumn(e.Graphics, ref rect, "#", _songListView.TrackNumberColumnWidth, this.Font, foreColorBrush); e.Graphics.DrawLine(linePen, rect.Left - 1, 0, rect.Left - 1, this.Height - 3); e.Graphics.DrawLine(linePenLight, rect.Left, 0, rect.Left, this.Height - 3); _colWidths[0] = Convert.ToInt32(rect.Left); SongListViewItem.DrawColumn(e.Graphics, ref rect, "Title", _songListView.TitleColumnWidth, this.Font, foreColorBrush); e.Graphics.DrawLine(linePen, rect.Left - 1, 0, rect.Left - 1, this.Height - 3); e.Graphics.DrawLine(linePenLight, rect.Left, 0, rect.Left, this.Height - 3); _colWidths[1] = Convert.ToInt32(rect.Left); SongListViewItem.DrawColumn(e.Graphics, ref rect, "Artist", _songListView.ArtistColumnWidth, this.Font, foreColorBrush); e.Graphics.DrawLine(linePen, rect.Left - 1, 0, rect.Left - 1, this.Height - 3); e.Graphics.DrawLine(linePenLight, rect.Left, 0, rect.Left, this.Height - 3); _colWidths[2] = Convert.ToInt32(rect.Left); if (_songListView.FlatMode) { SongListViewItem.DrawColumn(e.Graphics, ref rect, "Album", _songListView.AlbumColumnWidth, this.Font, foreColorBrush); e.Graphics.DrawLine(linePen, rect.Left - 1, 0, rect.Left - 1, this.Height - 3); e.Graphics.DrawLine(linePenLight, rect.Left, 0, rect.Left, this.Height - 3); _colWidths[3] = Convert.ToInt32(rect.Left); } SongListViewItem.DrawColumn(e.Graphics, ref rect, "Duration", _songListView.DurationColumnWidth, this.Font, foreColorBrush); e.Graphics.DrawLine(linePen, rect.Left - 1, 0, rect.Left - 1, this.Height - 3); e.Graphics.DrawLine(linePenLight, rect.Left, 0, rect.Left, this.Height - 3); _colWidths[(_songListView.FlatMode ? 4 : 3)] = Convert.ToInt32(rect.Left); SongListViewItem.DrawColumn(e.Graphics, ref rect, "Play Count", -1, this.Font, foreColorBrush); e.Graphics.DrawLine(linePen, 0, this.Height - 2, this.Width, this.Height - 2); // Check whether the header text is larger than the auto-size stuff in the columns MaybeSetColumnAutoWidth(0, "#", e.Graphics); MaybeSetColumnAutoWidth(1, "Title", e.Graphics); MaybeSetColumnAutoWidth(2, "Artist", e.Graphics); MaybeSetColumnAutoWidth(3, "Album", e.Graphics); MaybeSetColumnAutoWidth(4, "Duration", e.Graphics); MaybeSetColumnAutoWidth(5, "Play Count", e.Graphics); } } }
private void list_DragDrop(object sender, DragEventArgs e) { if (e.Effect == DragDropEffects.None) { return; } Point p = list.PointToClient(new Point(e.X, e.Y)); SongListViewItem item = list.GetItemAt(p.X - list.AutoScrollPosition.X, p.Y - list.AutoScrollPosition.Y); this.UseWaitCursor = true; var itemsToAdd = new List <SongListViewItem>(); if (e.Data.GetDataPresent(typeof(SongListViewItem[]))) { foreach (SongListViewItem old in (SongListViewItem[])e.Data.GetData(typeof(SongListViewItem[]))) { SongListViewItem myOld = FindItem(old.SongInfo.FileName); if (myOld != null) { list.Items.Remove(myOld); itemsToAdd.Add(myOld); } else { var newItem = new SongListViewItem(list); newItem.SongInfo = old.SongInfo; newItem.AlbumDisplay = old.AlbumDisplay; itemsToAdd.Add(newItem); } } list.ReCreateAndMeasure(); } else if (e.Data.GetDataPresent(DataFormats.FileDrop)) { // get the files, add them, and stuff string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (string file in files) { if (File.Exists(file)) { if (Array.IndexOf(this.Player.SupportedExtensions, "*" + Path.GetExtension(file)) != -1) { CreateOrAddItem(itemsToAdd, file); } } else if (Directory.Exists(file)) { string[] files2 = Directory.GetFiles(file, "*", SearchOption.AllDirectories); foreach (string file2 in files2) { if (Array.IndexOf(this.Player.SupportedExtensions, "*" + Path.GetExtension(file2)) != -1) { CreateOrAddItem(itemsToAdd, file2); } } } } } if (item == null) { list.Items.AddRange(itemsToAdd); } else { list.Items.InsertRange(item.Index, itemsToAdd); } list.ReCreateAndMeasure(); list.DragIndex = -1; list.Invalidate(); ListChanged?.Invoke(this, EventArgs.Empty); this.UseWaitCursor = false; }
internal void MeasureItems() { int right = 0; int bottom = 0; if (_items == null || _items.Count == 0) { // create a temp bitmap to work with var btm = new Bitmap(10, 10, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var g = Graphics.FromImage(btm); SizeF s = SongListViewItem.MeasureColumn(g, NoResultsString, -1, this.Font); right = Convert.ToInt32(s.Width); bottom = Convert.ToInt32(s.Height); } else { // create a temp bitmap to work with var btm = new Bitmap(10, 10, System.Drawing.Imaging.PixelFormat.Format32bppArgb); var g = Graphics.FromImage(btm); _widestalbum = 0; // just measure the albums first, so we know how wide the widest one is if (_showAlbumArt) { _items.ForEach(delegate(SongListViewItem item) { if (item.IsStartOfNewAlbum) { item.MeasureAlbum(g, 0, 0, _headerFont, this.Font); _widestalbum = Math.Max(_widestalbum, item.AlbumRectangle.Right + 1); } }); } else { _widestalbum = 0; } // now unfortunately we have to remeasure everything, since the albums have moved int y = 0; int lastAlbumBottom = 0; _items.ForEach(delegate(SongListViewItem item) { if (item.IsStartOfNewAlbum) { if (y <= lastAlbumBottom) { y = lastAlbumBottom; } // move this album down a bit from the previous one if (!_flatMode) { y += 10; } item.MeasureAlbum(g, 0, y, _headerFont, this.Font); right = Math.Max(right, item.AlbumRectangle.Right); bottom = Math.Max(bottom, item.AlbumRectangle.Bottom); lastAlbumBottom = item.AlbumRectangle.Bottom; } item.MeasureItem(g, _widestalbum, y, this.Font); y = item.Rectangle.Bottom; right = Math.Max(right, item.Rectangle.Right); bottom = Math.Max(bottom, item.Rectangle.Bottom); }); } MethodInvoker DoWork = delegate { this.AutoScrollMinSize = new Size(right + 10, bottom + 10); }; if (this.InvokeRequired) { Invoke(DoWork); } else { DoWork(); } ItemsMeasured?.Invoke(this, EventArgs.Empty); Invalidate(); }
private void CreateItemsSynchronously() { lock (this) { _albumArtLoader.Clear(); _creating = true; DisposeItems(); _items = new List <SongListViewItem>(); ColAutoWidths = new int[6]; if (_dataSource != null && _dataSource.Length > 0) { string lastAlbum = string.Empty; string lastDir = string.Empty; SongListViewItem albumItem = null; SongListViewItem prevItem = null; int flatAlbumWidth = this.Font.Height; int index = 0; foreach (SongInfo info in _dataSource) { var item = new SongListViewItem(this); item.SongInfo = info; item.PreviousItem = prevItem; if (prevItem != null) { prevItem.NextItem = item; } prevItem = item; if (string.IsNullOrEmpty(item.AlbumDisplay)) { item.AlbumDisplay = "Unknown Album"; } if (_flatMode || (lastAlbum != item.SongInfo.Album || lastDir != System.IO.Path.GetDirectoryName(info.FileName))) { // if its not flat mode, and the album name is the same, tack on the path if (!_flatMode && lastAlbum == item.SongInfo.Album) { item.AlbumDisplay = item.AlbumDisplay + " (" + System.IO.Path.GetPathRoot(info.FileName) + ")"; if (item.PreviousItem != null && !item.PreviousItem.AlbumItem.AlbumDisplay.EndsWith(" (" + System.IO.Path.GetPathRoot(item.PreviousItem.SongInfo.FileName) + ")")) { item.PreviousItem.AlbumItem.AlbumDisplay = item.PreviousItem.AlbumItem.AlbumDisplay + " (" + System.IO.Path.GetPathRoot(item.PreviousItem.SongInfo.FileName) + ")"; } } albumItem = item; item.IsStartOfNewAlbum = true; if (_showAlbumArt && _flatMode) { item.AlbumArtSize = flatAlbumWidth; // This is never true, because our SongInfo objects come from the database.. should be store album art? if (info.HasFrontCover) { item.AlbumArt = info.GetFrontCover(flatAlbumWidth, flatAlbumWidth); } else { _albumArtLoader.LoadAlbumArt(item, info.FileName, flatAlbumWidth, flatAlbumWidth); } } else { if (_showAlbumArt && _albumArtSize > 0) { item.AlbumArtSize = _albumArtSize; if (info.HasFrontCover) { item.AlbumArt = info.GetFrontCover(_albumArtSize, _albumArtSize); } else { _albumArtLoader.LoadAlbumArt(item, info.FileName, _albumArtSize, _albumArtSize); } } } lastAlbum = item.SongInfo.Album; lastDir = System.IO.Path.GetDirectoryName(info.FileName); } item.AlbumItem = albumItem; item.Index = index; _items.Add(item); index += 1; // Set the auto-sizing info for the columns int spacer = 1; Graphics g; try { g = this.CreateGraphics(); } catch (ThreadStateException) { return; } Font titleFont = this.Font; if (this.ListView.Player.CurrentSong != null && this.ListView.Player.CurrentSong.FileName.Equals(info.FileName)) { titleFont = this.CurrentSongFont; } Font regularFont = this.Font; if (string.IsNullOrEmpty(info.Title)) { MaybeSetColumnAutoWidth(0, (int)g.MeasureString(info.FileName, titleFont).Width + spacer); // Skip the next couple of columns because they are taken up by the file name if (info is LibraryEntry entry) { MaybeSetColumnAutoWidth(5, (int)g.MeasureString(entry.PlayCount.ToString(), regularFont).Width + spacer); } } else { if (info.TrackNumber > 0) { MaybeSetColumnAutoWidth(0, (int)g.MeasureString(info.TrackNumber.ToString(), regularFont).Width + spacer); } MaybeSetColumnAutoWidth(1, (int)g.MeasureString(info.Title, titleFont).Width + spacer); MaybeSetColumnAutoWidth(2, (int)g.MeasureString(info.Artist, regularFont).Width + spacer); if (this.FlatMode) { MaybeSetColumnAutoWidth(3, (int)g.MeasureString(info.Album, regularFont).Width + spacer); } MaybeSetColumnAutoWidth(4, (int)g.MeasureString(info.DurationDescription, regularFont).Width + spacer); if (info is LibraryEntry entry) { MaybeSetColumnAutoWidth(5, (int)g.MeasureString(entry.PlayCount.ToString(), regularFont).Width + spacer); } } } } } MeasureItems(); this.SelectedItems.Clear(); _lastClickedIndex = -1; _creating = false; }