emmental/emmental/tracklist/trackview.py
Anna Schumaker 70d7f5fa70 tracklist: Use the Gtk.ColumnView.scroll_to() function for scrolling
Rather than trying to implement this myself through manually moving the
scrolled window. It's much easier to simply let Gtk do the work for us.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-08-30 13:40:22 -04:00

97 lines
4.5 KiB
Python

# Copyright 2022 (c) Anna Schumaker.
"""A Gtk.ColumnView for displaying Tracks."""
from gi.repository import GObject
from gi.repository import Gio
from gi.repository import Gtk
from .. import db
from .. import factory
from .. import playlist
from . import row
class TrackView(Gtk.ScrolledWindow):
"""A Gtk.ColumnView that has been configured to show Tracks."""
playlist = GObject.Property(type=playlist.playlist.Playlist)
n_tracks = GObject.Property(type=int)
runtime = GObject.Property(type=float)
n_selected = GObject.Property(type=int)
have_selected = GObject.Property(type=bool, default=False)
def __init__(self, sql: db.Connection, **kwargs):
"""Initialize a TrackView."""
super().__init__(**kwargs)
self._filtermodel = Gtk.FilterListModel(filter=sql.tracks.get_filter(),
incremental=True)
self._selection = Gtk.MultiSelection(model=self._filtermodel)
self._columnview = Gtk.ColumnView(hexpand=True, vexpand=True,
show_row_separators=True,
enable_rubberband=True,
model=self._selection)
self.__append_column("Art", "cover", row.AlbumCover, resizable=False)
self.__append_column("Fav", "favorite", row.FavoriteButton,
resizable=False)
self.__append_column("Track", "number", row.TracknoString,
width=55, xalign=1.0, numeric=True)
self.__append_column("Title", "title", row.TrackString, width=300)
self.__append_column("Length", "length", row.LengthString,
xalign=1.0, numeric=True)
self.__append_column("Artist", "artist", row.TrackString, width=250)
self.__append_column("Album", "name", row.MediumString, width=350)
self.__append_column("Album Artist", "artist", row.AlbumString,
width=250, visible=False)
self.__append_column("Release", "release", row.AlbumString,
width=115, numeric=True)
self.__append_column("Play Count", "playcount", row.PlayCountString,
width=135, numeric=True)
self.__append_column("Last Started", "laststarted",
row.TimestampString, width=250,
visible=False, numeric=True)
self.__append_column("Last Played", "lastplayed",
row.TimestampString, width=250, numeric=True)
self.__append_column("Filepath", "path", row.PathString, visible=False)
self.bind_property("playlist", self._filtermodel, "model")
self._selection.bind_property("n-items", self, "n-tracks")
self._selection.connect("items-changed", self.__runtime_changed)
self._columnview.connect("activate", self.__track_activated)
self._columnview.add_css_class("emmental-track-list")
self.set_child(self._columnview)
def __append_column(self, title: str, property: str, row_type: type,
*, width: int = -1, visible: bool = True,
resizable: bool = True, **kwargs) -> None:
fctry = factory.Factory(row_type=row_type, property=property, **kwargs)
col = Gtk.ColumnViewColumn(title=title, factory=fctry, visible=visible,
resizable=resizable, fixed_width=width)
self._columnview.append_column(col)
def __runtime_changed(self, selection: Gtk.MultiSelection,
position: int, removed: int, added: int) -> None:
self.runtime = sum(t.length for t in self._selection)
def __track_activated(self, columnview: Gtk.ColumnView,
position: int) -> None:
self.playlist.request_track(self._selection[position])
self._selection.unselect_all()
def scroll_to_track(self, track: db.tracks.Track) -> None:
"""Scroll to the requested Track."""
for i in range(self._selection.props.n_items):
if self._selection[i] == track:
self._columnview.scroll_to(i, None, Gtk.ListScrollFlags.NONE)
@GObject.Property(type=Gio.ListModel)
def columns(self) -> Gio.ListModel:
"""Get the ListModel for the columns."""
return self._columnview.get_columns()
@GObject.Property(type=Gio.ListModel)
def selection_model(self) -> Gio.ListModel:
"""Get the SelectionModel for the ColumnView."""
return self._columnview.get_model()