Beispiel #1
0
 def _on_list_button_clicked(self, widget, unused=None):
     """
         Show current playback context popover
         @param widget as Gtk.Widget
     """
     if self.__list_popover is not None:
         return
     self.__next_was_inhibited = self.__next_popover.inhibited
     self.__next_popover.hide()
     self.__next_popover.inhibit(True)
     if Lp().player.current_track.id == Type.EXTERNALS:
         from lollypop.pop_externals import ExternalsPopover
         self.__list_popover = ExternalsPopover()
         self.__list_popover.set_relative_to(self.__list_button)
         self.__list_popover.populate()
         self.__list_popover.show()
     elif Lp().player.get_queue():
         from lollypop.pop_queue import QueuePopover
         self.__list_popover = QueuePopover()
         self.__list_popover.set_relative_to(self.__list_button)
         self.__list_popover.show()
     elif Lp().player.get_user_playlist_ids():
         from lollypop.pop_playlists import PlaylistsPopover
         self.__list_popover = PlaylistsPopover()
         self.__list_popover.set_relative_to(self.__list_button)
         self.__list_popover.show()
     else:
         from lollypop.pop_albums import AlbumsPopover
         self.__list_popover = AlbumsPopover()
         self.__list_popover.set_relative_to(self.__list_button)
         self.__list_popover.show()
     self.__list_popover.connect('closed', self.__on_list_popover_closed)
     return True
Beispiel #2
0
 def _on_list_button_clicked(self, widget, unused=None):
     """
         Show current playback context popover
         @param widget as Gtk.Widget
     """
     if self._list_popover is not None:
         return
     self._next_was_inhibited = self._next_popover.inhibited
     self._next_popover.hide()
     self._next_popover.inhibit(True)
     if Lp().player.current_track.id == Type.EXTERNALS:
         self._list_popover = ExternalsPopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.populate()
         self._list_popover.show()
     elif Lp().player.get_queue():
         self._list_popover = QueuePopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.show()
     elif Lp().player.get_user_playlist_ids():
         self._list_popover = PlaylistsPopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.show()
     else:
         self._list_popover = AlbumsPopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.show()
     self._list_popover.connect('closed', self._on_list_popover_closed)
     return True
Beispiel #3
0
 def _on_list_button_clicked(self, widget, unused=None):
     """
         Show current playback context popover
         @param widget as Gtk.Widget
     """
     if self._list_popover is not None:
         return
     self._next_popover.hide()
     if Lp().player.current_track.id == Type.EXTERNALS:
         self._list_popover = ExternalsPopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.populate()
         self._list_popover.show()
     elif Lp().player.get_queue():
         self._list_popover = QueuePopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.show()
     elif Lp().player.get_user_playlist_ids():
         self._list_popover = PlaylistsPopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.show()
     else:
         self._list_popover = AlbumsPopover()
         self._list_popover.set_relative_to(self._list_button)
         self._list_popover.show()
     self._list_popover.connect('closed', self._on_list_popover_closed)
     return True
Beispiel #4
0
    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfos.ui')
        builder.connect_signals(self)

        infobox = builder.get_object('infos')
        infobox.set_property('has-tooltip', True)
        self.add(infobox)

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')
        self._pop_albums = AlbumsPopover()
        self._pop_albums.set_relative_to(infobox)
        self._pop_tunein = TuneinPopover(RadiosManager())
        self._pop_tunein.set_relative_to(infobox)

        Lp.art.connect('cover-changed', self._update_cover)
        Lp.art.connect('logo-changed', self._update_logo)
Beispiel #5
0
    def __init__(self):
        Gtk.Bin.__init__(self)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfos.ui')
        builder.connect_signals(self)

        infobox = builder.get_object('infos')
        infobox.set_property('has-tooltip', True)
        self.add(infobox)

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')
        self._pop_albums = AlbumsPopover()
        self._pop_albums.set_relative_to(infobox)
        self._pop_tunein = TuneinPopover(RadiosManager())
        self._pop_tunein.set_relative_to(infobox)

        Lp.art.connect('cover-changed', self._update_cover)
        Lp.art.connect('logo-changed', self._update_logo)
Beispiel #6
0
 def _on_list_button_toggled(self, button):
     """
         Show current playback context popover
         @param button as Gtk.MenuButton
     """
     if not button.get_active():
         return
     self.__next_popover.hide()
     self.__next_popover.inhibit(True)
     if App().player.queue:
         from lollypop.pop_queue import QueuePopover
         popover = QueuePopover()
     elif App().player.playlist_ids:
         from lollypop.pop_playlists import PlaylistsPopover
         popover = PlaylistsPopover()
     else:
         from lollypop.pop_albums import AlbumsPopover
         popover = AlbumsPopover()
     popover.set_relative_to(button)
     popover.popup()
     popover.connect("closed", self.__on_popover_closed, button)
     return True
Beispiel #7
0
class ToolbarInfos(Gtk.Bin):
    """
        Init infos toolbar
    """
    def __init__(self):
        Gtk.Bin.__init__(self)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfos.ui')
        builder.connect_signals(self)

        infobox = builder.get_object('infos')
        infobox.set_property('has-tooltip', True)
        self.add(infobox)

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')
        self._pop_albums = AlbumsPopover()
        self._pop_albums.set_relative_to(infobox)
        self._pop_tunein = TuneinPopover(RadiosManager())
        self._pop_tunein.set_relative_to(infobox)

        Lp.art.connect('cover-changed', self._update_cover)
        Lp.art.connect('logo-changed', self._update_logo)

    """
        Update toolbar on current changed
        @param player as Player
    """
    def on_current_changed(self, player):
        art = None
        self._artist_label.set_text(player.current_track.artist)
        self._title_label.set_text(player.current_track.title)

        if player.current_track.id == Type.RADIOS:
            art = Lp.art.get_radio(player.current_track.artist,
                                   ArtSize.SMALL)
        elif player.current_track.id == Type.EXTERNALS:
            art = Lp.art.get_cover_for_uri(player.current_track.uri,
                                           ArtSize.SMALL,
                                           False)
        else:
            art = Lp.art.get_album(player.current_track.album_id,
                                   ArtSize.SMALL)
        if art is not None:
            self._cover.set_from_pixbuf(art)
            del art
            self._cover.set_tooltip_text(player.current_track.album)
            self._cover.show()
        else:
            self._cover.hide()

    """
        Update infos on status changed
        @param player as Player
    """
    def on_status_changed(self, player):
        pass

#######################
# PRIVATE             #
#######################
    """
        Update cover for album_id
        @param art as Art
        @param album id as int
    """
    def _update_cover(self, art, album_id):
        if Lp.player.current_track.album_id == album_id:
            pixbuf = Lp.art.get_album(album_id, ArtSize.SMALL)
            self._cover.set_from_pixbuf(pixbuf)
            del pixbuf

    """
        Update logo for name
        @param art as Art
        @param name as str
    """
    def _update_logo(self, art, name):
        if Lp.player.current_track.artist == name:
            pixbuf = Lp.art.get_radio(name, ArtSize.SMALL)
            self._cover.set_from_pixbuf(pixbuf)
            del pixbuf

    """
        Pop albums from current artistleft click
        Show playlist menu on right
        @param eventbox as Gtk.EventBox
        @param event as Gdk.Event
    """
    def _on_infobox_clicked(self, eventbox, event):
        if Lp.player.current_track.id == Type.EXTERNALS:
            expopover = ExternalsPopover()
            expopover.set_relative_to(eventbox)
            expopover.populate()
            expopover.show()
        elif Lp.player.current_track.id is not None:
            if event.button == 1:
                if Lp.player.current_track.id == Type.RADIOS:
                    self._pop_tunein.populate()
                    self._pop_tunein.show()
                else:
                    self._pop_albums.populate()
                    self._pop_albums.show()
            elif Lp.player.current_track.id >= 0:
                menu = PopToolbarMenu(Lp.player.current_track.id, None)
                popover = Gtk.Popover.new_from_model(eventbox, menu)
                popover.show()
            return True

    """
        Show tooltip if needed
        @param widget as Gtk.Widget
        @param x as int
        @param y as int
        @param keyboard as bool
        @param tooltip as Gtk.Tooltip
    """
    def _on_query_tooltip(self, widget, x, y, keyboard, tooltip):
        # GTK bug => https://bugzilla.gnome.org/show_bug.cgi?id=749965
        return False
        layout_title = self._title_label.get_layout()
        layout_artist = self._artist_label.get_layout()
        if layout_title.is_ellipsized() or layout_artist.is_ellipsized():
            artist = escape(self._artist_label.get_text())
            title = escape(self._title_label.get_text())
            tooltip.set_markup("<b>%s</b>\n%s" % (artist, title))
        else:
            return False
        return True

    """
        Show hand cursor over
    """
    def _on_eventbox_realize(self, eventbox):
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
Beispiel #8
0
class ToolbarEnd(Gtk.Bin):
    """
        Toolbar end
    """
    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        self.connect('show', self.__on_show)
        self.connect('hide', self.__on_hide)
        self.set_hexpand(True)
        self.__next_popover = NextPopover()
        self.__search = None
        self.__next_was_inhibited = False
        self.__timeout_id = None
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarEnd.ui')
        builder.connect_signals(self)

        self.add(builder.get_object('end'))

        self.__grid_next = builder.get_object('grid-next')

        self.__shuffle_button = builder.get_object('shuffle-button')
        self.__shuffle_image = builder.get_object('shuffle-button-image')
        shuffleAction = Gio.SimpleAction.new('shuffle-button', None)
        shuffleAction.connect('activate', self.__activate_shuffle_button)
        Lp().add_action(shuffleAction)
        Lp().set_accels_for_action("app.shuffle-button", ["<Control>r"])
        Lp().settings.connect('changed::shuffle', self.__on_playback_changed)
        Lp().settings.connect('changed::playback', self.__on_playback_changed)

        self.__party_button = builder.get_object('party-button')
        party_action = Gio.SimpleAction.new('party', None)
        party_action.connect('activate', self.__activate_party_button)
        Lp().add_action(party_action)
        Lp().set_accels_for_action("app.party", ["<Control>p"])

        self.__search_button = builder.get_object('search-button')
        self.__helper = TouchHelper(self.__search_button, "search",
                                    "<Control>f")
        self.__helper.set_long_func(self.__on_search_long)
        self.__helper.set_short_func(self.__on_search_short)

        self.__settings_button = builder.get_object('settings-button')

        self.__list_button = builder.get_object('list-button')
        self.__list_button.set_property('has-tooltip', True)
        self.__list_button.connect('query-tooltip',
                                   self.__on_list_button_query_tooltip)
        self.__list_popover = None
        Lp().player.connect('party-changed', self.__on_party_changed)
        Lp().player.connect('lock-changed', self.__on_lock_changed)

    def setup_menu(self, menu):
        """
            Add an application menu to menu button
            @parma: menu as Gio.Menu
        """
        self.__settings_button.show()
        self.__settings_button.set_menu_model(menu)

    def on_status_changed(self, player):
        """
            Update buttons on status changed
            @param player as Player
        """
        if player.is_playing:
            # Party mode can be activated
            # via Fullscreen class, so check button state
            self.__party_button.set_active(player.is_party)

    def on_next_changed(self, player, force=False):
        """
            Show next popover
            @param player as Player
            @param force to show the popover
        """
        # Do not show popover is this menu is active
        # or if we are hidden
        if self.__shuffle_button.get_active() or\
           not self.__grid_next.is_visible():
            return
        if self.__next_popover.should_be_shown() or force:
            if self.__next_popover.is_visible():
                self.__next_popover.update()
            else:
                self.__next_popover.set_relative_to(self.__grid_next)
                self.__next_popover.show()
        else:
            self.__next_popover.hide()

    def search(self, search):
        """
            Search item
            @param search as str
        """
        self.__on_search_short([])
        self.__search.set_text(search)

#######################
# PROTECTED           #
#######################

    def _on_shuffle_button_toggled(self, button):
        """
            Hide next popover
            @param button as Gtk.Button
        """
        if button.get_active():
            self.__next_popover.hide()
            self.__next_popover.inhibit(True)
        else:
            self.__next_popover.inhibit(False)
            if self.__next_popover.should_be_shown():
                self.__next_popover.show()

    def _on_party_button_toggled(self, button):
        """
            Set party mode on if party button active
            @param obj as Gtk.button
        """
        active = self.__party_button.get_active()
        self.__shuffle_button.set_sensitive(not active)
        if not Lp().settings.get_value('dark-ui'):
            settings = Gtk.Settings.get_default()
            settings.set_property("gtk-application-prefer-dark-theme", active)
        Lp().player.set_party(active)
        self.on_next_changed(Lp().player)

    def _on_party_press_event(self, eventbox, event):
        """
            Show party popover
            @param eventbox as Gtk.EventBox
            @param event as Gdk.Event
        """
        if event.button == 3:
            popover = PartyPopover()
            popover.set_relative_to(eventbox)
            self.__next_popover.hide()
            popover.connect('closed', self.__on_popover_closed)
            self.__next_popover.inhibit(True)
            popover.show()
            return True

    def _on_list_button_clicked(self, widget, unused=None):
        """
            Show current playback context popover
            @param widget as Gtk.Widget
        """
        if self.__list_popover is not None:
            return
        self.__next_was_inhibited = self.__next_popover.inhibited
        self.__next_popover.hide()
        self.__next_popover.inhibit(True)
        if Lp().player.current_track.id == Type.EXTERNALS:
            from lollypop.pop_externals import ExternalsPopover
            self.__list_popover = ExternalsPopover()
            self.__list_popover.set_relative_to(self.__list_button)
            self.__list_popover.populate()
            self.__list_popover.show()
        elif Lp().player.get_queue():
            from lollypop.pop_queue import QueuePopover
            self.__list_popover = QueuePopover()
            self.__list_popover.set_relative_to(self.__list_button)
            self.__list_popover.show()
        elif Lp().player.get_user_playlist_ids():
            from lollypop.pop_playlists import PlaylistsPopover
            self.__list_popover = PlaylistsPopover()
            self.__list_popover.set_relative_to(self.__list_button)
            self.__list_popover.show()
        else:
            from lollypop.pop_albums import AlbumsPopover
            self.__list_popover = AlbumsPopover()
            self.__list_popover.set_relative_to(self.__list_button)
            self.__list_popover.show()
        self.__list_popover.connect('closed', self.__on_list_popover_closed)
        return True

#######################
# PRIVATE             #
#######################

    def __on_search_long(self, args):
        """
            Show current track menu
            @param args as []
        """
        if Lp().window.view is not None:
            Lp().window.view.set_search_mode()

    def __on_search_short(self, args):
        """
            Show search popover
            @param args as []
        """
        self.__next_was_inhibited = self.__next_popover.inhibited
        self.__next_popover.hide()
        self.__next_popover.inhibit(True)
        if self.__search is None:
            from lollypop.pop_search import SearchPopover
            self.__search = SearchPopover()
            self.__search.connect('closed', self.__on_popover_closed)
        self.__search.set_relative_to(self.__search_button)
        self.__search.show()

    def __set_icon(self):
        """
            Set shuffle icon
        """
        shuffle = Lp().settings.get_enum('shuffle')
        repeat = Lp().settings.get_enum('playback')
        if repeat == NextContext.REPEAT_TRACK:
            self.__shuffle_image.get_style_context().remove_class('selected')
            self.__shuffle_image.set_from_icon_name(
                "media-playlist-repeat-song-symbolic",
                Gtk.IconSize.SMALL_TOOLBAR)
        elif shuffle == Shuffle.NONE:
            self.__shuffle_image.get_style_context().remove_class('selected')
            if repeat == NextContext.NONE:
                self.__shuffle_image.set_from_icon_name(
                    "media-playlist-repeat-symbolic",
                    Gtk.IconSize.SMALL_TOOLBAR)
            else:
                self.__shuffle_image.set_from_icon_name(
                    "media-playlist-consecutive-symbolic",
                    Gtk.IconSize.SMALL_TOOLBAR)
        else:
            self.__shuffle_image.set_from_icon_name(
                "media-playlist-shuffle-symbolic", Gtk.IconSize.SMALL_TOOLBAR)
            if shuffle == Shuffle.TRACKS:
                self.__shuffle_image.get_style_context().add_class('selected')
            else:
                self.__shuffle_image.get_style_context().remove_class(
                    'selected')

    def __activate_party_button(self, action=None, param=None):
        """
            Activate party button
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        self.__party_button.set_active(not self.__party_button.get_active())
        Lp().window.responsive_design()

    def __activate_shuffle_button(self, action=None, param=None):
        """
            Activate shuffle button
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        self.__shuffle_button.set_active(
            not self.__shuffle_button.get_active())

    def __on_lock_changed(self, player):
        """
            Lock toolbar
            @param player as Player
        """
        self.__party_button.set_sensitive(not player.locked)
        self.__list_button.set_sensitive(not player.locked)
        self.__shuffle_button.set_sensitive(not player.locked)

    def __on_playback_changed(self, settings, value):
        """
            Update shuffle icon
            @param settings as Gio.Settings, value as str
        """
        self.__set_icon()
        self.__next_popover.hide()

    def __on_party_changed(self, player, is_party):
        """
            On party change, sync toolbar
            @param player as Player
            @param is party as bool
        """
        if self.__party_button.get_active() != is_party:
            self.__activate_party_button()

    def __on_list_popover_closed(self, popover):
        """
            Reset variable
            @param popover as Gtk.Popover
        """
        self.__list_popover = None
        self.__on_popover_closed(popover)

    def __on_popover_closed(self, popover):
        """
            Restore next popover if needed
            @param popover as Gtk.Popover
        """
        if not self.__next_was_inhibited:
            self.__next_popover.inhibit(False)
        if self.__next_popover.should_be_shown():
            self.__next_popover.set_relative_to(self.__grid_next)
            self.__next_popover.show()

    def __on_show(self, widget):
        """
            Show popover if needed
            @param widget as Gtk.Widget
        """
        self.__set_icon()

    def __on_hide(self, widget):
        """
            Hide popover
            @param widget as Gtk.Widget
        """
        self.__next_popover.hide()

    def __on_list_button_query_tooltip(self, widget, x, y, keyboard, tooltip):
        """
            Show tooltip
            @param widget as Gtk.Widget
            @param x as int
            @param y as int
            @param keyboard as bool
            @param tooltip as Gtk.Tooltip
        """
        if Lp().player.current_track.id == Type.EXTERNALS:
            widget.set_tooltip_text(_("External tracks"))
        elif Lp().player.get_queue():
            widget.set_tooltip_text(_("Queue"))
        elif Lp().player.get_user_playlist_ids():
            widget.set_tooltip_text(_("Playing playlists"))
        else:
            widget.set_tooltip_text(_("Playing albums"))
Beispiel #9
0
class ToolbarInfos(Gtk.Bin):
    """
        Informations toolbar
    """
    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfos.ui')
        builder.connect_signals(self)

        infobox = builder.get_object('infos')
        infobox.set_property('has-tooltip', True)
        self.add(infobox)

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')
        self._pop_albums = AlbumsPopover()
        self._pop_albums.set_relative_to(infobox)
        self._pop_tunein = TuneinPopover(RadiosManager())
        self._pop_tunein.set_relative_to(infobox)

        Lp.art.connect('cover-changed', self._update_cover)
        Lp.art.connect('logo-changed', self._update_logo)

    def on_current_changed(self, player):
        """
            Update toolbar on current changed
            @param player as Player
        """
        art = None

        if player.current_track.artist == '':
            self._artist_label.hide()
        else:
            self._artist_label.show()
            self._artist_label.set_text(player.current_track.artist)
        if player.current_track.title == '':
            self._title_label.hide()
        else:
            self._title_label.show()
            self._title_label.set_text(player.current_track.title)

        if player.current_track.id == Type.RADIOS:
            art = Lp.art.get_radio(player.current_track.artist, ArtSize.SMALL)
        elif player.current_track.id == Type.EXTERNALS:
            art = Lp.art.get_cover_for_uri(player.current_track.uri,
                                           ArtSize.SMALL, False)
        else:
            art = Lp.art.get_album(player.current_track.album_id,
                                   ArtSize.SMALL)
        if art is not None:
            self._cover.set_from_surface(art)
            del art
            self._cover.set_tooltip_text(player.current_track.album.name)
            self._cover.show()
        else:
            self._cover.hide()

    def on_status_changed(self, player):
        """
            Update infos on status changed
            @param player as Player
        """
        pass

#######################
# PRIVATE             #
#######################

    def _update_cover(self, art, album_id):
        """
            Update cover for album_id
            @param art as Art
            @param album id as int
        """
        if Lp.player.current_track.album_id == album_id:
            pixbuf = Lp.art.get_album(album_id, ArtSize.SMALL)
            self._cover.set_from_surface(pixbuf)
            del pixbuf

    def _update_logo(self, art, name):
        """
            Update logo for name
            @param art as Art
            @param name as str
        """
        if Lp.player.current_track.artist == name:
            pixbuf = Lp.art.get_radio(name, ArtSize.SMALL)
            self._cover.set_from_surface(pixbuf)
            del pixbuf

    def _on_infobox_clicked(self, eventbox, event):
        """
            Pop albums from current artistleft click
            Show playlist menu on right
            @param eventbox as Gtk.EventBox
            @param event as Gdk.Event
        """
        if Lp.player.current_track.id == Type.EXTERNALS:
            expopover = ExternalsPopover()
            expopover.set_relative_to(eventbox)
            expopover.populate()
            expopover.show()
        elif Lp.player.current_track.id is not None:
            if event.button == 1:
                if Lp.player.current_track.id == Type.RADIOS:
                    self._pop_tunein.populate()
                    self._pop_tunein.show()
                else:
                    self._pop_albums.populate()
                    self._pop_albums.show()
            elif Lp.player.current_track.id >= 0:
                menu = PopToolbarMenu(Lp.player.current_track.id, None)
                popover = Gtk.Popover.new_from_model(eventbox, menu)
                popover.show()
            return True

    def _on_query_tooltip(self, widget, x, y, keyboard, tooltip):
        """
            Show tooltip if needed
            @param widget as Gtk.Widget
            @param x as int
            @param y as int
            @param keyboard as bool
            @param tooltip as Gtk.Tooltip
        """
        # Can't add a \n in markup
        # GTK bug => https://bugzilla.gnome.org/show_bug.cgi?id=749965
        layout_title = self._title_label.get_layout()
        layout_artist = self._artist_label.get_layout()
        if layout_title.is_ellipsized() or layout_artist.is_ellipsized():
            artist = escape(self._artist_label.get_text())
            title = escape(self._title_label.get_text())
            tooltip.set_markup("<b>%s</b> - %s" % (artist, title))
        else:
            return False
        return True

    def _on_eventbox_realize(self, eventbox):
        """
            Show hand cursor over
        """
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
Beispiel #10
0
class ToolbarEnd(Gtk.Bin):
    """
        Toolbar end
    """

    def __init__(self, app):
        """
            Init toolbar
            @param app as Gtk.Application
        """
        Gtk.Bin.__init__(self)
        self.connect('show', self._on_show)
        self.connect('hide', self._on_hide)
        self._next_popover = NextPopover()
        self._search = None
        self._next_was_inhibited = False
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarEnd.ui')
        builder.connect_signals(self)

        self.add(builder.get_object('end'))

        self._grid_next = builder.get_object('grid-next')

        self._shuffle_button = builder.get_object('shuffle-button')
        self._shuffle_image = builder.get_object('shuffle-button-image')
        shuffleAction = Gio.SimpleAction.new('shuffle-button', None)
        shuffleAction.connect('activate', self._activate_shuffle_button)
        app.add_action(shuffleAction)
        app.set_accels_for_action("app.shuffle-button", ["<Control>r"])
        Lp().settings.connect('changed::shuffle', self._on_shuffle_changed)

        self._party_button = builder.get_object('party-button')
        party_action = Gio.SimpleAction.new('party', None)
        party_action.connect('activate', self._activate_party_button)
        app.add_action(party_action)
        app.set_accels_for_action("app.party", ["<Control>p"])

        self._search_button = builder.get_object('search-button')
        search_action = Gio.SimpleAction.new('search', None)
        search_action.connect('activate', self._on_search_button_clicked)
        app.add_action(search_action)
        app.set_accels_for_action("app.search", ["<Control>f"])

        self._settings_button = builder.get_object('settings-button')

        self._list_button = builder.get_object('list-button')
        self._list_button.set_property('has-tooltip', True)
        self._list_button.connect('query-tooltip',
                                  self._on_list_button_query_tooltip)
        list_action = Gio.SimpleAction.new('list', None)
        list_action.connect('activate', self._on_list_button_clicked)
        app.add_action(list_action)
        app.set_accels_for_action("app.list", ["<Control>i"])
        self._list_popover = None
        Lp().player.connect('party-changed', self._on_party_changed)
        Lp().player.connect('state-changed', self._on_lock_changed)

    def setup_menu(self, menu):
        """
            Add an application menu to menu button
            @parma: menu as Gio.Menu
        """
        self._settings_button.show()
        self._settings_button.set_menu_model(menu)

    def on_status_changed(self, player):
        """
            Update buttons on status changed
            @param player as Player
        """
        if player.is_playing():
            # Party mode can be activated
            # via Fullscreen class, so check button state
            self._party_button.set_active(player.is_party())

    def on_next_changed(self, player, force=False):
        """
            Show next popover
            @param player as Player
            @param force to show the popover
        """
        # Do not show popover is this menu is active
        # or if we are hidden
        if self._shuffle_button.get_active() or\
           not self._grid_next.is_visible():
            return
        if self._next_popover.should_be_shown() or force:
            if self._next_popover.is_visible():
                self._next_popover.update()
            else:
                self._next_popover.set_relative_to(self._grid_next)
                self._next_popover.show()
        else:
            self._next_popover.hide()

#######################
# PRIVATE             #
#######################
    def _on_lock_changed(self, player):
        """
            Lock toolbar
            @param player as Player
        """
        self._party_button.set_sensitive(not player.locked)
        self._list_button.set_sensitive(not player.locked)
        self._shuffle_button.set_sensitive(not player.locked)

    def _on_shuffle_button_clicked(self, button):
        """
            Hide next popover
            @param button as Gtk.Button
        """
        self._next_popover.hide()

    def _set_shuffle_icon(self):
        """
            Set shuffle icon
        """
        shuffle = Lp().settings.get_enum('shuffle')
        if shuffle == Shuffle.NONE:
            self._shuffle_image.get_style_context().remove_class('selected')
            self._shuffle_image.set_from_icon_name(
                "media-playlist-consecutive-symbolic",
                Gtk.IconSize.SMALL_TOOLBAR)
        else:
            self._shuffle_image.set_from_icon_name(
                "media-playlist-shuffle-symbolic",
                Gtk.IconSize.SMALL_TOOLBAR)
            if shuffle == Shuffle.TRACKS:
                self._shuffle_image.get_style_context().add_class('selected')
            else:
                self._shuffle_image.get_style_context().remove_class(
                                                                    'selected')

    def _activate_party_button(self, action=None, param=None):
        """
            Activate party button
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        self._party_button.set_active(not self._party_button.get_active())
        Lp().window.responsive_design()

    def _activate_shuffle_button(self, action=None, param=None):
        """
            Activate shuffle button
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        self._shuffle_button.set_active(not self._shuffle_button.get_active())

    def _on_shuffle_changed(self, settings, value):
        """
            Mark shuffle button as active when shuffle active
            @param settings as Gio.Settings, value as str
        """
        self._set_shuffle_icon()
        self._next_popover.hide()

    def _on_search_button_clicked(self, obj, param=None):
        """
            Show search widget on search button clicked
            @param obj as Gtk.Button or Gtk.Action
        """
        self._next_was_inhibited = self._next_popover.inhibited
        self._next_popover.hide()
        self._next_popover.inhibit(True)
        if self._search is None:
            self._search = SearchPopover()
            self._search.connect('closed', self._on_popover_closed)
        self._search.set_relative_to(self._search_button)
        self._search.show()

    def _on_party_button_toggled(self, button):
        """
            Set party mode on if party button active
            @param obj as Gtk.button
        """
        active = self._party_button.get_active()
        self._shuffle_button.set_sensitive(not active)
        if not Lp().settings.get_value('dark-ui'):
            settings = Gtk.Settings.get_default()
            settings.set_property("gtk-application-prefer-dark-theme", active)
        Lp().player.set_party(active)
        self.on_next_changed(Lp().player)

    def _on_party_changed(self, player, is_party):
        """
            On party change, sync toolbar
            @param player as Player
            @param is party as bool
        """
        if self._party_button.get_active() != is_party:
            self._activate_party_button()

    def _on_list_button_clicked(self, widget, unused=None):
        """
            Show current playback context popover
            @param widget as Gtk.Widget
        """
        if self._list_popover is not None:
            return
        self._next_was_inhibited = self._next_popover.inhibited
        self._next_popover.hide()
        self._next_popover.inhibit(True)
        if Lp().player.current_track.id == Type.EXTERNALS:
            self._list_popover = ExternalsPopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.populate()
            self._list_popover.show()
        elif Lp().player.get_queue():
            self._list_popover = QueuePopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.show()
        elif Lp().player.get_user_playlist_ids():
            self._list_popover = PlaylistsPopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.show()
        else:
            self._list_popover = AlbumsPopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.show()
        self._list_popover.connect('closed', self._on_list_popover_closed)
        return True

    def _on_list_popover_closed(self, popover):
        """
            Reset variable
            @param popover as Gtk.Popover
        """
        self._list_popover = None
        self._on_popover_closed(popover)

    def _on_popover_closed(self, popover):
        """
            Restore next popover if needed
            @param popover as Gtk.Popover
        """
        if not self._next_was_inhibited:
            self._next_popover.inhibit(False)
        if self._next_popover.should_be_shown():
            self._next_popover.show()

    def _on_show(self, widget):
        """
            Show popover if needed
            @param widget as Gtk.Widget
        """
        self._set_shuffle_icon()

    def _on_hide(self, widget):
        """
            Hide popover
            @param widget as Gtk.Widget
        """
        self._next_popover.hide()

    def _on_button_press_event(self, eventbox, event):
        """
            Show party popover
            @param eventbox as Gtk.EventBox
            @param event as Gdk.Event
        """
        if event.button == 3:
            popover = PartyPopover()
            popover.set_relative_to(eventbox)
            self._next_popover.hide()
            popover.connect('closed', self._on_popover_closed)
            self._next_popover.inhibit(True)
            popover.show()
            return True

    def _on_list_button_query_tooltip(self, widget, x, y, keyboard, tooltip):
        """
            Show tooltip
            @param widget as Gtk.Widget
            @param x as int
            @param y as int
            @param keyboard as bool
            @param tooltip as Gtk.Tooltip
        """
        if Lp().player.current_track.id == Type.EXTERNALS:
            widget.set_tooltip_text(_("Externals tracks playing"))
        elif Lp().player.get_queue():
            widget.set_tooltip_text(_("Queue"))
        elif Lp().player.get_user_playlist_ids():
            widget.set_tooltip_text(_("Playing playlists"))
        else:
            widget.set_tooltip_text(_("Playing albums"))
Beispiel #11
0
class ToolbarInfos(Gtk.Bin):
    """
        Informations toolbar
    """

    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfos.ui')
        builder.connect_signals(self)

        infobox = builder.get_object('infos')
        infobox.set_property('has-tooltip', True)
        self.add(infobox)

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')
        self._pop_albums = AlbumsPopover()
        self._pop_albums.set_relative_to(infobox)
        self._pop_tunein = TuneinPopover(RadiosManager())
        self._pop_tunein.set_relative_to(infobox)

        Lp.art.connect('cover-changed', self._update_cover)
        Lp.art.connect('logo-changed', self._update_logo)

    def on_current_changed(self, player):
        """
            Update toolbar on current changed
            @param player as Player
        """
        art = None

        if player.current_track.artist == '':
            self._artist_label.hide()
        else:
            self._artist_label.show()
            self._artist_label.set_text(player.current_track.artist)
        if player.current_track.title == '':
            self._title_label.hide()
        else:
            self._title_label.show()
            self._title_label.set_text(player.current_track.title)

        if player.current_track.id == Type.RADIOS:
            art = Lp.art.get_radio(player.current_track.artist,
                                   ArtSize.SMALL*self.get_scale_factor())
        elif player.current_track.id == Type.EXTERNALS:
            art = Lp.art.get_cover_for_uri(
                    player.current_track.uri,
                    ArtSize.SMALL*self.get_scale_factor(),
                    False)
        else:
            art = Lp.art.get_album(player.current_track.album_id,
                                   ArtSize.SMALL*self.get_scale_factor())
        if art is not None:
            self._cover.set_from_surface(art)
            del art
            self._cover.set_tooltip_text(player.current_track.album.name)
            self._cover.show()
        else:
            self._cover.hide()

    def on_status_changed(self, player):
        """
            Update infos on status changed
            @param player as Player
        """
        pass

#######################
# PRIVATE             #
#######################
    def _update_cover(self, art, album_id):
        """
            Update cover for album_id
            @param art as Art
            @param album id as int
        """
        if Lp.player.current_track.album_id == album_id:
            pixbuf = Lp.art.get_album(album_id, ArtSize.SMALL)
            self._cover.set_from_surface(pixbuf)
            del pixbuf

    def _update_logo(self, art, name):
        """
            Update logo for name
            @param art as Art
            @param name as str
        """
        if Lp.player.current_track.artist == name:
            pixbuf = Lp.art.get_radio(name, ArtSize.SMALL)
            self._cover.set_from_surface(pixbuf)
            del pixbuf

    def _on_infobox_clicked(self, eventbox, event):
        """
            Pop albums from current artistleft click
            Show playlist menu on right
            @param eventbox as Gtk.EventBox
            @param event as Gdk.Event
        """
        if Lp.player.current_track.id == Type.EXTERNALS:
            expopover = ExternalsPopover()
            expopover.set_relative_to(eventbox)
            expopover.populate()
            expopover.show()
        elif Lp.player.current_track.id is not None:
            if event.button == 1:
                if Lp.player.current_track.id == Type.RADIOS:
                    self._pop_tunein.populate()
                    self._pop_tunein.show()
                else:
                    self._pop_albums.populate()
                    self._pop_albums.show()
            elif Lp.player.current_track.id >= 0:
                menu = PopToolbarMenu(Lp.player.current_track.id, None)
                popover = Gtk.Popover.new_from_model(eventbox, menu)
                rating = RatingWidget(Lp.player.current_track)
                rating.set_property('margin_top', 5)
                rating.set_property('margin_bottom', 5)
                rating.show()
                # Hack to add two widgets in popover
                # Use a Gtk.PopoverMenu later (GTK>3.16 available on Debian stable)
                stack = Gtk.Stack()
                grid = Gtk.Grid()
                grid.set_orientation(Gtk.Orientation.VERTICAL)
                stack.add_named(grid, 'main')
                stack.show_all()
                menu_widget = popover.get_child()
                menu_widget.reparent(grid)
                separator = Gtk.Separator()
                separator.show()
                grid.add(separator)
                grid.add(rating)
                popover.add(stack)
                popover.show()
            return True

    def _on_query_tooltip(self, widget, x, y, keyboard, tooltip):
        """
            Show tooltip if needed
            @param widget as Gtk.Widget
            @param x as int
            @param y as int
            @param keyboard as bool
            @param tooltip as Gtk.Tooltip
        """
        # Can't add a \n in markup
        # GTK bug => https://bugzilla.gnome.org/show_bug.cgi?id=749965
        layout_title = self._title_label.get_layout()
        layout_artist = self._artist_label.get_layout()
        if layout_title.is_ellipsized() or layout_artist.is_ellipsized():
            artist = escape(self._artist_label.get_text())
            title = escape(self._title_label.get_text())
            tooltip.set_markup("<b>%s</b> - %s" % (artist, title))
        else:
            return False
        return True

    def _on_eventbox_realize(self, eventbox):
        """
            Show hand cursor over
        """
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
Beispiel #12
0
class ToolbarEnd(Gtk.Bin):
    """
        Toolbar end
    """
    def __init__(self, app):
        """
            Init toolbar
            @param app as Gtk.Application
        """
        Gtk.Bin.__init__(self)
        self.connect('show', self._on_show)
        self.connect('hide', self._on_hide)
        self._next_popover = NextPopover()
        self._search = None
        self._timeout_id = None
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarEnd.ui')
        builder.connect_signals(self)

        self.add(builder.get_object('end'))

        self._grid_next = builder.get_object('grid-next')

        self._shuffle_button = builder.get_object('shuffle-button')
        self._shuffle_image = builder.get_object('shuffle-button-image')
        shuffleAction = Gio.SimpleAction.new('shuffle-button', None)
        shuffleAction.connect('activate', self._activate_shuffle_button)
        app.add_action(shuffleAction)
        app.set_accels_for_action("app.shuffle-button", ["<Control>r"])
        Lp().settings.connect('changed::shuffle', self._on_shuffle_changed)

        self._party_button = builder.get_object('party-button')
        party_action = Gio.SimpleAction.new('party', None)
        party_action.connect('activate', self._activate_party_button)
        app.add_action(party_action)
        app.set_accels_for_action("app.party", ["<Control>p"])

        self._search_button = builder.get_object('search-button')
        search_action = Gio.SimpleAction.new('search', None)
        search_action.connect('activate', self._on_search_button_clicked)
        app.add_action(search_action)
        app.set_accels_for_action("app.search", ["<Control>f"])

        self._settings_button = builder.get_object('settings-button')

        self._list_button = builder.get_object('list-button')
        self._list_button.set_property('has-tooltip', True)
        self._list_button.connect('query-tooltip',
                                  self._on_list_button_query_tooltip)
        list_action = Gio.SimpleAction.new('list', None)
        list_action.connect('activate', self._on_list_button_clicked)
        app.add_action(list_action)
        app.set_accels_for_action("app.list", ["<Control>l"])
        self._list_popover = None
        Lp().player.connect('party-changed', self._on_party_changed)

    def setup_menu(self, menu):
        """
            Add an application menu to menu button
            @parma: menu as Gio.Menu
        """
        self._settings_button.show()
        self._settings_button.set_menu_model(menu)

    def on_status_changed(self, player):
        """
            Update buttons on status changed
            @param player as Player
        """
        if player.is_playing():
            # Party mode can be activated
            # via Fullscreen class, so check button state
            self._party_button.set_active(player.is_party())

    def on_next_changed(self, player, force=False):
        """
            Show next popover
            @param player as Player
            @param force to show the popover
        """
        # Do not show popover is this menu is active
        # or if we are hidden
        if self._shuffle_button.get_active() or\
           not self._grid_next.is_visible():
            return
        self._timeout_id = None
        if self._next_popover.should_be_shown() or force:
            self._next_popover.update()
            if not self._next_popover.is_visible():
                self._next_popover.set_relative_to(self._grid_next)
                self._next_popover.show()
        else:
            self._next_popover.hide()

#######################
# PRIVATE             #
#######################

    def _on_shuffle_button_clicked(self, button):
        """
            Hide next popover
            @param button as Gtk.Button
        """
        self._next_popover.hide()

    def _on_button_press(self, button, event):
        """
            Show next popover on long press
            @param button as Gtk.Button
            @param event as Gdk.Event
        """
        self._timeout_id = GLib.timeout_add(500, self.on_next_changed,
                                            Lp().player, True)

    def _on_button_release(self, button, event):
        """
            If next popover shown, block event
            @param button as Gtk.Button
            @param event as Gdk.Event
        """
        if self._timeout_id is None:
            return True
        else:
            GLib.source_remove(self._timeout_id)
            self._timeout_id = None

    def _set_shuffle_icon(self):
        """
            Set shuffle icon
        """
        shuffle = Lp().settings.get_enum('shuffle')
        if shuffle == Shuffle.NONE:
            self._shuffle_image.get_style_context().remove_class('selected')
            self._shuffle_image.set_from_icon_name(
                "media-playlist-consecutive-symbolic",
                Gtk.IconSize.SMALL_TOOLBAR)
        else:
            self._shuffle_image.set_from_icon_name(
                "media-playlist-shuffle-symbolic", Gtk.IconSize.SMALL_TOOLBAR)
            if shuffle == Shuffle.TRACKS:
                self._shuffle_image.get_style_context().add_class('selected')
            else:
                self._shuffle_image.get_style_context().remove_class(
                    'selected')

    def _activate_party_button(self, action=None, param=None):
        """
            Activate party button
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        self._party_button.set_active(not self._party_button.get_active())
        Lp().window.responsive_design()

    def _activate_shuffle_button(self, action=None, param=None):
        """
            Activate shuffle button
            @param action as Gio.SimpleAction
            @param param as GLib.Variant
        """
        self._shuffle_button.set_active(not self._shuffle_button.get_active())

    def _on_shuffle_changed(self, settings, value):
        """
            Mark shuffle button as active when shuffle active
            @param settings as Gio.Settings, value as str
        """
        self._set_shuffle_icon()
        self._next_popover.hide()

    def _on_search_button_clicked(self, obj, param=None):
        """
            Show search widget on search button clicked
            @param obj as Gtk.Button or Gtk.Action
        """
        if self._search is None:
            self._search = SearchPopover()
            self._search.connect('closed', self._on_popover_closed)
        self._search.set_relative_to(self._search_button)
        self._next_popover.hide()
        self._search.show()

    def _on_party_button_toggled(self, button):
        """
            Set party mode on if party button active
            @param obj as Gtk.button
        """
        active = self._party_button.get_active()
        self._shuffle_button.set_sensitive(not active)
        if not Lp().settings.get_value('dark-ui'):
            settings = Gtk.Settings.get_default()
            settings.set_property("gtk-application-prefer-dark-theme", active)
        Lp().player.set_party(active)
        self.on_next_changed(Lp().player)

    def _on_party_changed(self, player, is_party):
        """
            On party change, sync toolbar
            @param player as Player
            @param is party as bool
        """
        if self._party_button.get_active() != is_party:
            self._activate_party_button()

    def _on_list_button_clicked(self, widget, unused=None):
        """
            Show current playback context popover
            @param widget as Gtk.Widget
        """
        if self._list_popover is not None:
            return
        self._next_popover.hide()
        if Lp().player.current_track.id == Type.EXTERNALS:
            self._list_popover = ExternalsPopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.populate()
            self._list_popover.show()
        elif Lp().player.get_queue():
            self._list_popover = QueuePopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.show()
        elif Lp().player.get_user_playlist_ids():
            self._list_popover = PlaylistsPopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.show()
        else:
            self._list_popover = AlbumsPopover()
            self._list_popover.set_relative_to(self._list_button)
            self._list_popover.show()
        self._list_popover.connect('closed', self._on_list_popover_closed)
        return True

    def _on_list_popover_closed(self, popover):
        """
            Reset variable
            @param popover as Gtk.Popover
        """
        self._list_popover = None
        self._on_popover_closed(popover)

    def _on_popover_closed(self, popover):
        """
            Restore next popover if needed
            @param popover as Gtk.Popover
        """
        if self._next_popover.should_be_shown():
            self._next_popover.show()

    def _on_show(self, widget):
        """
            Show popover if needed
            @param widget as Gtk.Widget
        """
        self._set_shuffle_icon()

    def _on_hide(self, widget):
        """
            Hide popover
            @param widget as Gtk.Widget
        """
        self._next_popover.hide()

    def _on_list_button_query_tooltip(self, widget, x, y, keyboard, tooltip):
        """
            Show tooltip
            @param widget as Gtk.Widget
            @param x as int
            @param y as int
            @param keyboard as bool
            @param tooltip as Gtk.Tooltip
        """
        if Lp().player.current_track.id == Type.EXTERNALS:
            widget.set_tooltip_text(_("Externals tracks playing"))
        elif Lp().player.get_queue():
            widget.set_tooltip_text(_("Queue"))
        elif Lp().player.get_user_playlist_ids():
            widget.set_tooltip_text(_("Playing playlists"))
        else:
            widget.set_tooltip_text(_("Playing albums"))