...
 
Commits (19)
# Compiling the resources
VCS_TAG = ''
if get_option('profile') != 'default'
git = find_program('git', required : false)
if git.found()
VCS_TAG = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip()
endif
if VCS_TAG == ''
VCS_TAG = '-devel'
else
VCS_TAG = '-@0@'.format(VCS_TAG)
endif
endif
about_dialog_conf = configuration_data()
about_dialog_conf.set('PACKAGE_VERSION', '@0@@1@'.format(meson.project_version(), VCS_TAG))
about_dialog_conf.set('PACKAGE_URL', PACKAGE_URL)
about_dialog_conf.set('PROGRAM_NAME', 'Music' + NAME_SUFFIX)
about_dialog_conf.set('APPID', APPLICATION_ID)
# about_dialog is defined in data/ui/meson.build to generate the output file in that directory
gnome.compile_resources(
PROJECT_RDNN_NAME,
PROJECT_RDNN_NAME + '.gresource.xml',
gresource_bundle: true,
source_dir: '.',
source_dir: meson.current_build_dir(),
install_dir: PKGDATA_DIR,
install: true,
dependencies: configure_file(
input: 'AboutDialog.ui.in',
output: 'AboutDialog.ui',
configuration: about_dialog_conf
)
dependencies: about_dialog
)
# Installing the schema file
......
@binding-set unbind-ctrl-space {
unbind "<ctrl>space";
}
/* Use widget for libgd classes, since they aren't updated
to gtk+-3.20 css naming yet. */
flowbox, treeview, widget {
-gtk-key-bindings: unbind-ctrl-space;
}
.discsongsflowbox > flowboxchild {
padding: 0px;
}
......
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/Music">
<file preprocess="xml-stripblanks">AboutDialog.ui</file>
<file alias="gtk/menus.ui" preprocess="xml-stripblanks">app-menu.ui</file>
<file alias="gtk/help-overlay.ui" preprocess="xml-stripblanks">help-overlay.ui</file>
<file>application.css</file>
<file>initial-state.png</file>
<file preprocess="xml-stripblanks">AlbumCover.ui</file>
<file preprocess="xml-stripblanks">AlbumWidget.ui</file>
<file preprocess="xml-stripblanks">ArtistAlbumWidget.ui</file>
<file preprocess="xml-stripblanks">ArtistAlbumsWidget.ui</file>
<file preprocess="xml-stripblanks">DiscBox.ui</file>
<file preprocess="xml-stripblanks">DropDown.ui</file>
<file preprocess="xml-stripblanks">EmptyView.ui</file>
<file preprocess="xml-stripblanks">FilterView.ui</file>
<file preprocess="xml-stripblanks">PlayerToolbar.ui</file>
<file preprocess="xml-stripblanks">Searchbar.ui</file>
<file preprocess="xml-stripblanks">SelectionBarMenuButton.ui</file>
<file preprocess="xml-stripblanks">SelectionToolbar.ui</file>
<file preprocess="xml-stripblanks">SidebarRow.ui</file>
<file preprocess="xml-stripblanks">SongWidget.ui</file>
<file preprocess="xml-stripblanks">HeaderBar.ui</file>
<file preprocess="xml-stripblanks">PlaylistContextMenu.ui</file>
<file preprocess="xml-stripblanks">PlaylistControls.ui</file>
<file preprocess="xml-stripblanks">PlaylistDialog.ui</file>
<file preprocess="xml-stripblanks">TwoLineTip.ui</file>
<file preprocess="xml-stripblanks">ui/AboutDialog.ui</file>
<file alias="gtk/menus.ui" preprocess="xml-stripblanks">ui/app-menu.ui</file>
<file alias="gtk/help-overlay.ui" preprocess="xml-stripblanks">ui/help-overlay.ui</file>
<file>org.gnome.Music.css</file>
<file>icons/initial-state.png</file>
<file preprocess="xml-stripblanks">ui/AlbumCover.ui</file>
<file preprocess="xml-stripblanks">ui/AlbumWidget.ui</file>
<file preprocess="xml-stripblanks">ui/ArtistAlbumWidget.ui</file>
<file preprocess="xml-stripblanks">ui/ArtistAlbumsWidget.ui</file>
<file preprocess="xml-stripblanks">ui/DiscBox.ui</file>
<file preprocess="xml-stripblanks">ui/DropDown.ui</file>
<file preprocess="xml-stripblanks">ui/EmptyView.ui</file>
<file preprocess="xml-stripblanks">ui/FilterView.ui</file>
<file preprocess="xml-stripblanks">ui/PlayerToolbar.ui</file>
<file preprocess="xml-stripblanks">ui/Searchbar.ui</file>
<file preprocess="xml-stripblanks">ui/SelectionBarMenuButton.ui</file>
<file preprocess="xml-stripblanks">ui/SelectionToolbar.ui</file>
<file preprocess="xml-stripblanks">ui/SidebarRow.ui</file>
<file preprocess="xml-stripblanks">ui/SongWidget.ui</file>
<file preprocess="xml-stripblanks">ui/HeaderBar.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistContextMenu.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistControls.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistDialog.ui</file>
<file preprocess="xml-stripblanks">ui/TwoLineTip.ui</file>
</gresource>
</gresources>
# AboutDialog.ui configuration
VCS_TAG = ''
if get_option('profile') != 'default'
git = find_program('git', required : false)
if git.found()
VCS_TAG = run_command('git', 'rev-parse', '--short', 'HEAD').stdout().strip()
endif
if VCS_TAG == ''
VCS_TAG = '-devel'
else
VCS_TAG = '-@0@'.format(VCS_TAG)
endif
endif
about_dialog_conf = configuration_data()
about_dialog_conf.set('PACKAGE_VERSION', '@0@@1@'.format(meson.project_version(), VCS_TAG))
about_dialog_conf.set('PACKAGE_URL', PACKAGE_URL)
about_dialog_conf.set('PROGRAM_NAME', 'Music' + NAME_SUFFIX)
about_dialog_conf.set('APPID', APPLICATION_ID)
about_dialog = configure_file(
input: 'AboutDialog.ui.in',
output: 'AboutDialog.ui',
configuration: about_dialog_conf
)
\ No newline at end of file
......@@ -43,12 +43,14 @@ logger = logging.getLogger(__name__)
@log
def _make_icon_frame(pixbuf, art_size=None, scale=1):
def _make_icon_frame(icon_surface, art_size=None, scale=1, default_icon=False):
border = 3
degrees = pi / 180
radius = 3
ratio = pixbuf.get_height() / pixbuf.get_width()
icon_w = icon_surface.get_width()
icon_h = icon_surface.get_height()
ratio = icon_h / icon_w
# Scale down the image according to the biggest axis
if ratio > 1:
......@@ -70,7 +72,7 @@ def _make_icon_frame(pixbuf, art_size=None, scale=1):
ctx.arc(radius, radius, radius - 0.5, 180 * degrees, 270 * degrees)
ctx.close_path()
ctx.set_line_width(0.6)
ctx.set_source_rgb(0.2, 0.2, 0.2)
ctx.set_source_rgba(0, 0, 0, 0.7)
ctx.stroke_preserve()
# fill the center
......@@ -78,12 +80,17 @@ def _make_icon_frame(pixbuf, art_size=None, scale=1):
ctx.fill()
matrix = cairo.Matrix()
matrix.scale(pixbuf.get_width() / (w - border * 2),
pixbuf.get_height() / (h - border * 2))
matrix.translate(-border, -border)
# paste the scaled pixbuf in the center
Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 0, 0)
if default_icon:
matrix.translate(-w * (1 / 3), -h * (1 / 3))
ctx.set_operator(cairo.Operator.DIFFERENCE)
else:
matrix.scale(
icon_w / ((w - border * 2) * scale),
icon_h / ((h - border * 2) * scale))
matrix.translate(-border, -border)
ctx.set_source_surface(icon_surface, 0, 0)
pattern = ctx.get_source()
pattern.set_matrix(matrix)
ctx.rectangle(border, border, w - border * 2, h - border * 2)
......@@ -100,6 +107,7 @@ class DefaultIcon(GObject.GObject):
MUSIC = 'folder-music-symbolic'
_cache = {}
_default_theme = Gtk.IconTheme.get_default()
def __repr__(self):
return '<DefaultIcon>'
......@@ -110,32 +118,11 @@ class DefaultIcon(GObject.GObject):
@log
def _make_default_icon(self, icon_type, art_size, scale):
width = art_size.width * scale
height = art_size.height * scale
# TODO: Load icon async.
default_theme = Gtk.IconTheme.get_default()
icon_info = default_theme.lookup_icon_for_scale(
icon_type.value, max(art_size.width, art_size.height), scale, 0)
icon = icon_info.load_icon()
result = GdkPixbuf.Pixbuf.new(
icon.get_colorspace(), True, icon.get_bits_per_sample(), width,
height)
result.fill(0xffffffff)
icon_scale = 0.33
def icon_offset(x):
return int((x / 2) - (x * icon_scale * 0.5))
icon.composite(
result, icon_offset(width), icon_offset(height),
width * icon_scale, height * icon_scale, icon_offset(width),
icon_offset(height), icon_scale, icon_scale,
GdkPixbuf.InterpType.HYPER, 0x77)
icon_info = self._default_theme.lookup_icon_for_scale(
icon_type.value, art_size.width / 3, scale, 0)
icon = icon_info.load_surface()
icon_surface = _make_icon_frame(result, art_size, scale)
icon_surface = _make_icon_frame(icon, art_size, scale, True)
return icon_surface
......@@ -222,7 +209,9 @@ class Art(GObject.GObject):
@log
def _cache_hit(self, klass, pixbuf):
surface = _make_icon_frame(pixbuf, self._size, self._scale)
surface = Gdk.cairo_surface_create_from_pixbuf(
pixbuf, self._scale, None)
surface = _make_icon_frame(surface, self._size, self._scale)
self._surface = surface
self._set_grilo_thumbnail_path()
......
......@@ -61,7 +61,7 @@ class Application(Gtk.Application):
def _init_style(self):
css_provider_file = Gio.File.new_for_uri(
'resource:///org/gnome/Music/application.css')
'resource:///org/gnome/Music/org.gnome.Music.css')
css_provider = Gtk.CssProvider()
css_provider.load_from_file(css_provider_file)
screen = Gdk.Screen.get_default()
......
......@@ -44,8 +44,7 @@ class AlbumsView(BaseView):
super().__init__('albums', _("Albums"), window)
self.player = player
self._album_widget = AlbumWidget(
player, self, self._header_bar, self._selection_toolbar)
self._album_widget = AlbumWidget(player, self)
self.add(self._album_widget)
self.albums_selected = []
self.all_items = []
......@@ -54,7 +53,7 @@ class AlbumsView(BaseView):
@log
def _on_changes_pending(self, data=None):
if (self._init and not self._header_bar.selection_mode):
if (self._init and not self.props.selection_mode):
self._offset = 0
self.populate()
grilo.changes_pending['Albums'] = False
......@@ -63,7 +62,7 @@ class AlbumsView(BaseView):
def _on_selection_mode_changed(self, widget, data=None):
super()._on_selection_mode_changed(widget, data)
if (not self._header_bar.selection_mode
if (not self.props.selection_mode
and grilo.changes_pending['Albums']):
self._on_changes_pending()
......@@ -86,7 +85,7 @@ class AlbumsView(BaseView):
@log
def _back_button_clicked(self, widget, data=None):
self._header_bar.state = HeaderBar.State.MAIN
self._headerbar.state = HeaderBar.State.MAIN
self.set_visible_child(self._grid)
@log
......@@ -98,9 +97,9 @@ class AlbumsView(BaseView):
# Update and display the album widget if not in selection mode
self._album_widget.update(item)
self._header_bar.props.state = HeaderBar.State.CHILD
self._header_bar.props.title = utils.get_album_title(item)
self._header_bar.props.subtitle = utils.get_artist_name(item)
self._headerbar.props.state = HeaderBar.State.CHILD
self._headerbar.props.title = utils.get_album_title(item)
self._headerbar.props.subtitle = utils.get_artist_name(item)
self.set_visible_child(self._album_widget)
@log
......@@ -113,7 +112,7 @@ class AlbumsView(BaseView):
def get_selected_songs(self, callback):
# FIXME: we call into private objects with full knowledge of
# what is there
if self._header_bar.props.state == HeaderBar.State.CHILD:
if self._headerbar.props.state == HeaderBar.State.CHILD:
callback(self._album_widget._disc_listbox.get_selected_items())
else:
self.items_selected = []
......@@ -157,7 +156,7 @@ class AlbumsView(BaseView):
and child.props.media in self.albums_selected):
self.albums_selected.remove(child.props.media)
self._update_header_from_selection(len(self.albums_selected))
self.props.selected_items_count = len(self.albums_selected)
@log
def _get_selected_album_songs(self):
......@@ -171,7 +170,7 @@ class AlbumsView(BaseView):
if item:
self.items_selected.append(item)
if remaining == 0:
if self.albums_index < len(self.albums_selected):
if self.albums_index < self.props.selected_items_count:
self._get_selected_album_songs()
else:
self.items_selected_callback(self.items_selected)
......
......@@ -58,8 +58,7 @@ class ArtistsView(BaseView):
sidebar_container = Gtk.ScrolledWindow()
sidebar_container.add(self._sidebar)
super().__init__(
'artists', _("Artists"), window, True, sidebar_container)
super().__init__('artists', _("Artists"), window, sidebar_container)
self.player = player
self._artists = {}
......@@ -125,7 +124,7 @@ class ArtistsView(BaseView):
self._view.add(new_artist_albums_widget)
artist_albums = ArtistAlbumsWidget(
artist, albums, self.player, self._header_bar,
artist, albums, self.player, self._headerbar,
self._selection_toolbar, self._window)
self._artists[artist.casefold()]['widget'] = artist_albums
new_artist_albums_widget.add(artist_albums)
......@@ -185,7 +184,7 @@ class ArtistsView(BaseView):
if row.props.selected:
selected_artists += 1
self._update_header_from_selection(selected_artists)
self.props.selected_items_count = selected_artists
@log
def _on_selection_mode_changed(self, widget, data=None):
......@@ -209,12 +208,10 @@ class ArtistsView(BaseView):
@log
def select_all(self):
self._toggle_all_selection(True)
self._update_header_from_selection(len(self._sidebar))
@log
def unselect_all(self):
self._toggle_all_selection(False)
self._update_header_from_selection(0)
@log
def get_selected_songs(self, callback):
......
......@@ -34,18 +34,19 @@ class BaseView(Gtk.Stack):
_now_playing_icon_name = 'media-playback-start-symbolic'
_error_icon_name = 'dialog-error-symbolic'
selected_items_count = GObject.Property(type=int, default=0, minimum=0)
selection_mode = GObject.Property(type=bool, default=False)
def __repr__(self):
return '<BaseView>'
@log
def __init__(self, name, title, window, use_sidebar=False, sidebar=None):
def __init__(self, name, title, window, sidebar=None):
"""Initialize
:param name: The view name
:param title: The view title
:param GtkWidget window: The main window
:param use_sidebar: Whether to use sidebar
:param sidebar: The sidebar object (Default: Gtk.Box)
"""
......@@ -72,22 +73,14 @@ class BaseView(Gtk.Stack):
# Setup the main view
self._setup_view()
if use_sidebar:
self.stack = Gtk.Stack()
dummy = Gtk.Frame(visible=False)
self.stack.add_named(dummy, 'dummy')
if sidebar:
self.stack.add_named(sidebar, 'sidebar')
else:
self.stack.add_named(self._box, 'sidebar')
self.stack.set_visible_child_name('dummy')
self._grid.add(self.stack)
if not use_sidebar or sidebar:
self._grid.add(self._box)
if sidebar:
self._grid.add(sidebar)
self._grid.add(self._box)
self._star_handler = StarHandlerWidget(self, 9)
self._window = window
self._header_bar = window.headerbar
self._headerbar = window._headerbar
self._selection_toolbar = window.selection_toolbar
self.name = name
......@@ -103,11 +96,7 @@ class BaseView(Gtk.Stack):
grilo.connect('changes-pending', self._on_changes_pending)
self.bind_property(
'selection-mode', self._selection_toolbar, 'visible',
GObject.BindingFlags.SYNC_CREATE)
self.bind_property(
'selection-mode', self._header_bar, 'selection-mode',
'selection-mode', self._window, 'selection-mode',
GObject.BindingFlags.BIDIRECTIONAL)
if (grilo.tracker is not None
......@@ -125,11 +114,11 @@ class BaseView(Gtk.Stack):
@log
def _on_grilo_ready(self, data=None):
if (self._header_bar.props.stack.props.visible_child == self
if (self._headerbar.props.stack.props.visible_child == self
and not self._init):
self._populate()
self._header_bar.props.stack.connect(
self._headerbar.props.stack.connect(
'notify::visible-child', self._on_headerbar_visible)
@log
......@@ -138,12 +127,6 @@ class BaseView(Gtk.Stack):
and not self._init):
self._populate()
@log
def _update_header_from_selection(self, n_items):
"""Updates header during item selection."""
self._selection_toolbar.props.items_selected = n_items
self._header_bar.props.items_selected = n_items
@log
def _populate(self, data=None):
self.populate()
......@@ -184,27 +167,16 @@ class BaseView(Gtk.Stack):
self.model[itr][6] = value
count += 1
itr = self.model.iter_next(itr)
return count
@log
def select_all(self):
"""Select all the available songs."""
count = self._set_selection(True)
self._selection_toolbar.props.items_selected = count
self._update_header_from_selection(count)
self.props.selected_items_count = self._set_selection(True)
@log
def unselect_all(self):
"""Unselects all the selected songs."""
self._set_selection(False)
self._selection_toolbar.props.items_selected = 0
self._header_bar.props.items_selected = 0
@log
def set_player_visible(self, visible):
"""Set PlayWidget action visibility
:param bool visible: Set actionbar visibility
"""
self._window.player_toolbar.set_visible(visible)
self.props.selected_items_count = 0
......@@ -32,7 +32,7 @@ from gnomemusic.albumartcache import Art
from gnomemusic.query import Query
@Gtk.Template(resource_path="/org/gnome/Music/EmptyView.ui")
@Gtk.Template(resource_path="/org/gnome/Music/ui/EmptyView.ui")
class EmptyView(Gtk.Stack):
"""Empty view when there is no music to display
......@@ -102,7 +102,7 @@ class EmptyView(Gtk.Stack):
self._main_label.props.label = _("Hey DJ")
self._main_label.props.margin_bottom = 18
self._icon.props.resource = "/org/gnome/Music/initial-state.png"
self._icon.props.resource = "/org/gnome/Music/icons/initial-state.png"
self._icon.props.margin_bottom = 32
self._icon.props.height_request = Art.Size.LARGE.height
self._icon.props.width_request = Art.Size.LARGE.width
......
......@@ -64,7 +64,7 @@ class PlaylistView(BaseView):
sidebar_container.add(self._sidebar)
super().__init__(
'playlists', _("Playlists"), window, True, sidebar_container)
'playlists', _("Playlists"), window, sidebar_container)
self._window = window
self.player = player
......@@ -115,9 +115,8 @@ class PlaylistView(BaseView):
self._sidebar.set_selection_mode(Gtk.SelectionMode.SINGLE)
self._sidebar.connect('row-activated', self._on_playlist_activated)
self._grid.insert_column(0)
self._grid.child_set_property(self.stack, 'top-attach', 0)
self._grid.child_set_property(self.stack, 'height', 2)
self._grid.child_set_property(sidebar_container, 'top-attach', 0)
self._grid.child_set_property(sidebar_container, 'height', 2)
self._iter_to_clean = None
self._iter_to_clean_model = None
......@@ -679,7 +678,7 @@ class PlaylistView(BaseView):
if self.player.playing_playlist(
PlayerPlaylist.Type.PLAYLIST, playlist_id):
self.player.stop()
self.set_player_visible(False)
self._window.set_player_visible(False)
if row_next:
self._sidebar.select_row(row_next)
......
......@@ -65,8 +65,7 @@ class SearchView(BaseView):
self._albums_selected = []
self._albums = {}
self._albums_index = 0
self._album_widget = AlbumWidget(
player, self, self._header_bar, self._selection_toolbar)
self._album_widget = AlbumWidget(player, self)
self.add(self._album_widget)
self._artists_albums_selected = []
......@@ -103,7 +102,7 @@ class SearchView(BaseView):
@log
def _back_button_clicked(self, widget, data=None):
self._header_bar.searchbar.reveal(True, False)
self._headerbar.searchbar.reveal(True, False)
if self.get_visible_child() == self._artist_albums_widget:
self._artist_albums_widget.destroy()
......@@ -113,7 +112,7 @@ class SearchView(BaseView):
self._window.views[View.ALBUM]._grid)
self.set_visible_child(self._grid)
self._header_bar.props.state = HeaderBar.State.MAIN
self._headerbar.props.state = HeaderBar.State.MAIN
@log
def _on_item_activated(self, treeview, path, column):
......@@ -136,26 +135,26 @@ class SearchView(BaseView):
item = self.model[_iter][5]
self._album_widget.update(item)
self._header_bar.props.state = HeaderBar.State.SEARCH
self._headerbar.props.state = HeaderBar.State.SEARCH
self._header_bar.props.title = title
self._header_bar.props.subtitle = artist
self._headerbar.props.title = title
self._headerbar.props.subtitle = artist
self.set_visible_child(self._album_widget)
self._header_bar.searchbar.reveal(False)
self._headerbar.searchbar.reveal(False)
elif self.model[_iter][12] == 'artist':
artist = self.model[_iter][2]
albums = self._artists[artist.casefold()]['albums']
self._artist_albums_widget = ArtistAlbumsWidget(
artist, albums, self.player, self._header_bar,
artist, albums, self.player, self._headerbar,
self._selection_toolbar, self._window, True)
self.add(self._artist_albums_widget)
self._artist_albums_widget.show()
self._header_bar.props.state = HeaderBar.State.SEARCH
self._header_bar.props.title = artist
self._headerbar.props.state = HeaderBar.State.SEARCH
self._headerbar.props.title = artist
self.set_visible_child(self._artist_albums_widget)
self._header_bar.searchbar.reveal(False)
self._headerbar.searchbar.reveal(False)
elif self.model[_iter][12] == 'song':
if self.model[_iter][11] != ValidationStatus.FAILED:
c_iter = self._songs_model.convert_child_iter_to_iter(_iter)[1]
......@@ -188,7 +187,8 @@ class SearchView(BaseView):
iter_ = self.model.get_iter(path)
self.model[iter_][6] = not self.model[iter_][6]
selected_iters = self._get_selected_iters()
self._update_header_from_selection(len(selected_iters))
self.props.selected_items_count = len(selected_iters)
@log
def _get_selected_iters(self):
......@@ -417,7 +417,7 @@ class SearchView(BaseView):
@log
def populate(self):
self._init = True
self._header_bar.props.state = HeaderBar.State.MAIN
self._headerbar.props.state = HeaderBar.State.MAIN
@log
def get_selected_songs(self, callback):
......
......@@ -225,7 +225,8 @@ class SongsView(BaseView):
*event.get_coords())
iter_ = self.model.get_iter(path)
self.model[iter_][6] = not self.model[iter_][6]
self._update_header_from_selection(len(self.get_selected_songs()))
self.props.selected_items_count = len(self.get_selected_songs())
@log
def _update_model(self, player, position):
......
......@@ -27,7 +27,7 @@ from gi.repository import Gtk
from gnomemusic import log
@Gtk.Template(resource_path='/org/gnome/Music/AboutDialog.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/AboutDialog.ui')
class AboutDialog(Gtk.AboutDialog):
"""About dialog"""
......
......@@ -32,7 +32,7 @@ from gnomemusic.albumartcache import Art
from gnomemusic.widgets.twolinetip import TwoLineTip
@Gtk.Template(resource_path='/org/gnome/Music/AlbumCover.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/AlbumCover.ui')
class AlbumCover(Gtk.FlowBoxChild):
"""Cover tile as used in AlbumsView
......
......@@ -35,7 +35,7 @@ from gnomemusic.widgets.songwidget import SongWidget
import gnomemusic.utils as utils
@Gtk.Template(resource_path='/org/gnome/Music/AlbumWidget.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/AlbumWidget.ui')
class AlbumWidget(Gtk.EventBox):
"""Album widget.
......@@ -54,6 +54,7 @@ class AlbumWidget(Gtk.EventBox):
_running_info_label = Gtk.Template.Child()
_title_label = Gtk.Template.Child()
selected_items_count = GObject.Property(type=int, default=0, minimum=0)
selection_mode = GObject.Property(type=bool, default=False)
_duration = 0
......@@ -62,13 +63,11 @@ class AlbumWidget(Gtk.EventBox):
return '<AlbumWidget>'
@log
def __init__(self, player, parent_view, header_bar, selection_toolbar):
def __init__(self, player, parent_view):
"""Initialize the AlbumWidget.
:param player: The player object
:param parent_view: The view this widget is part of
:param header_bar: The header bar object
:param selection_toolbar: The selection toolbar object
"""
super().__init__()
......@@ -80,18 +79,19 @@ class AlbumWidget(Gtk.EventBox):
self._create_model()
self._album = None
self._header_bar = header_bar
self._selection_toolbar = selection_toolbar
self.bind_property(
'selection-mode', self._disc_listbox, 'selection-mode',
GObject.BindingFlags.BIDIRECTIONAL)
self.bind_property(
'selection-mode', self._header_bar, 'selection-mode',
'selection-mode', self._parent_view, 'selection-mode',
GObject.BindingFlags.BIDIRECTIONAL |
GObject.BindingFlags.SYNC_CREATE)
self.bind_property(
'selected-items-count', self._parent_view, 'selected-items-count')
self.show_all()
@log
......@@ -179,8 +179,7 @@ class AlbumWidget(Gtk.EventBox):
@log
def _on_selection_changed(self, widget):
n_items = len(self._disc_listbox.get_selected_items())
self._selection_toolbar.props.items_selected = n_items
self._header_bar.items_selected = n_items
self.props.selected_items_count = n_items
@log
def _create_disc_box(self, disc_nr, disc_songs):
......
......@@ -34,7 +34,7 @@ from gnomemusic.widgets.songwidget import SongWidget
logger = logging.getLogger(__name__)
@Gtk.Template(resource_path='/org/gnome/Music/ArtistAlbumsWidget.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/ArtistAlbumsWidget.ui')
class ArtistAlbumsWidget(Gtk.Box):
"""Widget containing all albums by an artist
......@@ -54,7 +54,7 @@ class ArtistAlbumsWidget(Gtk.Box):
@log
def __init__(
self, artist, albums, player, header_bar, selection_toolbar,
self, artist, albums, player, headerbar, selection_toolbar,
window, selection_mode_allowed=False):
super().__init__(orientation=Gtk.Orientation.VERTICAL)
self._player = player
......@@ -62,7 +62,7 @@ class ArtistAlbumsWidget(Gtk.Box):
self._window = window
self._selection_mode_allowed = selection_mode_allowed
self._selection_toolbar = selection_toolbar
self._header_bar = header_bar
self._headerbar = headerbar
self._artist_label.props.label = self._artist
......@@ -89,7 +89,7 @@ class ArtistAlbumsWidget(Gtk.Box):
Gtk.SizeGroupMode.HORIZONTAL)
self.bind_property(
'selection-mode', self._header_bar, 'selection-mode',
'selection-mode', self._headerbar, 'selection-mode',
GObject.BindingFlags.BIDIRECTIONAL |
GObject.BindingFlags.SYNC_CREATE)
......@@ -129,7 +129,7 @@ class ArtistAlbumsWidget(Gtk.Box):
@log
def _add_album(self, album):
widget = ArtistAlbumWidget(
album, self._player, self._model, self._header_bar,
album, self._player, self._model, self._headerbar,
self._selection_mode_allowed, self._songs_grid_size_group,
self._cover_size_group)
......@@ -199,8 +199,8 @@ class ArtistAlbumsWidget(Gtk.Box):
if row[6]:
selected_items += 1
self._selection_toolbar.props.items_selected = selected_items
self._header_bar.props.items_selected = selected_items
self._selection_toolbar.props.selected_items_count = selected_items
self._headerbar.props.selected_items_count = selected_items
@log
def select_all(self):
......
......@@ -32,7 +32,7 @@ from gnomemusic.widgets.disclistboxwidget import DiscBox
import gnomemusic.utils as utils
@Gtk.Template(resource_path='/org/gnome/Music/ArtistAlbumWidget.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/ArtistAlbumWidget.ui')
class ArtistAlbumWidget(Gtk.Box):
__gtype_name__ = 'ArtistAlbumWidget'
......
......@@ -82,7 +82,7 @@ class DiscSongsFlowBox(Gtk.FlowBox):
self.props.min_children_per_line = max_per_line
@Gtk.Template(resource_path='/org/gnome/Music/DiscBox.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/DiscBox.ui')
class DiscBox(Gtk.Box):
"""A widget which compromises one disc
......
......@@ -32,7 +32,7 @@ from gnomemusic.widgets.searchbar import Searchbar
from gnomemusic.utils import View
@Gtk.Template(resource_path="/org/gnome/Music/SelectionBarMenuButton.ui")
@Gtk.Template(resource_path="/org/gnome/Music/ui/SelectionBarMenuButton.ui")
class SelectionBarMenuButton(Gtk.MenuButton):
"""Button for popup to select all or no items
......@@ -49,24 +49,24 @@ class SelectionBarMenuButton(Gtk.MenuButton):
def __init__(self):
super().__init__()
self._items_selected = 0
self._selected_items_count = 0
@GObject.Property(type=int, default=0, minimum=0)
def items_selected(self):
def selected_items_count(self):
"""The number of items selected
:returns: Number of items selected
:rtype: int
"""
return self._items_selected
return self._selected_items_count
@items_selected.setter
def items_selected(self, value):
@selected_items_count.setter
def selected_items_count(self, value):
"""Set the number of items selected
:param int value: The number of items selected
"""
self._items_selected = value
self._selected_items_count = value
if value > 0:
text = ngettext(
......@@ -76,7 +76,7 @@ class SelectionBarMenuButton(Gtk.MenuButton):
self._menu_label.props.label = _("Click on items to select them")
@Gtk.Template(resource_path="/org/gnome/Music/HeaderBar.ui")
@Gtk.Template(resource_path="/org/gnome/Music/ui/HeaderBar.ui")
class HeaderBar(Gtk.HeaderBar):
"""Headerbar of the application"""
......@@ -94,7 +94,7 @@ class HeaderBar(Gtk.HeaderBar):
_cancel_button = Gtk.Template.Child()
_back_button = Gtk.Template.Child()
items_selected = GObject.Property(type=int, default=0, minimum=0)
selected_items_count = GObject.Property(type=int, default=0, minimum=0)
selection_mode_allowed = GObject.Property(type=bool, default=True)
stack = GObject.Property(type=Gtk.Stack)
......@@ -136,7 +136,8 @@ class HeaderBar(Gtk.HeaderBar):
GObject.BindingFlags.BIDIRECTIONAL |
GObject.BindingFlags.SYNC_CREATE)
self.bind_property(
"items-selected", self._selection_menu, "items-selected")
"selected-items-count", self._selection_menu,
"selected-items-count")
self.connect(
"notify::selection-mode-allowed",
......@@ -202,6 +203,9 @@ class HeaderBar(Gtk.HeaderBar):
@Gtk.Template.Callback()
@log
def _on_back_button_clicked(self, widget=None):
if self.props.selection_mode:
return
window = self.get_toplevel()
visible_child = window.curr_view.props.visible_child
......
......@@ -35,7 +35,7 @@ from gnomemusic.widgets.twolinetip import TwoLineTip
import gnomemusic.utils as utils
@Gtk.Template(resource_path='/org/gnome/Music/PlayerToolbar.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/PlayerToolbar.ui')
class PlayerToolbar(Gtk.ActionBar):
"""Main Player widget object
......@@ -66,10 +66,10 @@ class PlayerToolbar(Gtk.ActionBar):
return '<PlayerToolbar>'
@log
def __init__(self, player, headerbar):
def __init__(self, player, main_window):
super().__init__()
self._headerbar = headerbar
self._main_window = main_window
self._player = player
self._progress_scale.player = self._player.get_gst_player()
......@@ -80,8 +80,6 @@ class PlayerToolbar(Gtk.ActionBar):
self._sync_repeat_image()
self._headerbar.connect(
'notify::selection-mode', self._on_selection_mode_changed)
self._player.connect('clock-tick', self._on_clock_tick)
self._player.connect('song-changed', self._update_view)
self._player.connect('prev-next-invalidated', self._sync_prev_next)
......@@ -118,13 +116,6 @@ class PlayerToolbar(Gtk.ActionBar):
def _on_next_button_clicked(self, button):
self._player.next()
@log
def _on_selection_mode_changed(self, headerbar, selection_mode):
if self._headerbar.props.selection_mode:
self.hide()
elif self._player.props.playing:
self.show()
@log
def _sync_repeat_image(self, player=None):
icon = None
......@@ -141,7 +132,7 @@ class PlayerToolbar(Gtk.ActionBar):
@log
def _sync_playing(self, player):
if not self._headerbar.props.selection_mode:
if not self._main_window.props.selection_mode:
self.show()
if self._player.get_playback_status() == Playback.PLAYING:
......
......@@ -27,7 +27,7 @@ from gi.repository import Gtk
from gnomemusic import log
@Gtk.Template(resource_path='/org/gnome/Music/PlaylistContextMenu.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/PlaylistContextMenu.ui')
class PlaylistContextMenu(Gtk.Popover):
__gtype_name__ = 'PlaylistContextMenu'
......
......@@ -30,7 +30,7 @@ from gnomemusic import log
import gnomemusic.utils as utils
@Gtk.Template(resource_path='/org/gnome/Music/PlaylistControls.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/PlaylistControls.ui')
class PlaylistControls(Gtk.Grid):
"""Widget holding the playlist controls"""
......
......@@ -30,7 +30,7 @@ from gnomemusic.playlists import Playlists
import gnomemusic.utils as utils
@Gtk.Template(resource_path="/org/gnome/Music/PlaylistDialog.ui")
@Gtk.Template(resource_path="/org/gnome/Music/ui/PlaylistDialog.ui")
class PlaylistDialog(Gtk.Dialog):
"""Dialog for adding items to a playlist"""
......
......@@ -160,7 +160,7 @@ class SourceManager(BaseManager):
grilo.search_source = src
@Gtk.Template(resource_path="/org/gnome/Music/FilterView.ui")
@Gtk.Template(resource_path="/org/gnome/Music/ui/FilterView.ui")
class FilterView(Gtk.TreeView):
"""TreeView for search entry items
......@@ -254,7 +254,7 @@ class FilterView(Gtk.TreeView):
self.props.manager.entry.emit('changed')
@Gtk.Template(resource_path="/org/gnome/Music/DropDown.ui")
@Gtk.Template(resource_path="/org/gnome/Music/ui/DropDown.ui")
class DropDown(Gtk.Revealer):
"""Dropdown source/option selection widget for search
......@@ -314,7 +314,7 @@ class DropDown(Gtk.Revealer):
return grilo_id == "grl-tracker-source"
@Gtk.Template(resource_path="/org/gnome/Music/Searchbar.ui")
@Gtk.Template(resource_path="/org/gnome/Music/ui/Searchbar.ui")
class Searchbar(Gtk.SearchBar):
"""Widget containing the search entry
"""
......
......@@ -27,7 +27,7 @@ from gi.repository import GObject, Gtk
from gnomemusic import log
@Gtk.Template(resource_path='/org/gnome/Music/SelectionToolbar.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/SelectionToolbar.ui')
class SelectionToolbar(Gtk.ActionBar):
__gtype_name__ = 'SelectionToolbar'
......@@ -38,7 +38,7 @@ class SelectionToolbar(Gtk.ActionBar):
'add-to-playlist': (GObject.SignalFlags.RUN_FIRST, None, ())
}
items_selected = GObject.Property(type=int, default=0, minimum=0)
selected_items_count = GObject.Property(type=int, default=0, minimum=0)
def __repr__(self):
return '<SelectionToolbar>'
......@@ -47,7 +47,8 @@ class SelectionToolbar(Gtk.ActionBar):
def __init__(self):
super().__init__()
self.connect('notify::items-selected', self._on_item_selection_changed)
self.connect(
'notify::selected-items-count', self._on_item_selection_changed)
@Gtk.Template.Callback()
@log
......@@ -56,7 +57,7 @@ class SelectionToolbar(Gtk.ActionBar):
@log
def _on_item_selection_changed(self, widget, data):
if self.props.items_selected > 0:
if self.props.selected_items_count > 0:
self._add_to_playlist_button.props.sensitive = True
else:
self._add_to_playlist_button.props.sensitive = False
......@@ -27,7 +27,7 @@ from gi.repository import GObject, Gtk
from gnomemusic import log
@Gtk.Template(resource_path='/org/gnome/Music/SidebarRow.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/SidebarRow.ui')
class SidebarRow(Gtk.ListBoxRow):
"""Row for sidebars
......
......@@ -36,7 +36,7 @@ from gnomemusic.playlists import Playlists, StaticPlaylists
from gnomemusic.widgets.starimage import StarImage # noqa: F401
@Gtk.Template(resource_path='/org/gnome/Music/SongWidget.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/SongWidget.ui')
class SongWidget(Gtk.EventBox):
"""The single song widget used in DiscListBox
......
......@@ -27,7 +27,7 @@ from gi.repository import GObject, Gtk
from gnomemusic import log
@Gtk.Template(resource_path='/org/gnome/Music/TwoLineTip.ui')
@Gtk.Template(resource_path='/org/gnome/Music/ui/TwoLineTip.ui')
class TwoLineTip(Gtk.Box):
"""Tooltip with two lines of text
......
<
......@@ -29,7 +29,7 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
from gi.repository import Gtk, Gdk, Gio, GLib
from gi.repository import Gtk, Gdk, Gio, GLib, GObject
from gettext import gettext as _
from gnomemusic import log
......@@ -59,6 +59,9 @@ playlists = Playlists.get_default()
class Window(Gtk.ApplicationWindow):
selected_items_count = GObject.Property(type=int, default=0, minimum=0)
selection_mode = GObject.Property(type=bool, default=False)
def __repr__(self):
return '<Window>'
......@@ -113,7 +116,7 @@ class Window(Gtk.ApplicationWindow):
and view_count == 1):
self._switch_to_player_view()
elif (not available
and not self.headerbar.props.selection_mode
and not self.props.selection_mode
and view_count != 1):
self._stack.disconnect(self._on_notify_model_id)
self.disconnect(self._key_press_event_id)
......@@ -149,9 +152,9 @@ class Window(Gtk.ApplicationWindow):
@log
def _setup_view(self):
self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.headerbar = HeaderBar()
self._headerbar = HeaderBar()
self.player = Player(self)
self.player_toolbar = PlayerToolbar(self.player, self.headerbar)
self.player_toolbar = PlayerToolbar(self.player, self)
self.selection_toolbar = SelectionToolbar()
self.views = [None] * len(View)
self._stack = Gtk.Stack(
......@@ -161,6 +164,19 @@ class Window(Gtk.ApplicationWindow):
visible=True,
can_focus=False)
self.connect('notify::selection-mode', self._on_selection_mode_changed)
self.bind_property(
'selected-items-count', self._headerbar, 'selected-items-count')
self.bind_property(
'selected-items-count', self.selection_toolbar,
'selected-items-count')
self.bind_property(
'selection-mode', self._headerbar, 'selection-mode',
GObject.BindingFlags.BIDIRECTIONAL |
GObject.BindingFlags.SYNC_CREATE)
self.bind_property(
'selection-mode', self.selection_toolbar, 'visible',
GObject.BindingFlags.SYNC_CREATE)
# Create only the empty view at startup
# if no music, switch to empty view and hide stack
# if some music is available, populate stack with mainviews,
......@@ -175,23 +191,21 @@ class Window(Gtk.ApplicationWindow):
self._overlay = Gtk.Overlay()
self._overlay.add(self._stack)
# FIXME: Need to find a proper way to do this.
self._overlay.add_overlay(self.headerbar.searchbar._dropdown)
self.set_titlebar(self.headerbar)
self._box.pack_start(self.headerbar.searchbar, False, False, 0)
self._overlay.add_overlay(self._headerbar.searchbar._dropdown)
self.set_titlebar(self._headerbar)
self._box.pack_start(self._headerbar.searchbar, False, False, 0)
self._box.pack_start(self._overlay, True, True, 0)
self._box.pack_start(self.player_toolbar, False, False, 0)
self._box.pack_start(self.selection_toolbar, False, False, 0)
self.add(self._box)
self.headerbar._search_button.connect(
self._headerbar._search_button.connect(
'toggled', self._on_search_toggled)
self.headerbar.connect(
'notify::selection-mode', self._on_selection_mode_changed)
self.selection_toolbar.connect(
'add-to-playlist', self._on_add_to_playlist)
self.headerbar.props.state = HeaderBar.State.MAIN
self.headerbar.show()
self._headerbar.props.state = HeaderBar.State.MAIN
self._headerbar.show()
self._overlay.show()
self.player_toolbar.show_all()
self._box.show()
......@@ -218,7 +232,7 @@ class Window(Gtk.ApplicationWindow):
else:
self.views[View.EMPTY].props.state = EmptyView.State.INITIAL
self.headerbar.props.state = HeaderBar.State.EMPTY
self._headerbar.props.state = HeaderBar.State.EMPTY
@log
def _switch_to_player_view(self):
......@@ -245,9 +259,9 @@ class Window(Gtk.ApplicationWindow):
self.views[View.SEARCH] = Gtk.Box()
self.views[View.EMPTY].props.state = EmptyView.State.SEARCH
self.headerbar.props.state = HeaderBar.State.MAIN
self.headerbar.props.stack = self._stack
self.headerbar.searchbar.show()
self._headerbar.props.state = HeaderBar.State.MAIN
self._headerbar.props.stack = self._stack
self._headerbar.searchbar.show()
self.views[View.ALBUM] = AlbumsView(self, self.player)
self.views[View.ARTIST] = ArtistsView(self, self.player)
......@@ -255,6 +269,11 @@ class Window(Gtk.ApplicationWindow):
self.views[View.PLAYLIST] = PlaylistView(self, self.player)
self.views[View.SEARCH] = SearchView(self, self.player)
selectable_views = [View.ALBUM, View.ARTIST, View.SONG, View.SEARCH]
for view in selectable_views:
self.views[view].bind_property(
'selected-items-count', self, 'selected-items-count')
# empty view has already been created in self._setup_view starting at
# View.ALBUM
# empty view state is changed once album view is visible to prevent it
......@@ -269,9 +288,9 @@ class Window(Gtk.ApplicationWindow):
@log
def _select_all(self, action=None, param=None):
if not self.headerbar.props.selection_mode:
if not self.props.selection_mode:
return
if self.headerbar.props.state == HeaderBar.State.MAIN:
if self._headerbar.props.state == HeaderBar.State.MAIN:
view = self._stack.get_visible_child()
else:
view = self._stack.get_visible_child().get_visible_child()
......@@ -280,9 +299,9 @@ class Window(Gtk.ApplicationWindow):
@log
def _select_none(self, action=None, param=None):
if not self.headerbar.props.selection_mode:
if not self.props.selection_mode:
return
if self.headerbar.props.state == HeaderBar.State.MAIN:
if self._headerbar.props.state == HeaderBar.State.MAIN:
view = self._stack.get_visible_child()
view.unselect_all()
else:
......@@ -306,8 +325,8 @@ class Window(Gtk.ApplicationWindow):
# Open search bar on Ctrl + F
if (keyval == Gdk.KEY_f
and not self.views[View.PLAYLIST].rename_active
and self.headerbar.props.state != HeaderBar.State.SEARCH):
self.headerbar.searchbar.toggle()
and self._headerbar.props.state != HeaderBar.State.SEARCH):
self._headerbar.searchbar.toggle()
# Play / Pause on Ctrl + SPACE
if keyval == Gdk.KEY_space:
self.player.play_pause()
......@@ -337,7 +356,7 @@ class Window(Gtk.ApplicationWindow):
elif modifiers == mod1_mask:
# Go back from Album view on Alt + Left
if keyval == Gdk.KEY_Left:
self.headerbar._on_back_button_clicked()
self._headerbar._on_back_button_clicked()
# Headerbar switching
if keyval in [Gdk.KEY_1, Gdk.KEY_KP_1]:
self._toggle_view(View.ALBUM)
......@@ -368,21 +387,21 @@ class Window(Gtk.ApplicationWindow):
self.views[View.PLAYLIST].remove_playlist()
# Close selection mode or search bar after Esc is pressed
if keyval == Gdk.KEY_Escape:
if self.headerbar.props.selection_mode:
self.headerbar.props.selection_mode = False
if self.props.selection_mode:
self.props.selection_mode = False
else:
self.headerbar.searchbar.reveal(False)
self._headerbar.searchbar.reveal(False)
# Open the search bar when typing printable chars.
key_unic = Gdk.keyval_to_unicode(keyval)
if ((not self.headerbar.searchbar.get_search_mode()
if ((not self._headerbar.searchbar.get_search_mode()
and not keyval == Gdk.KEY_space)
and GLib.unichar_isprint(chr(key_unic))
and (modifiers == shift_mask
or modifiers == 0)
and not self.views[View.PLAYLIST].rename_active
and self.headerbar.props.state != HeaderBar.State.SEARCH):
self.headerbar.searchbar.reveal(True)
and self._headerbar.props.state != HeaderBar.State.SEARCH):
self._headerbar.searchbar.reveal(True)
@log
def do_button_release_event(self, event):
......@@ -393,7 +412,7 @@ class Window(Gtk.ApplicationWindow):
__, code = event.get_button()
# Mouse button 8 is the navigation button
if code == 8:
self.headerbar._on_back_button_clicked()
self._headerbar._on_back_button_clicked()
@log
def _notify_mode_disconnect(self, data=None):
......@@ -412,14 +431,9 @@ class Window(Gtk.ApplicationWindow):
or self.prev_view == self.views[View.EMPTY])):
self.curr_view.set_visible_child(self.curr_view._grid)
# Slide out sidebar on switching to Artists or Playlists view
if self.curr_view == self.views[View.ARTIST] or \
self.curr_view == self.views[View.PLAYLIST]:
self.curr_view.stack.set_visible_child_name('dummy')
self.curr_view.stack.set_visible_child_name('sidebar')
if (self.curr_view != self.views[View.SEARCH]
and self.curr_view != self.views[View.EMPTY]):
self.headerbar.searchbar.reveal(False)
self._headerbar.searchbar.reveal(False)
# Disable the selection button for the EmptySearch and Playlist
# view
......@@ -428,7 +442,7 @@ class Window(Gtk.ApplicationWindow):
self.views[View.PLAYLIST]
]
allowed = self.curr_view not in no_selection_mode
self.headerbar.props.selection_mode_allowed = allowed
self._headerbar.props.selection_mode_allowed = allowed
# Disable renaming playlist if it was active when leaving
# Playlist view
......@@ -442,20 +456,20 @@ class Window(Gtk.ApplicationWindow):
# the search mode. This fixes the behaviour as needed, but is
# incorrect: searchview currently does not switch states
# correctly.
if (not self.headerbar.props.selection_mode
and not self.headerbar.props.state == HeaderBar.State.CHILD
and not self.headerbar.props.state == HeaderBar.State.SEARCH):
if (not self.props.selection_mode
and not self._headerbar.props.state == HeaderBar.State.CHILD
and not self._headerbar.props.state == HeaderBar.State.SEARCH):
self._stack.set_visible_child(self.views[view_enum])
@log
def _on_search_toggled(self, button, data=None):
self.headerbar.searchbar.reveal(
self._headerbar.searchbar.reveal(
button.get_active(), self.curr_view != self.views[View.SEARCH])
if (not button.get_active()
and (self.curr_view == self.views[View.SEARCH]
or self.curr_view == self.views[View.EMPTY])):
child = self.curr_view.get_visible_child()
if self.headerbar.props.state == HeaderBar.State.MAIN:
if self._headerbar.props.state == HeaderBar.State.MAIN:
# We should get back to the view before the search
self._stack.set_visible_child(
self.views[View.SEARCH].previous_view)
......@@ -464,12 +478,16 @@ class Window(Gtk.ApplicationWindow):
and child != self.curr_view._artist_albums_widget):
self._stack.set_visible_child(self.views[View.ALBUM])
if self.headerbar.props.selection_mode:
self.headerbar.props.selection_mode = False
if self.props.selection_mode:
self.props.selection_mode = False
@log
def _on_selection_mode_changed(self, widget, data=None):
if self.headerbar.props.selection_mode == False:
if self.props.selection_mode:
self.player_toolbar.hide()
elif self.player.props.playing:
self.player_toolbar.show()
if not self.props.selection_mode:
self._on_changes_pending()
@log
......@@ -486,7 +504,7 @@ class Window(Gtk.ApplicationWindow):
if playlist_dialog.run() == Gtk.ResponseType.ACCEPT:
playlists.add_to_playlist(
playlist_dialog.get_selected(), selected_songs)
self.headerbar.props.selection_mode = False