def __popup_menu(self, y=None, relative=None): """ Show menu at y or row @param y as int @param relative as Gtk.Widget """ if self.__base_mask & SelectionListMask.SIDEBAR: menu = None row_id = None if relative is None: relative = self._box.get_row_at_y(y) if relative is not None: row_id = relative.id if row_id is None: from lollypop.menu_selectionlist import SelectionListMenu menu = SelectionListMenu(self, self.mask, App().window.folded) elif not App().settings.get_value("save-state"): from lollypop.menu_selectionlist import SelectionListRowMenu menu = SelectionListRowMenu(row_id, App().window.folded) if menu is not None: from lollypop.widgets_menu import MenuBuilder menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, relative, None, None, None)
def _on_menu_button_clicked(self, button): """ Show playlist menu @param button as Gtk.Button """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_search import SearchMenu menu = SearchMenu(App().window.folded) menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, button, None, None, button)
def __on_menu_button_clicked(self, button): """ Save to playlist @param button as Gtk.Button """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_current_albums import CurrentAlbumsMenu menu = CurrentAlbumsMenu(App().window.folded) menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, button, None, None, button)
def __on_menu_button_clicked(self, button): """ Show suggestions menu @param button as Gtk.Button """ from lollypop.menu_suggestions import SuggestionsMenu from lollypop.widgets_menu import MenuBuilder menu = SuggestionsMenu(App().window.folded) menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, button, None, None, button)
def __on_menu_button_clicked(self, button): """ Show playlist menu @param button as Gtk.Button """ from lollypop.menu_selectionlist import SelectionListMenu from lollypop.widgets_menu import MenuBuilder menu = SelectionListMenu(self.__view, SelectionListMask.PLAYLISTS, App().window.folded) menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, button, None, None, button)
def _on_menu_button_clicked(self, button): """ Show album menu @param button as Gtk.Button """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_artist import ArtistMenu from lollypop.menu_similars import SimilarsMenu from lollypop.menu_artwork import ArtistArtworkMenu menu = ArtistMenu(self.__artist_ids[0], self.__storage_type, self.view_type, App().window.folded) menu_widget = MenuBuilder(menu, False) menu_widget.show() menu_ext = SimilarsMenu(self.__artist_ids[0]) menu_ext.show() menu_widget.add_widget(menu_ext) if App().window.folded: menu_ext2 = ArtistArtworkMenu(self.__artist_ids[0], self.view_type, True) menu_ext2.connect("hidden", self.__close_artwork_menu) menu_ext2.show() menu_widget.add_widget(menu_ext2) popup_widget(menu_widget, button, None, None, button)
def __popup_menu(self, x, y): """ Popup menu for album @param x as int @param y as int """ row = self._box.get_row_at_y(y) if row is None: return from lollypop.menu_objects import AlbumMenu from lollypop.widgets_menu import MenuBuilder menu = AlbumMenu(row.album, ViewType.ALBUM, self.view_type) menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, self._box, x, y, row)
def __on_banner_show_menu(self, banner, button): """ Show contextual menu @param banner as AlbumsBannerWidget @param button as Gtk.Button """ from lollypop.menu_objects import AlbumsMenu from lollypop.widgets_menu import MenuBuilder albums = [] for child in self._box.get_children(): if child.data.storage_type & StorageType.COLLECTION: albums.append(child.data) title = get_title_for_genres_artists(self._genre_ids, self._artist_ids) menu = AlbumsMenu(title, albums, self.view_type) menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, button, None, None, button)
def __popup_menu(self, child): """ Popup menu for playlist @param child as PlaylistRoundedWidget """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_playlist import PlaylistMenu, PlaylistMenuExt menu = PlaylistMenu(child.data, self.view_type, App().window.folded) menu_widget = MenuBuilder(menu) if child.data >= 0: menu_widget = MenuBuilder(menu) menu_ext = PlaylistMenuExt(child.data) menu_ext.show() menu_widget.add_widget(menu_ext) else: menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, child, None, None, None)
def _get_menu_widget(self, child): """ Get menu widget @param child as AlbumSimpleWidget @return Gtk.Widget """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_decade import DecadeMenu menu = DecadeMenu(child.data, self.view_type, App().window.folded) return MenuBuilder(menu)
def _get_menu_widget(self, child): """ Get menu widget @param child as AlbumSimpleWidget @return Gtk.Widget """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_objects import AlbumMenu menu = AlbumMenu(child.data, self.storage_type, self.view_type) return MenuBuilder(menu)
def _on_menu_button_clicked(self, button): """ Show playlist menu @param button as Gtk.Button """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_playlist import PlaylistMenu, PlaylistMenuExt menu = PlaylistMenu(self.__playlist_id, self.view_type, App().window.folded) menu_widget = MenuBuilder(menu) if self.__playlist_id >= 0: menu_widget = MenuBuilder(menu) menu_ext = PlaylistMenuExt(self.__playlist_id) menu_ext.show() menu_widget.add_widget(menu_ext) else: menu_widget = MenuBuilder(menu) menu_widget.show() popup_widget(menu_widget, button, None, None, button)
def _on_shuffle_button_toggled(self, button): """ Popup shuffle menu @param button as Gtk.ToggleButton """ if button.get_active(): if self.__app_menu is not None: emit_signal(self.__app_menu, "hidden", True) self.__party_submenu.remove_all() self.__init_party_submenu() from lollypop.widgets_menu import MenuBuilder self.__playback_menu = MenuBuilder(self.__shuffle_menu) self.__playback_menu.show() popover = popup_widget(self.__playback_menu, button, None, None, None) if popover is None: self.__playback_menu.connect("hidden", self.__on_menu_hidden, button) else: popover.connect("hidden", self.__on_menu_hidden, button) elif self.__playback_menu is not None and App().window.folded: emit_signal(self.__playback_menu, "hidden", True)
def _get_menu_widget(self, child): """ Get menu widget @param child as AlbumSimpleWidget @return Gtk.Widget """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_artist import ArtistMenu from lollypop.menu_similars import SimilarsMenu menu = ArtistMenu(child.data, self.storage_type, self.view_type, App().window.folded) menu_widget = MenuBuilder(menu, False) menu_widget.show() menu_ext = SimilarsMenu(child.data) menu_ext.show() menu_widget.add_widget(menu_ext) return menu_widget
def popup_menu(self, parent, x=None, y=None): """ Popup menu for track @param parent as Gtk.Widget @param x as int @param y as int """ def on_hidden(widget, hide): self.set_indicator() from lollypop.menu_objects import TrackMenu, TrackMenuExt from lollypop.widgets_menu import MenuBuilder menu = TrackMenu(self._track, self.__view_type) menu_widget = MenuBuilder(menu) menu_widget.show() if not self._track.storage_type & StorageType.EPHEMERAL: menu_ext = TrackMenuExt(self._track) menu_ext.show() menu_widget.add_widget(menu_ext) popover = popup_widget(menu_widget, parent, x, y, self) if popover is None: menu_widget.connect("hidden", on_hidden) else: popover.connect("hidden", on_hidden)
def _on_menu_button_clicked(self, button): """ Show album menu @param button as Gtk.Button """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_objects import AlbumMenu from lollypop.menu_artwork import AlbumArtworkMenu menu = AlbumMenu(self.__album, self.__storage_type, self.view_type) menu_widget = MenuBuilder(menu) menu_widget.show() if App().window.folded: menu_ext = AlbumArtworkMenu(self.__album, self.view_type, True) menu_ext.connect("hidden", self.__close_artwork_menu) menu_ext.show() menu_widget.add_widget(menu_ext, -2) popup_widget(menu_widget, button, None, None, button)
def __popup_menu(self): """ Show contextual menu """ if App().window.folded or not self.__artwork.get_visible(): return track = App().player.current_track if track.id >= 0: from lollypop.menu_objects import TrackMenu, TrackMenuExt from lollypop.widgets_menu import MenuBuilder menu = TrackMenu(track, ViewType.TOOLBAR) menu_widget = MenuBuilder(menu) menu_widget.show() if not track.storage_type & StorageType.EPHEMERAL: menu_ext = TrackMenuExt(track) menu_ext.show() menu_widget.add_widget(menu_ext) self.set_state_flags(Gtk.StateFlags.FOCUSED, False) popup_widget(menu_widget, self.__eventbox, None, None, None)
def _on_badge_button_release(self, eventbox, event): """ Show artist artwork manager @param eventbox as Gtk.EventBox @param event as Gdk.Event """ from lollypop.widgets_menu import MenuBuilder from lollypop.menu_artwork import ArtistArtworkMenu menu = Gio.Menu() if App().window.folded: from lollypop.menu_header import ArtistMenuHeader menu.append_item(ArtistMenuHeader(self.__artist_ids[0])) menu_widget = MenuBuilder(menu, False) menu_widget.show() menu_ext = ArtistArtworkMenu(self.__artist_ids[0], self.view_type, False) menu_ext.connect("hidden", self.__close_artwork_menu) menu_ext.show() menu_widget.add_widget(menu_ext) self.__artwork_popup = popup_widget(menu_widget, eventbox, None, None, None)
def _on_primary_press_gesture(self, x, y, event): """ Show artwork popover @param x as int @param y as int @param event as Gdk.Event """ if self._view_type & ViewType.ALBUM: from lollypop.widgets_menu import MenuBuilder from lollypop.menu_artwork import AlbumArtworkMenu menu = Gio.Menu() if App().window.folded: from lollypop.menu_header import AlbumMenuHeader menu.append_item(AlbumMenuHeader(self._album)) menu_widget = MenuBuilder(menu, False) menu_widget.show() menu_ext = AlbumArtworkMenu(self._album, self._view_type, False) menu_ext.connect("hidden", self.__close_artwork_menu) menu_ext.show() menu_widget.add_widget(menu_ext, False) self._artwork_popup = popup_widget(menu_widget, self, None, None, None)
class ToolbarEnd(Gtk.Bin): """ Toolbar end """ def __init__(self, window): """ Init toolbar @param window as Window """ Gtk.Bin.__init__(self) self.set_hexpand(True) self.__search_popover = None self.__devices_popover = None self.__app_menu = None self.__playback_menu = None self.__timeout_id = None builder = Gtk.Builder() builder.add_from_resource("/org/gnome/Lollypop/ToolbarEnd.ui") self.__shuffle_menu = builder.get_object("shuffle-menu") self.__party_submenu = builder.get_object("party_submenu") self.add(builder.get_object("end")) self.__shuffle_action = Gio.SimpleAction.new_stateful( "shuffle", None, App().settings.get_value("shuffle")) self.__shuffle_action.connect("change-state", self.__on_shuffle_change_state) self.__repeat_action = Gio.SimpleAction.new_stateful( "repeat", GLib.VariantType.new("s"), GLib.Variant("s", "none")) self.__repeat_action.set_state(App().settings.get_value("repeat")) self.__repeat_action.connect("change-state", self.__on_repeat_change_state) App().add_action(self.__shuffle_action) App().add_action(self.__repeat_action) self.__playback_button = builder.get_object("playback_button") self.__playback_button_image = builder.get_object( "shuffle_button_image") shuffle_button_action = Gio.SimpleAction.new("shuffle-button", None) shuffle_button_action.connect("activate", self.__on_shuffle_button_activate) App().add_action(shuffle_button_action) App().set_accels_for_action("app.shuffle-button", ["<Control>r"]) App().settings.connect("changed::shuffle", self.__on_repeat_changed) App().settings.connect("changed::repeat", self.__on_repeat_changed) party_action = Gio.SimpleAction.new_stateful( "party", None, GLib.Variant.new_boolean(App().player.is_party)) party_action.connect("change-state", self.__on_party_mode_change_state) App().add_action(party_action) App().set_accels_for_action("app.party", ["<Control>p"]) scrobbling_disabled = App().settings.get_value("disable-scrobbling") scrobbling_action = Gio.SimpleAction.new_stateful( "scrobbling", None, GLib.Variant.new_boolean(not scrobbling_disabled)) scrobbling_action.connect("change-state", self.__on_scrobbling_mode_change_state) App().add_action(scrobbling_action) App().set_accels_for_action("app.scrobbling", ["<Control><Shift>s"]) self.__menu_button = builder.get_object("menu_button") self.__home_button = builder.get_object("home_button") self.__devices_button = builder.get_object("devices_button") self.__playback_button = builder.get_object("playback_button") self.__set_shuffle_icon() button_progress_bar = ButtonProgressBar() overlay = builder.get_object("overlay") overlay.add_overlay(button_progress_bar) overlay.set_overlay_pass_through(button_progress_bar, True) self.__devices_popover = DevicesPopover(button_progress_bar) self.__devices_popover.connect( "hidden", self.__on_menu_hidden, self.__devices_button) self.__devices_popover.connect("content-changed", self.__on_devices_content_changed) self.__devices_popover.populate() builder.connect_signals(self) window.container.widget.connect("notify::folded", self.__on_container_folded) window.container.connect("can-go-back-changed", self.__on_can_go_back_changed) self.__on_container_folded(None, "folded") @property def devices_popover(self): """ Get Devices Popover @return DevicesPopover """ return self.__devices_popover ####################### # PROTECTED # ####################### def _on_home_button_clicked(self, button): """ Go home in adaptive mode @param button as Gtk.Button """ App().window.container.go_home() def _on_shuffle_button_toggled(self, button): """ Popup shuffle menu @param button as Gtk.ToggleButton """ if button.get_active(): if self.__app_menu is not None: emit_signal(self.__app_menu, "hidden", True) self.__party_submenu.remove_all() self.__init_party_submenu() from lollypop.widgets_menu import MenuBuilder self.__playback_menu = MenuBuilder(self.__shuffle_menu) self.__playback_menu.show() popover = popup_widget(self.__playback_menu, button, None, None, None) if popover is None: self.__playback_menu.connect("hidden", self.__on_menu_hidden, button) else: popover.connect("hidden", self.__on_menu_hidden, button) elif self.__playback_menu is not None and App().window.folded: emit_signal(self.__playback_menu, "hidden", True) def _on_devices_button_toggled(self, button): """ Create submenu @param button as Gtk.ToggleButton """ if button.get_active(): self.__devices_popover.set_relative_to(button) self.__devices_popover.popup() def _on_settings_button_toggled(self, button): """ Popup application menu @param button as Gtk.ToggleButton """ from lollypop.menu_application import ApplicationMenu if button.get_active(): if self.__playback_menu is not None: emit_signal(self.__playback_menu, "hidden", True) self.__app_menu = ApplicationMenu() self.__app_menu.show() popover = popup_widget(self.__app_menu, button, None, None, None) if popover is None: self.__app_menu.connect("hidden", self.__on_menu_hidden, button) else: popover.connect("hidden", self.__on_menu_hidden, button) elif self.__app_menu is not None and App().window.folded: emit_signal(self.__app_menu, "hidden", True) ####################### # PRIVATE # ####################### def __init_party_submenu(self): """ Init party submenu with current ids """ def update_actions(): # Update state with a thread party_ids = list(App().settings.get_value("party-ids")) all_ids = App().genres.get_ids() + [Type.WEB] all_selected = not party_ids or len(party_ids) == len(all_ids) App().lookup_action("all_party_ids").set_state( GLib.Variant.new_boolean(all_selected)) for genre_id in all_ids: in_party_ids = not party_ids or genre_id in party_ids action = App().lookup_action("genre_%s" % genre_id) action.set_state(GLib.Variant.new_boolean(in_party_ids)) def update_party_ids(party_ids, value, genre_id): all_ids = App().genres.get_ids() + [Type.WEB] if value: if genre_id not in party_ids: party_ids.append(genre_id) if len(party_ids) == len(all_ids): party_ids = [] else: if not party_ids: party_ids = all_ids if genre_id in party_ids: party_ids.remove(genre_id) return party_ids def on_change_state(action, value, genre_id): party_ids = list(App().settings.get_value("party-ids")) all_ids = App().genres.get_ids() + [Type.WEB] action.set_state(value) if genre_id is None: for genre_id in all_ids: action = App().lookup_action("genre_%s" % genre_id) action.set_state(value) party_ids = update_party_ids(party_ids, value, genre_id) else: party_ids = update_party_ids(party_ids, value, genre_id) all_selected = not party_ids or len(party_ids) == len(all_ids) App().lookup_action("all_party_ids").set_state( GLib.Variant("b", all_selected)) App().settings.set_value("party-ids", GLib.Variant("ai", party_ids)) App().task_helper.run(App().player.set_party_ids, callback=( lambda x: App().player.set_next(),)) # Create actions action = Gio.SimpleAction.new_stateful( "all_party_ids", None, GLib.Variant.new_boolean(False)) action.connect("change-state", on_change_state, None) App().add_action(action) item = Gio.MenuItem.new(_("All genres"), "app.all_party_ids") self.__party_submenu.append_item(item) genres = App().genres.get() genres += [(Type.WEB, _("Web"), _("Web"))] for (genre_id, name, sortname) in genres: action_name = "genre_%s" % genre_id action = Gio.SimpleAction.new_stateful( action_name, None, GLib.Variant.new_boolean(False)) action.connect("change-state", on_change_state, genre_id) if genre_id == Type.WEB: action.set_enabled(get_network_available("YOUTUBE")) App().add_action(action) menu_str = name if len(name) < 20 else name[0:20] + "…" item = Gio.MenuItem.new(menu_str, "app.%s" % action_name) self.__party_submenu.append_item(item) App().task_helper.run(update_actions) def __set_shuffle_icon(self): """ Set shuffle icon """ shuffle = App().settings.get_value("shuffle") repeat = App().settings.get_enum("repeat") if shuffle: self.__playback_button_image.set_from_icon_name( "media-playlist-shuffle-symbolic", Gtk.IconSize.BUTTON) elif repeat == Repeat.TRACK: self.__playback_button_image.get_style_context().remove_class( "selected") self.__playback_button_image.set_from_icon_name( "media-playlist-repeat-song-symbolic", Gtk.IconSize.BUTTON) elif repeat == Repeat.ALL: self.__playback_button_image.set_from_icon_name( "media-playlist-repeat-symbolic", Gtk.IconSize.BUTTON) else: self.__playback_button_image.set_from_icon_name( "media-playlist-consecutive-symbolic", Gtk.IconSize.BUTTON) def __on_party_mode_change_state(self, action, value): """ Activate party mode @param action as Gio.SimpleAction @param value as bool """ if not App().gtk_application_prefer_dark_theme and\ not App().settings.get_value("dark-ui"): settings = Gtk.Settings.get_default() settings.set_property("gtk-application-prefer-dark-theme", value) App().player.set_party(value.get_boolean()) action.set_state(value) self.__shuffle_action.set_enabled(not value) self.__repeat_action.set_enabled(not value) def __on_scrobbling_mode_change_state(self, action, value): """ Change scrobbling option @param action as Gio.SimpleAction @param value as bool """ action.set_state(value) App().settings.set_value("disable-scrobbling", GLib.Variant("b", not value)) def __on_shuffle_change_state(self, action, value): """ Update shuffle setting @param action as Gio.SimpleAction @param value as bool """ App().settings.set_value("shuffle", value) action.set_state(value) def __on_repeat_change_state(self, action, value): """ Update playback setting @param action as Gio.SimpleAction @param value as GLib.Variant """ App().settings.set_value("repeat", value) action.set_state(value) def __on_shuffle_button_activate(self, action, param): """ Activate shuffle button @param action as Gio.SimpleAction @param param as GLib.Variant """ self.__playback_button.set_active( not self.__playback_button.get_active()) def __on_repeat_changed(self, settings, value): """ Update shuffle icon @param settings as Gio.Settings @param value as GLib.Variant """ self.__set_shuffle_icon() def __on_menu_hidden(self, menu, hide, button): """ Restore button state and reset menus @param menu as MenuWidget @param hide as bool @param button as Gtk.Button """ self.__app_menu = None self.__playback_menu = None button.set_active(False) def __on_devices_content_changed(self, popover, count): """ Show/Hide device button @param popover as DevicesPopover @param count as int """ if count: self.__devices_button.show() else: self.__devices_button.hide() def __on_container_folded(self, leaflet, folded): """ Show/Hide home button @param leaflet as Handy.Leaflet @param folded as Gparam """ if App().window.folded: self.__home_button.show() self.__home_button.set_sensitive(True) else: self.__home_button.hide() def __on_can_go_back_changed(self, container, back): """ Make button sensitive @param container as Container @param back as bool """ if back: self.__home_button.set_sensitive(True) else: self.__home_button.set_sensitive(False)