mirror of
https://github.com/SoongNoonien/mpdevil.git
synced 2023-08-10 21:12:44 +03:00
reworked genre filter
This commit is contained in:
parent
a4eba33bdc
commit
59af81866f
78
bin/mpdevil
78
bin/mpdevil
@ -1437,6 +1437,10 @@ class ScrolledFocusFrame(FocusFrame):
|
||||
scroll=Gtk.ScrolledWindow()
|
||||
scroll.add(widget)
|
||||
|
||||
# allow hide/show without .show_all()
|
||||
scroll.set_visible(True)
|
||||
widget.set_visible(True)
|
||||
|
||||
self.add(scroll)
|
||||
|
||||
class SongPopover(Gtk.Popover):
|
||||
@ -2485,42 +2489,32 @@ class AlbumWindow(FocusFrame):
|
||||
|
||||
class Browser(Gtk.Paned):
|
||||
def __init__(self, client, settings):
|
||||
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
super().__init__()
|
||||
self._client=client
|
||||
self._settings=settings
|
||||
|
||||
# widgets
|
||||
label=Gtk.Label(ellipsize=Pango.EllipsizeMode.MIDDLE)
|
||||
self._genres_button=Gtk.ToggleButton(image=label, tooltip_text=_("Filter by genre"))
|
||||
self._genre_select=GenreSelect(self._client)
|
||||
self._artist_window=ArtistWindow(self._client, self._settings, self._genre_select)
|
||||
self._album_window=AlbumWindow(self._client, self._settings, self._artist_window)
|
||||
genre_focus_frame=ScrolledFocusFrame(self._genre_select)
|
||||
artist_focus_frame=ScrolledFocusFrame(self._artist_window)
|
||||
|
||||
# stacks
|
||||
self._artists_genres_stack=Gtk.Stack(transition_type=Gtk.StackTransitionType.OVER_RIGHT_LEFT)
|
||||
self._artists_genres_stack.add_named(ScrolledFocusFrame(self._artist_window), "artists")
|
||||
self._artists_genres_stack.add_named(ScrolledFocusFrame(self._genre_select), "genres")
|
||||
|
||||
# connect
|
||||
self._genres_button.connect("toggled", self._on_genres_toggled)
|
||||
self._genre_select.connect("item-selected", self._on_genre_chnaged)
|
||||
self._client.emitter.connect("disconnected", self._on_disconnected)
|
||||
self._client.emitter.connect("reconnected", self._on_reconnected)
|
||||
# hide/show genre filter
|
||||
self._settings.bind("genre-filter", genre_focus_frame, "no-show-all", Gio.SettingsBindFlags.INVERT_BOOLEAN|Gio.SettingsBindFlags.GET)
|
||||
self._settings.bind("genre-filter", genre_focus_frame, "visible", Gio.SettingsBindFlags.GET)
|
||||
self._settings.connect("changed::genre-filter", self._on_genre_filter_changed)
|
||||
|
||||
# packing
|
||||
hbox=Gtk.Box(spacing=6, border_width=6)
|
||||
hbox.pack_start(self._genres_button, True, True, 0)
|
||||
vbox=Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
vbox.pack_start(hbox, False, False, 0)
|
||||
vbox.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), False, False, 0)
|
||||
vbox.pack_start(self._artists_genres_stack, True, True, 0)
|
||||
self.pack1(vbox, False, False)
|
||||
self.pack2(self._album_window, True, False)
|
||||
self.paned1=Gtk.Paned()
|
||||
self.paned1.pack1(artist_focus_frame, False, False)
|
||||
self.paned1.pack2(self._album_window, True, False)
|
||||
self.pack1(genre_focus_frame, False, False)
|
||||
self.pack2(self.paned1, True, False)
|
||||
|
||||
def back_to_current_album(self, force=False):
|
||||
song=self._client.currentsong()
|
||||
if song:
|
||||
self._genres_button.set_active(False)
|
||||
# get artist name
|
||||
artist=song[self._settings.get_artist_type()][0]
|
||||
# deactivate genre filter to show all artists (if needed)
|
||||
@ -2535,26 +2529,10 @@ class Browser(Gtk.Paned):
|
||||
else:
|
||||
self._genre_select.deactivate()
|
||||
|
||||
def _on_genres_toggled(self, widget):
|
||||
if widget.get_active():
|
||||
self._artists_genres_stack.set_visible_child_name("genres")
|
||||
else:
|
||||
self._artists_genres_stack.set_visible_child_name("artists")
|
||||
|
||||
def _on_reconnected(self, *args):
|
||||
self._genres_button.set_sensitive(True)
|
||||
|
||||
def _on_disconnected(self, *args):
|
||||
self._genres_button.set_active(False)
|
||||
self._genres_button.set_sensitive(False)
|
||||
|
||||
def _on_genre_chnaged(self, *args):
|
||||
genre=self._genre_select.get_selected()
|
||||
if genre is None:
|
||||
self._genres_button.get_image().set_text(self._genre_select.select_all_string)
|
||||
else:
|
||||
self._genres_button.get_image().set_text(genre)
|
||||
self._genres_button.set_active(False)
|
||||
def _on_genre_filter_changed(self, settings, key):
|
||||
if self._client.connected():
|
||||
if not settings.get_boolean(key):
|
||||
self._genre_select.deactivate()
|
||||
|
||||
############
|
||||
# playlist #
|
||||
@ -3601,6 +3579,7 @@ class ShortcutsWindow(Gtk.ShortcutsWindow):
|
||||
("<Shift><Control>p", _("Cycle through profiles in reversed order"), None, window_group),
|
||||
("<Control>m", _("Toggle mini player"), None, window_group),
|
||||
("<Control>l", _("Toggle lyrics"), None, window_group),
|
||||
("<Control>g", _("Toggle genre filter"), None, window_group),
|
||||
("<Control>f", _("Toggle search"), None, window_group),
|
||||
("Escape", _("Back to current album"), None, window_group),
|
||||
("space", _("Play/Pause"), None, playback_group),
|
||||
@ -3709,6 +3688,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
action.connect("activate", getattr(self, ("_on_"+name.replace("-","_"))))
|
||||
self.add_action(action)
|
||||
self.add_action(self._settings.create_action("mini-player"))
|
||||
self.add_action(self._settings.create_action("genre-filter"))
|
||||
self.add_action(self._settings.create_action("active-profile"))
|
||||
|
||||
# shortcuts
|
||||
@ -3740,6 +3720,11 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
self._back_button=Gtk.Button(image=icon("go-previous-symbolic"), tooltip_text=_("Back to current album"), no_show_all=True)
|
||||
self._back_button.set_can_focus(False)
|
||||
self._settings.bind("mini-player", self._back_button, "visible", Gio.SettingsBindFlags.INVERT_BOOLEAN|Gio.SettingsBindFlags.GET)
|
||||
self._genre_button=Gtk.ToggleButton(
|
||||
image=icon("org.mpdevil.mpdevil-genre-symbolic"), tooltip_text=_("Filter by genre"), no_show_all=True)
|
||||
self._genre_button.set_can_focus(False)
|
||||
self._settings.bind("mini-player", self._genre_button, "visible", Gio.SettingsBindFlags.INVERT_BOOLEAN|Gio.SettingsBindFlags.GET)
|
||||
self._settings.bind("genre-filter", self._genre_button, "active", Gio.SettingsBindFlags.DEFAULT)
|
||||
|
||||
# stack
|
||||
self._stack=Gtk.Stack(transition_type=Gtk.StackTransitionType.CROSSFADE)
|
||||
@ -3805,12 +3790,14 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
self._header_bar.set_show_close_button(True)
|
||||
self.set_titlebar(self._header_bar)
|
||||
self._header_bar.pack_start(self._back_button)
|
||||
self._header_bar.pack_start(self._genre_button)
|
||||
self._header_bar.pack_end(self._menu_button)
|
||||
self._header_bar.pack_end(self._search_button)
|
||||
else:
|
||||
action_bar.pack_start(self._back_button)
|
||||
action_bar.pack_end(self._menu_button)
|
||||
action_bar.pack_end(self._search_button)
|
||||
action_bar.pack_end(self._genre_button)
|
||||
action_bar.pack_start(playback_control)
|
||||
action_bar.pack_start(seek_bar)
|
||||
action_bar.pack_start(audio)
|
||||
@ -3836,8 +3823,9 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
Gtk.main_iteration_do(True)
|
||||
# restore paned settings when window is visible (fixes a bug when window is maximized)
|
||||
self._settings.bind("paned0", self._paned0, "position", Gio.SettingsBindFlags.DEFAULT)
|
||||
self._settings.bind("paned1", self._browser, "position", Gio.SettingsBindFlags.DEFAULT)
|
||||
self._settings.bind("paned1", self._browser.paned1, "position", Gio.SettingsBindFlags.DEFAULT)
|
||||
self._settings.bind("paned2", self._paned2, "position", Gio.SettingsBindFlags.DEFAULT)
|
||||
self._settings.bind("paned3", self._browser, "position", Gio.SettingsBindFlags.DEFAULT)
|
||||
|
||||
# start client
|
||||
def callback(*args):
|
||||
@ -3947,6 +3935,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
self.lookup_action(action).set_enabled(True)
|
||||
self._search_button.set_sensitive(True)
|
||||
self._back_button.set_sensitive(True)
|
||||
self._genre_button.set_sensitive(True)
|
||||
|
||||
def _on_disconnected(self, *args):
|
||||
self.set_title("mpdevil")
|
||||
@ -3957,6 +3946,7 @@ class MainWindow(Gtk.ApplicationWindow):
|
||||
self._search_button.set_active(False)
|
||||
self._search_button.set_sensitive(False)
|
||||
self._back_button.set_sensitive(False)
|
||||
self._genre_button.set_sensitive(False)
|
||||
|
||||
def _on_size_allocate(self, widget, rect):
|
||||
if not self.is_maximized() and not self._settings.get_boolean("mini-player"):
|
||||
@ -4011,7 +4001,7 @@ class mpdevil(Gtk.Application):
|
||||
("mpd.consume", ["<Control>o"]),("mpd.seek-forward", ["KP_Multiply"]),("mpd.seek-backward", ["KP_Divide"]),
|
||||
("win.profile-next", ["<Control>p"]),("win.profile-prev", ["<Shift><Control>p"]),
|
||||
("win.show-info", ["<Control>i","Menu"]),("win.append", ["<Control>plus"]),
|
||||
("win.play", ["<Control>Return"]),("win.enqueue", ["<Control>e"])
|
||||
("win.play", ["<Control>Return"]),("win.enqueue", ["<Control>e"]),("win.genre-filter", ["<Control>g"])
|
||||
)
|
||||
for action, accels in action_accels:
|
||||
self.set_accels_for_action(action, accels)
|
||||
|
150
data/icons/scalable/org.mpdevil.mpdevil-genre-symbolic.svg
Normal file
150
data/icons/scalable/org.mpdevil.mpdevil-genre-symbolic.svg
Normal file
@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16px" height="16px" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<filter id="a" x="0" y="0" width="1" height="1">
|
||||
<feColorMatrix in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
|
||||
</filter>
|
||||
<mask id="b">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".3"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="c">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="d">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".05"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="e">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="f">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".05"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="g">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="h">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".05"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="i">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="j">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".05"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="k">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="l">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".05"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="m">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="n">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".05"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="o">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="p">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".3"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="q">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="r">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".5"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="s">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="t">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".4"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="u">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="v">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".4"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="w">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="x">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".5"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="y">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<mask id="z">
|
||||
<g filter="url(#a)">
|
||||
<path d="m0 0h16v16h-16z" fill-opacity=".5"/>
|
||||
</g>
|
||||
</mask>
|
||||
<clipPath id="A">
|
||||
<path d="m0 0h1024v800h-1024z"/>
|
||||
</clipPath>
|
||||
<path d="m2 2.867v5.2021l5.8015 5.8015c0.16256 0.16256 0.359 0.17611 0.51817 0.01694l5.534-5.534c0.19304-0.19305 0.1795-0.38948 0.01693-0.55204l-5.8015-5.8015h-5.2021c-0.40303 0-0.86701 0.42673-0.86701 0.86701zm2.601 0.83314c0.5114 0 0.92797 0.41657 0.92797 0.92797s-0.41657 0.92797-0.92797 0.92797c-0.5114 0-0.92797-0.41657-0.92797-0.92797s0.41657-0.92797 0.92797-0.92797z" fill="#2e3436" stroke-width=".86701"/>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#c)" mask="url(#b)">
|
||||
<path d="m562.46 212.06h10.449c-1.1836 0.49219-1.2969 2.4609 0 3h-10.449z" fill="#2e3436"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#e)" mask="url(#d)">
|
||||
<path d="m16 632h1v1h-1z" fill="#2e3436" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#g)" mask="url(#f)">
|
||||
<path d="m17 631h1v1h-1z" fill="#2e3436" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#i)" mask="url(#h)">
|
||||
<path d="m18 634h1v1h-1z" fill="#2e3436" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#k)" mask="url(#j)">
|
||||
<path d="m16 634h1v1h-1z" fill="#2e3436" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#m)" mask="url(#l)">
|
||||
<path d="m17 635h1v1h-1z" fill="#2e3436" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#o)" mask="url(#n)">
|
||||
<path d="m19 635h1v1h-1z" fill="#2e3436" fill-rule="evenodd"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#q)" mask="url(#p)">
|
||||
<path d="m136 660v7h7v-7z" fill="#2e3436"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#s)" mask="url(#r)">
|
||||
<path d="m199 642h3v12h-3z" fill="#2e3436"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#u)" mask="url(#t)">
|
||||
<path d="m209.5 144.16c0.27734 0 0.5 0.22266 0.5 0.5v1c0 0.27734-0.22266 0.5-0.5 0.5s-0.5-0.22266-0.5-0.5v-1c0-0.27734 0.22266-0.5 0.5-0.5z" fill="#2e3436"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#w)" mask="url(#v)">
|
||||
<path d="m206.5 144.16c0.27734 0 0.5 0.22266 0.5 0.5v1c0 0.27734-0.22266 0.5-0.5 0.5s-0.5-0.22266-0.5-0.5v-1c0-0.27734 0.22266-0.5 0.5-0.5z" fill="#2e3436"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#y)" mask="url(#x)">
|
||||
<path d="m229.5 143.16c-0.54688 0-1 0.45703-1 1 0 0.54688 0.45312 1 1 1s1-0.45312 1-1c0-0.54297-0.45312-1-1-1z" fill="#2e3436"/>
|
||||
</g>
|
||||
<g transform="translate(-640 -624)" clip-path="url(#A)" mask="url(#z)">
|
||||
<path d="m226.45 143.16c-0.51953 0-0.95312 0.43359-0.95312 0.95312v0.09375c0 0.51953 0.43359 0.95312 0.95312 0.95312h0.09375c0.51953 0 0.95312-0.43359 0.95312-0.95312v-0.09375c0-0.51953-0.43359-0.95312-0.95312-0.95312z" fill="#2e3436"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.1 KiB |
@ -28,6 +28,14 @@
|
||||
<default>572</default>
|
||||
<summary>Default position of paned1/paned0 separator</summary>
|
||||
</key>
|
||||
<key type="i" name="paned3">
|
||||
<default>246</default>
|
||||
<summary>Default position of genre/artist separator</summary>
|
||||
</key>
|
||||
<key type="b" name="genre-filter">
|
||||
<default>false</default>
|
||||
<summary>Show genre filter</summary>
|
||||
</key>
|
||||
<key type="b" name="mini-player">
|
||||
<default>false</default>
|
||||
<summary>Start player in mini player mode</summary>
|
||||
|
1
setup.py
1
setup.py
@ -24,6 +24,7 @@ DistUtilsExtra.auto.setup(
|
||||
('share/icons/hicolor/scalable/status/', ['data/icons/scalable/org.mpdevil.mpdevil-single-symbolic.svg']),
|
||||
('share/icons/hicolor/scalable/status/', ['data/icons/scalable/org.mpdevil.mpdevil-consume-symbolic.svg']),
|
||||
('share/icons/hicolor/scalable/status/', ['data/icons/scalable/org.mpdevil.mpdevil-consume-symbolic-rtl.svg']),
|
||||
('share/icons/hicolor/scalable/actions/', ['data/icons/scalable/org.mpdevil.mpdevil-genre-symbolic.svg']),
|
||||
],
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user