tracklist: Add a VisibleColumns button

This button shows a popover menu to set the visibility of our columns.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2022-10-25 11:00:32 -04:00
parent ff1d772a05
commit f1e18549ff
5 changed files with 137 additions and 0 deletions

View File

@ -7,6 +7,7 @@ from gi.repository import Gtk
from .. import db
from .. import entry
from .. import playlist
from . import buttons
from . import trackview
@ -20,14 +21,20 @@ class Card(Gtk.Box):
"""Set up the Tracklist widget."""
super().__init__(sql=sql, orientation=Gtk.Orientation.VERTICAL,
spacing=6, **kwargs)
self._top_left = Gtk.Box()
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._trackview = trackview.TrackView(sql, margin_start=6,
margin_end=6)
self._visible_cols = buttons.VisibleColumns(self._trackview.columns)
self._top_left.append(self._visible_cols)
self._top_box.set_start_widget(self._top_left)
self._top_box.set_center_widget(self._filter)
self.append(self._top_box)
self.append(self._trackview)

View File

@ -0,0 +1,44 @@
# Copyright 2022 (c) Anna Schumaker.
"""Extra buttons for the TrackList."""
from gi.repository import GObject
from gi.repository import Gio
from gi.repository import Gtk
from .. import buttons
from .. import factory
class VisibleSwitch(factory.ListRow):
"""A list row containing a Gtk.Switch."""
def __init__(self, listitem: Gtk.ListItem):
"""Initialize a VisibleSwitch ListRow."""
super().__init__(listitem=listitem, child=Gtk.Switch())
def do_bind(self) -> None:
"""Bind the visible property to the switch active property."""
self.bind_and_set_property("visible", "active", bidirectional=True)
class VisibleColumns(buttons.PopoverButton):
"""Shows a Popover Menu to select which columns are visible."""
columns = GObject.Property(type=Gio.ListModel)
def __init__(self, columns: Gio.ListModel, **kwargs):
"""Initialize the VisibleColumns button."""
super().__init__(columns=columns, icon_name="columns-symbolic",
has_frame=False, **kwargs)
self._selection = Gtk.NoSelection(model=self.columns)
self.popover_child = Gtk.ColumnView(model=self._selection,
show_row_separators=True)
self.__append_column(factory.InscriptionFactory("title"),
"Column", width=125)
self.__append_column(factory.Factory(row_type=VisibleSwitch),
"Visible")
self.popover_child.add_css_class("data-table")
def __append_column(self, factory: factory.Factory,
title: str, *, width: int = -1) -> None:
column = Gtk.ColumnViewColumn(factory=factory, title=title,
fixed_width=width)
self.popover_child.append_column(column)

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 1 3 v 2 h 6 v -2 z m 8 0 v 2 h 6 v -2 z m -8 4 v 2 h 6 v -2 z m 8 0 v 2 h 6 v -2 z m -8 4 v 2 h 6 v -2 z m 8 0 v 2 h 6 v -2 z m 0 0" fill="#222222"/></svg>

After

Width:  |  Height:  |  Size: 293 B

View File

@ -0,0 +1,71 @@
# Copyright 2022 (c) Anna Schumaker
"""Tests extra buttons for the TrackList."""
import unittest
import unittest.mock
import emmental.tracklist.buttons
from gi.repository import Gio
from gi.repository import Gtk
class TestVisibleColumns(unittest.TestCase):
"""Test the Visible Columns button."""
def setUp(self):
"""Set up common variables."""
self.columns = Gio.ListStore()
self.button = emmental.tracklist.buttons.VisibleColumns(self.columns)
def test_init(self):
"""Test that the Visible Columns button is set up properly."""
self.assertIsInstance(self.button, emmental.buttons.PopoverButton)
self.assertFalse(self.button.get_has_frame())
self.assertEqual(self.button.get_icon_name(), "columns-symbolic")
self.assertEqual(self.button.columns, self.columns)
def test_popover_child(self):
"""Test that the popover_child was set up properly."""
self.assertIsInstance(self.button.popover_child, Gtk.ColumnView)
self.assertIsInstance(self.button._selection, Gtk.NoSelection)
self.assertTrue(self.button.popover_child.get_show_row_separators())
self.assertTrue(self.button.popover_child.has_css_class("data-table"))
self.assertEqual(self.button.popover_child.get_model(),
self.button._selection)
self.assertEqual(self.button._selection.get_model(),
self.button.columns)
def test_columns(self):
"""Test the popover_child columns."""
columns = self.button.popover_child.get_columns()
self.assertEqual(len(columns), 2)
self.assertIsInstance(columns[0].get_factory(),
emmental.factory.InscriptionFactory)
self.assertEqual(columns[0].get_title(), "Column")
self.assertEqual(columns[0].get_fixed_width(), 125)
self.assertIsInstance(columns[1].get_factory(),
emmental.factory.Factory)
self.assertEqual(columns[1].get_factory().row_type,
emmental.tracklist.buttons.VisibleSwitch)
self.assertEqual(columns[1].get_title(), "Visible")
self.assertEqual(columns[1].get_fixed_width(), -1)
def test_visible_switch(self):
"""Test the visible switch widget."""
item = Gtk.Label()
listitem = Gtk.ListItem()
listitem.get_item = unittest.mock.Mock(return_value=item)
switch = emmental.tracklist.buttons.VisibleSwitch(listitem)
self.assertIsInstance(switch, emmental.factory.ListRow)
self.assertIsInstance(switch.child, Gtk.Switch)
switch.bind()
self.assertEqual(len(switch.bindings), 1)
self.assertTrue(switch.child.get_active())
item.set_visible(False)
self.assertFalse(switch.child.get_active())
switch.child.set_active(True)
item.set_visible(True)

View File

@ -22,6 +22,7 @@ class TestTracklist(tests.util.TestCase):
"""Test that the Tracklist has been set up correctly."""
self.assertIsInstance(self.tracklist, Gtk.Box)
self.assertIsInstance(self.tracklist._top_box, Gtk.CenterBox)
self.assertIsInstance(self.tracklist._top_left, Gtk.Box)
self.assertEqual(self.tracklist.sql, self.sql)
self.assertEqual(self.tracklist.get_spacing(), 6)
@ -36,9 +37,21 @@ class TestTracklist(tests.util.TestCase):
self.assertEqual(self.tracklist.get_first_child(),
self.tracklist._top_box)
self.assertEqual(self.tracklist._top_box.get_start_widget(),
self.tracklist._top_left)
self.assertTrue(self.tracklist.has_css_class("card"))
def test_visible_columns(self):
"""Test the visible columns button."""
self.assertIsInstance(self.tracklist._visible_cols,
emmental.tracklist.buttons.VisibleColumns)
self.assertEqual(self.tracklist._visible_cols.columns,
self.tracklist._trackview.columns)
self.assertEqual(self.tracklist._top_left.get_first_child(),
self.tracklist._visible_cols)
def test_filter(self):
"""Test the Tracklist Filter entry."""
self.assertIsInstance(self.tracklist._filter, emmental.entry.Filter)