Example #1
0
 def __on_info_short(self, args):
     """
         Show track information popover
         @param args as []
     """
     if Lp().player.current_track.id == Type.EXTERNALS:
         from lollypop.pop_externals import ExternalsPopover
         expopover = ExternalsPopover()
         expopover.set_relative_to(self._infobox)
         expopover.populate()
         expopover.show()
     elif Lp().player.current_track.id is not None:
         if Lp().player.current_track.id == Type.RADIOS:
             if self.__pop_tunein is None:
                 from lollypop.pop_tunein import TuneinPopover
                 self.__pop_tunein = TuneinPopover()
                 self.__pop_tunein.populate()
                 self.__pop_tunein.set_relative_to(self._infobox)
             self.__pop_tunein.show()
         else:
             if self.__pop_info is None:
                 from lollypop.pop_info import InfoPopover
                 self.__pop_info = InfoPopover()
                 self.__pop_info.set_relative_to(self._infobox)
             self.__pop_info.show()
Example #2
0
 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:
                 if self._pop_tunein is None:
                     self._pop_tunein = TuneinPopover()
                     self._pop_tunein.populate()
                     self._pop_tunein.set_relative_to(self._infobox)
                 self._pop_tunein.show()
             else:
                 if self._pop_infos is None:
                     self._pop_infos = InfosPopover()
                     self._pop_infos.set_relative_to(self._infobox)
                 self._pop_infos.show()
         elif Lp().player.current_track.id >= 0:
             popover = TrackMenuPopover(
                 Lp().player.current_track.id,
                 PopToolbarMenu(Lp().player.current_track.id))
             popover.set_relative_to(self._infobox)
             popover.show()
         return True
Example #3
0
 def _on_title_release_event(self, widget, event):
     """
         Show track information popover
         On long press/right click: show current track menu
         @param widget as Gtk.Widget
         @param event as Gdk.Event
     """
     if self._timeout_id is not None:
         GLib.source_remove(self._timeout_id)
         self._timeout_id = None
         if Lp().player.current_track.id == Type.EXTERNALS:
             expopover = ExternalsPopover()
             expopover.set_relative_to(widget)
             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:
                     if self._pop_tunein is None:
                         self._pop_tunein = TuneinPopover()
                         self._pop_tunein.populate()
                         self._pop_tunein.set_relative_to(widget)
                     self._pop_tunein.show()
                 else:
                     if self._pop_info is None:
                         self._pop_info = InfoPopover()
                         self._pop_info.set_relative_to(widget)
                     self._pop_info.show()
             else:
                 self._show_track_menu()
     return True
Example #4
0
 def _on_search_clicked(self, widget):
     """
         Show popover for searching radios
         @param widget as Gtk.Widget
     """
     if self.__pop_tunein is None:
         self.__pop_tunein = TuneinPopover(self.__radios)
         self.__pop_tunein.populate()
     self.__pop_tunein.set_relative_to(widget)
     self.__pop_tunein.popup()
Example #5
0
 def __init__(self):
     """
         Init view
     """
     FlowBoxView.__init__(self)
     ViewController.__init__(self, ViewControllerType.RADIO)
     self._widget_class = RadioWidget
     self.__radios = Radios()
     builder = Gtk.Builder()
     builder.add_from_resource("/org/gnome/Lollypop/RadiosView.ui")
     builder.connect_signals(self)
     self.insert_row(0)
     self.attach(builder.get_object("widget"), 0, 0, 1, 1)
     self.__pop_tunein = TuneinPopover(self.__radios)
     self.__pop_tunein.set_relative_to(builder.get_object("search_btn"))
 def __on_info_short(self, args):
     """
         Show track information popover
         @param args as []
     """
     if Lp().player.current_track.id == Type.EXTERNALS:
         from lollypop.pop_externals import ExternalsPopover
         expopover = ExternalsPopover()
         expopover.set_relative_to(self._infobox)
         expopover.populate()
         expopover.show()
     elif Lp().player.current_track.id is not None:
         if Lp().player.current_track.id == Type.RADIOS:
             if self.__pop_tunein is None:
                 from lollypop.pop_tunein import TuneinPopover
                 self.__pop_tunein = TuneinPopover()
                 self.__pop_tunein.populate()
                 self.__pop_tunein.set_relative_to(self._infobox)
             self.__pop_tunein.show()
         else:
             if self.__pop_info is None:
                 from lollypop.pop_info import InfoPopover
                 self.__pop_info = InfoPopover()
                 self.__pop_info.set_relative_to(self._infobox)
             self.__pop_info.show()
Example #7
0
    def __init__(self):
        View.__init__(self)

        self._signal = None

        self._radios_manager = RadiosManager()
        self._radios_manager.connect('playlists-changed',
                                     self._on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')

        self._pop_tunein = TuneinPopover(self._radios_manager)
        self._pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._sizegroup = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.BOTH)

        self._radiobox = Gtk.FlowBox()
        self._radiobox.set_sort_func(self._sort_radios)
        self._radiobox.set_selection_mode(Gtk.SelectionMode.NONE)
        self._radiobox.connect("child-activated", self._on_album_activated)
        self._radiobox.set_property('column-spacing', 5)
        self._radiobox.set_property('row-spacing', 5)
        self._radiobox.set_homogeneous(True)
        self._radiobox.set_max_children_per_line(1000)
        self._radiobox.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._viewport.add(self._radiobox)
        self._scrolledWindow.set_property('expand', True)

        self.add(widget)
        self.add(self._scrolledWindow)
Example #8
0
 def _on_title_release_event(self, widget, event):
     """
         Show track information popover
         On long press/right click: show current track menu
         @param widget as Gtk.Widget
         @param event as Gdk.Event
     """
     if self._timeout_id is not None:
         GLib.source_remove(self._timeout_id)
         self._timeout_id = None
         if Lp().player.current_track.id == Type.EXTERNALS:
             expopover = ExternalsPopover()
             expopover.set_relative_to(widget)
             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:
                     if self._pop_tunein is None:
                         self._pop_tunein = TuneinPopover()
                         self._pop_tunein.populate()
                         self._pop_tunein.set_relative_to(widget)
                     self._pop_tunein.show()
                 else:
                     if self._pop_info is None:
                         self._pop_info = InfoPopover()
                         self._pop_info.set_relative_to(widget)
                     self._pop_info.show()
             else:
                 self._show_track_menu()
     return True
Example #9
0
 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:
                 if self._pop_tunein is None:
                     self._pop_tunein = TuneinPopover()
                     self._pop_tunein.populate()
                     self._pop_tunein.set_relative_to(self._infobox)
                 self._pop_tunein.show()
             else:
                 if self._pop_infos is None:
                     self._pop_infos = InfosPopover()
                     self._pop_infos.set_relative_to(self._infobox)
                 self._pop_infos.show()
         elif Lp().player.current_track.id >= 0:
             menu = PopToolbarMenu(Lp().player.current_track.id)
             popover = TrackMenuPopover(
                         Lp().player.current_track.id,
                         PopToolbarMenu(Lp().player.current_track.id))
             popover.set_relative_to(self._infobox)
             popover.show()
         return True
Example #10
0
    def __init__(self):
        """
            Init view
        """
        View.__init__(self)

        self._signal = None

        self._radios_manager = RadiosManager()
        self._radios_manager.connect('playlists-changed',
                                     self._on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')
        self._empty = builder.get_object('empty')

        self._pop_tunein = TuneinPopover(self._radios_manager)
        self._pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._sizegroup = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.BOTH)

        self._radiobox = Gtk.FlowBox()
        self._radiobox.set_sort_func(self._sort_radios)
        self._radiobox.set_selection_mode(Gtk.SelectionMode.NONE)
        self._radiobox.connect("child-activated", self._on_album_activated)
        self._radiobox.set_property('column-spacing', 5)
        self._radiobox.set_property('row-spacing', 5)
        self._radiobox.set_homogeneous(True)
        self._radiobox.set_max_children_per_line(1000)
        self._radiobox.show()

        self._stack = Gtk.Stack()
        self._stack.set_transition_duration(500)
        self._stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self._stack.add(self._scrolledWindow)
        self._stack.add(self._empty)
        self._stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._viewport.add(self._radiobox)
        self._scrolledWindow.set_property('expand', True)

        self.add(widget)
        self.add(self._stack)
Example #11
0
    def __init__(self):
        """
            Init view
        """
        LazyLoadingView.__init__(self, True)
        self.__signal = Lp().art.connect("radio-artwork-changed",
                                         self.__on_logo_changed)

        self.__radios_manager = Radios()
        self.__radios_manager.connect("radios-changed",
                                      self.__on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource("/org/gnome/Lollypop/RadiosView.ui")
        builder.connect_signals(self)
        widget = builder.get_object("widget")
        self.__empty = builder.get_object("empty")

        self.__pop_tunein = TuneinPopover(self.__radios_manager)
        self.__pop_tunein.set_relative_to(builder.get_object("search_btn"))

        self._box = Gtk.FlowBox()
        self._box.set_selection_mode(Gtk.SelectionMode.NONE)
        # Allow lazy loading to not jump up and down
        self._box.set_homogeneous(True)
        self._box.set_max_children_per_line(1000)
        self._box.set_filter_func(self._filter_func)
        self._box.show()

        self.__stack = Gtk.Stack()
        self.__stack.set_transition_duration(500)
        self.__stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self.__stack.add(self._scrolled)
        self.__stack.add(self.__empty)
        self.__stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property("margin", 5)
        self._scrolled.set_property("expand", True)

        self.add(widget)
        self.add(self.__stack)
Example #12
0
    def __init__(self):
        """
            Init view
        """
        LazyLoadingView.__init__(self)
        self._signal = Lp().art.connect('radio-artwork-changed',
                                        self._on_logo_changed)

        self._radios_manager = Radios()
        self._radios_manager.connect('radios-changed', self._on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')
        self._empty = builder.get_object('empty')

        self._pop_tunein = TuneinPopover(self._radios_manager)
        self._pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._radiobox = Gtk.FlowBox()
        self._radiobox.set_selection_mode(Gtk.SelectionMode.NONE)
        self._radiobox.set_property('column-spacing', 5)
        self._radiobox.set_property('row-spacing', 5)
        self._radiobox.set_homogeneous(True)
        self._radiobox.set_max_children_per_line(1000)
        self._radiobox.show()

        self._stack = Gtk.Stack()
        self._stack.set_transition_duration(500)
        self._stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self._stack.add(self._scrolled)
        self._stack.add(self._empty)
        self._stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._scrolled.set_property('expand', True)

        self.add(widget)
        self.add(self._stack)
Example #13
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)
Example #14
0
    def __init__(self):
        """
            Init view
        """
        View.__init__(self)
        self._signal = Lp().art.connect('radio-artwork-changed',
                                        self._on_logo_changed)

        self._radios_manager = Radios()
        self._radios_manager.connect('radios-changed',
                                     self._on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')
        self._empty = builder.get_object('empty')

        self._pop_tunein = TuneinPopover(self._radios_manager)
        self._pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._sizegroup = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.BOTH)

        self._radiobox = Gtk.FlowBox()
        self._radiobox.set_selection_mode(Gtk.SelectionMode.NONE)
        self._radiobox.connect("child-activated", self._on_album_activated)
        self._radiobox.set_property('column-spacing', 5)
        self._radiobox.set_property('row-spacing', 5)
        self._radiobox.set_homogeneous(True)
        self._radiobox.set_max_children_per_line(1000)
        self._radiobox.show()

        self._stack = Gtk.Stack()
        self._stack.set_transition_duration(500)
        self._stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self._stack.add(self._scrolled)
        self._stack.add(self._empty)
        self._stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._viewport.add(self._radiobox)
        self._scrolled.set_property('expand', True)

        self.add(widget)
        self.add(self._stack)
Example #15
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)
Example #16
0
    def __init__(self):
        """
            Init view
        """
        LazyLoadingView.__init__(self, True)
        self.__signal = Lp().art.connect('radio-artwork-changed',
                                         self.__on_logo_changed)

        self.__radios_manager = Radios()
        self.__radios_manager.connect('radios-changed',
                                      self.__on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')
        self.__empty = builder.get_object('empty')

        self.__pop_tunein = TuneinPopover(self.__radios_manager)
        self.__pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._box = Gtk.FlowBox()
        self._box.set_selection_mode(Gtk.SelectionMode.NONE)
        # Allow lazy loading to not jump up and down
        self._box.set_homogeneous(True)
        self._box.set_max_children_per_line(1000)
        self._box.set_filter_func(self._filter_func)
        self._box.show()

        self.__stack = Gtk.Stack()
        self.__stack.set_transition_duration(500)
        self.__stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self.__stack.add(self._scrolled)
        self.__stack.add(self.__empty)
        self.__stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._scrolled.set_property('expand', True)

        self.add(widget)
        self.add(self.__stack)
Example #17
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)

        self._pop_tunein = None
        self._pop_infos = None
        self._cover_size = ArtSize.SMALL

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

        self._labels = builder.get_object('nowplaying_labels')
        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover_frame = builder.get_object('frame')
        self._cover = builder.get_object('cover')

        Lp().art.connect('album-artwork-changed', self._update_cover)
        Lp().art.connect('radio-artwork-changed', self._update_logo)

    def get_preferred_height(self):
        """
            Return preferred height
            @return (int, int)
        """
        return self._labels.get_preferred_height()

    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_artwork(
                player.current_track.artist,
                self._cover_size * self.get_scale_factor())
        elif player.current_track.id == Type.EXTERNALS:
            art = Lp().art.get_album_artwork2(
                player.current_track.uri,
                self._cover_size * self.get_scale_factor())
        elif player.current_track.id is not None:
            art = Lp().art.get_album_artwork(
                player.current_track.album,
                self._cover_size * 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_frame.show()
        else:
            self._cover_frame.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:
            surface = Lp().art.get_album_artwork(
                Lp().player.current_track.album, self._cover_size)
            self._cover.set_from_surface(surface)
            del surface

    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_artwork(name, self._cover_size)
            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:
                    if self._pop_tunein is None:
                        self._pop_tunein = TuneinPopover()
                        self._pop_tunein.populate()
                        self._pop_tunein.set_relative_to(self._infobox)
                    self._pop_tunein.show()
                else:
                    if self._pop_infos is None:
                        self._pop_infos = InfosPopover()
                        self._pop_infos.set_relative_to(self._infobox)
                    self._pop_infos.show()
            elif Lp().player.current_track.id >= 0:
                popover = TrackMenuPopover(
                    Lp().player.current_track.id,
                    PopToolbarMenu(Lp().player.current_track.id))
                popover.set_relative_to(self._infobox)
                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
        """
        style = self.get_style_context()
        padding = style.get_padding(style.get_state())
        self._cover_size = self.get_allocated_height()\
            - padding.top - padding.bottom - 2
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
Example #18
0
class RadiosView(View):
    """
        Show radios in a grid
    """

    def __init__(self):
        """
            Init view
        """
        View.__init__(self)
        self._signal = Lp().art.connect('radio-artwork-changed',
                                        self._on_logo_changed)

        self._radios_manager = Radios()
        self._radios_manager.connect('radios-changed',
                                     self._on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')
        self._empty = builder.get_object('empty')

        self._pop_tunein = TuneinPopover(self._radios_manager)
        self._pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._sizegroup = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.BOTH)

        self._radiobox = Gtk.FlowBox()
        self._radiobox.set_selection_mode(Gtk.SelectionMode.NONE)
        self._radiobox.connect("child-activated", self._on_album_activated)
        self._radiobox.set_property('column-spacing', 5)
        self._radiobox.set_property('row-spacing', 5)
        self._radiobox.set_homogeneous(True)
        self._radiobox.set_max_children_per_line(1000)
        self._radiobox.show()

        self._stack = Gtk.Stack()
        self._stack.set_transition_duration(500)
        self._stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self._stack.add(self._scrolled)
        self._stack.add(self._empty)
        self._stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._viewport.add(self._radiobox)
        self._scrolled.set_property('expand', True)

        self.add(widget)
        self.add(self._stack)

    def populate(self):
        """
            Populate view with tracks from playlist
            Thread safe
        """
        Lp().player.set_radios(self._radios_manager.get())
        if Lp().player.current_track.id == Type.RADIOS:
            Lp().player.set_next()  # We force next update
            Lp().player.set_prev()  # We force prev update
        t = Thread(target=self._populate)
        t.daemon = True
        t.start()

#######################
# PRIVATE             #
#######################
    def _populate(self):
        """
            Populate view with tracks from playlist
            Thread safe
        """
        radios = []
        # Get radios name
        for (name, url) in self._radios_manager.get():
            radios.append(name)
        GLib.idle_add(self._show_stack, radios)

    def _get_children(self):
        """
            Return view children
            @return [RadioWidget]
        """
        children = []
        for child in self._radiobox.get_children():
            widget = child.get_child()
            children.append(widget)
        return children

    def _on_destroy(self, widget):
        """
            Disconnect signals
            @param widget as Gtk.Widget
        """
        if self._signal is not None:
            Lp().art.disconnect(self._signal)

    def _on_new_clicked(self, widget):
        """
            Show popover for adding a new radio
            @param widget as Gtk.Widget
        """
        popover = RadioPopover('', self._radios_manager)
        popover.set_relative_to(widget)
        popover.show()

    def _on_search_clicked(self, widget):
        """
            Show popover for searching radios
            @param widget as Gtk.Widget
        """
        self._pop_tunein.populate()
        self._pop_tunein.show()

    def _on_radios_changed(self, manager):
        """
            Update radios
            @param manager as PlaylistManager
        """
        radios_name = []
        currents = []
        new_name = None
        old_widget = None
        old_child = None

        # Get radios name
        for (name, url) in manager.get():
            radios_name.append(name)

        # Get currents widget less removed
        for child in self._radiobox.get_children():
            widget = child.get_child()
            if widget.get_name() not in radios_name:
                old_widget = widget
                old_child = child
            else:
                currents.append(widget.get_name())

        # Add the new radio
        for name in radios_name:
            if name not in currents:
                new_name = name
                break

        # Rename widget
        if new_name is not None:
            if old_widget is not None:
                old_widget.set_name(new_name)
            else:
                radios = [new_name]
                self._show_stack(radios)
        # Delete widget
        elif old_widget is not None:
            self._radiobox.remove(old_child)
            old_widget.destroy()
            if not self._radiobox.get_children():
                self._show_stack([])

        # Update player state based on current view
        radios = []
        for child in self._radiobox.get_children():
            widget = child.get_child()
            name = widget.get_name()
            url = manager.get_url(name)
            radios.append((name, url))
        Lp().player.set_radios(radios)
        if Lp().player.current_track.id == Type.RADIOS:
            Lp().player.set_next()  # We force next update
            Lp().player.set_prev()  # We force prev update

    def _on_logo_changed(self, player, name):
        """
            Update radio logo
            @param player as Plyaer
            @param name as string
        """
        for child in self._radiobox.get_children():
            widget = child.get_child()
            if widget.get_name() == name:
                widget.update_cover()

    def _show_stack(self, radios):
        """
            Switch empty/radios view based on radios
            @param [radio names as string]
        """
        if radios:
            self._stack.set_visible_child(self._scrolled)
            self._add_radios(radios, True)
        else:
            self._stack.set_visible_child(self._empty)

    def _add_radios(self, radios, first=False):
        """
            Pop a radio and add it to the view,
            repeat operation until radio list is empty
            @param [radio names as string]
            @param first as bool
        """
        if radios and not self._stop:
            radio = radios.pop(0)
            widget = RadioWidget(radio,
                                 self._radios_manager)
            widget.show()
            self._sizegroup.add_widget(widget)
            if first:
                self._radiobox.insert(widget, 0)
            else:
                self._radiobox.insert(widget, -1)
            GLib.idle_add(self._add_radios, radios)
        else:
            self._stop = False
        return None

    def _on_album_activated(self, flowbox, child):
        """
            Play album
            @param flowbox as Gtk.Flowbox
            @child as Gtk.FlowboxChild
        """
        name = child.get_child().get_name()
        url = self._radios_manager.get_url(name)
        if url:
            track = Track()
            track.set_radio(name, url)
            Lp().player.load(track)
Example #19
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)

        self._pop_tunein = None
        self._pop_infos = None

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

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')

        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,
                                   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(Lp.player.current_track.album,
                                      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:
                    if self._pop_tunein is None:
                        self._pop_tunein = TuneinPopover()
                        self._pop_tunein.populate()
                        self._pop_tunein.set_relative_to(self._infobox)
                    self._pop_tunein.show()
                else:
                    if self._pop_infos is None:
                        self._pop_infos = InfosPopover()
                        self._pop_infos.set_relative_to(self._infobox)
                    self._pop_infos.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_margin_top(5)
                rating.set_margin_bottom(5)
                rating.set_property('halign', Gtk.Align.START)
                rating.set_property('hexpand', True)
                rating.show()
                loved = LovedWidget(Lp.player.current_track.id)
                loved.set_margin_end(5)
                loved.set_margin_top(5)
                loved.set_margin_bottom(5)
                loved.set_property('halign', Gtk.Align.END)
                loved.set_property('hexpand', True)
                loved.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)
                hgrid = Gtk.Grid()
                hgrid.add(rating)
                hgrid.add(loved)
                hgrid.show()
                grid.add(hgrid)
                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))
Example #20
0
 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:
                 if self._pop_tunein is None:
                     self._pop_tunein = TuneinPopover()
                     self._pop_tunein.populate()
                     self._pop_tunein.set_relative_to(self._infobox)
                 self._pop_tunein.show()
             else:
                 if self._pop_infos is None:
                     self._pop_infos = InfosPopover()
                     self._pop_infos.set_relative_to(self._infobox)
                 self._pop_infos.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_margin_top(5)
             rating.set_margin_bottom(5)
             rating.set_property('halign', Gtk.Align.START)
             rating.set_property('hexpand', True)
             rating.show()
             loved = LovedWidget(Lp.player.current_track.id)
             loved.set_margin_end(5)
             loved.set_margin_top(5)
             loved.set_margin_bottom(5)
             loved.set_property('halign', Gtk.Align.END)
             loved.set_property('hexpand', True)
             loved.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)
             hgrid = Gtk.Grid()
             hgrid.add(rating)
             hgrid.add(loved)
             hgrid.show()
             grid.add(hgrid)
             popover.add(stack)
             popover.show()
         return True
Example #21
0
class RadiosView(View):
    """
        Show radios in a grid
    """
    def __init__(self):
        """
            Init view
        """
        View.__init__(self)
        self._signal = Lp().art.connect('radio-artwork-changed',
                                        self._on_logo_changed)

        self._radios_manager = Radios()
        self._radios_manager.connect('radios-changed', self._on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')
        self._empty = builder.get_object('empty')

        self._pop_tunein = TuneinPopover(self._radios_manager)
        self._pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._sizegroup = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.BOTH)

        self._radiobox = Gtk.FlowBox()
        self._radiobox.set_selection_mode(Gtk.SelectionMode.NONE)
        self._radiobox.connect("child-activated", self._on_album_activated)
        self._radiobox.set_property('column-spacing', 5)
        self._radiobox.set_property('row-spacing', 5)
        self._radiobox.set_homogeneous(True)
        self._radiobox.set_max_children_per_line(1000)
        self._radiobox.show()

        self._stack = Gtk.Stack()
        self._stack.set_transition_duration(500)
        self._stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self._stack.add(self._scrolledWindow)
        self._stack.add(self._empty)
        self._stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._viewport.add(self._radiobox)
        self._scrolledWindow.set_property('expand', True)

        self.add(widget)
        self.add(self._stack)

    def populate(self):
        """
            Populate view with tracks from playlist
            Thread safe
        """
        t = Thread(target=self._populate)
        t.daemon = True
        t.start()

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

    def _populate(self):
        """
            Populate view with tracks from playlist
            Thread safe
        """
        radios = []
        # Get radios name
        for (name, url) in self._radios_manager.get():
            radios.append(name)
        GLib.idle_add(self._show_stack, radios)

    def _get_children(self):
        """
            Return view children
            @return [RadioWidget]
        """
        children = []
        for child in self._radiobox.get_children():
            widget = child.get_child()
            children.append(widget)
        return children

    def _on_destroy(self, widget):
        """
            Disconnect signals
            @param widget as Gtk.Widget
        """
        if self._signal is not None:
            Lp().art.disconnect(self._signal)

    def _on_new_clicked(self, widget):
        """
            Show popover for adding a new radio
            @param widget as Gtk.Widget
        """
        popover = RadioPopover('', self._radios_manager)
        popover.set_relative_to(widget)
        popover.show()

    def _on_search_clicked(self, widget):
        """
            Show popover for searching radios
            @param widget as Gtk.Widget
        """
        self._pop_tunein.populate()
        self._pop_tunein.show()

    def _on_radios_changed(self, manager):
        """
            Update radios
            @param manager as PlaylistManager
        """
        radios_name = []
        currents = []
        new_name = None
        old_widget = None
        old_child = None

        # Get radios name
        for (name, url) in manager.get():
            radios_name.append(name)

        # Get currents widget less removed
        for child in self._radiobox.get_children():
            widget = child.get_child()
            if widget.get_name() not in radios_name:
                old_widget = widget
                old_child = child
            else:
                currents.append(widget.get_name())

        # Add the new radio
        for name in radios_name:
            if name not in currents:
                new_name = name
                break

        # Rename widget
        if new_name is not None:
            if old_widget is not None:
                old_widget.set_name(new_name)
            else:
                radios = [new_name]
                self._show_stack(radios)
        # Delete widget
        elif old_widget is not None:
            self._radiobox.remove(old_child)
            old_widget.destroy()
            if not self._radiobox.get_children():
                self._show_stack([])

    def _on_logo_changed(self, player, name):
        """
            Update radio logo
            @param player as Plyaer
            @param name as string
        """
        for child in self._radiobox.get_children():
            widget = child.get_child()
            if widget.get_name() == name:
                widget.update_cover()

    def _show_stack(self, radios):
        """
            Switch empty/radios view based on radios
            @param [radio names as string]
        """
        if radios:
            self._stack.set_visible_child(self._scrolledWindow)
            self._add_radios(radios, True)
        else:
            self._stack.set_visible_child(self._empty)

    def _add_radios(self, radios, first=False):
        """
            Pop a radio and add it to the view,
            repeat operation until radio list is empty
            @param [radio names as string]
            @param first as bool
        """
        if radios and not self._stop:
            radio = radios.pop(0)
            widget = RadioWidget(radio, self._radios_manager)
            widget.show()
            self._sizegroup.add_widget(widget)
            if first:
                self._radiobox.insert(widget, 0)
            else:
                self._radiobox.insert(widget, -1)
            GLib.idle_add(self._add_radios, radios)
        else:
            self._stop = False
        return None

    def _on_album_activated(self, flowbox, child):
        """
            Play album
            @param flowbox as Gtk.Flowbox
            @child as Gtk.FlowboxChild
        """
        name = child.get_child().get_name()
        url = self._radios_manager.get_url(name)
        if url:
            track = Track()
            track.set_radio(name, url)
            Lp().player.load(track)
Example #22
0
class RadiosView(FlowBoxView, ViewController):
    """
        Show radios flow box
    """
    def __init__(self, view_type=ViewType.SCROLLED):
        """
            Init view
            @param view_type as ViewType
        """
        FlowBoxView.__init__(self, view_type)
        ViewController.__init__(self, ViewControllerType.RADIO)
        self._widget_class = RadioWidget
        self._empty_icon_name = get_icon_name(Type.RADIOS)
        self.__radios = Radios()
        builder = Gtk.Builder()
        builder.add_from_resource("/org/gnome/Lollypop/RadiosView.ui")
        builder.connect_signals(self)
        self.insert_row(0)
        self.attach(builder.get_object("widget"), 0, 0, 1, 1)
        self.__pop_tunein = None
        if not get_network_available("TUNEIN"):
            builder.get_object("search_btn").hide()

    def populate(self, radio_ids):
        """
            Add radio widgets
            @param radio_ids as [int]
        """
        FlowBoxView.populate(self, radio_ids)

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

    def _add_items(self, radio_ids):
        """
            Add radios to the view
            Start lazy loading
            @param radio ids as [int]
        """
        self._remove_placeholder()
        widget = FlowBoxView._add_items(self, radio_ids, self.__radios,
                                        self._view_type)
        if widget is not None:
            widget.connect("overlayed", self.on_overlayed)

    def _on_new_clicked(self, widget):
        """
            Show popover for adding a new radio
            @param widget as Gtk.Widget
        """
        from lollypop.pop_radio import RadioPopover
        popover = RadioPopover(None, self.__radios)
        popover.set_relative_to(widget)
        popover.popup()

    def _on_search_clicked(self, widget):
        """
            Show popover for searching radios
            @param widget as Gtk.Widget
        """
        if self.__pop_tunein is None:
            self.__pop_tunein = TuneinPopover(self.__radios)
            self.__pop_tunein.populate()
        self.__pop_tunein.set_relative_to(widget)
        self.__pop_tunein.popup()

    def _on_artwork_changed(self, artwork, name):
        """
            Update children artwork if matching name
            @param artwork as Artwork
            @param name as str
        """
        for child in self._box.get_children():
            if name == child.name:
                child.set_artwork()

    def _on_map(self, widget):
        """
            Set active ids
        """
        FlowBoxView._on_map(self, widget)
        if not App().settings.get_value("show-sidebar"):
            App().window.emit("show-can-go-back", True)
            App().window.emit("can-go-back-changed", True)
        self.__signal_id = self.__radios.connect("radio-changed",
                                                 self.__on_radio_changed)
        App().settings.set_value("state-one-ids",
                                 GLib.Variant("ai", [Type.RADIOS]))
        App().settings.set_value("state-two-ids", GLib.Variant("ai", []))
        App().settings.set_value("state-three-ids", GLib.Variant("ai", []))

    def _on_unmap(self, widget):
        """
            Destroy popover
            @param widget as Gtk.Widget
        """
        FlowBoxView._on_unmap(self, widget)
        if self.__signal_id is not None:
            self.__radios.disconnect(self.__signal_id)
            self.__signal_id = None
        if self.__pop_tunein is not None:
            self.__pop_tunein.destroy()
            self.__pop_tunein = None

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

    def __on_radio_changed(self, radios, radio_id):
        """
            Update view based on radio_id status
            @param radios as Radios
            @param radio_id as int
        """
        exists = radios.exists(radio_id)
        if exists:
            item = None
            for child in self._box.get_children():
                if child.id == radio_id:
                    item = child
                    break
            if item is None:
                self._add_items([radio_id])
            else:
                name = self.__radios.get_name(radio_id)
                item.rename(name)
        else:
            for child in self._box.get_children():
                if child.id == radio_id:
                    child.destroy()
Example #23
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))
Example #24
0
class RadiosView(LazyLoadingView):
    """
        Show radios in a grid
    """
    def __init__(self):
        """
            Init view
        """
        LazyLoadingView.__init__(self, True)
        self.__signal = Lp().art.connect("radio-artwork-changed",
                                         self.__on_logo_changed)

        self.__radios_manager = Radios()
        self.__radios_manager.connect("radios-changed",
                                      self.__on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource("/org/gnome/Lollypop/RadiosView.ui")
        builder.connect_signals(self)
        widget = builder.get_object("widget")
        self.__empty = builder.get_object("empty")

        self.__pop_tunein = TuneinPopover(self.__radios_manager)
        self.__pop_tunein.set_relative_to(builder.get_object("search_btn"))

        self._box = Gtk.FlowBox()
        self._box.set_selection_mode(Gtk.SelectionMode.NONE)
        # Allow lazy loading to not jump up and down
        self._box.set_homogeneous(True)
        self._box.set_max_children_per_line(1000)
        self._box.set_filter_func(self._filter_func)
        self._box.show()

        self.__stack = Gtk.Stack()
        self.__stack.set_transition_duration(500)
        self.__stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self.__stack.add(self._scrolled)
        self.__stack.add(self.__empty)
        self.__stack.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property("margin", 5)
        self._scrolled.set_property("expand", True)

        self.add(widget)
        self.add(self.__stack)

    def populate(self):
        """
            Populate view with tracks from playlist
        """
        Lp().player.set_radios(self.__radios_manager.get())
        if Lp().player.current_track.id == Type.RADIOS:
            Lp().player.set_next()  # We force next update
            Lp().player.set_prev()  # We force prev update
        helper = TaskHelper()
        helper.run(self.__get_radios, callback=(self.__on_get_radios, ))

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

    def _get_children(self):
        """
            Return view children
            @return [RadioWidget]
        """
        children = []
        for child in self._box.get_children():
            children.append(child)
        return children

    def _on_destroy(self, widget):
        """
            Disconnect signals
            @param widget as Gtk.Widget
        """
        LazyLoadingView._on_destroy(self, widget)
        if self.__signal is not None:
            Lp().art.disconnect(self.__signal)

    def _on_new_clicked(self, widget):
        """
            Show popover for adding a new radio
            @param widget as Gtk.Widget
        """
        popover = RadioPopover("", self.__radios_manager)
        popover.set_relative_to(widget)
        popover.show()

    def _on_search_clicked(self, widget):
        """
            Show popover for searching radios
            @param widget as Gtk.Widget
        """
        self.__pop_tunein.populate()
        self.__pop_tunein.show()

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

    def __get_radios(self):
        """
            Get radios
            @return [name]
        """
        radios = []
        # Get radios name
        for (name, url) in self.__radios_manager.get():
            radios.append(name)
        return radios

    def __on_radios_changed(self, manager):
        """
            Update radios
            @param manager as PlaylistManager
        """
        radios_name = []
        currents = []
        new_name = None
        old_child = None

        # Get radios name
        for (name, url) in manager.get():
            radios_name.append(name)

        # Get currents widget less removed
        for child in self._box.get_children():
            if child.title not in radios_name:
                old_child = child
            else:
                currents.append(child.title)

        # Add the new radio
        for name in radios_name:
            if name not in currents:
                new_name = name
                break

        # Rename widget
        if new_name is not None:
            if old_child is not None:
                old_child.set_name(new_name)
            else:
                radios = [new_name]
                self.__show_stack(radios)
        # Delete widget
        elif old_child is not None:
            old_child.destroy()
            if not self._box.get_children():
                self.__show_stack([])

        # Update player state based on current view
        radios = []
        for child in self._box.get_children():
            name = child.title
            url = manager.get_url(name)
            radios.append((name, url))
        Lp().player.set_radios(radios)
        if Lp().player.current_track.id == Type.RADIOS:
            Lp().player.set_next()  # We force next update
            Lp().player.set_prev()  # We force prev update

    def __show_stack(self, radios):
        """
            Switch empty/radios view based on radios
            @param [radio names as string]
        """
        if radios:
            self.__stack.set_visible_child(self._scrolled)
            self.__add_radios(radios, True)
        else:
            self.__stack.set_visible_child(self.__empty)

    def __add_radios(self, radios, first=False):
        """
            Pop a radio and add it to the view,
            repeat operation until radio list is empty
            @param [radio names as string]
            @param first as bool
        """
        if self._stop:
            self._stop = False
            return
        if radios:
            radio = radios.pop(0)
            widget = RadioWidget(radio, self.__radios_manager)
            widget.connect("overlayed", self._on_overlayed)
            widget.show()
            self._lazy_queue.append(widget)
            if first:
                self._box.insert(widget, 0)
            else:
                self._box.insert(widget, -1)
            GLib.idle_add(self.__add_radios, radios)
        else:
            GLib.idle_add(self.lazy_loading)
            if self._viewport.get_child() is None:
                self._viewport.add(self._box)

    def __on_logo_changed(self, player, name):
        """
            Update radio logo
            @param player as Plyaer
            @param name as string
        """
        for child in self._box.get_children():
            if child.title == name:
                child.update_cover()

    def __on_get_radios(self, radios):
        """
            Switch empty/radios view based on radios
            @param [radio names as string]
        """
        if radios:
            self.__stack.set_visible_child(self._scrolled)
            self.__add_radios(radios, True)
        else:
            self.__stack.set_visible_child(self.__empty)
Example #25
0
class RadiosView(FlowBoxView, ViewController):
    """
        Show radios flow box
    """
    def __init__(self):
        """
            Init view
        """
        FlowBoxView.__init__(self)
        ViewController.__init__(self, ViewControllerType.RADIO)
        self._widget_class = RadioWidget
        self.__radios = Radios()
        builder = Gtk.Builder()
        builder.add_from_resource("/org/gnome/Lollypop/RadiosView.ui")
        builder.connect_signals(self)
        self.insert_row(0)
        self.attach(builder.get_object("widget"), 0, 0, 1, 1)
        self.__pop_tunein = TuneinPopover(self.__radios)
        self.__pop_tunein.set_relative_to(builder.get_object("search_btn"))

    def populate(self, radio_ids):
        """
            Add radio widgets
            @param radio_ids as [int]
        """
        if radio_ids:
            FlowBoxView.populate(self, radio_ids)
        else:
            self._scrolled.hide()
            view = MessageView(_("No favorite radios"))
            view.show()
            self.add(view)

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

    def _add_items(self, radio_ids):
        """
            Add radios to the view
            Start lazy loading
            @param radio ids as [int]
        """
        widget = FlowBoxView._add_items(self, radio_ids, self.__radios)
        if widget is not None:
            widget.connect("overlayed", self.on_overlayed)

    def _on_new_clicked(self, widget):
        """
            Show popover for adding a new radio
            @param widget as Gtk.Widget
        """
        from lollypop.pop_radio import RadioPopover
        popover = RadioPopover(None, self.__radios)
        popover.set_relative_to(widget)
        popover.popup()

    def _on_search_clicked(self, widget):
        """
            Show popover for searching radios
            @param widget as Gtk.Widget
        """
        self.__pop_tunein.populate()
        self.__pop_tunein.show()

    def _on_artwork_changed(self, artwork, name):
        """
            Update children artwork if matching name
            @param artwork as Artwork
            @param name as str
        """
        for child in self._box.get_children():
            if name == child.name:
                child.set_artwork()

    def _on_map(self, widget):
        """
            Set active ids
        """
        self.__signal_id = self.__radios.connect("radio-changed",
                                                 self.__on_radio_changed)
        App().settings.set_value("state-one-ids",
                                 GLib.Variant("ai", [Type.RADIOS]))
        App().settings.set_value("state-two-ids", GLib.Variant("ai", []))

    def _on_unmap(self, widget):
        """
            Destroy popover
            @param widget as Gtk.Widget
        """
        if self.__signal_id is not None:
            self.__radios.disconnect(self.__signal_id)
            self.__signal_id = None
        self.__pop_tunein.destroy()

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

    def __add_radio(self, radio_id):
        """
            Add radio
            @param radio_id as int
        """
        widget = RadioWidget(radio_id, self.__radios)
        self._box.insert(widget, 0)
        widget.populate()
        widget.show()

    def __on_radio_changed(self, radios, radio_id):
        """
            Update view based on radio_id status
            @param radios as Radios
            @param radio_id as int
        """
        exists = radios.exists(radio_id)
        if exists:
            item = None
            for child in self._box.get_children():
                if child.id == radio_id:
                    item = child
                    break
            if item is None:
                self.__add_radio(radio_id)
            else:
                name = self.__radios.get_name(radio_id)
                item.rename(name)
        else:
            for child in self._box.get_children():
                if child.id == radio_id:
                    child.destroy()
Example #26
0
class ToolbarInfo(Gtk.Bin, InfosController):
    """
        Informations toolbar
    """
    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        InfosController.__init__(self, ArtSize.SMALL)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfo.ui')
        builder.connect_signals(self)
        self.__pop_tunein = None
        self.__pop_info = None
        self.__timeout_id = None
        self.__width = 0

        self._infobox = builder.get_object('info')
        self.add(self._infobox)

        helper = TouchHelper(self._infobox, None, None)
        helper.set_long_func(self.__on_info_long)
        helper.set_short_func(self.__on_info_short)

        self._spinner = builder.get_object('spinner')

        self.__labels = builder.get_object('nowplaying_labels')
        self.__labels.connect('query-tooltip', self.__on_query_tooltip)
        self.__labels.set_property('has-tooltip', True)

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')
        self._cover.set_property('has-tooltip', True)
        # Since GTK 3.20, we can set cover full height
        if Gtk.get_minor_version() > 18:
            self._cover.get_style_context().add_class('toolbar-cover-frame')
        else:
            self._cover.get_style_context().add_class('small-cover-frame')

        self.connect('realize', self.__on_realize)
        Lp().player.connect('loading-changed', self.__on_loading_changed)
        Lp().art.connect('album-artwork-changed', self.__update_cover)
        Lp().art.connect('radio-artwork-changed', self.__update_logo)

    def do_get_preferred_width(self):
        """
            We force preferred width
            @return (int, int)
        """
        return (self.__width, self.__width)

    def get_preferred_height(self):
        """
            Return preferred height
            @return (int, int)
        """
        return self.__labels.get_preferred_height()

    def set_width(self, width):
        """
            Set widget width
            @param width as int
        """
        self.__width = width
        self.set_property('width-request', width)

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

    def _on_eventbox_realize(self, eventbox):
        """
            Show hand cursor over
        """
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))

#######################
# 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:
            surface = Lp().art.get_album_artwork(
                Lp().player.current_track.album, self._artsize,
                self._cover.get_scale_factor())
            self._cover.set_from_surface(surface)
            del surface

    def __update_logo(self, art, name):
        """
            Update logo for name
            @param art as Art
            @param name as str
        """
        if Lp().player.current_track.album_artist == name:
            pixbuf = Lp().art.get_radio_artwork(name, self._artsize)
            self._cover.set_from_surface(pixbuf)
            del pixbuf

    def __on_info_long(self, args):
        """
            Show current track menu
            @param args as []
        """
        if Lp().player.current_track.id >= 0:
            from lollypop.pop_menu import PlaylistsMenu
            from lollypop.pop_menu import TrackMenuPopover
            popover = TrackMenuPopover(
                Lp().player.current_track,
                PlaylistsMenu(Lp().player.current_track))
            popover.set_relative_to(self._infobox)
            popover.show()

    def __on_info_short(self, args):
        """
            Show track information popover
            @param args as []
        """
        if Lp().player.current_track.id == Type.EXTERNALS:
            from lollypop.pop_externals import ExternalsPopover
            expopover = ExternalsPopover()
            expopover.set_relative_to(self._infobox)
            expopover.populate()
            expopover.show()
        elif Lp().player.current_track.id is not None:
            if Lp().player.current_track.id == Type.RADIOS:
                if self.__pop_tunein is None:
                    from lollypop.pop_tunein import TuneinPopover
                    self.__pop_tunein = TuneinPopover()
                    self.__pop_tunein.populate()
                    self.__pop_tunein.set_relative_to(self._infobox)
                self.__pop_tunein.show()
            else:
                if self.__pop_info is None:
                    from lollypop.pop_info import InfoPopover
                    self.__pop_info = InfoPopover()
                    self.__pop_info.set_relative_to(self._infobox)
                self.__pop_info.show()

    def __on_loading_changed(self, player, show):
        """
            Show spinner based on loading status
            @param player as player
            @param show as bool
        """
        if show:
            self._title_label.hide()
            self._artist_label.hide()
            self._cover.hide()
            self._spinner.show()
            self._spinner.start()
            self._infobox.show()
        else:
            self._spinner.hide()
            self._spinner.stop()

    def __on_realize(self, toolbar):
        """
            Calculate art size
            @param toolbar as ToolbarInfos
        """
        style = self.get_style_context()
        padding = style.get_padding(style.get_state())
        self._artsize = self.get_allocated_height()\
            - padding.top - padding.bottom
        # Since GTK 3.20, we can set cover full height
        if Gtk.get_minor_version() < 20:
            self._artsize -= 2

    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
        """
        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 = GLib.markup_escape_text(self._artist_label.get_text())
            title = GLib.markup_escape_text(self._title_label.get_text())
            tooltip.set_markup("<b>%s</b> - %s" % (artist, title))
        else:
            return False
        return True
Example #27
0
 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:
                 if self._pop_tunein is None:
                     self._pop_tunein = TuneinPopover()
                     self._pop_tunein.populate()
                     self._pop_tunein.set_relative_to(self._infobox)
                 self._pop_tunein.show()
             else:
                 if self._pop_infos is None:
                     self._pop_infos = InfosPopover()
                     self._pop_infos.set_relative_to(self._infobox)
                 self._pop_infos.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_margin_top(5)
             rating.set_margin_bottom(5)
             rating.set_property('halign', Gtk.Align.START)
             rating.set_property('hexpand', True)
             rating.show()
             loved = LovedWidget(Lp().player.current_track.id)
             loved.set_margin_end(5)
             loved.set_margin_top(5)
             loved.set_margin_bottom(5)
             loved.set_property('halign', Gtk.Align.END)
             loved.set_property('hexpand', True)
             loved.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)
             hgrid = Gtk.Grid()
             hgrid.add(rating)
             hgrid.add(loved)
             hgrid.show()
             grid.add(hgrid)
             popover.add(stack)
             popover.show()
         return True
Example #28
0
class ToolbarInfo(Gtk.Bin, InfosController):
    """
        Informations toolbar
    """

    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        InfosController.__init__(self, ArtSize.SMALL)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfo.ui')
        builder.connect_signals(self)
        self.__pop_tunein = None
        self.__pop_info = None
        self.__timeout_id = None
        self.__width = 0

        self._infobox = builder.get_object('info')
        self.add(self._infobox)

        helper = TouchHelper(self._infobox, None, None)
        helper.set_long_func(self.__on_info_long)
        helper.set_short_func(self.__on_info_short)

        self._spinner = builder.get_object('spinner')

        self.__labels = builder.get_object('nowplaying_labels')
        self.__labels.connect('query-tooltip', self.__on_query_tooltip)
        self.__labels.set_property('has-tooltip', True)

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover = builder.get_object('cover')
        self._cover.set_property('has-tooltip', True)
        # Since GTK 3.20, we can set cover full height
        if Gtk.get_minor_version() > 18:
            self._cover.get_style_context().add_class('toolbar-cover-frame')
        else:
            self._cover.get_style_context().add_class('small-cover-frame')

        self.connect('realize', self.__on_realize)
        Lp().player.connect('loading-changed', self.__on_loading_changed)
        Lp().art.connect('album-artwork-changed', self.__update_cover)
        Lp().art.connect('radio-artwork-changed', self.__update_logo)

    def do_get_preferred_width(self):
        """
            We force preferred width
            @return (int, int)
        """
        return (self.__width, self.__width)

    def get_preferred_height(self):
        """
            Return preferred height
            @return (int, int)
        """
        return self.__labels.get_preferred_height()

    def set_width(self, width):
        """
            Set widget width
            @param width as int
        """
        self.__width = width
        self.set_property('width-request', width)

#######################
# PROTECTED           #
#######################
    def _on_eventbox_realize(self, eventbox):
        """
            Show hand cursor over
        """
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))

#######################
# 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:
            surface = Lp().art.get_album_artwork(
                                       Lp().player.current_track.album,
                                       self._artsize,
                                       self._cover.get_scale_factor())
            self._cover.set_from_surface(surface)
            del surface

    def __update_logo(self, art, name):
        """
            Update logo for name
            @param art as Art
            @param name as str
        """
        if Lp().player.current_track.album_artist == name:
            pixbuf = Lp().art.get_radio_artwork(name, self._artsize)
            self._cover.set_from_surface(pixbuf)
            del pixbuf

    def __on_info_long(self, args):
        """
            Show current track menu
            @param args as []
        """
        if Lp().player.current_track.id >= 0:
            from lollypop.pop_menu import PlaylistsMenu
            from lollypop.pop_menu import TrackMenuPopover
            popover = TrackMenuPopover(
                        Lp().player.current_track,
                        PlaylistsMenu(Lp().player.current_track))
            popover.set_relative_to(self._infobox)
            popover.show()

    def __on_info_short(self, args):
        """
            Show track information popover
            @param args as []
        """
        if Lp().player.current_track.id == Type.EXTERNALS:
            from lollypop.pop_externals import ExternalsPopover
            expopover = ExternalsPopover()
            expopover.set_relative_to(self._infobox)
            expopover.populate()
            expopover.show()
        elif Lp().player.current_track.id is not None:
            if Lp().player.current_track.id == Type.RADIOS:
                if self.__pop_tunein is None:
                    from lollypop.pop_tunein import TuneinPopover
                    self.__pop_tunein = TuneinPopover()
                    self.__pop_tunein.populate()
                    self.__pop_tunein.set_relative_to(self._infobox)
                self.__pop_tunein.show()
            else:
                if self.__pop_info is None:
                    from lollypop.pop_info import InfoPopover
                    self.__pop_info = InfoPopover()
                    self.__pop_info.set_relative_to(self._infobox)
                self.__pop_info.show()

    def __on_loading_changed(self, player, show):
        """
            Show spinner based on loading status
            @param player as player
            @param show as bool
        """
        if show:
            self._title_label.hide()
            self._artist_label.hide()
            self._cover.hide()
            self._spinner.show()
            self._spinner.start()
            self._infobox.show()
        else:
            self._spinner.hide()
            self._spinner.stop()

    def __on_realize(self, toolbar):
        """
            Calculate art size
            @param toolbar as ToolbarInfos
        """
        style = self.get_style_context()
        padding = style.get_padding(style.get_state())
        self._artsize = self.get_allocated_height()\
            - padding.top - padding.bottom
        # Since GTK 3.20, we can set cover full height
        if Gtk.get_minor_version() < 20:
            self._artsize -= 2

    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
        """
        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 = GLib.markup_escape_text(self._artist_label.get_text())
            title = GLib.markup_escape_text(self._title_label.get_text())
            tooltip.set_markup("<b>%s</b> - %s" % (artist, title))
        else:
            return False
        return True
Example #29
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)

        self._pop_tunein = None
        self._pop_infos = None
        self._cover_size = ArtSize.SMALL

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

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover_frame = builder.get_object('frame')
        self._cover = builder.get_object('cover')

        Lp().art.connect('album-artwork-changed', self._update_cover)
        Lp().art.connect('radio-artwork-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_artwork(
                player.current_track.artist,
                self._cover_size * self.get_scale_factor())
        elif player.current_track.id == Type.EXTERNALS:
            art = Lp().art.get_album_artwork2(
                player.current_track.uri,
                self._cover_size * self.get_scale_factor())
        elif player.current_track.id is not None:
            art = Lp().art.get_album_artwork(
                player.current_track.album,
                self._cover_size * 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_frame.show()
        else:
            self._cover_frame.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:
            surface = Lp().art.get_album_artwork(
                Lp().player.current_track.album, self._cover_size)
            self._cover.set_from_surface(surface)
            del surface

    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_artwork(name, self._cover_size)
            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:
                    if self._pop_tunein is None:
                        self._pop_tunein = TuneinPopover()
                        self._pop_tunein.populate()
                        self._pop_tunein.set_relative_to(self._infobox)
                    self._pop_tunein.show()
                else:
                    if self._pop_infos is None:
                        self._pop_infos = InfosPopover()
                        self._pop_infos.set_relative_to(self._infobox)
                    self._pop_infos.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_margin_top(5)
                rating.set_margin_bottom(5)
                rating.set_property('halign', Gtk.Align.START)
                rating.set_property('hexpand', True)
                rating.show()
                loved = LovedWidget(Lp().player.current_track.id)
                loved.set_margin_end(5)
                loved.set_margin_top(5)
                loved.set_margin_bottom(5)
                loved.set_property('halign', Gtk.Align.END)
                loved.set_property('hexpand', True)
                loved.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)
                hgrid = Gtk.Grid()
                hgrid.add(rating)
                hgrid.add(loved)
                hgrid.show()
                grid.add(hgrid)
                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
        """
        style = self.get_style_context()
        padding = style.get_padding(style.get_state())
        self._cover_size = self.get_allocated_height()\
            - padding.top - padding.bottom
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
Example #30
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))
Example #31
0
class ToolbarInfo(Gtk.Bin, InfosController):
    """
        Informations toolbar
    """
    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        InfosController.__init__(self, ArtSize.SMALL)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfo.ui')
        builder.connect_signals(self)
        self._pop_tunein = None
        self._pop_info = None
        self._timeout_id = None
        self._width = 0

        self._infobox = builder.get_object('info')
        self.add(self._infobox)

        self._labels = builder.get_object('nowplaying_labels')

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover_frame = builder.get_object('frame')
        self._cover = builder.get_object('cover')
        self._cover.set_property('has-tooltip', True)

        self.connect('realize', self._on_realize)
        Lp().art.connect('album-artwork-changed', self._update_cover)
        Lp().art.connect('radio-artwork-changed', self._update_logo)

    def do_get_preferred_width(self):
        """
            We force preferred width
            @return (int, int)
        """
        return (self._width, self._width)

    def get_preferred_height(self):
        """
            Return preferred height
            @return (int, int)
        """
        return self._labels.get_preferred_height()

    def set_width(self, width):
        """
            Set widget width
            @param width as int
        """
        self._width = width
        self.set_property('width-request', width)

#######################
# 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:
            surface = Lp().art.get_album_artwork(
                Lp().player.current_track.album, ArtSize.SMALL)
            self._cover.set_from_surface(surface)
            del surface

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

    def _show_track_menu(self):
        """
            Show current track menu
        """
        self._timeout_id = None
        if Lp().player.current_track.id >= 0:
            popover = TrackMenuPopover(
                Lp().player.current_track.id,
                PopToolbarMenu(Lp().player.current_track.id))
            popover.set_relative_to(self._infobox)
            popover.show()

    def _on_title_press_event(self, widget, event):
        """
            On long press: show current track menu
            @param widget as Gtk.Widget
            @param event as Gdk.Event

        """
        self._timeout_id = GLib.timeout_add(500, self._show_track_menu)
        return True

    def _on_title_release_event(self, widget, event):
        """
            Show track information popover
            On long press/right click: show current track menu
            @param widget as Gtk.Widget
            @param event as Gdk.Event
        """
        if self._timeout_id is not None:
            GLib.source_remove(self._timeout_id)
            self._timeout_id = None
            if Lp().player.current_track.id == Type.EXTERNALS:
                expopover = ExternalsPopover()
                expopover.set_relative_to(widget)
                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:
                        if self._pop_tunein is None:
                            self._pop_tunein = TuneinPopover()
                            self._pop_tunein.populate()
                            self._pop_tunein.set_relative_to(widget)
                        self._pop_tunein.show()
                    else:
                        if self._pop_info is None:
                            self._pop_info = InfoPopover()
                            self._pop_info.set_relative_to(widget)
                        self._pop_info.show()
                else:
                    self._show_track_menu()
        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_realize(self, toolbar):
        """
            @param toolbar as ToolbarInfos
        """
        style = self.get_style_context()
        padding = style.get_padding(style.get_state())
        self._artsize = self.get_allocated_height()\
            - padding.top - padding.bottom - 2

    def _on_eventbox_realize(self, eventbox):
        """
            Show hand cursor over
        """
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
 def __on_button_press_event(self, widget, event):
     """
         Show current track menu
         @param widget as Gtk.Widget
         @param event as Gdk.Event
     """
     if event.button == 1:
         if App().player.current_track.id == Type.RADIOS:
             from lollypop.pop_tunein import TuneinPopover
             popover = TuneinPopover()
             popover.populate()
         elif App().player.current_track.id is not None:
             from lollypop.pop_information import InformationPopover
             popover = InformationPopover()
             popover.populate()
         popover.set_relative_to(self._infobox)
         popover.popup()
     else:
         from lollypop.pop_menu import ToolbarMenu
         menu = ToolbarMenu(App().player.current_track)
         if App().player.current_track.id >= 0:
             from lollypop.pop_menu import TrackMenuPopover
             popover = TrackMenuPopover(App().player.current_track, menu)
             popover.set_relative_to(self._infobox)
         elif App().player.current_track.id == Type.RADIOS:
             popover = Popover.new_from_model(self._infobox, menu)
         popover.popup()
     return True
Example #33
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)

        self._pop_tunein = None
        self._pop_infos = None
        self._cover_size = ArtSize.SMALL

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

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover_frame = builder.get_object('frame')
        self._cover = builder.get_object('cover')

        Lp().art.connect('album-artwork-changed', self._update_cover)
        Lp().art.connect('radio-artwork-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_artwork(
                                   player.current_track.artist,
                                   self._cover_size*self.get_scale_factor())
        elif player.current_track.id == Type.EXTERNALS:
            art = Lp().art.get_album_artwork2(
                    player.current_track.uri,
                    self._cover_size*self.get_scale_factor())
        elif player.current_track.id is not None:
            art = Lp().art.get_album_artwork(
                                   player.current_track.album,
                                   self._cover_size*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_frame.show()
        else:
            self._cover_frame.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:
            surface = Lp().art.get_album_artwork(
                                       Lp().player.current_track.album,
                                       self._cover_size)
            self._cover.set_from_surface(surface)
            del surface

    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_artwork(name, self._cover_size)
            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:
                    if self._pop_tunein is None:
                        self._pop_tunein = TuneinPopover()
                        self._pop_tunein.populate()
                        self._pop_tunein.set_relative_to(self._infobox)
                    self._pop_tunein.show()
                else:
                    if self._pop_infos is None:
                        self._pop_infos = InfosPopover()
                        self._pop_infos.set_relative_to(self._infobox)
                    self._pop_infos.show()
            elif Lp().player.current_track.id >= 0:
                menu = PopToolbarMenu(Lp().player.current_track.id)
                popover = TrackMenuPopover(
                            Lp().player.current_track.id,
                            PopToolbarMenu(Lp().player.current_track.id))
                popover.set_relative_to(self._infobox)
                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
        """
        style = self.get_style_context()
        padding = style.get_padding(style.get_state())
        self._cover_size = self.get_allocated_height()\
            - padding.top - padding.bottom
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
Example #34
0
class RadiosView(View):
    """
        Init radios ui with a scrolled grid of radios widgets
    """
    def __init__(self):
        View.__init__(self)

        self._signal = None

        self._radios_manager = RadiosManager()
        self._radios_manager.connect('playlists-changed',
                                     self._on_radios_changed)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/RadiosView.ui')
        builder.connect_signals(self)
        widget = builder.get_object('widget')

        self._pop_tunein = TuneinPopover(self._radios_manager)
        self._pop_tunein.set_relative_to(builder.get_object('search_btn'))

        self._sizegroup = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.BOTH)

        self._radiobox = Gtk.FlowBox()
        self._radiobox.set_sort_func(self._sort_radios)
        self._radiobox.set_selection_mode(Gtk.SelectionMode.NONE)
        self._radiobox.connect("child-activated", self._on_album_activated)
        self._radiobox.set_property('column-spacing', 5)
        self._radiobox.set_property('row-spacing', 5)
        self._radiobox.set_homogeneous(True)
        self._radiobox.set_max_children_per_line(1000)
        self._radiobox.show()

        self._viewport.set_property("valign", Gtk.Align.START)
        self._viewport.set_property('margin', 5)
        self._viewport.add(self._radiobox)
        self._scrolledWindow.set_property('expand', True)

        self.add(widget)
        self.add(self._scrolledWindow)

    """
        Populate view with tracks from playlist
        Thread safe
    """
    def populate(self):
        radios_name = []
        # Get radios name
        for (i, name) in self._radios_manager.get():
            radios_name.append(name)
        GLib.idle_add(self._add_radios, radios_name)

    """
        Connect player signal
    """
    def do_show(self):
        View.do_show(self)
        self._signal = Lp.art.connect('logo-changed',
                                      self._on_logo_changed)

    """
        Disconnect player signal
    """
    def do_hide(self):
        View.do_hide(self)
        if self._signal is not None:
            Lp.art.disconnect(self._signal)

#######################
# PRIVATE             #
#######################
    """
        Return view children
        @return [RadioWidget]
    """
    def _get_children(self):
        children = []
        for child in self._radiobox.get_children():
            widget = child.get_child()
            children.append(widget)
        return children

    """
        Sort radios
        @param a as Gtk.FlowBoxChild
        @param b as Gtk.FlowBoxChild
    """
    def _sort_radios(self, a, b):
        child1 = a.get_children()[0]
        child2 = b.get_children()[0]
        return child1.get_name().lower() > child2.get_name().lower()

    """
        Show popover for adding a new radio
        @param widget as Gtk.Widget
    """
    def _on_new_clicked(self, widget):
        popover = RadioPopover('', self._radios_manager)
        popover.set_relative_to(widget)
        popover.show()

    """
        Show popover for searching radios
        @param widget as Gtk.Widget
    """
    def _on_search_clicked(self, widget):
        self._pop_tunein.populate()
        self._pop_tunein.show()

    """
        Update radios
        @param manager as PlaylistManager
    """
    def _on_radios_changed(self, manager):
        radios_name = []
        currents = []
        new_name = None
        old_widget = None
        old_child = None

        # Get radios name
        for (i, name) in manager.get():
            radios_name.append(name)

        # Get currents widget less removed
        for child in self._radiobox.get_children():
            widget = child.get_child()
            if widget.get_name() not in radios_name:
                old_widget = widget
                old_child = child
            else:
                currents.append(widget.get_name())

        # Add the new radio
        for name in radios_name:
            if name not in currents:
                new_name = name
                break

        # Rename widget
        if new_name is not None:
            if old_widget is not None:
                old_widget.set_name(new_name)
            else:
                self._add_radios([new_name])
        # Delete widget
        elif old_widget is not None:
            self._radiobox.remove(old_child)
            old_widget.destroy()

    """
        Update radio logo
        @param player as Plyaer
        @param name as string
    """
    def _on_logo_changed(self, player, name):
        for child in self._radiobox.get_children():
            widget = child.get_child()
            if widget.get_name() == name:
                widget.update_cover()

    """
        Pop a radio and add it to the view,
        repeat operation until radio list is empty
        @param [radio names as string]
    """
    def _add_radios(self, radios):
        if radios and not self._stop:
            radio = radios.pop(0)
            widget = RadioWidget(radio,
                                 self._radios_manager)
            widget.show()
            self._sizegroup.add_widget(widget)
            self._radiobox.insert(widget, -1)
            GLib.idle_add(self._add_radios, radios)
        else:
            self._stop = False
        return None

    """
        Play album
        @param flowbox as Gtk.Flowbox
        @child as Gtk.FlowboxChild
    """
    def _on_album_activated(self, flowbox, child):
        name = child.get_child().get_name()
        uris = self._radios_manager.get_tracks(name)
        if len(uris) > 0:
            track = Track()
            track.set_radio(name, uris[0])
            Lp.player.load(track)
Example #35
0
class ToolbarInfo(Gtk.Bin, InfosController):
    """
        Informations toolbar
    """

    def __init__(self):
        """
            Init toolbar
        """
        Gtk.Bin.__init__(self)
        InfosController.__init__(self, ArtSize.SMALL)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ToolbarInfo.ui')
        builder.connect_signals(self)
        self._pop_tunein = None
        self._pop_info = None
        self._timeout_id = None
        self._width = 0

        self._infobox = builder.get_object('info')
        self.add(self._infobox)

        self._labels = builder.get_object('nowplaying_labels')

        self._title_label = builder.get_object('title')
        self._artist_label = builder.get_object('artist')
        self._cover_frame = builder.get_object('frame')
        self._cover = builder.get_object('cover')
        self._cover.set_property('has-tooltip', True)
        # Since GTK 3.20, we can set cover full height
        if Gtk.get_minor_version() > 18:
            self._cover.get_style_context().add_class('toolbar-cover-frame')
        else:
            self._cover.get_style_context().add_class('small-cover-frame')

        self.connect('realize', self._on_realize)
        Lp().art.connect('album-artwork-changed', self._update_cover)
        Lp().art.connect('radio-artwork-changed', self._update_logo)

    def do_get_preferred_width(self):
        """
            We force preferred width
            @return (int, int)
        """
        return (self._width, self._width)

    def get_preferred_height(self):
        """
            Return preferred height
            @return (int, int)
        """
        return self._labels.get_preferred_height()

    def set_width(self, width):
        """
            Set widget width
            @param width as int
        """
        self._width = width
        self.set_property('width-request', width)

#######################
# 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:
            surface = Lp().art.get_album_artwork(
                                       Lp().player.current_track.album,
                                       ArtSize.SMALL)
            self._cover.set_from_surface(surface)
            del surface

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

    def _show_track_menu(self):
        """
            Show current track menu
        """
        self._timeout_id = None
        if Lp().player.current_track.id >= 0:
            popover = TrackMenuPopover(
                        Lp().player.current_track.id,
                        PopToolbarMenu(Lp().player.current_track.id))
            popover.set_relative_to(self._infobox)
            popover.show()

    def _on_title_press_event(self, widget, event):
        """
            On long press: show current track menu
            @param widget as Gtk.Widget
            @param event as Gdk.Event

        """
        self._timeout_id = GLib.timeout_add(500, self._show_track_menu)
        return True

    def _on_title_release_event(self, widget, event):
        """
            Show track information popover
            On long press/right click: show current track menu
            @param widget as Gtk.Widget
            @param event as Gdk.Event
        """
        if self._timeout_id is not None:
            GLib.source_remove(self._timeout_id)
            self._timeout_id = None
            if Lp().player.current_track.id == Type.EXTERNALS:
                expopover = ExternalsPopover()
                expopover.set_relative_to(widget)
                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:
                        if self._pop_tunein is None:
                            self._pop_tunein = TuneinPopover()
                            self._pop_tunein.populate()
                            self._pop_tunein.set_relative_to(widget)
                        self._pop_tunein.show()
                    else:
                        if self._pop_info is None:
                            self._pop_info = InfoPopover()
                            self._pop_info.set_relative_to(widget)
                        self._pop_info.show()
                else:
                    self._show_track_menu()
        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_realize(self, toolbar):
        """
            @param toolbar as ToolbarInfos
        """
        style = self.get_style_context()
        padding = style.get_padding(style.get_state())
        self._artsize = self.get_allocated_height()\
            - padding.top - padding.bottom
        # Since GTK 3.20, we can set cover full height
        if Gtk.get_minor_version() < 20:
            self._artsize -= 2

    def _on_eventbox_realize(self, eventbox):
        """
            Show hand cursor over
        """
        eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1))
 def __on_button_release_event(self, widget, event):
     """
         Handle buttons
         @param widget as Gtk.Widget
         @param event as Gdk.Event
     """
     if App().window.is_adaptive or not self._artwork.get_visible():
         return
     if App().player.current_track.id == Type.RADIOS:
         from lollypop.pop_tunein import TuneinPopover
         popover = TuneinPopover()
         popover.populate()
     elif App().player.current_track.id is not None:
         from lollypop.pop_information import InformationPopover
         popover = InformationPopover()
         popover.populate()
     popover.set_relative_to(self._infobox)
     popover.popup()
     return True