97 lines
4.5 KiB
Python
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()
|