Compare commits

...

10 commits

18 changed files with 615 additions and 1146 deletions

View file

@ -30,6 +30,10 @@
font-weight:bold; font-weight:bold;
} }
window.fullscreen #cover_box {
background: black;
}
#cover_info_revealer { #cover_info_revealer {
background-color:alpha(@theme_bg_color, 0.8); background-color:alpha(@theme_bg_color, 0.8);
box-shadow:0 0 10px @theme_bg_color; box-shadow:0 0 10px @theme_bg_color;
@ -45,5 +49,12 @@ actionbar {
} }
gridview child { gridview child {
padding: 10px; padding: 1px;
}
gridview.selection child {
opacity: 0.5;
}
gridview.selection child:hover,
gridview.selection child:selected {
opacity: 1;
} }

View file

@ -41,6 +41,7 @@
<property name="valign">fill</property> <property name="valign">fill</property>
<child> <child>
<object class="GtkViewport" id="cover_box"> <object class="GtkViewport" id="cover_box">
<property name="name">cover_box</property>
<property name="hexpand">true</property> <property name="hexpand">true</property>
<property name="halign">fill</property> <property name="halign">fill</property>
<property name="vexpand">true</property> <property name="vexpand">true</property>
@ -53,27 +54,13 @@
<property name="valign">fill</property> <property name="valign">fill</property>
<property name="icon-name">image-x-generic-symbolic</property> <property name="icon-name">image-x-generic-symbolic</property>
<property name="icon-size">large</property> <property name="icon-size">large</property>
<!--
<signal name="button-press-event" handler="on_cover_box_pressed" swapped="no"/>
-->
</object> </object>
</child> </child>
</object> </object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="name">cover-scroll</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
</object> </object>
<!--
<packing>
<property name="index">-1</property>
</packing>
-->
</child> </child>
<child type="overlay"> <child type="overlay">
<object class="GtkRevealer" id="info_revealer"> <object class="GtkRevealer" id="info_revealer">
@ -81,9 +68,6 @@
<property name="transition-type">slide-right</property> <property name="transition-type">slide-right</property>
<property name="name">cover_info_revealer</property> <property name="name">cover_info_revealer</property>
<style> <style>
<!--
<class name="sidebar"/>
-->
<class name="background"/> <class name="background"/>
</style> </style>
<child> <child>
@ -95,9 +79,6 @@
<property name="name">cover_info_scroll</property> <property name="name">cover_info_scroll</property>
<child> <child>
<object class="GtkViewport"> <object class="GtkViewport">
<!--
<property name="shadow-type">none</property>
-->
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
@ -154,14 +135,6 @@
</object> </object>
</child> </child>
</object> </object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">10</property>
<property name="position">0</property>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkScale" id="songs_scale"> <object class="GtkScale" id="songs_scale">
@ -171,19 +144,7 @@
<property name="restrict-to-fill-level">False</property> <property name="restrict-to-fill-level">False</property>
<property name="digits">0</property> <property name="digits">0</property>
<property name="draw-value">False</property> <property name="draw-value">False</property>
<!--
<signal name="button-press-event" handler="on_songs_start_change" swapped="no"/>
<signal name="button-release-event" handler="on_songs_change" swapped="no"/>
-->
</object> </object>
<!--
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
-->
</child> </child>
</object> </object>
</child> </child>

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<template class="McgInfoDialog" parent="GtkAboutDialog">
<property name="can-focus">False</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window-position">center</property>
<property name="type-hint">dialog</property>
<property name="gravity">center</property>
<property name="program-name">CoverGrid</property>
<property name="version">3.1</property>
<property name="comments" translatable="yes">CoverGrid is a client for the Music Player Daemon, focusing on albums instead of single tracks.</property>
<property name="website">http://www.suruatoel.xyz/codes/mcg</property>
<property name="logo-icon-name">xyz.suruatoel.mcg</property>
<property name="license-type">gpl-3-0</property>
<child internal-child="vbox">
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</template>
</interface>

View file

@ -15,419 +15,204 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="halign">end</property> <property name="halign">end</property>
<child> <child>
<object class="GtkScale" id="grid_scale"> <object class="GtkScale" id="grid_scale">
<property name="width-request">350</property> <property name="width-request">350</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="adjustment">grid_adjustment</property> <property name="adjustment">grid_adjustment</property>
<property name="restrict-to-fill-level">False</property> <property name="restrict-to-fill-level">False</property>
<property name="fill-level">-1</property> <property name="fill-level">-1</property>
<property name="round-digits">0</property> <property name="round-digits">0</property>
<property name="digits">0</property> <property name="digits">0</property>
<property name="has-origin">False</property> <property name="has-origin">False</property>
<!-- <signal name="value-changed" handler="on_grid_scale_changed" swapped="no"/>
<signal name="button-release-event" handler="on_grid_scale_changed" swapped="no"/> </object>
--> </child>
<signal name="change-value" handler="on_grid_scale_change" swapped="no"/> <child>
</object> <object class="GtkButton" id="library-toolbar-update">
<!-- <property name="label" translatable="yes">update library</property>
<packing> <signal name="clicked" handler="on_update_clicked" swapped="no"/>
<property name="expand">True</property> </object>
<property name="fill">True</property> </child>
<property name="position">0</property> <child>
</packing> <object class="GtkBox" id="library-toolbar-sort">
--> <property name="orientation">vertical</property>
<child>
<object class="GtkSeparator">
<property name="orientation">vertical</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Sort</property>
</object>
</child>
<child>
<object class="GtkCheckButton" id="sort_artist">
<property name="label" translatable="yes">sort by artist</property>
<property name="receives-default">False</property>
<property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckButton" id="sort_title">
<property name="label" translatable="yes">sort by title</property>
<property name="receives-default">False</property>
<property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckButton" id="sort_year">
<property name="label" translatable="yes">sort by year</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckButton" id="toolbar_sort_order_button">
<property name="label">sort library descending</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<signal name="toggled" handler="on_sort_order_toggled" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child> </child>
<child> </object>
<object class="GtkButton" id="library-toolbar-update">
<property name="label">gtk-refresh</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"/>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child>
<child>
<object class="GtkBox" id="library-toolbar-sort">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
-->
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Sort</property>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child>
<child>
<object class="GtkCheckButton" id="sort_artist">
<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="draw-indicator">True</property>
-->
<property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
-->
</child>
<child>
<object class="GtkCheckButton" id="sort_title">
<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="draw-indicator">True</property>
-->
<property name="group">sort_year</property>
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
-->
</child>
<child>
<object class="GtkCheckButton" id="sort_year">
<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="active">True</property>
<!--
<property name="draw-indicator">True</property>
-->
<signal name="toggled" handler="on_sort_toggled" swapped="no"/>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
-->
</child>
<child>
<object class="GtkCheckButton" id="toolbar_sort_order_button">
<property name="label">gtk-sort-descending</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<!--
<property name="use-stock">True</property>
<property name="draw-indicator">True</property>
-->
<property name="active">True</property>
<signal name="toggled" handler="on_sort_order_toggled" swapped="no"/>
</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>
</object>
</child>
</object>
<object class="GtkBox" id="toolbar"> <object class="GtkBox" id="toolbar">
<property name="orientation">horizontal</property> <property name="orientation">horizontal</property>
<property name="halign">end</property> <property name="halign">end</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child>
<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="tooltip-text" translatable="yes">Search the library</property>
<signal name="toggled" handler="on_search_toggled" swapped="no"/>
<child> <child>
<object class="GtkImage"> <object class="GtkToggleButton" id="toolbar_search_bar">
<property name="visible">True</property> <property name="receives-default">True</property>
<property name="can-focus">False</property> <property name="tooltip-text" translatable="yes">Search the library</property>
<property name="icon-name">system-search-symbolic</property> <child>
</object> <object class="GtkImage">
<property name="icon-name">system-search-symbolic</property>
</object>
</child>
<!--
<accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-->
</object>
</child> </child>
<!--
<accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-->
</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>
<object class="GtkToggleButton" id="select_button">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Select multiple albums</property>
<signal name="toggled" handler="on_select_toggled" swapped="no"/>
<child> <child>
<object class="GtkImage"> <object class="GtkToggleButton" id="select_button">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">object-select-symbolic</property>
</object>
</child>
</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>
<object class="GtkMenuButton">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Settings and actions</property>
<property name="popover">toolbar_popover</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
</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>
</object>
<template class="McgLibraryPanel" parent="AdwBin">
<child>
<object class="GtkStack">
<property name="transition-type">slide-left-right</property>
<child>
<object class="GtkBox" id="panel_normal">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchBar" id="filter_bar">
<!--
<property name="app-paintable">True</property>
-->
<signal name="notify" handler="on_filter_bar_notify" swapped="no"/>
<child>
<object class="GtkSearchEntry" id="filter_entry">
<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">True</property>
<property name="primary-icon-name">edit-find-symbolic</property> <property name="tooltip-text" translatable="yes">Select multiple albums</property>
<property name="primary-icon-activatable">False</property> <signal name="toggled" handler="on_select_toggled" swapped="no"/>
<property name="primary-icon-sensitive">False</property> <child>
--> <object class="GtkImage">
<property name="placeholder-text" translatable="yes">search library</property> <property name="icon-name">object-select-symbolic</property>
<signal name="search-changed" handler="on_filter_entry_changed" swapped="no"/> </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>
<child> <child>
<placeholder/> <object class="GtkMenuButton">
</child>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkBox" id="progress_box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">True</property>
<property name="orientation">vertical</property> <property name="receives-default">True</property>
<child type="center"> <property name="tooltip-text" translatable="yes">Settings and actions</property>
<object class="GtkBox"> <property name="popover">toolbar_popover</property>
<property name="visible">True</property> <child>
<property name="can-focus">False</property> <object class="GtkImage">
<property name="orientation">vertical</property>
<child type="center">
<object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="halign">center</property> <property name="icon-name">open-menu-symbolic</property>
</object>
</child>
</object>
</child>
</object>
<template class="McgLibraryPanel" parent="AdwBin">
<child>
<object class="GtkStack" id="library_stack">
<property name="transition-type">slide-left-right</property>
<child>
<object class="GtkBox" id="panel_normal">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">10</property>
<child> <child>
<object class="GtkImage" id="progress_image"> <object class="GtkSearchBar" id="filter_bar">
<property name="icon-size">large</property> <property name="search-mode-enabled" bind-source="toolbar_search_bar" bind-property="active" bind-flags="sync-create"/>
<property name="icon-name">image-x-generic-symbolic</property> <child>
</object> <object class="GtkSearchEntry" id="filter_entry">
<!-- <property name="placeholder-text" translatable="yes">search library</property>
<packing> <signal name="search-changed" handler="on_filter_entry_changed" swapped="no"/>
<property name="expand">False</property> </object>
<property name="fill">True</property> </child>
<property name="position">0</property> </object>
</packing>
-->
</child> </child>
<child> <child>
<object class="GtkProgressBar" id="progress_bar"> <object class="GtkStack" id="stack">
<property name="width-request">200</property> <property name="transition-type">crossfade</property>
<property name="visible">True</property> <child>
<property name="can-focus">False</property> <object class="GtkBox" id="progress_box">
<property name="pulse-step">0</property> <property name="orientation">vertical</property>
<property name="show-text">True</property> <child type="center">
</object> <object class="GtkBox">
<!-- <property name="orientation">vertical</property>
<packing> <child type="center">
<property name="expand">False</property> <object class="GtkBox">
<property name="fill">True</property> <property name="halign">center</property>
<property name="position">1</property> <property name="orientation">vertical</property>
</packing> <property name="spacing">10</property>
--> <child>
</child> <object class="GtkImage" id="progress_image">
</object> <property name="icon-size">large</property>
<!-- <property name="icon-name">image-x-generic-symbolic</property>
<packing> </object>
<property name="expand">False</property> </child>
<property name="fill">True</property> <child>
<property name="position">1</property> <object class="GtkProgressBar" id="progress_bar">
</packing> <property name="width-request">200</property>
--> <property name="visible">True</property>
</child> <property name="can-focus">False</property>
<child> <property name="pulse-step">0</property>
<placeholder/> <property name="show-text">True</property>
</child> </object>
</object> </child>
<!-- </object>
<packing> </child>
<property name="expand">False</property> </object>
<property name="fill">True</property> </child>
<property name="position">1</property> </object>
</packing> </child>
--> <child>
</child> <object class="GtkScrolledWindow" id="scroll">
<child> <property name="vexpand">true</property>
<placeholder/> <child>
</child> <object class="GtkGridView" id="library_grid">
</object> <property name="orientation">vertical</property>
<!-- <property name="single_click_activate">true</property>
<packing> <signal name="activate" handler="on_library_grid_clicked"/>
<property name="name">page1</property> <style>
<property name="title">page1</property> <class name="no-bg"/>
</packing> </style>
--> <property name="factory">
</child> <object class="GtkBuilderListItemFactory">
<child> <property name="bytes">
<object class="GtkScrolledWindow" id="scroll">
<property name="vexpand">true</property>
<child>
<object class="GtkGridView" id="library_grid">
<property name="orientation">vertical</property>
<!--
<signal name="activate" handler="on_library_grid_clicked" swapped="no"/>
<signal name="selection-changed" handler="on_library_grid_selection_changed" swapped="no"/>
<signal name="size-allocate" handler="on_resize" swapped="no"/>
-->
<style>
<class name="no-bg"/>
</style>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes">
<![CDATA[ <![CDATA[
<?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>
@ -449,202 +234,98 @@
</template> </template>
</interface> </interface>
]]> ]]>
</property> </property>
</object> </object>
</property> </property>
</object>
</child>
<style>
<class name="no-bg"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkRevealer" id="actionbar_revealer">
<property name="transition-type">slide-up</property>
<child>
<object class="GtkActionBar" id="actionbar">
<child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">cancel</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_cancel_clicked" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">queue</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_add_clicked" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="panel_standalone">
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="standalone_stack">
<property name="vexpand">true</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkSpinner" id="standalone_spinner">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="standalone_scroll">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="kinetic-scrolling">False</property>
<property name="overlay-scrolling">False</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkImage" id="standalone_image">
<property name="icon-name">gtk-missing-image</property>
<property name="icon-size">large</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkActionBar" id="actionbar_standalone">
<child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">play</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/>
</object>
</child>
<child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">queue</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_queue_clicked" swapped="no"/>
</object>
</child>
</object>
</child>
</object> </object>
</child> </child>
<style>
<class name="no-bg"/>
</style>
</object>
<!--
<packing>
<property name="name">page0</property>
<property name="title">page0</property>
<property name="position">1</property>
</packing>
-->
</child>
</object>
<!--
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
-->
</child>
<child>
<object class="GtkRevealer" id="actionbar_revealer">
<property name="transition-type">none</property>
<property name="reveal-child">false</property>
<child>
<object class="GtkActionBar" id="library-actionbar">
<child>
<object class="GtkButton">
<property name="label" translatable="yes">cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_selection_cancel_clicked" swapped="no"/>
</object>
<!--
<packing>
<property name="pack-type">end</property>
<property name="position">1</property>
</packing>
-->
</child>
<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_selection_add_clicked" swapped="no"/>
</object>
<!--
<packing>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
-->
</child>
</object>
</child>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
-->
</child>
</object>
<!--
<packing>
<property name="name">page0</property>
<property name="title">page0</property>
</packing>
-->
</child>
<child>
<object class="GtkBox" id="panel_standalone">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStack" id="standalone_stack">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkSpinner" id="standalone_spinner">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<!--
<packing>
<property name="name">standalone-spinne</property>
</packing>
-->
</child>
<child>
<object class="GtkScrolledWindow" id="standalone_scroll">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="kinetic-scrolling">False</property>
<property name="overlay-scrolling">False</property>
<!--
<signal name="size-allocate" handler="on_standalone_scroll_size_allocate" swapped="no"/>
-->
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<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_size">6</property>
-->
</object>
</child>
</object>
</child>
</object>
<!--
<packing>
<property name="name">standalone-scroll</property>
<property name="position">1</property>
</packing>
-->
</child>
</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>
<object class="GtkButton">
<property name="label" translatable="yes">play</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/>
</object>
<!--
<packing>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
-->
</child>
</object>
<!--
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
-->
</child>
</object>
<!--
<packing>
<property name="name">page1</property>
<property name="title">page1</property>
<property name="position">1</property>
</packing>
-->
</child>
</object> </object>
</child> </child>
</template> </template>

View file

@ -12,9 +12,7 @@
<property name="can-focus">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">Select multiple albums</property> <property name="tooltip-text" translatable="yes">Select multiple albums</property>
<!--
<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="icon-name">object-select-symbolic</property> <property name="icon-name">object-select-symbolic</property>
@ -28,9 +26,7 @@
<property name="can-focus">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">Clear the playlist</property> <property name="tooltip-text" translatable="yes">Clear the playlist</property>
<!--
<signal name="clicked" handler="on_clear_clicked" swapped="no"/> <signal name="clicked" handler="on_clear_clicked" swapped="no"/>
-->
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property> <property name="visible">True</property>
@ -43,7 +39,7 @@
</object> </object>
<template class="McgPlaylistPanel" parent="AdwBin"> <template class="McgPlaylistPanel" parent="AdwBin">
<child> <child>
<object class="GtkStack"> <object class="GtkStack" id="playlist_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">
@ -54,16 +50,10 @@
<child> <child>
<object class="GtkGridView" id="playlist_grid"> <object class="GtkGridView" id="playlist_grid">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<!--
<property name="item-padding">0</property>
-->
<property name="single-click-activate">true</property> <property name="single-click-activate">true</property>
<signal name="activate" handler="on_playlist_grid_clicked"/> <signal name="activate" handler="on_playlist_grid_clicked"/>
<!--
<signal name="selection-changed" handler="on_playlist_grid_selection_changed" swapped="no"/>
-->
<style> <style>
<class name="no-bg"/> <class name="no-bg"/>
</style> </style>
<property name="factory"> <property name="factory">
<object class="GtkBuilderListItemFactory"> <object class="GtkBuilderListItemFactory">
@ -103,7 +93,7 @@
</object> </object>
</child> </child>
<style> <style>
<class name="no-bg"/> <class name="no-bg"/>
</style> </style>
</object> </object>
</child> </child>
@ -112,22 +102,18 @@
<property name="transition-type">slide-up</property> <property name="transition-type">slide-up</property>
<child> <child>
<object class="GtkActionBar" id="actionbar"> <object class="GtkActionBar" id="actionbar">
<child> <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="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>
</child> </child>
<child> <child type="end">
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">remove</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_selection_remove_clicked" swapped="no"/> <signal name="clicked" handler="on_selection_remove_clicked" swapped="no"/>
-->
</object> </object>
</child> </child>
</object> </object>
@ -141,6 +127,7 @@
<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="vexpand">true</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>
@ -153,9 +140,6 @@
<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>
@ -163,9 +147,7 @@
<child> <child>
<object class="GtkImage" id="standalone_image"> <object class="GtkImage" id="standalone_image">
<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>
@ -176,22 +158,18 @@
</child> </child>
<child> <child>
<object class="GtkActionBar" id="actionbar_standalone"> <object class="GtkActionBar" id="actionbar_standalone">
<child> <child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">remove</property>
<property name="receives-default">True</property>
<!--
<signal name="clicked" handler="on_standalone_remove_clicked" swapped="no"/>
-->
</object>
</child>
<child>
<object class="GtkButton"> <object class="GtkButton">
<property name="label" translatable="yes">play</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_play_clicked" swapped="no"/> <signal name="clicked" handler="on_standalone_play_clicked" swapped="no"/>
--> </object>
</child>
<child type="end">
<object class="GtkButton">
<property name="label" translatable="yes">remove</property>
<property name="receives-default">True</property>
<signal name="clicked" handler="on_standalone_remove_clicked" swapped="no"/>
</object> </object>
</child> </child>
</object> </object>

View file

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 --> <!-- Generated with glade 3.38.2 -->
<interface> <interface>
<requires lib="gtk+" version="3.18"/> <requires lib="gtk+" version="4.8"/>
<requires lib="adw" version="1.2" />
<template class="McgShortcutsDialog" parent="GtkShortcutsWindow"> <template class="McgShortcutsDialog" parent="GtkShortcutsWindow">
<property name="modal">True</property> <property name="modal">1</property>
<child> <child>
<object class="GtkShortcutsSection"> <object class="GtkShortcutsSection">
<property name="visible">1</property> <property name="visible">1</property>
@ -11,53 +12,45 @@
<property name="max-height">10</property> <property name="max-height">10</property>
<child> <child>
<object class="GtkShortcutsGroup"> <object class="GtkShortcutsGroup">
<property name="visible">1</property>
<property name="title" translatable="yes">General</property> <property name="title" translatable="yes">General</property>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;KP_1</property> <property name="accelerator">&lt;primary&gt;KP_1</property>
<property name="title" translatable="yes">Switch to the Connection panel</property> <property name="title" translatable="yes">Switch to the Connection panel</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;KP_2</property> <property name="accelerator">&lt;primary&gt;KP_2</property>
<property name="title" translatable="yes">Switch to the Cover panel</property> <property name="title" translatable="yes">Switch to the Cover panel</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;KP_3</property> <property name="accelerator">&lt;primary&gt;KP_3</property>
<property name="title" translatable="yes">Switch to the Playlist panel</property> <property name="title" translatable="yes">Switch to the Playlist panel</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;KP_4</property> <property name="accelerator">&lt;primary&gt;KP_4</property>
<property name="title" translatable="yes">Switch to the Library panel</property> <property name="title" translatable="yes">Switch to the Library panel</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;k</property> <property name="accelerator">&lt;primary&gt;k</property>
<property name="title" translatable="yes">Show the keyboard shortcuts</property> <property name="title" translatable="yes">Show the keyboard shortcuts</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;i</property> <property name="accelerator">&lt;primary&gt;i</property>
<property name="title" translatable="yes">Open the info dialog</property> <property name="title" translatable="yes">Open the info dialog</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;q</property> <property name="accelerator">&lt;primary&gt;q</property>
<property name="title" translatable="yes">Quit the application</property> <property name="title" translatable="yes">Quit the application</property>
</object> </object>
@ -66,25 +59,21 @@
</child> </child>
<child> <child>
<object class="GtkShortcutsGroup"> <object class="GtkShortcutsGroup">
<property name="visible">1</property>
<property name="title" translatable="yes">Player</property> <property name="title" translatable="yes">Player</property>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;c</property> <property name="accelerator">&lt;primary&gt;c</property>
<property name="title" translatable="yes">Connect or disconnect</property> <property name="title" translatable="yes">Connect or disconnect</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;p</property> <property name="accelerator">&lt;primary&gt;p</property>
<property name="title" translatable="yes">Switch between play and pause</property> <property name="title" translatable="yes">Switch between play and pause</property>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;r</property> <property name="accelerator">&lt;primary&gt;r</property>
<property name="title" translatable="yes">Clear the playlist</property> <property name="title" translatable="yes">Clear the playlist</property>
</object> </object>
@ -93,11 +82,9 @@
</child> </child>
<child> <child>
<object class="GtkShortcutsGroup"> <object class="GtkShortcutsGroup">
<property name="visible">1</property>
<property name="title" translatable="yes">Cover Panel</property> <property name="title" translatable="yes">Cover Panel</property>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">F11</property> <property name="accelerator">F11</property>
<property name="title" translatable="yes">Show the cover in fullscreen mode</property> <property name="title" translatable="yes">Show the cover in fullscreen mode</property>
</object> </object>
@ -106,11 +93,9 @@
</child> </child>
<child> <child>
<object class="GtkShortcutsGroup"> <object class="GtkShortcutsGroup">
<property name="visible">1</property>
<property name="title" translatable="yes">Library Panel</property> <property name="title" translatable="yes">Library Panel</property>
<child> <child>
<object class="GtkShortcutsShortcut"> <object class="GtkShortcutsShortcut">
<property name="visible">1</property>
<property name="accelerator">&lt;primary&gt;f</property> <property name="accelerator">&lt;primary&gt;f</property>
<property name="title" translatable="yes">Search the library</property> <property name="title" translatable="yes">Search the library</property>
</object> </object>

View file

@ -4,9 +4,8 @@
<requires lib="adw" version="1.2" /> <requires lib="adw" version="1.2" />
<template class="McgAppWindow" parent="AdwApplicationWindow"> <template class="McgAppWindow" parent="AdwApplicationWindow">
<property name="content"> <property name="content">
<object class="GtkBox"> <object class="AdwToolbarView" id="toolbar_view">
<property name="orientation">vertical</property> <child type="top">
<child>
<object class="AdwHeaderBar" id="headerbar"> <object class="AdwHeaderBar" id="headerbar">
<property name="centering-policy">strict</property> <property name="centering-policy">strict</property>
<property name="show_end_title_buttons">true</property> <property name="show_end_title_buttons">true</property>
@ -44,30 +43,35 @@
</child> </child>
</object> </object>
</child> </child>
<child> <property name="content">
<object class="AdwToastOverlay" id="info_toast"> <object class="GtkBox" id="content_box">
<property name="orientation">vertical</property>
<child> <child>
<object class="GtkStack" id="content_stack"> <object class="AdwToastOverlay" id="info_toast">
<property name="name">content_stack</property>
<property name="vexpand">true</property>
<child> <child>
<object class="AdwViewStack" id="panel_stack"> <object class="GtkStack" id="content_stack">
<property name="name">content_stack</property>
<property name="vexpand">true</property> <property name="vexpand">true</property>
<signal name="notify::visible-child" handler="on_stack_switched" swapped="no"/> <child>
<object class="AdwViewStack" id="panel_stack">
<property name="vexpand">true</property>
<signal name="notify::visible-child" handler="on_stack_switched" swapped="no"/>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="AdwViewSwitcherBar">
<property name="stack">panel_stack</property>
<binding name="reveal">
<lookup name="title-visible">headerbar_panel_switcher</lookup>
</binding>
</object>
</child>
</object> </object>
</child> </property>
<child>
<object class="AdwViewSwitcherBar">
<property name="stack">panel_stack</property>
<binding name="reveal">
<lookup name="title-visible">headerbar_panel_switcher</lookup>
</binding>
</object>
</child>
</object> </object>
</property> </property>
</template> </template>

View file

@ -6,9 +6,8 @@
<file>ui/window.ui</file> <file>ui/window.ui</file>
<!-- <!--
<file>ui/gtk.menu.ui</file> <file>ui/gtk.menu.ui</file>
<file>ui/info-dialog.ui</file>
<file>ui/shortcuts-dialog.ui</file>
--> -->
<file>ui/shortcuts-dialog.ui</file>
<file>ui/connection-panel.ui</file> <file>ui/connection-panel.ui</file>
<file>ui/album-headerbar.ui</file> <file>ui/album-headerbar.ui</file>
<file>ui/server-panel.ui</file> <file>ui/server-panel.ui</file>

View file

@ -26,7 +26,9 @@ class Application(Gtk.Application):
self._window = None self._window = None
self._info_dialog = None self._info_dialog = None
self._verbosity = logging.WARNING self._verbosity = logging.WARNING
#self.create_action('quit', self.quit, ['<primary>q']) self.set_accels_for_action('window.close', ['<primary>q'])
self.set_accels_for_action('win.show-help-overlay', ['<primary>k'])
self.set_accels_for_action('app.info', ['<primary>i'])
#self.create_action('about', self.on_about_action) #self.create_action('about', self.on_about_action)
#self.create_action('preferences', self.on_preferences_action) #self.create_action('preferences', self.on_preferences_action)
@ -50,12 +52,15 @@ class Application(Gtk.Application):
def on_menu_info(self, action, value): def on_menu_info(self, action, value):
# FIXME Info dialog self._info_dialog = Adw.AboutDialog()
#if not self._info_dialog: self._info_dialog.set_application_icon("xyz.suruatoel.mcg")
# self._info_dialog = InfoDialog() self._info_dialog.set_application_name("CoverGrid")
#self._info_dialog.run() self._info_dialog.set_version("3.1")
#self._info_dialog.hide() self._info_dialog.set_comments("CoverGrid is a client for the Music Player Daemon, focusing on albums instead of single tracks.")
pass self._info_dialog.set_website("https://www.suruatoel.xyz/codes/mcg")
self._info_dialog.set_license_type(Gtk.License.GPL_3_0)
self._info_dialog.set_issue_url("https://git.suruatoel.xyz/coderkun/mcg")
self._info_dialog.present()
def on_menu_quit(self, action, value): def on_menu_quit(self, action, value):
@ -111,6 +116,7 @@ class Application(Gtk.Application):
def _setup_adw(self): def _setup_adw(self):
Adw.HeaderBar() Adw.HeaderBar()
Adw.ToolbarView()
Adw.ViewSwitcherTitle() Adw.ViewSwitcherTitle()
Adw.ViewSwitcherBar() Adw.ViewSwitcherBar()
Adw.ViewStackPage() Adw.ViewStackPage()

View file

@ -616,17 +616,16 @@ 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 album.get_tracks():
for track in self._albums[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())) if 'id' in track_id_response:
if 'id' in track_id_response: track_id = track_id_response['id']
track_id = track_id_response['id'] self._logger.debug("track id: %r", track_id)
self._logger.debug("track id: %r", track_id) if track_id is not None:
if track_id is not None: track_ids.append(track_id)
track_ids.append(track_id)
return track_ids return track_ids
@ -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

@ -63,6 +63,17 @@ class CoverPanel(Gtk.Overlay):
# Initial actions # Initial actions
GObject.idle_add(self._enable_tracklist) GObject.idle_add(self._enable_tracklist)
# Click handler for image
clickController = Gtk.GestureClick()
clickController.connect('pressed', self.on_cover_box_pressed)
self.cover_box.add_controller(clickController)
# Button controller for songs scale
buttonController = Gtk.GestureClick()
buttonController.connect('pressed', self.on_songs_scale_pressed)
buttonController.connect('unpaired-release', self.on_songs_scale_released)
self.songs_scale.add_controller(buttonController)
def get_toolbar(self): def get_toolbar(self):
return self.toolbar return self.toolbar
@ -72,11 +83,9 @@ class CoverPanel(Gtk.Overlay):
pass pass
# FIXME on_cover_box_pressed() def on_cover_box_pressed(self, widget, npress, x, y):
#@Gtk.Template.Callback() if self._current_album and npress == 2:
#def on_cover_box_pressed(self, widget, event): self.emit('toggle-fullscreen')
# if self._current_album and event.type == Gdk.EventType._2BUTTON_PRESS:
# self.emit('toggle-fullscreen')
def set_width(self, width): def set_width(self, width):
@ -84,16 +93,12 @@ class CoverPanel(Gtk.Overlay):
self.cover_info_scroll.set_max_content_width(width // 2) self.cover_info_scroll.set_max_content_width(width // 2)
# FIXME on_songs_start_change() def on_songs_scale_pressed(self, widget, npress, x, y):
#@Gtk.Template.Callback() if self._timer:
#def on_songs_start_change(self, widget, event): GObject.source_remove(self._timer)
# if self._timer: self._timer = None
# GObject.source_remove(self._timer)
# self._timer = None
def on_songs_scale_released(self, widget, x, y, npress, sequence):
#@Gtk.Template.Callback()
def on_songs_change(self, widget, event):
value = int(self.songs_scale.get_value()) value = int(self.songs_scale.get_value())
time = self._current_album.get_length() time = self._current_album.get_length()
tracks = self._current_album.get_tracks() tracks = self._current_album.get_tracks()
@ -150,13 +155,12 @@ class CoverPanel(Gtk.Overlay):
def set_fullscreen(self, active): def set_fullscreen(self, active):
if active: if active:
self.info_revealer.set_reveal_child(False) self.info_revealer.set_reveal_child(False)
self.cover_box.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 1))
GObject.idle_add(self._resize_image) GObject.idle_add(self._resize_image)
self._fullscreened = True self._fullscreened = True
else: else:
self._fullscreened = False self._fullscreened = False
self.info_revealer.set_reveal_child(True) if self._current_album:
self.cover_box.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 0)) self.info_revealer.set_reveal_child(True)
GObject.idle_add(self._resize_image) GObject.idle_add(self._resize_image)
@ -171,7 +175,6 @@ class CoverPanel(Gtk.Overlay):
self._cover_pixbuf = None self._cover_pixbuf = None
else: else:
# Reset image # Reset image
self._cover_pixbuf = self._get_default_image()
self._cover_pixbuf = None self._cover_pixbuf = None
self._current_size = None self._current_size = None
self._current_cover_album = album self._current_cover_album = album
@ -205,7 +208,8 @@ class CoverPanel(Gtk.Overlay):
def _enable_tracklist(self): def _enable_tracklist(self):
if self._current_album: if self._current_album:
# enable # enable
self.info_revealer.set_reveal_child(True) if not self._fullscreened:
self.info_revealer.set_reveal_child(True)
else: else:
# disable # disable
self.info_revealer.set_reveal_child(False) self.info_revealer.set_reveal_child(False)
@ -231,7 +235,7 @@ class CoverPanel(Gtk.Overlay):
"""Diese Methode skaliert das geladene Bild aus dem Pixelpuffer """Diese Methode skaliert das geladene Bild aus dem Pixelpuffer
auf die Größe des Fensters unter Beibehalt der Seitenverhältnisse auf die Größe des Fensters unter Beibehalt der Seitenverhältnisse
""" """
# FIXME Get size # Get size
size_width = self.cover_stack.get_size(Gtk.Orientation.HORIZONTAL) size_width = self.cover_stack.get_size(Gtk.Orientation.HORIZONTAL)
size_height = self.cover_stack.get_size(Gtk.Orientation.HORIZONTAL) size_height = self.cover_stack.get_size(Gtk.Orientation.HORIZONTAL)
# Abort if size is the same # Abort if size is the same
@ -258,7 +262,5 @@ class CoverPanel(Gtk.Overlay):
height = int(math.floor(pixbuf.get_height()*ratio)) height = int(math.floor(pixbuf.get_height()*ratio))
if width <= 0 or height <= 0: if width <= 0 or height <= 0:
return return
# FIXME Pixelpuffer auf Oberfläche zeichnen
#self.cover_image.set_allocation(self.cover_scroll.get_allocation())
self.cover_image.set_from_pixbuf(pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.HYPER)) self.cover_image.set_from_pixbuf(pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.HYPER))
self.cover_image.show() self.cover_image.show()

View file

@ -1,15 +0,0 @@
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
import logging
from gi.repository import Gtk, GdkPixbuf
@Gtk.Template(resource_path='/xyz/suruatoel/mcg/ui/info-dialog.ui')
class InfoDialog(Gtk.AboutDialog):
__gtype_name__ = 'McgInfoDialog'

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,14 @@ 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, ()),
'start-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 +64,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,38 +81,31 @@ 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
self._grid_pixbufs = {} self._grid_pixbufs = {}
self._grid_width = 0
self._old_ranges = {} self._old_ranges = {}
self._library_lock = threading.Lock() self._library_lock = threading.Lock()
self._library_stop = threading.Event() self._library_stop = threading.Event()
self._icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()) self._icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default())
self._standalone_pixbuf = None self._standalone_pixbuf = None
self._selected_albums = [] self._selected_albums = []
self._allocation = (0, 0)
self._is_selected = False self._is_selected = False
# Widgets # Widgets
# 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('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 = {
@ -123,6 +114,11 @@ class LibraryPanel(Adw.Bin):
SortOrder.YEAR: self.sort_year SortOrder.YEAR: self.sort_year
} }
# Button controller for grid scale
buttonController = Gtk.GestureClick()
buttonController.connect('unpaired-release', self.on_grid_scale_released)
self.grid_scale.add_controller(buttonController)
def get_headerbar_standalone(self): def get_headerbar_standalone(self):
return self._headerbar_standalone return self._headerbar_standalone
@ -136,148 +132,84 @@ 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')
# FXME on_grid_scale_changed def on_grid_scale_released(self, widget, x, y, npress, sequence):
#@Gtk.Template.Callback() size = math.floor(self.grid_scale.get_value())
def on_grid_scale_change(self, widget, scroll, value): range = self.grid_scale.get_adjustment()
self.emit('start-scale', value)
# FXME on_grid_scale_changed
#@Gtk.Template.Callback()
def on_grid_scale_changed(self, widget, event):
self.emit('end-scale', self.grid_scale.get_value())
self.toolbar_popover.popdown()
#@Gtk.Template.Callback()
def on_sort_toggled(self, widget):
if widget.get_active():
sort = [key for key, value in self._toolbar_sort_buttons.items() if value is widget][0]
self.emit('sort', sort)
#@Gtk.Template.Callback()
def on_sort_order_toggled(self, button):
if button.get_active():
sort_type = Gtk.SortType.DESCENDING
else:
sort_type = Gtk.SortType.ASCENDING
self.emit('sort-type', sort_type)
# FIXME on_resize()
#@Gtk.Template.Callback()
def on_resize(self, widget, event):
new_allocation = (widget.get_allocation().width, widget.get_allocation().height)
if new_allocation == self._allocation:
return
self._allocation = new_allocation
self.grid_scale.clear_marks()
width = widget.get_allocation().width
lower = int(self.grid_scale.get_adjustment().get_lower())
upper = int(self.grid_scale.get_adjustment().get_upper())
countMin = max(int(width / upper), 1)
countMax = max(int(width / lower), 1)
for index in range(countMin, countMax):
pixel = int(width / index)
pixel = pixel - (2 * int(pixel / 100))
self.grid_scale.add_mark(
pixel,
Gtk.PositionType.BOTTOM,
None
)
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):
self.emit('update')
def on_toolbar_scale(self, widget, value):
size = math.floor(value)
range = self.grid_scale.get_adjustment()
if size < range.get_lower() or size > range.get_upper(): if size < range.get_lower() or size > range.get_upper():
return return
self._item_size = size self._item_size = size
#GObject.idle_add(self.library_grid.set_item_padding, size / 100)
GObject.idle_add(self._set_widget_grid_size, self.library_grid, size, True)
def on_toolbar_scaled(self, widget, value):
size = round(value)
range = self.grid_scale.get_adjustment()
if size < range.get_lower() or size > range.get_upper():
return False
self.emit('item-size-changed', size) self.emit('item-size-changed', size)
self._redraw() self._redraw()
return False GObject.idle_add(self.toolbar_popover.popdown)
def on_toolbar_sort(self, widget, sort): @Gtk.Template.Callback()
self._change_sort(sort) def on_grid_scale_changed(self, widget):
size = math.floor(self.grid_scale.get_value())
range = widget.get_adjustment()
if size < range.get_lower() or size > range.get_upper():
return
self._set_widget_grid_size(self.library_grid, size, True)
def on_toolbar_sort_type(self, widget, sort_type): @Gtk.Template.Callback()
self._sort_type = sort_type def on_sort_toggled(self, widget):
#self._library_grid_model.set_sort_column_id(2, sort_type) if widget.get_active():
self.emit('sort-type-changed', sort_type) self._sort_order = [key for key, value in self._toolbar_sort_buttons.items() if value is widget][0]
self._sort_grid_model()
self.emit('sort-order-changed', self._sort_order)
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_filter_bar_notify(self, widget, value): def on_sort_order_toggled(self, button):
if self.toolbar_search_bar.get_active() is not self.filter_bar.get_search_mode(): if button.get_active():
self.toolbar_search_bar.set_active(self.filter_bar.get_search_mode()) self._sort_type = Gtk.SortType.DESCENDING
else:
self._sort_type = Gtk.SortType.ASCENDING
self._sort_grid_model()
self.emit('sort-type-changed', button.get_active())
#@Gtk.Template.Callback() def set_size(self, width, height):
self._set_marks()
self._resize_standalone_image()
@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,50 +221,24 @@ 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)
# FIXME on_standalone_scroll_size_allocate() @Gtk.Template.Callback()
#@Gtk.Template.Callback()
def on_standalone_scroll_size_allocate(self, widget, allocation):
self._resize_standalone_image()
#@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 +264,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:
if button and not button.get_active(): 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) self._sort_type = sort_type_gtk
else: self.toolbar_sort_order_button.set_active(sort_type)
sort_type_gtk = Gtk.SortType.ASCENDING self._sort_grid_model()
self.toolbar_sort_order_button.set_active(False)
if self._sort_type != sort_type_gtk:
self._sort_type = sort_type_gtk
self._library_grid_model.set_sort_column_id(2, sort_type)
def get_sort_type(self): def get_sort_type(self):
@ -416,25 +314,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) GObject.idle_add(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:
@ -446,14 +337,13 @@ class LibraryPanel(Adw.Bin):
) )
""" """
self._library_lock.acquire() self._library_lock.acquire()
self._library_stop.clear()
self._albums = albums self._albums = albums
stack_transition_type = self.stack.get_transition_type()
GObject.idle_add(self.stack.set_transition_type, Gtk.StackTransitionType.NONE)
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.stack.set_transition_type, stack_transition_type)
self.library_grid.set_model(None) GObject.idle_add(self._library_grid_model.remove_all)
#self.library_grid.freeze_child_notify()
self._library_grid_model.remove_all()
i = 0 i = 0
n = len(albums) n = len(albums)
@ -468,7 +358,7 @@ class LibraryPanel(Adw.Bin):
# Exception is handled by client # Exception is handled by client
pass pass
except Exception as e: except Exception as e:
self._logger.exception("Failed to load albumart") self._logger.exception("Failed to load albumart", e)
if pixbuf is None: if pixbuf is None:
pixbuf = self._icon_theme.lookup_icon( pixbuf = self._icon_theme.lookup_icon(
Utils.STOCK_ICON_DEFAULT, Utils.STOCK_ICON_DEFAULT,
@ -480,20 +370,15 @@ class LibraryPanel(Adw.Bin):
) )
if pixbuf is not None: if pixbuf is not None:
self._grid_pixbufs[album.get_id()] = pixbuf self._grid_pixbufs[album.get_id()] = pixbuf
self._library_grid_model.append(GridItem(album, pixbuf)) GObject.idle_add(self._library_grid_model.append, GridItem(album, pixbuf))
i += 1 i += 1
GObject.idle_add(self.progress_bar.set_fraction, i/n) GObject.idle_add(self.progress_bar.set_fraction, i/n)
GObject.idle_add(self.progress_bar.set_text, locale.gettext("Loading images")) GObject.idle_add(self.progress_bar.set_text, locale.gettext("Loading images"))
if self._library_stop.is_set():
self._library_lock.release()
return
self.library_grid.set_model(self._library_grid_filter)
#self.library_grid.thaw_child_notify()
#self.library_grid.set_item_width(-1)
self._library_lock.release() self._library_lock.release()
self.stack.set_visible_child(self.scroll) GObject.idle_add(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):
@ -504,50 +389,31 @@ class LibraryPanel(Adw.Bin):
def _set_widget_grid_size_thread(self, grid_widget, size, vertical): def _set_widget_grid_size_thread(self, grid_widget, size, vertical):
self._library_lock.acquire() self._library_lock.acquire()
self._library_stop.clear() self._library_stop.clear()
grid_filter = grid_widget.get_model() if size == self._item_size:
grid_model = grid_filter.get_model()
# get old_range
grid_widget_id = id(grid_widget)
if grid_widget_id not in self._old_ranges or self._old_ranges[grid_widget_id] is None:
self._old_ranges[grid_widget_id] = range(0, len(grid_filter))
old_range = self._old_ranges[grid_widget_id]
old_start = len(old_range) > 0 and old_range[0] or 0
old_end = len(old_range) > 0 and old_range[len(old_range)-1] + 1 or 0
# calculate visible range
w = (grid_widget.get_allocation().width // size) + (vertical and 0 or 1)
h = (grid_widget.get_allocation().height // size) + (vertical and 1 or 0)
c = w * h
vis_range = grid_widget.get_visible_range()
if vis_range is None:
self._library_lock.release() self._library_lock.release()
return return
(vis_start,), (vis_end,) = vis_range for i in range(self._library_grid_model.get_n_items()):
vis_end = min(vis_start + c, len(grid_filter)) grid_item = self._library_grid_model.get_item(i)
vis_range = range(vis_start, vis_end) album_id = grid_item.get_album().get_id()
# set pixbuf pixbuf = self._grid_pixbufs[album_id]
cur_start = min(old_start, vis_start) if pixbuf is not None:
cur_end = max(old_end, vis_end)
cur_range = range(cur_start, cur_end)
for index in cur_range:
iter = grid_filter.convert_iter_to_child_iter(grid_filter[index].iter)
if index in vis_range:
album_id = grid_model.get_value(iter, 2)
pixbuf = self._grid_pixbufs[album_id]
pixbuf = pixbuf.scale_simple(size, size, GdkPixbuf.InterpType.NEAREST) pixbuf = pixbuf.scale_simple(size, size, GdkPixbuf.InterpType.NEAREST)
else: else:
pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, 1, 1) pixbuf = self._icon_theme.lookup_icon(
grid_model.set_value(iter, 0, pixbuf) Utils.STOCK_ICON_DEFAULT,
None,
size,
size,
Gtk.TextDirection.LTR,
Gtk.IconLookupFlags.FORCE_SYMBOLIC
)
GObject.idle_add(grid_item.set_cover, pixbuf)
if self._library_stop.is_set(): if self._library_stop.is_set():
self._library_lock.release() self._library_lock.release()
return return
self._old_ranges[grid_widget_id] = vis_range
grid_widget.set_item_width(size)
self._library_lock.release() self._library_lock.release()
@ -562,13 +428,34 @@ class LibraryPanel(Adw.Bin):
self.set_albums(self._host, self._albums) self.set_albums(self._host, self._albums)
def _set_marks(self):
width = self.scroll.get_width()
if width == self._grid_width:
return
self._grid_width = width
self.grid_scale.clear_marks()
lower = int(self.grid_scale.get_adjustment().get_lower())
upper = int(self.grid_scale.get_adjustment().get_upper())
countMin = max(int(width / upper), 1)
countMax = max(int(width / lower), 1)
for index in range(countMin, countMax):
pixel = int(width / index)
pixel = pixel - (2 * int(pixel / 100))
self.grid_scale.add_mark(
pixel,
Gtk.PositionType.BOTTOM,
None
)
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')
@ -576,15 +463,19 @@ class LibraryPanel(Adw.Bin):
"""Diese Methode skaliert das geladene Bild aus dem Pixelpuffer """Diese Methode skaliert das geladene Bild aus dem Pixelpuffer
auf die Größe des Fensters unter Beibehalt der Seitenverhältnisse auf die Größe des Fensters unter Beibehalt der Seitenverhältnisse
""" """
# Get size
size_width = self.standalone_stack.get_width()
size_height = self.standalone_stack.get_height()
# Get pixelbuffer
pixbuf = self._standalone_pixbuf pixbuf = self._standalone_pixbuf
size = self.standalone_scroll.get_allocation()
# Check pixelbuffer # Check pixelbuffer
if pixbuf is None: if pixbuf is None:
return return
# Skalierungswert für Breite und Höhe ermitteln # Skalierungswert für Breite und Höhe ermitteln
ratioW = float(size.width) / float(pixbuf.get_width()) ratioW = float(size_width) / float(pixbuf.get_width())
ratioH = float(size.height) / float(pixbuf.get_height()) ratioH = float(size_height) / float(pixbuf.get_height())
# Kleineren beider Skalierungswerte nehmen, nicht Hochskalieren # Kleineren beider Skalierungswerte nehmen, nicht Hochskalieren
ratio = min(ratioW, ratioH) ratio = min(ratioW, ratioH)
ratio = min(ratio, 1) ratio = min(ratio, 1)
@ -594,7 +485,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 +498,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

@ -25,7 +25,6 @@ mcg_sources = [
'client.py', 'client.py',
'connectionpanel.py', 'connectionpanel.py',
'coverpanel.py', 'coverpanel.py',
'infodialog.py',
'librarypanel.py', 'librarypanel.py',
'playlistpanel.py', 'playlistpanel.py',
'serverpanel.py', 'serverpanel.py',

View file

@ -29,13 +29,12 @@ class PlaylistPanel(Adw.Bin):
'remove-multiple-albums': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), 'remove-multiple-albums': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
'play': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), 'play': (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)),
'albumart': (GObject.SIGNAL_RUN_FIRST, None, (str,)), 'albumart': (GObject.SIGNAL_RUN_FIRST, None, (str,)),
'select': (GObject.SIGNAL_RUN_FIRST, None, (bool,)),
'clear-playlist': (GObject.SIGNAL_RUN_FIRST, None, ())
} }
# Widgets # Widgets
playlist_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,17 +68,15 @@ class PlaylistPanel(Adw.Bin):
self._is_selected = False self._is_selected = False
# Widgets # Widgets
# FIXME Toolbar signals
#self._toolbar.connect('select', self.on_toolbar_select)
#self._toolbar.connect('clear-playlist', self.on_toolbar_clear)
# Header bar # Header bar
self._headerbar_standalone = AlbumHeaderbar() self._headerbar_standalone = AlbumHeaderbar()
self._headerbar_standalone.connect('close', self.on_headerbar_close_clicked) self._headerbar_standalone.connect('close', self.on_headerbar_close_clicked)
# Playlist Grid: Model # Playlist Grid: Model
self._playlist_grid_model = Gio.ListStore() self._playlist_grid_model = Gio.ListStore()
self._playlist_grid_selection = Gtk.MultiSelection.new(self._playlist_grid_model) self._playlist_grid_selection_multi = Gtk.MultiSelection.new(self._playlist_grid_model)
self._playlist_grid_selection_single = Gtk.SingleSelection.new(self._playlist_grid_model)
# Playlist Grid # Playlist Grid
self.playlist_grid.set_model(self._playlist_grid_selection) self.playlist_grid.set_model(self._playlist_grid_selection_single)
def get_headerbar_standalone(self): def get_headerbar_standalone(self):
@ -94,32 +91,23 @@ class PlaylistPanel(Adw.Bin):
self._is_selected = selected self._is_selected = selected
def on_toolbar_select(self, widget, active): @Gtk.Template.Callback()
if active: def on_select_toggled(self, widget):
if self.select_button.get_active():
self.actionbar_revealer.set_reveal_child(True) self.actionbar_revealer.set_reveal_child(True)
self.playlist_grid.set_selection_mode(Gtk.SelectionMode.MULTIPLE) self.playlist_grid.set_model(self._playlist_grid_selection_multi)
self.playlist_grid.set_single_click_activate(False)
self.playlist_grid.get_style_context().add_class(Utils.CSS_SELECTION) self.playlist_grid.get_style_context().add_class(Utils.CSS_SELECTION)
else: else:
self.actionbar_revealer.set_reveal_child(False) self.actionbar_revealer.set_reveal_child(False)
self.playlist_grid.set_selection_mode(Gtk.SelectionMode.SINGLE) self.playlist_grid.set_model(self._playlist_grid_selection_single)
self.playlist_grid.set_single_click_activate(True)
self.playlist_grid.get_style_context().remove_class(Utils.CSS_SELECTION) self.playlist_grid.get_style_context().remove_class(Utils.CSS_SELECTION)
def on_toolbar_clear(self, widget): @Gtk.Template.Callback()
self.emit('clear-playlist')
# FIXME on_select_toggled()
#@Gtk.Template.Callback()
def on_select_toggled(self, widget):
self.emit('select', widget.get_active())
# FIXME on_clear_clicked()
#@Gtk.Template.Callback()
def on_clear_clicked(self, widget): def on_clear_clicked(self, widget):
if widget is self.playlist_clear_button: self.emit('clear-playlist')
self.emit('clear-playlist')
@Gtk.Template.Callback() @Gtk.Template.Callback()
@ -131,9 +119,8 @@ class PlaylistPanel(Adw.Bin):
self._selected_albums = [album] self._selected_albums = [album]
self.emit('albumart', id) self.emit('albumart', id)
# FIXME Show standalone album # Show standalone album
return if widget.get_model() == self._playlist_grid_selection_single:
if widget.get_selection_mode() == Gtk.SelectionMode.SINGLE:
# Set labels # Set labels
self._headerbar_standalone.set_album(album) self._headerbar_standalone.set_album(album)
@ -145,49 +132,37 @@ class PlaylistPanel(Adw.Bin):
self.standalone_spinner.start() self.standalone_spinner.start()
# FIXME on_playlist_grid_selection_changed() @Gtk.Template.Callback()
#@Gtk.Template.Callback()
def on_playlist_grid_selection_changed(self, widget):
self._selected_albums = []
for path in widget.get_selected_items():
iter = self._playlist_grid_model.get_iter(path)
hash = self._playlist_grid_model.get_value(iter, 2)
self._selected_albums.append(self._playlist_albums[hash])
#@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_remove_clicked(self, widget): def on_selection_remove_clicked(self, widget):
self.emit('remove-multiple-albums', self._selected_albums) self.emit('remove-multiple-albums', self._get_selected_albums())
self.select_button.set_active(False) self.select_button.set_active(False)
# FIXME on_standalone_scroll_size_allocate()
#@Gtk.Template.Callback()
def on_standalone_scroll_size_allocate(self, widget, allocation):
self._resize_standalone_image()
def on_headerbar_close_clicked(self, widget): def on_headerbar_close_clicked(self, widget):
self._close_standalone() self._close_standalone()
#@Gtk.Template.Callback() @Gtk.Template.Callback()
def on_standalone_remove_clicked(self, widget): def on_standalone_remove_clicked(self, widget):
self.emit('remove-album', self._selected_albums[0]) self.emit('remove-album', self._get_selected_albums()[0])
self._close_standalone() self._close_standalone()
#@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]) self.emit('play', self._get_selected_albums()[0])
self._close_standalone() self._close_standalone()
def set_size(self, width, height):
self._resize_standalone_image()
def set_item_size(self, item_size): def set_item_size(self, item_size):
if self._item_size != item_size: if self._item_size != item_size:
self._item_size = item_size self._item_size = item_size
@ -240,8 +215,6 @@ class PlaylistPanel(Adw.Bin):
for album in playlist: for album in playlist:
self._playlist_albums[album.get_id()] = album self._playlist_albums[album.get_id()] = album
self._playlist_grid_model.remove_all() self._playlist_grid_model.remove_all()
# FIXME Set item padding dynamically?
#GObject.idle_add(self.playlist_grid.set_item_padding, size / 100)
cache = client.MCGCache(host, size) cache = client.MCGCache(host, size)
for album in playlist: for album in playlist:
@ -270,7 +243,7 @@ class PlaylistPanel(Adw.Bin):
self._playlist_lock.release() self._playlist_lock.release()
return return
self.playlist_grid.set_model(self._playlist_grid_selection) self.playlist_grid.set_model(self._playlist_grid_selection_single)
self._playlist_lock.release() self._playlist_lock.release()
@ -286,12 +259,12 @@ class PlaylistPanel(Adw.Bin):
def _open_standalone(self): def _open_standalone(self):
self.set_visible_child(self.panel_standalone) self.playlist_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.playlist_stack.set_visible_child(self.panel_normal)
self.emit('close-standalone') self.emit('close-standalone')
@ -299,15 +272,19 @@ class PlaylistPanel(Adw.Bin):
"""Diese Methode skaliert das geladene Bild aus dem Pixelpuffer """Diese Methode skaliert das geladene Bild aus dem Pixelpuffer
auf die Größe des Fensters unter Beibehalt der Seitenverhältnisse auf die Größe des Fensters unter Beibehalt der Seitenverhältnisse
""" """
# Get size
size_width = self.standalone_stack.get_width()
size_height = self.standalone_stack.get_height()
# Get pixelbuffer
pixbuf = self._standalone_pixbuf pixbuf = self._standalone_pixbuf
size = self.standalone_scroll.get_allocation()
# Check pixelbuffer # Check pixelbuffer
if pixbuf is None: if pixbuf is None:
return return
# Skalierungswert für Breite und Höhe ermitteln # Skalierungswert für Breite und Höhe ermitteln
ratioW = float(size.width) / float(pixbuf.get_width()) ratioW = float(size_width) / float(pixbuf.get_width())
ratioH = float(size.height) / float(pixbuf.get_height()) ratioH = float(size_height) / float(pixbuf.get_height())
# Kleineren beider Skalierungswerte nehmen, nicht Hochskalieren # Kleineren beider Skalierungswerte nehmen, nicht Hochskalieren
ratio = min(ratioW, ratioH) ratio = min(ratioW, ratioH)
ratio = min(ratio, 1) ratio = min(ratio, 1)
@ -317,7 +294,6 @@ class PlaylistPanel(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()
@ -331,3 +307,11 @@ class PlaylistPanel(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.playlist_grid.get_model().get_n_items()):
if self.playlist_grid.get_model().is_selected(i):
albums.append(self.playlist_grid.get_model().get_item(i).get_album())
return albums

View file

@ -2,8 +2,8 @@
import gi import gi
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk from gi.repository import Gtk

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,21 @@ class GridItem(GObject.GObject):
def get_album(self): def get_album(self):
return self._album return self._album
def set_cover(self, cover):
self.cover = Gdk.Texture.new_for_pixbuf(cover)
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

@ -9,13 +9,14 @@ try:
use_keyring = True use_keyring = True
except: except:
use_keyring = False use_keyring = False
use_keyring = False
import locale import locale
import logging import logging
from gi.repository import Gtk, Adw, Gdk, GObject, GLib, Gio from gi.repository import Gtk, Adw, Gdk, GObject, GLib, Gio
from . import client from . import client
#from .shortcutsdialog import ShortcutsDialog from .shortcutsdialog import ShortcutsDialog
from .connectionpanel import ConnectionPanel from .connectionpanel import ConnectionPanel
from .serverpanel import ServerPanel from .serverpanel import ServerPanel
from .coverpanel import CoverPanel from .coverpanel import CoverPanel
@ -59,6 +60,7 @@ class Window(Adw.ApplicationWindow):
_CUSTOM_STARTUP_COMPLETE = 'startup-complete' _CUSTOM_STARTUP_COMPLETE = 'startup-complete'
# Widgets # Widgets
toolbar_view = Gtk.Template.Child()
content_stack = Gtk.Template.Child() content_stack = Gtk.Template.Child()
panel_stack = Gtk.Template.Child() panel_stack = Gtk.Template.Child()
toolbar_stack = Gtk.Template.Child() toolbar_stack = Gtk.Template.Child()
@ -86,8 +88,8 @@ class Window(Adw.ApplicationWindow):
self._headerbar_connection_button_active = True self._headerbar_connection_button_active = True
self._headerbar_playpause_button_active = True self._headerbar_playpause_button_active = True
# FIXME Help/Shortcuts dialog # Help/Shortcuts dialog
#self.set_help_overlay(ShortcutsDialog()) self.set_help_overlay(ShortcutsDialog())
# Login screen # Login screen
self._connection_panel = ConnectionPanel() self._connection_panel = ConnectionPanel()
@ -99,20 +101,20 @@ class Window(Adw.ApplicationWindow):
self._panels.append(self._cover_panel) self._panels.append(self._cover_panel)
# Playlist panel # Playlist panel
self._playlist_panel = PlaylistPanel(self._mcg) self._playlist_panel = PlaylistPanel(self._mcg)
#self._playlist_panel.connect('open-standalone', self.on_panel_open_standalone) self._playlist_panel.connect('open-standalone', self.on_panel_open_standalone)
#self._playlist_panel.connect('close-standalone', self.on_panel_close_standalone) self._playlist_panel.connect('close-standalone', self.on_panel_close_standalone)
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)
self.panel_stack.add_titled(self._server_panel, 'server-panel', locale.gettext("Server")) self.panel_stack.add_titled_with_icon(self._server_panel, 'server-panel', locale.gettext("Server"), "network-wired-symbolic")
self.panel_stack.add_titled_with_icon(self._cover_panel, 'cover-panel', locale.gettext("Cover"), "image-x-generic-symbolic") self.panel_stack.add_titled_with_icon(self._cover_panel, 'cover-panel', locale.gettext("Cover"), "image-x-generic-symbolic")
self.panel_stack.add_titled(self._playlist_panel, 'playlist-panel', locale.gettext("Playlist")) self.panel_stack.add_titled_with_icon(self._playlist_panel, 'playlist-panel', locale.gettext("Playlist"), "view-list-symbolic")
self.panel_stack.add_titled(self._library_panel, 'library-panel', locale.gettext("Library")) self.panel_stack.add_titled_with_icon(self._library_panel, 'library-panel', locale.gettext("Library"), "emblem-music-symbolic")
# Header # Header
#self._playlist_panel.get_headerbar_standalone().connect('close', self.on_panel_close_standalone) #self._playlist_panel.get_headerbar_standalone().connect('close', self.on_panel_close_standalone)
#self._library_panel.get_headerbar_standalone().connect('close', self.on_panel_close_standalone) #self._library_panel.get_headerbar_standalone().connect('close', self.on_panel_close_standalone)
@ -135,6 +137,7 @@ class Window(Adw.ApplicationWindow):
# Signals # Signals
self.connect("notify::default-width", self.on_resize) self.connect("notify::default-width", self.on_resize)
self.connect("notify::default-height", self.on_resize)
self.connect("notify::maximized", self.on_maximized) self.connect("notify::maximized", self.on_maximized)
self.connect("notify::fullscreened", self.on_fullscreened) self.connect("notify::fullscreened", self.on_fullscreened)
self._connection_panel.connect('connection-changed', self.on_connection_panel_connection_changed) self._connection_panel.connect('connection-changed', self.on_connection_panel_connection_changed)
@ -230,7 +233,7 @@ class Window(Adw.ApplicationWindow):
def on_menu_toggle_fullscreen(self, action, value): def on_menu_toggle_fullscreen(self, action, value):
self.panel_stack.set_visible_child(self.cover_panel_page) self.panel_stack.set_visible_child(self._cover_panel)
if not self._state.get_property(WindowState.IS_FULLSCREENED): if not self._state.get_property(WindowState.IS_FULLSCREENED):
self.fullscreen() self.fullscreen()
else: else:
@ -252,6 +255,8 @@ class Window(Adw.ApplicationWindow):
if not self._state.get_property(WindowState.IS_MAXIMIZED): if not self._state.get_property(WindowState.IS_MAXIMIZED):
self._state.set_property(WindowState.WIDTH, width) self._state.set_property(WindowState.WIDTH, width)
self._state.set_property(WindowState.HEIGHT, height) self._state.set_property(WindowState.HEIGHT, height)
GObject.idle_add(self._playlist_panel.set_size, width, height)
GObject.idle_add(self._library_panel.set_size, width, height)
def on_maximized(self, widget, maximized): def on_maximized(self, widget, maximized):
@ -259,7 +264,7 @@ class Window(Adw.ApplicationWindow):
def on_fullscreened(self, widget, fullscreened): def on_fullscreened(self, widget, fullscreened):
self._fullscreen(fullscreened is True) self._fullscreen(self.is_fullscreen())
# HeaderBar callbacks # HeaderBar callbacks
@ -298,12 +303,16 @@ class Window(Adw.ApplicationWindow):
# False # False
#) #)
def on_panel_open_standalone(self, panel): def on_panel_open_standalone(self, panel):
self.set_titlebar(panel.get_headerbar_standalone()) self.toolbar_view.add_top_bar(panel.get_headerbar_standalone())
self.toolbar_view.remove(self.headerbar)
def on_panel_close_standalone(self, headerbar): def on_panel_close_standalone(self, panel):
self.set_titlebar(self.headerbar) self.toolbar_view.add_top_bar(self.headerbar)
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)
@ -377,11 +386,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):
@ -544,17 +553,11 @@ class Window(Adw.ApplicationWindow):
if self._state.get_property(WindowState.IS_FULLSCREENED): if self._state.get_property(WindowState.IS_FULLSCREENED):
self.headerbar.hide() self.headerbar.hide()
self._cover_panel.set_fullscreen(True) self._cover_panel.set_fullscreen(True)
# Hide cursor self.set_cursor(Gdk.Cursor.new_from_name("none", None))
self.get_window().set_cursor(
Gdk.Cursor.new_from_name(Gdk.Display.get_default(), "none")
)
else: else:
self.headerbar.show() self.headerbar.show()
self._cover_panel.set_fullscreen(False) self._cover_panel.set_fullscreen(False)
# Reset cursor self.set_cursor(Gdk.Cursor.new_from_name("default", None))
self.get_window().set_cursor(
Gdk.Cursor.new_from_name(Gdk.Display.get_default(), "default")
)
def _save_visible_panel(self): def _save_visible_panel(self):