fixup! Port UI to GTK 4

This commit is contained in:
coderkun 2024-02-02 15:11:25 +01:00
commit 2744e1f351
6 changed files with 383 additions and 735 deletions

View file

@ -28,164 +28,68 @@
<property name="has-origin">False</property> <property name="has-origin">False</property>
<!-- <!--
<signal name="button-release-event" handler="on_grid_scale_changed" swapped="no"/> <signal name="button-release-event" handler="on_grid_scale_changed" swapped="no"/>
-->
<signal name="change-value" handler="on_grid_scale_change" swapped="no"/> <signal name="change-value" handler="on_grid_scale_change" swapped="no"/>
</object>
<!--
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
--> -->
</object>
</child> </child>
<child> <child>
<object class="GtkButton" id="library-toolbar-update"> <object class="GtkButton" id="library-toolbar-update">
<property name="label">gtk-refresh</property> <property name="label" translatable="yes">update library</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<!--
<property name="relief">none</property>
<property name="use-stock">True</property>
-->
<signal name="clicked" handler="on_update_clicked" swapped="no"/> <signal name="clicked" handler="on_update_clicked" swapped="no"/>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkBox" id="library-toolbar-sort"> <object class="GtkBox" id="library-toolbar-sort">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkSeparator"> <object class="GtkSeparator">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkLabel"> <object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Sort</property> <property name="label" translatable="yes">Sort</property>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="sort_artist"> <object class="GtkCheckButton" id="sort_artist">
<property name="label" translatable="yes">sort by artist</property> <property name="label" translatable="yes">sort by artist</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<!--
<property name="draw-indicator">True</property>
-->
<property name="group">sort_year</property> <property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/> <signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="sort_title"> <object class="GtkCheckButton" id="sort_title">
<property name="label" translatable="yes">sort by title</property> <property name="label" translatable="yes">sort by title</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<!--
<property name="draw-indicator">True</property>
-->
<property name="group">sort_year</property> <property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/> <signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="sort_year"> <object class="GtkCheckButton" id="sort_year">
<property name="label" translatable="yes">sort by year</property> <property name="label" translatable="yes">sort by year</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<property name="active">True</property> <property name="active">True</property>
<!--
<property name="draw-indicator">True</property>
-->
<signal name="toggled" handler="on_sort_toggled" swapped="no"/> <signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkCheckButton" id="toolbar_sort_order_button"> <object class="GtkCheckButton" id="toolbar_sort_order_button">
<property name="label">gtk-sort-descending</property> <property name="label">sort library descending</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="receives-default">False</property> <property name="receives-default">False</property>
<!--
<property name="use-stock">True</property>
<property name="draw-indicator">True</property>
-->
<property name="active">True</property> <property name="active">True</property>
<signal name="toggled" handler="on_sort_order_toggled" swapped="no"/> <signal name="toggled" handler="on_sort_order_toggled" swapped="no"/>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
-->
</child>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
-->
</child> </child>
</object> </object>
</child> </child>
</object> </object>
</child>
</object>
<object class="GtkBox" id="toolbar"> <object class="GtkBox" id="toolbar">
<property name="orientation">horizontal</property> <property name="orientation">horizontal</property>
@ -193,15 +97,10 @@
<property name="spacing">6</property> <property name="spacing">6</property>
<child> <child>
<object class="GtkToggleButton" id="toolbar_search_bar"> <object class="GtkToggleButton" id="toolbar_search_bar">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Search the library</property> <property name="tooltip-text" translatable="yes">Search the library</property>
<signal name="toggled" handler="on_search_toggled" swapped="no"/>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">system-search-symbolic</property> <property name="icon-name">system-search-symbolic</property>
</object> </object>
</child> </child>
@ -209,14 +108,6 @@
<accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/> <accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/>
--> -->
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
<property name="non-homogeneous">True</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkToggleButton" id="select_button"> <object class="GtkToggleButton" id="select_button">
@ -227,20 +118,10 @@
<signal name="toggled" handler="on_select_toggled" swapped="no"/> <signal name="toggled" handler="on_select_toggled" swapped="no"/>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">object-select-symbolic</property> <property name="icon-name">object-select-symbolic</property>
</object> </object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
<property name="non-homogeneous">True</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkMenuButton"> <object class="GtkMenuButton">
@ -257,39 +138,22 @@
</object> </object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
<property name="non-homogeneous">True</property>
</packing>
-->
</child> </child>
</object> </object>
<template class="McgLibraryPanel" parent="AdwBin"> <template class="McgLibraryPanel" parent="AdwBin">
<child> <child>
<object class="GtkStack"> <object class="GtkStack" id="library_stack">
<property name="transition-type">slide-left-right</property> <property name="transition-type">slide-left-right</property>
<child> <child>
<object class="GtkBox" id="panel_normal"> <object class="GtkBox" id="panel_normal">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkSearchBar" id="filter_bar"> <object class="GtkSearchBar" id="filter_bar">
<!-- <property name="search-mode-enabled" bind-source="toolbar_search_bar" bind-property="active" bind-flags="sync-create"/>
<property name="app-paintable">True</property>
-->
<signal name="notify" handler="on_filter_bar_notify" swapped="no"/>
<child> <child>
<object class="GtkSearchEntry" id="filter_entry"> <object class="GtkSearchEntry" id="filter_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<!-- <!--
<property name="primary-icon-name">edit-find-symbolic</property>
<property name="primary-icon-activatable">False</property> <property name="primary-icon-activatable">False</property>
<property name="primary-icon-sensitive">False</property> <property name="primary-icon-sensitive">False</property>
--> -->
@ -298,36 +162,18 @@
</object> </object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
-->
</child>
<child>
<placeholder/>
</child> </child>
<child> <child>
<object class="GtkStack" id="stack"> <object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="transition-type">crossfade</property> <property name="transition-type">crossfade</property>
<child> <child>
<object class="GtkBox" id="progress_box"> <object class="GtkBox" id="progress_box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child type="center"> <child type="center">
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child type="center"> <child type="center">
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">center</property> <property name="halign">center</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">10</property> <property name="spacing">10</property>
@ -336,13 +182,6 @@
<property name="icon-size">large</property> <property name="icon-size">large</property>
<property name="icon-name">image-x-generic-symbolic</property> <property name="icon-name">image-x-generic-symbolic</property>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkProgressBar" id="progress_bar"> <object class="GtkProgressBar" id="progress_bar">
@ -352,45 +191,12 @@
<property name="pulse-step">0</property> <property name="pulse-step">0</property>
<property name="show-text">True</property> <property name="show-text">True</property>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child>
<child>
<placeholder/>
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child>
<child>
<placeholder/>
</child> </child>
</object> </object>
<!--
<packing>
<property name="name">page1</property>
<property name="title">page1</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkScrolledWindow" id="scroll"> <object class="GtkScrolledWindow" id="scroll">
@ -398,11 +204,8 @@
<child> <child>
<object class="GtkGridView" id="library_grid"> <object class="GtkGridView" id="library_grid">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<!-- <property name="single_click_activate">true</property>
<signal name="activate" handler="on_library_grid_clicked" swapped="no"/> <signal name="activate" handler="on_library_grid_clicked"/>
<signal name="selection-changed" handler="on_library_grid_selection_changed" swapped="no"/>
<signal name="size-allocate" handler="on_resize" swapped="no"/>
-->
<style> <style>
<class name="no-bg"/> <class name="no-bg"/>
</style> </style>
@ -413,21 +216,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<template class="GtkListItem"> <template class="GtkListItem">
<property name="activatable">true</property>
<property name="child"> <property name="child">
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<!--
<child>
<object class="GtkLabel">
<property name="hexpand">false</property>
<binding name="label">
<lookup name="title" type="GridItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</binding>
</object>
</child>
-->
<child> <child>
<object class="GtkPicture"> <object class="GtkPicture">
<property name="content-fit">contain</property> <property name="content-fit">contain</property>
@ -458,98 +250,46 @@
<class name="no-bg"/> <class name="no-bg"/>
</style> </style>
</object> </object>
<!--
<packing>
<property name="name">page0</property>
<property name="title">page0</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkRevealer" id="actionbar_revealer"> <object class="GtkRevealer" id="actionbar_revealer">
<property name="transition-type">none</property> <property name="transition-type">slide-up</property>
<property name="reveal-child">false</property>
<child>
<object class="GtkActionBar" id="library-actionbar">
<child> <child>
<object class="GtkActionBar" id="actionbar">
<child type="end">
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">cancel</property> <property name="label" translatable="yes">cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_cancel_clicked" swapped="no"/> <signal name="clicked" handler="on_selection_cancel_clicked" swapped="no"/>
</object> </object>
<!--
<packing>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
<child> <child type="end">
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">queue</property> <property name="label" translatable="yes">queue</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_add_clicked" swapped="no"/> <signal name="clicked" handler="on_selection_add_clicked" swapped="no"/>
</object> </object>
<!--
<packing>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
-->
</child> </child>
</object> </object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
-->
</child> </child>
</object> </object>
<!--
<packing>
<property name="name">page0</property>
<property name="title">page0</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkBox" id="panel_standalone"> <object class="GtkBox" id="panel_standalone">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkStack" id="standalone_stack"> <object class="GtkStack" id="standalone_stack">
<property name="visible">True</property> <property name="vexpand">true</property>
<property name="can-focus">False</property>
<property name="transition-type">crossfade</property> <property name="transition-type">crossfade</property>
<child> <child>
<object class="GtkSpinner" id="standalone_spinner"> <object class="GtkSpinner" id="standalone_spinner">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
</object> </object>
<!--
<packing>
<property name="name">standalone-spinne</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkScrolledWindow" id="standalone_scroll"> <object class="GtkScrolledWindow" id="standalone_scroll">
@ -557,93 +297,41 @@
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="kinetic-scrolling">False</property> <property name="kinetic-scrolling">False</property>
<property name="overlay-scrolling">False</property> <property name="overlay-scrolling">False</property>
<!--
<signal name="size-allocate" handler="on_standalone_scroll_size_allocate" swapped="no"/>
-->
<child> <child>
<object class="GtkViewport"> <object class="GtkViewport">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkImage" id="standalone_image"> <object class="GtkImage" id="standalone_image">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">gtk-missing-image</property> <property name="icon-name">gtk-missing-image</property>
<!-- <property name="icon-size">large</property>
<property name="icon_size">6</property>
-->
</object> </object>
</child> </child>
</object> </object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="name">standalone-scroll</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
-->
</child>
<child>
<object class="GtkActionBar" id="library-standalone-actionbar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">queue</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_queue_clicked" swapped="no"/>
</object>
<!--
<packing>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkActionBar" id="actionbar_standalone">
<child type="end">
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">play</property> <property name="label" translatable="yes">play</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/> <signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/>
</object> </object>
<!-- </child>
<packing> <child type="end">
<property name="pack-type">end</property> <object class="GtkButton">
<property name="position">0</property> <property name="label" translatable="yes">queue</property>
</packing> <property name="receives-default">True</property>
--> <signal name="clicked" handler="on_standalone_queue_clicked" swapped="no"/>
</object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
</object> </object>
<!--
<packing>
<property name="name">page1</property>
<property name="title">page1</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
</object> </object>
</child> </child>

View file

@ -160,16 +160,16 @@
<object class="GtkActionBar" id="actionbar_standalone"> <object class="GtkActionBar" id="actionbar_standalone">
<child type="end"> <child type="end">
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">remove</property> <property name="label" translatable="yes">play</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_remove_clicked" swapped="no"/> <signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/>
</object> </object>
</child> </child>
<child type="end"> <child type="end">
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">play</property> <property name="label" translatable="yes">remove</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/> <signal name="clicked" handler="on_standalone_remove_clicked" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>

View file

@ -616,9 +616,8 @@ class Client(Base):
def _queue_album(self, album): def _queue_album(self, album):
track_ids = [] track_ids = []
if album in self._albums:
self._logger.info("add album %s", album) self._logger.info("add album %s", album)
for track in self._albums[album].get_tracks(): for track in album.get_tracks():
self._logger.info("addid: %r", track.get_file()) self._logger.info("addid: %r", track.get_file())
track_id = None track_id = None
track_id_response = self._parse_dict(self._call('addid', track.get_file())) track_id_response = self._parse_dict(self._call('addid', track.get_file()))
@ -1093,7 +1092,7 @@ class MCGAlbum:
return True return True
def compare(album1, album2, criterion=None): def compare(album1, album2, criterion=None, reverse=False):
if criterion == None: if criterion == None:
criterion = SortOrder.TITLE criterion = SortOrder.TITLE
if criterion == SortOrder.ARTIST: if criterion == SortOrder.ARTIST:
@ -1103,20 +1102,22 @@ class MCGAlbum:
elif criterion == SortOrder.YEAR: elif criterion == SortOrder.YEAR:
value_function = "get_date" value_function = "get_date"
reverseMultiplier = -1 if reverse else 1
value1 = getattr(album1, value_function)() value1 = getattr(album1, value_function)()
value2 = getattr(album2, value_function)() value2 = getattr(album2, value_function)()
if value1 is None and value2 is None: if value1 is None and value2 is None:
return 0 return 0
elif value1 is None: elif value1 is None:
return -1 return -1 * reverseMultiplier
elif value2 is None: elif value2 is None:
return 1 return 1 * reverseMultiplier
if value1 < value2: if value1 < value2:
return -1 return -1 * reverseMultiplier
elif value1 == value2: elif value1 == value2:
return 0 return 0
else: else:
return 1 return 1 * reverseMultiplier

View file

@ -16,6 +16,7 @@ from mcg.albumheaderbar import AlbumHeaderbar
from mcg.utils import SortOrder from mcg.utils import SortOrder
from mcg.utils import Utils from mcg.utils import Utils
from mcg.utils import GridItem from mcg.utils import GridItem
from mcg.utils import SearchFilter
@ -32,20 +33,18 @@ class LibraryPanel(Adw.Bin):
'queue-multiple': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), 'queue-multiple': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
'item-size-changed': (GObject.SIGNAL_RUN_FIRST, None, (int,)), 'item-size-changed': (GObject.SIGNAL_RUN_FIRST, None, (int,)),
'sort-order-changed': (GObject.SIGNAL_RUN_FIRST, None, (int,)), 'sort-order-changed': (GObject.SIGNAL_RUN_FIRST, None, (int,)),
'sort-type-changed': (GObject.SIGNAL_RUN_FIRST, None, (Gtk.SortType,)), 'sort-type-changed': (GObject.SIGNAL_RUN_FIRST, None, (bool,)),
'albumart': (GObject.SIGNAL_RUN_FIRST, None, (str,)), 'albumart': (GObject.SIGNAL_RUN_FIRST, None, (str,)),
'select': (GObject.SIGNAL_RUN_FIRST, None, (bool,)),
'toggle-search': (GObject.SIGNAL_RUN_FIRST, None, (bool,)),
'update': (GObject.SIGNAL_RUN_FIRST, None, ()), 'update': (GObject.SIGNAL_RUN_FIRST, None, ()),
'start-scale': (GObject.SIGNAL_RUN_FIRST, None, (int,)), 'start-scale': (GObject.SIGNAL_RUN_FIRST, None, (int,)),
'end-scale': (GObject.SIGNAL_RUN_FIRST, None, (int,)), 'end-scale': (GObject.SIGNAL_RUN_FIRST, None, (int,)),
'sort': (GObject.SIGNAL_RUN_FIRST, None, (int,)),
'sort-type': (GObject.SIGNAL_RUN_FIRST, None, (Gtk.SortType,))
} }
# Widgets # Widgets
library_stack = Gtk.Template.Child()
panel_normal = Gtk.Template.Child()
panel_standalone = Gtk.Template.Child() panel_standalone = Gtk.Template.Child()
actionbar_revealer = Gtk.Template.Child() actionbar_revealer = Gtk.Template.Child()
# Toolbar # Toolbar
@ -69,6 +68,9 @@ class LibraryPanel(Adw.Bin):
scroll = Gtk.Template.Child() scroll = Gtk.Template.Child()
# Library Grid # Library Grid
library_grid = Gtk.Template.Child() library_grid = Gtk.Template.Child()
# Action bar (normal)
actionbar = Gtk.Template.Child()
actionbar_standalone = Gtk.Template.Child()
# Standalone Image # Standalone Image
standalone_stack = Gtk.Template.Child() standalone_stack = Gtk.Template.Child()
standalone_spinner = Gtk.Template.Child() standalone_spinner = Gtk.Template.Child()
@ -83,7 +85,6 @@ class LibraryPanel(Adw.Bin):
self._buttons = {} self._buttons = {}
self._albums = None self._albums = None
self._host = "localhost" self._host = "localhost"
self._filter_string = ""
self._item_size = 150 self._item_size = 150
self._sort_order = SortOrder.YEAR self._sort_order = SortOrder.YEAR
self._sort_type = Gtk.SortType.DESCENDING self._sort_type = Gtk.SortType.DESCENDING
@ -99,22 +100,19 @@ class LibraryPanel(Adw.Bin):
# Widgets # Widgets
# FIXME Toolbar signals # FIXME Toolbar signals
#self._toolbar.connect('select', self.on_toolbar_select)
#self._toolbar.connect('toggle-search', self.on_toolbar_toggle_search)
#self._toolbar.connect('update', self.on_toolbar_update)
#self._toolbar.connect('start-scale', self.on_toolbar_scale) #self._toolbar.connect('start-scale', self.on_toolbar_scale)
#self._toolbar.connect('end-scale', self.on_toolbar_scaled) #self._toolbar.connect('end-scale', self.on_toolbar_scaled)
#self._toolbar.connect('sort', self.on_toolbar_sort)
#self._toolbar.connect('sort-type', self.on_toolbar_sort_type)
# Header bar # Header bar
self._headerbar_standalone = AlbumHeaderbar() self._headerbar_standalone = AlbumHeaderbar()
self._headerbar_standalone.connect('close', self.on_standalone_close_clicked) self._headerbar_standalone.connect('close', self.on_standalone_close_clicked)
# Library Grid: Model # Library Grid: Model
self._library_grid_model = Gio.ListStore() self._library_grid_model = Gio.ListStore()
self._library_grid_selection = Gtk.MultiSelection.new(self._library_grid_model) self._library_grid_filter = Gtk.FilterListModel()
self._library_grid_filter = self._library_grid_selection self._library_grid_filter.set_model(self._library_grid_model)
self._library_grid_selection_multi = Gtk.MultiSelection.new(self._library_grid_filter)
self._library_grid_selection_single = Gtk.SingleSelection.new(self._library_grid_filter)
# Library Grid # Library Grid
self.library_grid.set_model(self._library_grid_filter) self.library_grid.set_model(self._library_grid_selection_single)
# Toolbar menu # Toolbar menu
self.grid_scale.set_value(self._item_size) self.grid_scale.set_value(self._item_size)
self._toolbar_sort_buttons = { self._toolbar_sort_buttons = {
@ -136,17 +134,21 @@ class LibraryPanel(Adw.Bin):
self._is_selected = selected self._is_selected = selected
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_select_toggled(self, widget): def on_select_toggled(self, widget):
self.emit('select', widget.get_active()) if self.select_button.get_active():
self.actionbar_revealer.set_reveal_child(True)
self.library_grid.set_model(self._library_grid_selection_multi)
self.library_grid.set_single_click_activate(False)
self.library_grid.get_style_context().add_class(Utils.CSS_SELECTION)
else:
self.actionbar_revealer.set_reveal_child(False)
self.library_grid.set_model(self._library_grid_selection_single)
self.library_grid.set_single_click_activate(True)
self.library_grid.get_style_context().remove_class(Utils.CSS_SELECTION)
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_search_toggled(self, widget):
self.emit('toggle-search', widget.get_active())
#@Gtk.Template.Callback()
def on_update_clicked(self, widget): def on_update_clicked(self, widget):
self.emit('update') self.emit('update')
@ -164,20 +166,22 @@ class LibraryPanel(Adw.Bin):
self.toolbar_popover.popdown() self.toolbar_popover.popdown()
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_sort_toggled(self, widget): def on_sort_toggled(self, widget):
if widget.get_active(): if widget.get_active():
sort = [key for key, value in self._toolbar_sort_buttons.items() if value is widget][0] self._sort_order = [key for key, value in self._toolbar_sort_buttons.items() if value is widget][0]
self.emit('sort', sort) self._sort_grid_model()
self.emit('sort-order-changed', self._sort_order)
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_sort_order_toggled(self, button): def on_sort_order_toggled(self, button):
if button.get_active(): if button.get_active():
sort_type = Gtk.SortType.DESCENDING self._sort_type = Gtk.SortType.DESCENDING
else: else:
sort_type = Gtk.SortType.ASCENDING self._sort_type = Gtk.SortType.ASCENDING
self.emit('sort-type', sort_type) self._sort_grid_model()
self.emit('sort-type-changed', button.get_active())
# FIXME on_resize() # FIXME on_resize()
@ -204,21 +208,6 @@ class LibraryPanel(Adw.Bin):
) )
def on_toolbar_toggle_search(self, widget, active):
self.filter_bar.set_search_mode(active)
def on_toolbar_select(self, widget, active):
if active:
self.actionbar_revealer.set_reveal_child(True)
self.library_grid.set_selection_mode(Gtk.SelectionMode.MULTIPLE)
self.library_grid.get_style_context().add_class(Utils.CSS_SELECTION)
else:
self.actionbar_revealer.set_reveal_child(False)
self.library_grid.set_selection_mode(Gtk.SelectionMode.SINGLE)
self.library_grid.get_style_context().remove_class(Utils.CSS_SELECTION)
def on_toolbar_update(self, widget): def on_toolbar_update(self, widget):
self.emit('update') self.emit('update')
@ -243,41 +232,22 @@ class LibraryPanel(Adw.Bin):
return False return False
def on_toolbar_sort(self, widget, sort): @Gtk.Template.Callback()
self._change_sort(sort)
def on_toolbar_sort_type(self, widget, sort_type):
self._sort_type = sort_type
#self._library_grid_model.set_sort_column_id(2, sort_type)
self.emit('sort-type-changed', sort_type)
#@Gtk.Template.Callback()
def on_filter_bar_notify(self, widget, value):
if self.toolbar_search_bar.get_active() is not self.filter_bar.get_search_mode():
self.toolbar_search_bar.set_active(self.filter_bar.get_search_mode())
#@Gtk.Template.Callback()
def on_filter_entry_changed(self, widget): def on_filter_entry_changed(self, widget):
self._filter_string = self.filter_entry.get_text() self._library_grid_filter.set_filter(SearchFilter(self.filter_entry.get_text()))
GObject.idle_add(self._library_grid_filter.refilter)
# FIXME on_library_grid_clicked() @Gtk.Template.Callback()
#@Gtk.Template.Callback() def on_library_grid_clicked(self, widget, position):
def on_library_grid_clicked(self, widget, path):
# Get selected album # Get selected album
path = self._library_grid_filter.convert_path_to_child_path(path) item = self._library_grid_filter.get_item(position)
iter = self._library_grid_model.get_iter(path) album = item.get_album()
id = self._library_grid_model.get_value(iter, 2) id = album.get_id()
album = self._albums[id]
self._selected_albums = [album] self._selected_albums = [album]
self.emit('albumart', id) self.emit('albumart', id)
# Show standalone album # Show standalone album
if widget.get_selection_mode() == Gtk.SelectionMode.SINGLE: if widget.get_model() == self._library_grid_selection_single:
# Set labels # Set labels
self._headerbar_standalone.set_album(album) self._headerbar_standalone.set_album(album)
@ -289,34 +259,14 @@ class LibraryPanel(Adw.Bin):
self.standalone_spinner.start() self.standalone_spinner.start()
# FIXME on_library_grid_selection_changed() @Gtk.Template.Callback()
#@Gtk.Template.Callback()
def on_library_grid_selection_changed(self, widget):
self._selected_albums = []
for path in widget.get_selected_items():
path = self._library_grid_filter.convert_path_to_child_path(path)
iter = self._library_grid_model.get_iter(path)
id = self._library_grid_model.get_value(iter, 2)
self._selected_albums.insert(0, self._albums[id])
def on_filter_visible(self, model, iter, data):
id = model.get_value(iter, 2)
if not id in self._albums.keys():
return
album = self._albums[id]
return album.filter(self._filter_string)
#@Gtk.Template.Callback()
def on_selection_cancel_clicked(self, widget): def on_selection_cancel_clicked(self, widget):
self.select_button.set_active(False) self.select_button.set_active(False)
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_selection_add_clicked(self, widget): def on_selection_add_clicked(self, widget):
ids = [album.get_id() for album in self._selected_albums] self.emit('queue-multiple', self._get_selected_albums())
self.emit('queue-multiple', ids)
self.select_button.set_active(False) self.select_button.set_active(False)
@ -326,13 +276,13 @@ class LibraryPanel(Adw.Bin):
self._resize_standalone_image() self._resize_standalone_image()
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_standalone_play_clicked(self, widget): def on_standalone_play_clicked(self, widget):
self.emit('play', self._selected_albums[0].get_id()) self.emit('play', self._selected_albums[0].get_id())
self._close_standalone() self._close_standalone()
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_standalone_queue_clicked(self, widget): def on_standalone_queue_clicked(self, widget):
self.emit('queue', self._selected_albums[0].get_id()) self.emit('queue', self._selected_albums[0].get_id())
self._close_standalone() self._close_standalone()
@ -358,29 +308,21 @@ class LibraryPanel(Adw.Bin):
def set_sort_order(self, sort): def set_sort_order(self, sort):
if self._sort_order != sort:
button = self._toolbar_sort_buttons[sort] button = self._toolbar_sort_buttons[sort]
if button and not button.get_active(): if button:
self._sort_order = [key for key, value in self._toolbar_sort_buttons.items() if value is button][0]
if not button.get_active():
button.set_active(True) button.set_active(True)
self._sort_order = sort self._sort_grid_model()
self._library_grid_model.set_sort_func(2, self.compare_albums, self._sort_order)
def get_sort_order(self):
return self._sort_order
def set_sort_type(self, sort_type): def set_sort_type(self, sort_type):
if self._sort_type != sort_type: sort_type_gtk = Gtk.SortType.DESCENDING if sort_type else Gtk.SortType.ASCENDING
if sort_type:
sort_type_gtk = Gtk.SortType.DESCENDING if sort_type_gtk != self._sort_type:
self.toolbar_sort_order_button.set_active(True)
else:
sort_type_gtk = Gtk.SortType.ASCENDING
self.toolbar_sort_order_button.set_active(False)
if self._sort_type != sort_type_gtk:
self._sort_type = sort_type_gtk self._sort_type = sort_type_gtk
self._library_grid_model.set_sort_column_id(2, sort_type) self.toolbar_sort_order_button.set_active(sort_type)
self._sort_grid_model()
def get_sort_type(self): def get_sort_type(self):
@ -416,25 +358,18 @@ class LibraryPanel(Adw.Bin):
GObject.idle_add(self._show_image) GObject.idle_add(self._show_image)
def compare_albums(self, model, row1, row2, criterion): def _sort_grid_model(self):
id1 = model.get_value(row1, 2) self._library_grid_model.sort(self._grid_model_compare_func, self._sort_order, self._sort_type)
id2 = model.get_value(row2, 2)
if not id1 or not id2:
return def _grid_model_compare_func(self, item1, item2, criterion, order):
return client.MCGAlbum.compare(self._albums[id1], self._albums[id2], criterion) return client.MCGAlbum.compare(item1.get_album(), item2.get_album(), criterion, (order == Gtk.SortType.DESCENDING))
def stop_threads(self): def stop_threads(self):
self._library_stop.set() self._library_stop.set()
def _change_sort(self, sort):
self._sort_order = sort
self._library_grid_model.set_sort_func(2, self.compare_albums, sort)
self.emit('sort-order-changed', sort)
def _set_albums(self, host, albums, size): def _set_albums(self, host, albums, size):
""" """
if not self._is_selected and albums != self._albums: if not self._is_selected and albums != self._albums:
@ -451,6 +386,7 @@ class LibraryPanel(Adw.Bin):
GObject.idle_add(self.stack.set_visible_child, self.progress_box) GObject.idle_add(self.stack.set_visible_child, self.progress_box)
GObject.idle_add(self.progress_bar.set_fraction, 0.0) GObject.idle_add(self.progress_bar.set_fraction, 0.0)
#GObject.idle_add(self.library_grid.set_item_padding, size / 100) #GObject.idle_add(self.library_grid.set_item_padding, size / 100)
temp_model = self.library_grid.get_model()
self.library_grid.set_model(None) self.library_grid.set_model(None)
#self.library_grid.freeze_child_notify() #self.library_grid.freeze_child_notify()
self._library_grid_model.remove_all() self._library_grid_model.remove_all()
@ -489,11 +425,12 @@ class LibraryPanel(Adw.Bin):
self._library_lock.release() self._library_lock.release()
return return
self.library_grid.set_model(self._library_grid_filter) self.library_grid.set_model(temp_model)
#self.library_grid.thaw_child_notify() #self.library_grid.thaw_child_notify()
#self.library_grid.set_item_width(-1) #self.library_grid.set_item_width(-1)
self._library_lock.release() self._library_lock.release()
self.stack.set_visible_child(self.scroll) self.stack.set_visible_child(self.scroll)
self._sort_grid_model()
def _set_widget_grid_size(self, grid_widget, size, vertical): def _set_widget_grid_size(self, grid_widget, size, vertical):
@ -563,12 +500,12 @@ class LibraryPanel(Adw.Bin):
def _open_standalone(self): def _open_standalone(self):
self.set_visible_child(self.panel_standalone) self.library_stack.set_visible_child(self.panel_standalone)
self.emit('open-standalone') self.emit('open-standalone')
def _close_standalone(self): def _close_standalone(self):
self.set_visible_child(self.get_children()[0]) self.library_stack.set_visible_child(self.panel_normal)
self.emit('close-standalone') self.emit('close-standalone')
@ -594,7 +531,6 @@ class LibraryPanel(Adw.Bin):
if width <= 0 or height <= 0: if width <= 0 or height <= 0:
return return
# Pixelpuffer auf Oberfläche zeichnen # Pixelpuffer auf Oberfläche zeichnen
self.standalone_image.set_allocation(self.standalone_scroll.get_allocation())
self.standalone_image.set_from_pixbuf(pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.HYPER)) self.standalone_image.set_from_pixbuf(pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.HYPER))
self.standalone_image.show() self.standalone_image.show()
@ -608,3 +544,11 @@ class LibraryPanel(Adw.Bin):
Gtk.TextDirection.LTR, Gtk.TextDirection.LTR,
Gtk.IconLookupFlags.FORCE_SYMBOLIC Gtk.IconLookupFlags.FORCE_SYMBOLIC
) )
def _get_selected_albums(self):
albums = []
for i in range(self.library_grid.get_model().get_n_items()):
if self.library_grid.get_model().is_selected(i):
albums.append(self.library_grid.get_model().get_item(i).get_album())
return albums

View file

@ -8,7 +8,7 @@ import locale
import os import os
import urllib import urllib
from gi.repository import Gdk, GdkPixbuf, GObject from gi.repository import Gdk, GdkPixbuf, GObject, Gtk
@ -112,3 +112,17 @@ class GridItem(GObject.GObject):
def get_album(self): def get_album(self):
return self._album return self._album
class SearchFilter(Gtk.Filter):
def __init__(self, search_string):
super().__init__()
self._search_string = search_string
def do_match(self, grid_item):
return grid_item.get_album().filter(self._search_string)

View file

@ -105,8 +105,8 @@ class Window(Adw.ApplicationWindow):
self._panels.append(self._playlist_panel) self._panels.append(self._playlist_panel)
# Library panel # Library panel
self._library_panel = LibraryPanel(self._mcg) self._library_panel = LibraryPanel(self._mcg)
#self._library_panel.connect('open-standalone', self.on_panel_open_standalone) self._library_panel.connect('open-standalone', self.on_panel_open_standalone)
#self._library_panel.connect('close-standalone', self.on_panel_close_standalone) self._library_panel.connect('close-standalone', self.on_panel_close_standalone)
self._panels.append(self._library_panel) self._panels.append(self._library_panel)
# Stack # Stack
self.content_stack.add_child(self._connection_panel) self.content_stack.add_child(self._connection_panel)
@ -309,6 +309,7 @@ class Window(Adw.ApplicationWindow):
self.toolbar_view.add_top_bar(self.headerbar) self.toolbar_view.add_top_bar(self.headerbar)
self.toolbar_view.remove(panel.get_headerbar_standalone()) self.toolbar_view.remove(panel.get_headerbar_standalone())
def on_connection_panel_connection_changed(self, widget, host, port, password): def on_connection_panel_connection_changed(self, widget, host, port, password):
self._settings.set_string(Window.SETTING_HOST, host) self._settings.set_string(Window.SETTING_HOST, host)
self._settings.set_int(Window.SETTING_PORT, port) self._settings.set_int(Window.SETTING_PORT, port)
@ -381,11 +382,11 @@ class Window(Adw.ApplicationWindow):
def on_library_panel_sort_order_changed(self, widget, sort_order): def on_library_panel_sort_order_changed(self, widget, sort_order):
self._settings.set_enum(Window.SETTING_SORT_ORDER, self._library_panel.get_sort_order()) self._settings.set_enum(Window.SETTING_SORT_ORDER, sort_order)
def on_library_panel_sort_type_changed(self, widget, sort_type): def on_library_panel_sort_type_changed(self, widget, sort_type):
self._settings.set_boolean(Window.SETTING_SORT_TYPE, self._library_panel.get_sort_type()) self._settings.set_boolean(Window.SETTING_SORT_TYPE, sort_type)
def on_library_panel_albumart(self, widget, album): def on_library_panel_albumart(self, widget, album):