header: Convert the Open button to an Adw.ActionRow
And put it in the new Menu button popover list. I don't expect this to be a common action, so the extra button press is acceptable. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
c5867badae
commit
a944af7f3e
|
@ -49,10 +49,11 @@ class Header(Gtk.HeaderBar):
|
|||
|
||||
icon = "sidebar-show-symbolic"
|
||||
self._show_sidebar = Gtk.ToggleButton(icon_name=icon, has_frame=False)
|
||||
self._open = open.Button()
|
||||
self._open = open.OpenRow()
|
||||
|
||||
self._menu_box = Gtk.ListBox(selection_mode=Gtk.SelectionMode.NONE)
|
||||
self._menu_box.add_css_class("boxed-list")
|
||||
self._menu_box.append(self._open)
|
||||
|
||||
icon = "open-menu-symbolic"
|
||||
self._menu_button = buttons.PopoverButton(popover_child=self._menu_box,
|
||||
|
@ -94,7 +95,6 @@ class Header(Gtk.HeaderBar):
|
|||
GObject.BindingFlags.BIDIRECTIONAL)
|
||||
|
||||
self.pack_start(self._show_sidebar)
|
||||
self.pack_start(self._open)
|
||||
if __debug__:
|
||||
self._window = settings.Window(sql)
|
||||
self._settings = Gtk.Button(icon_name="settings-symbolic",
|
||||
|
@ -131,7 +131,7 @@ class Header(Gtk.HeaderBar):
|
|||
f"normalizing: {rg_status}")
|
||||
self._vol_button.set_tooltip_text(status)
|
||||
|
||||
def __track_requested(self, button: open.Button,
|
||||
def __track_requested(self, button: open.OpenRow,
|
||||
path: pathlib.Path) -> None:
|
||||
self.emit("track-requested", path)
|
||||
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
# Copyright 2023 (c) Anna Schumaker.
|
||||
"""A custom Button that opens a FileDialog to select a file for playback."""
|
||||
"""A custom Adw.ActionRow to select a file for playback."""
|
||||
import pathlib
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gio
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
|
||||
|
||||
class Button(Gtk.Button):
|
||||
"""Our pre-configured open button."""
|
||||
class OpenRow(Adw.ActionRow):
|
||||
"""Our pre-configured open Adw.ActionRow."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize our open button."""
|
||||
super().__init__(icon_name="document-open-symbolic",
|
||||
tooltip_text="open a file for playback")
|
||||
"""Initialize our open ActionRow."""
|
||||
super().__init__(activatable=True, title="Open File",
|
||||
subtitle="Select a file for playback")
|
||||
self._prefix = Gtk.Image(icon_name="document-open-symbolic")
|
||||
self._filters = Gio.ListStore()
|
||||
self._filter = Gtk.FileFilter(name="Audio Files",
|
||||
mime_types=["inode/directory",
|
||||
|
@ -23,6 +25,9 @@ class Button(Gtk.Button):
|
|||
|
||||
self._filters.append(self._filter)
|
||||
|
||||
self.connect("activated", self.__on_activated)
|
||||
self.add_prefix(self._prefix)
|
||||
|
||||
def __async_ready(self, dialog: Gtk.FileDialog, task: Gio.Task) -> None:
|
||||
try:
|
||||
file = dialog.open_finish(task)
|
||||
|
@ -30,8 +35,9 @@ class Button(Gtk.Button):
|
|||
except GLib.Error:
|
||||
pass
|
||||
|
||||
def do_clicked(self) -> None:
|
||||
"""Handle a click event."""
|
||||
def __on_activated(self, row: Adw.ActionRow) -> None:
|
||||
"""Handle activating an OpenRow."""
|
||||
self.get_ancestor(Gtk.Popover).popdown()
|
||||
self._dialog.open(self.get_ancestor(Gtk.Window), None,
|
||||
self.__async_ready)
|
||||
|
||||
|
|
|
@ -52,8 +52,10 @@ class TestHeader(tests.util.TestCase):
|
|||
self.assertFalse(self.header.show_sidebar)
|
||||
|
||||
def test_open(self):
|
||||
"""Check that the Open button works as expected."""
|
||||
self.assertIsInstance(self.header._open, emmental.header.open.Button)
|
||||
"""Check that the Open ActionRow works as expected."""
|
||||
self.assertIsInstance(self.header._open, emmental.header.open.OpenRow)
|
||||
self.assertEqual(self.header._menu_box.get_row_at_index(0),
|
||||
self.header._open)
|
||||
|
||||
signal = unittest.mock.Mock()
|
||||
self.header.connect("track-requested", signal)
|
||||
|
@ -95,6 +97,9 @@ class TestHeader(tests.util.TestCase):
|
|||
Gtk.SelectionMode.NONE)
|
||||
self.assertTrue(self.header._menu_box.has_css_class("boxed-list"))
|
||||
|
||||
self.assertEqual(self.header._menu_box.get_row_at_index(0),
|
||||
self.header._open)
|
||||
|
||||
def test_volume_icons(self):
|
||||
"""Check that the volume icons box is set up properly."""
|
||||
self.assertIsInstance(self.header._icons, Gtk.Box)
|
||||
|
|
|
@ -1,58 +1,69 @@
|
|||
# Copyright 2023 (c) Anna Schumaker.
|
||||
"""Tests our Open button."""
|
||||
"""Tests our Open Adw.ActionRow."""
|
||||
import emmental.header.open
|
||||
import pathlib
|
||||
import unittest
|
||||
from gi.repository import Gio
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
|
||||
|
||||
class TestButton(unittest.TestCase):
|
||||
"""Test the Open button."""
|
||||
class TestOpenRow(unittest.TestCase):
|
||||
"""Test the Open row."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.button = emmental.header.open.Button()
|
||||
self.row = emmental.header.open.OpenRow()
|
||||
|
||||
def test_button(self):
|
||||
"""Check that the button was set up properly."""
|
||||
self.assertIsInstance(self.button, Gtk.Button)
|
||||
self.assertEqual(self.button.get_icon_name(), "document-open-symbolic")
|
||||
self.assertEqual(self.button.get_tooltip_text(),
|
||||
"open a file for playback")
|
||||
def test_action_row(self):
|
||||
"""Check that the action row was set up properly."""
|
||||
self.assertIsInstance(self.row, Adw.ActionRow)
|
||||
self.assertIsInstance(self.row._prefix, Gtk.Image)
|
||||
|
||||
self.assertEqual(self.row.props.title, "Open File")
|
||||
self.assertEqual(self.row.props.subtitle, "Select a file for playback")
|
||||
self.assertTrue(self.row.props.activatable)
|
||||
|
||||
self.assertEqual(self.row._prefix.props.icon_name,
|
||||
"document-open-symbolic")
|
||||
|
||||
def test_filter(self):
|
||||
"""Check that the file filter is set up properly."""
|
||||
self.assertIsInstance(self.button._filter, Gtk.FileFilter)
|
||||
self.assertIsInstance(self.button._filters, Gio.ListStore)
|
||||
self.assertIsInstance(self.row._filter, Gtk.FileFilter)
|
||||
self.assertIsInstance(self.row._filters, Gio.ListStore)
|
||||
|
||||
self.assertEqual(self.button._filter.get_name(), "Audio Files")
|
||||
self.assertEqual(self.button._filters[0], self.button._filter)
|
||||
self.assertEqual(self.row._filter.get_name(), "Audio Files")
|
||||
self.assertEqual(self.row._filters[0], self.row._filter)
|
||||
|
||||
def test_dialog(self):
|
||||
"""Check that the file dialog is set up properly."""
|
||||
self.assertIsInstance(self.button._dialog, Gtk.FileDialog)
|
||||
self.assertEqual(self.button._dialog.get_title(), "Pick a Track")
|
||||
self.assertEqual(self.button._dialog.get_filters(),
|
||||
self.button._filters)
|
||||
self.assertTrue(self.button._dialog.get_modal())
|
||||
self.assertIsInstance(self.row._dialog, Gtk.FileDialog)
|
||||
self.assertEqual(self.row._dialog.get_title(), "Pick a Track")
|
||||
self.assertEqual(self.row._dialog.get_filters(),
|
||||
self.row._filters)
|
||||
self.assertTrue(self.row._dialog.get_modal())
|
||||
|
||||
def test_clicked(self):
|
||||
"""Test clicking on the button."""
|
||||
with unittest.mock.patch.object(self.button._dialog,
|
||||
"open") as mock_open:
|
||||
self.button.emit("clicked")
|
||||
mock_open.assert_called_with(None, None,
|
||||
self.button._Button__async_ready)
|
||||
def test_activate(self):
|
||||
"""Test activating an OpenRow."""
|
||||
listbox = Gtk.ListBox()
|
||||
popover = Gtk.Popover(child=listbox)
|
||||
listbox.append(self.row)
|
||||
|
||||
with unittest.mock.patch.object(self.button._dialog,
|
||||
with unittest.mock.patch.object(popover, "popdown") as mock_popdown:
|
||||
with unittest.mock.patch.object(self.row._dialog,
|
||||
"open") as mock_open:
|
||||
self.row.emit("activated")
|
||||
mock_popdown.assert_called()
|
||||
mock_open.assert_called_with(None, None,
|
||||
self.row._OpenRow__async_ready)
|
||||
|
||||
with unittest.mock.patch.object(self.row._dialog,
|
||||
"open_finish") as mock_finish:
|
||||
task = Gio.Task()
|
||||
signal = unittest.mock.Mock()
|
||||
mock_finish.return_value = Gio.File.new_for_path("/a/b/c/1.ogg")
|
||||
self.button.connect("track-requested", signal)
|
||||
self.row.connect("track-requested", signal)
|
||||
|
||||
self.button._Button__async_ready(self.button._dialog, task)
|
||||
self.row._OpenRow__async_ready(self.row._dialog, task)
|
||||
mock_finish.assert_called_with(task)
|
||||
signal.assert_called_with(self.button,
|
||||
pathlib.Path("/a/b/c/1.ogg"))
|
||||
signal.assert_called_with(self.row, pathlib.Path("/a/b/c/1.ogg"))
|
||||
|
|
Loading…
Reference in New Issue