tracklist: Create a basic Tracklist widget
For now it only has the Gtk.CenterBox child with an entry.Filter widget, but this will be expanded on in future patches. I also take the chance to bind the factory:visible-playlist property to the playlist displayed in the tracklist. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
0d27a09233
commit
2c2462c3d6
|
@ -11,6 +11,7 @@ from . import nowplaying
|
||||||
from . import options
|
from . import options
|
||||||
from . import playlist
|
from . import playlist
|
||||||
from . import sidebar
|
from . import sidebar
|
||||||
|
from . import tracklist
|
||||||
from . import window
|
from . import window
|
||||||
from gi.repository import GObject
|
from gi.repository import GObject
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
@ -156,12 +157,19 @@ class Application(Adw.Application):
|
||||||
"show-all-artists")
|
"show-all-artists")
|
||||||
return side_bar
|
return side_bar
|
||||||
|
|
||||||
|
def build_tracklist(self) -> tracklist.Card:
|
||||||
|
"""Build a new tracklist card."""
|
||||||
|
track_list = tracklist.Card(sql=self.db)
|
||||||
|
self.factory.bind_property("visible-playlist", track_list, "playlist")
|
||||||
|
return track_list
|
||||||
|
|
||||||
def build_window(self) -> window.Window:
|
def build_window(self) -> window.Window:
|
||||||
"""Build a new window instance."""
|
"""Build a new window instance."""
|
||||||
win = window.Window(VERSION_STRING,
|
win = window.Window(VERSION_STRING,
|
||||||
header=self.build_header(),
|
header=self.build_header(),
|
||||||
now_playing=self.build_now_playing(),
|
now_playing=self.build_now_playing(),
|
||||||
sidebar=self.build_sidebar())
|
sidebar=self.build_sidebar(),
|
||||||
|
tracklist=self.build_tracklist())
|
||||||
|
|
||||||
for (setting, property) in [("window.width", "default-width"),
|
for (setting, property) in [("window.width", "default-width"),
|
||||||
("window.height", "default-height"),
|
("window.height", "default-height"),
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright 2022 (c) Anna Schumaker.
|
||||||
|
"""A card for displaying a list of tracks."""
|
||||||
|
from gi.repository import GObject
|
||||||
|
from gi.repository import Gtk
|
||||||
|
from .. import db
|
||||||
|
from .. import entry
|
||||||
|
from .. import playlist
|
||||||
|
|
||||||
|
|
||||||
|
class Card(Gtk.Box):
|
||||||
|
"""Our Tracklist."""
|
||||||
|
|
||||||
|
sql = GObject.Property(type=db.Connection)
|
||||||
|
playlist = GObject.Property(type=playlist.playlist.Playlist)
|
||||||
|
|
||||||
|
def __init__(self, sql: db.Connection, **kwargs):
|
||||||
|
"""Set up the Tracklist widget."""
|
||||||
|
super().__init__(sql=sql, orientation=Gtk.Orientation.VERTICAL,
|
||||||
|
spacing=6, **kwargs)
|
||||||
|
self._top_box = Gtk.CenterBox(margin_top=6, margin_start=6,
|
||||||
|
margin_end=6)
|
||||||
|
self._filter = entry.Filter("tracks", hexpand=True,
|
||||||
|
margin_start=100, margin_end=100)
|
||||||
|
|
||||||
|
self._top_box.set_center_widget(self._filter)
|
||||||
|
self.append(self._top_box)
|
||||||
|
|
||||||
|
self._filter.connect("search-changed", self.__search_changed)
|
||||||
|
|
||||||
|
self.add_css_class("card")
|
||||||
|
|
||||||
|
def __search_changed(self, filter: entry.Filter) -> None:
|
||||||
|
self.sql.tracks.filter(filter.get_query())
|
|
@ -109,6 +109,7 @@ class TestEmmental(unittest.TestCase):
|
||||||
self.assertIsInstance(win.header, emmental.header.Header)
|
self.assertIsInstance(win.header, emmental.header.Header)
|
||||||
self.assertIsInstance(win.now_playing, emmental.nowplaying.Card)
|
self.assertIsInstance(win.now_playing, emmental.nowplaying.Card)
|
||||||
self.assertIsInstance(win.sidebar, emmental.sidebar.Card)
|
self.assertIsInstance(win.sidebar, emmental.sidebar.Card)
|
||||||
|
self.assertIsInstance(win.tracklist, emmental.tracklist.Card)
|
||||||
|
|
||||||
self.assertEqual(win.header.title, emmental.VERSION_STRING)
|
self.assertEqual(win.header.title, emmental.VERSION_STRING)
|
||||||
|
|
||||||
|
@ -168,6 +169,22 @@ class TestEmmental(unittest.TestCase):
|
||||||
|
|
||||||
self.assertEqual(win.sidebar.sql, self.application.db)
|
self.assertEqual(win.sidebar.sql, self.application.db)
|
||||||
|
|
||||||
|
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||||
|
def test_tracklist(self, new_callable: io.StringIO):
|
||||||
|
"""Check that the tracklist widget is wired up properly."""
|
||||||
|
self.application.db = emmental.db.Connection()
|
||||||
|
self.application.factory = emmental.playlist.Factory(
|
||||||
|
self.application.db)
|
||||||
|
self.application.player = emmental.audio.Player()
|
||||||
|
win = self.application.build_window()
|
||||||
|
|
||||||
|
self.assertEqual(win.tracklist.sql, self.application.db)
|
||||||
|
|
||||||
|
playlist = self.application.db.playlists.create("Test Playlist")
|
||||||
|
self.application.factory.db_visible = playlist
|
||||||
|
self.assertEqual(win.tracklist.playlist,
|
||||||
|
self.application.factory.visible_playlist)
|
||||||
|
|
||||||
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
@unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
|
||||||
def test_playlist_factory(self, mock_stdout: io.StringIO):
|
def test_playlist_factory(self, mock_stdout: io.StringIO):
|
||||||
"""Test that the Playlist Factory is wired up properly."""
|
"""Test that the Playlist Factory is wired up properly."""
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# Copyright 2022 (c) Anna Schumaker.
|
||||||
|
"""Tests our Tracklist card."""
|
||||||
|
import unittest.mock
|
||||||
|
import emmental.tracklist
|
||||||
|
import tests.util
|
||||||
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
|
||||||
|
class TestTracklist(tests.util.TestCase):
|
||||||
|
"""Tests the Tracklist card."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Set up common variables."""
|
||||||
|
super().setUp()
|
||||||
|
self.tracklist = emmental.tracklist.Card(self.sql)
|
||||||
|
self.db_plist = self.sql.playlists.create("Test Playlist")
|
||||||
|
self.playlist = emmental.playlist.playlist.Playlist(self.sql,
|
||||||
|
self.db_plist)
|
||||||
|
|
||||||
|
def test_init(self):
|
||||||
|
"""Test that the Tracklist has been set up correctly."""
|
||||||
|
self.assertIsInstance(self.tracklist, Gtk.Box)
|
||||||
|
self.assertIsInstance(self.tracklist._top_box, Gtk.CenterBox)
|
||||||
|
|
||||||
|
self.assertEqual(self.tracklist.sql, self.sql)
|
||||||
|
self.assertEqual(self.tracklist.get_spacing(), 6)
|
||||||
|
self.assertEqual(self.tracklist.get_orientation(),
|
||||||
|
Gtk.Orientation.VERTICAL)
|
||||||
|
|
||||||
|
self.assertEqual(self.tracklist._top_box.get_margin_top(), 6)
|
||||||
|
self.assertEqual(self.tracklist._top_box.get_margin_start(), 6)
|
||||||
|
self.assertEqual(self.tracklist._top_box.get_margin_end(), 6)
|
||||||
|
self.assertEqual(self.tracklist._top_box.get_orientation(),
|
||||||
|
Gtk.Orientation.HORIZONTAL)
|
||||||
|
|
||||||
|
self.assertEqual(self.tracklist.get_first_child(),
|
||||||
|
self.tracklist._top_box)
|
||||||
|
|
||||||
|
self.assertTrue(self.tracklist.has_css_class("card"))
|
||||||
|
|
||||||
|
def test_filter(self):
|
||||||
|
"""Test the Tracklist Filter entry."""
|
||||||
|
self.assertIsInstance(self.tracklist._filter, emmental.entry.Filter)
|
||||||
|
self.assertEqual(self.tracklist._top_box.get_center_widget(),
|
||||||
|
self.tracklist._filter)
|
||||||
|
|
||||||
|
self.assertEqual(self.tracklist._filter.get_margin_start(), 100)
|
||||||
|
self.assertEqual(self.tracklist._filter.get_margin_end(), 100)
|
||||||
|
self.assertEqual(self.tracklist._filter.get_placeholder_text(),
|
||||||
|
"type to filter tracks")
|
||||||
|
self.assertTrue(self.tracklist._filter.get_hexpand())
|
||||||
|
|
||||||
|
with unittest.mock.patch.object(self.sql.tracks,
|
||||||
|
"filter") as mock_filter:
|
||||||
|
self.tracklist._filter.set_text("test text")
|
||||||
|
self.tracklist._filter.emit("search-changed")
|
||||||
|
mock_filter.assert_called_with("*test text*")
|
||||||
|
|
||||||
|
def test_playlist(self):
|
||||||
|
"""Test the playlist property."""
|
||||||
|
self.assertIsNone(self.tracklist.playlist)
|
||||||
|
|
||||||
|
self.tracklist.playlist = self.playlist
|
||||||
|
self.assertEqual(self.tracklist.playlist, self.playlist)
|
Loading…
Reference in New Issue