def _on_lastfm_btn_clicked(self, button): if Lp.lastfm is not None: if Lp.player.current_track.aartist_id == Type.COMPILATIONS: artist = Lp.player.current_track.artist else: artist = Lp.player.current_track.aartist popover = InfosPopover(artist, Lp.player.current_track.title) popover.set_relative_to(button) popover.populate() popover.show()
def _on_label_button_release(self, eventbox, event): """ On clicked label, show artist informations in a popover @param eventbox as Gtk.EventBox @param event as Gdk.Event """ if (Lp.lastfm is not None or self.Wikipedia is not None) and\ self._album.artist_id != Type.COMPILATIONS: popover = InfosPopover(self._album.artist_name) popover.set_relative_to(eventbox) popover.populate() popover.show()
def _on_infos_btn_clicked(self, button): """ Show current artist informations @param button as Gtk.Button """ if InfosPopover.should_be_shown(): artist_id = Lp.player.current_track.aartist_id if artist_id == Type.COMPILATIONS: artist = Lp.player.current_track.artist else: artist = Lp.player.current_track.aartist popover = InfosPopover(artist, Lp.player.current_track.id) popover.set_relative_to(button) popover.populate() popover.show()
def _on_infos_btn_clicked(self, button): """ Show current artist informations @param button as Gtk.Button """ if InfosPopover.should_be_shown(): artist_id = Lp.player.current_track.album_artist_id if artist_id == Type.COMPILATIONS: artist = Lp.player.current_track.artist else: artist = Lp.player.current_track.album_artist popover = InfosPopover(artist, Lp.player.current_track.id) popover.set_relative_to(button) popover.populate() popover.show()
class ArtistView(View): """ Show artist albums and tracks """ def __init__(self, artist_id, genre_id): """ Init ArtistView @param artist id as int @param genre id as int """ View.__init__(self) self._artist_id = artist_id self._genre_id = genre_id self._signal_id = None self._artist_name = Lp.artists.get_name(artist_id) if Lp.lastfm is not None: self._popover = InfosPopover(self._artist_name) builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/ArtistView.ui') builder.connect_signals(self) self.attach(builder.get_object('ArtistView'), 0, 0, 1, 1) builder.get_object('artist').set_label(self._artist_name) self._pop_allowed = True self._albumbox = Gtk.Grid() self._albumbox.set_row_spacing(20) self._albumbox.set_property("orientation", Gtk.Orientation.VERTICAL) self._albumbox.show() self._scrolledWindow.set_property('expand', True) self._viewport.set_property("valign", Gtk.Align.START) self._viewport.add(self._albumbox) self.add(self._scrolledWindow) def populate(self): """ Populate the view @thread safe """ albums = self._get_albums() GLib.idle_add(self._add_albums, albums, self._genre_id) ####################### # PRIVATE # ####################### def _get_albums(self): """ Get albums @return album ids as [int] @thread safe """ sql = Lp.db.get_cursor() if self._artist_id == Type.COMPILATIONS: albums = Lp.albums.get_compilations(self._genre_id, sql) elif self._genre_id == Type.ALL: albums = Lp.albums.get_ids(self._artist_id, None, sql) else: albums = Lp.albums.get_ids(self._artist_id, self._genre_id, sql) sql.close() return albums def _get_children(self): """ Return view children @return [AlbumWidget] """ return self._albumbox.get_children() def _add_albums(self, albums, genre_id): """ Pop an album and add it to the view, repeat operation until album list is empty @param [album ids as int] @param genre id as int """ size_group = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.HORIZONTAL) if albums and not self._stop: widget = AlbumDetailedWidget(albums.pop(0), genre_id, self._pop_allowed, False, size_group) widget.show() start_new_thread(widget.populate, ()) self._albumbox.add(widget) GLib.idle_add(self._add_albums, albums, genre_id) else: self._stop = False def _on_label_realize(self, eventbox): """ Change pointer on label @param eventbox as Gtk.EventBox """ if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS: eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1)) def _on_label_button_release(self, eventbox, event): """ On clicked label, show artist informations in a popover @param eventbox as Gtk.EventBox @param event as Gdk.Event """ if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS: self._popover.set_relative_to(eventbox) self._popover.populate() self._popover.show()
class ArtistView(View): """ Show artist albums and tracks """ try: from lollypop.wikipedia import Wikipedia except: Wikipedia = None def __init__(self, artist_id, genre_id): """ Init ArtistView @param artist id as int @param genre id as int """ View.__init__(self) self._artist_id = artist_id self._genre_id = genre_id self._signal_id = None self._artist_name = Lp.artists.get_name(artist_id) if Lp.lastfm is not None or self.Wikipedia is not None: self._popover = InfosPopover(self._artist_name) builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/ArtistView.ui') builder.connect_signals(self) self.attach(builder.get_object('ArtistView'), 0, 0, 1, 1) builder.get_object('artist').set_label(self._artist_name) self._pop_allowed = True self._albumbox = Gtk.Grid() self._albumbox.set_row_spacing(20) self._albumbox.set_property("orientation", Gtk.Orientation.VERTICAL) self._albumbox.show() self._scrolledWindow.set_property('expand', True) self._viewport.set_property("valign", Gtk.Align.START) self._viewport.add(self._albumbox) self.add(self._scrolledWindow) def populate(self, albums): """ Populate the view """ self._add_albums(albums) ####################### # PRIVATE # ####################### def _get_children(self): """ Return view children @return [AlbumWidget] """ return self._albumbox.get_children() def _add_albums(self, albums): """ Pop an album and add it to the view, repeat operation until album list is empty @param [album ids as int] """ size_group = Gtk.SizeGroup(mode=Gtk.SizeGroupMode.HORIZONTAL) widget = AlbumDetailedWidget(albums.pop(0), self._genre_id, self._pop_allowed, False, size_group) widget.connect('finished', self._on_album_finished, albums) widget.show() start_new_thread(widget.populate, ()) self._albumbox.add(widget) def _on_album_finished(self, album, albums): """ Add another album @param album as AlbumDetailedWidget @param [album ids as int] """ if albums and not self._stop: self._add_albums(albums) else: self._stop = False def _on_label_realize(self, eventbox): """ Change pointer on label @param eventbox as Gtk.EventBox """ if (Lp.lastfm is not None or self.Wikipedia is not None) and\ self._artist_id != Type.COMPILATIONS: eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1)) def _on_label_button_release(self, eventbox, event): """ On clicked label, show artist informations in a popover @param eventbox as Gtk.EventBox @param event as Gdk.Event """ if (Lp.lastfm is not None or self.Wikipedia is not None) and\ self._artist_id != Type.COMPILATIONS: self._popover.set_relative_to(eventbox) self._popover.populate() self._popover.show()
class AlbumDetailedWidget(AlbumWidget): """ Init detailed album widget @param album id as int @param genre id as int @param parent width as int @param pop_allowed as bool if widget can show popovers @param scrolled as bool @param size group as Gtk.SizeGroup """ def __init__(self, album_id, genre_id, pop_allowed, scrolled, size_group): AlbumWidget.__init__(self, album_id) self._artist_id = Lp.albums.get_artist_id(album_id) self._album_id = album_id self._genre_id = genre_id builder = Gtk.Builder() if scrolled: builder.add_from_resource( '/org/gnome/Lollypop/AlbumContextWidget.ui') else: builder.add_from_resource( '/org/gnome/Lollypop/AlbumDetailedWidget.ui') builder.connect_signals(self) if scrolled: artist = translate_artist_name(Lp.albums.get_artist_name(album_id)) builder.get_object('artist').set_text(artist) builder.get_object('artist').show() if Lp.lastfm is not None: self._popover = InfosPopover(artist) self._stars = [] self._stars.append(builder.get_object('star0')) self._stars.append(builder.get_object('star1')) self._stars.append(builder.get_object('star2')) self._stars.append(builder.get_object('star3')) self._stars.append(builder.get_object('star4')) self._on_leave_notify(None, None) grid = builder.get_object('tracks') self._discs = Lp.albums.get_discs(album_id, genre_id) self._tracks_left = {} self._tracks_right = {} show_label = len(self._discs) > 1 i = 0 for disc in self._discs: if show_label: label = Gtk.Label() label.set_text(_("Disc %s") % disc) label.set_property('halign', Gtk.Align.START) label.get_style_context().add_class('dim-label') if i: label.set_property('margin-top', 30) label.show() grid.attach(label, 0, i, 2, 1) i += 1 sep = Gtk.Separator() sep.show() grid.attach(sep, 0, i, 2, 1) i += 1 self._tracks_left[disc] = TracksWidget(pop_allowed) self._tracks_right[disc] = TracksWidget(pop_allowed) grid.attach(self._tracks_left[disc], 0, i, 1, 1) grid.attach(self._tracks_right[disc], 1, i, 1, 1) size_group.add_widget(self._tracks_left[disc]) size_group.add_widget(self._tracks_right[disc]) self._tracks_left[disc].connect('activated', self._on_activated) self._tracks_left[disc].connect('button-press-event', self._on_button_press_event) self._tracks_right[disc].connect('activated', self._on_activated) self._tracks_right[disc].connect('button-press-event', self._on_button_press_event) self._tracks_left[disc].show() self._tracks_right[disc].show() i += 1 self._cover = builder.get_object('cover') self.set_cover() self._title_label = Lp.albums.get_name(album_id) builder.get_object('title').set_label(self._title_label) builder.get_object('year').set_label(Lp.albums.get_year(album_id)) self.add(builder.get_object('AlbumDetailedWidget')) if pop_allowed: self._menu = builder.get_object('menu') self._eventbox = builder.get_object('eventbox') self._eventbox.connect('realize', self._on_eventbox_realize) self._eventbox.connect("button-press-event", self._show_web_art) self._menu.connect('clicked', self._pop_menu) self._menu.show() else: self._eventbox = None """ Update playing indicator """ def update_playing_indicator(self): for disc in self._discs: self._tracks_left[disc].update_playing(Lp.player.current_track.id) self._tracks_right[disc].update_playing(Lp.player.current_track.id) """ Populate tracks @thread safe """ def populate(self): self._stop = False sql = Lp.db.get_cursor() for disc in self._discs: mid_tracks = int(0.5+Lp.albums.get_count_for_disc(self._album_id, self._genre_id, disc, sql)/2) tracks = Lp.albums.get_tracks_infos(self._album_id, self._genre_id, disc, sql) self.populate_list_left(tracks[:mid_tracks], disc, 1) self.populate_list_right(tracks[mid_tracks:], disc, mid_tracks + 1) """ Populate left list, thread safe @param track's ids as array of int @param track position as int """ def populate_list_left(self, tracks, disc, pos): GLib.idle_add(self._add_tracks, tracks, self._tracks_left[disc], pos) """ Populate right list, thread safe @param track's ids as array of int @param track position as int """ def populate_list_right(self, tracks, disc, pos): GLib.idle_add(self._add_tracks, tracks, self._tracks_right[disc], pos) ####################### # PRIVATE # ####################### """ Popup menu for album @param widget as Gtk.Button @param album id as int """ def _pop_menu(self, widget): pop_menu = AlbumMenuPopover(self._album_id, self._genre_id) popover = Gtk.Popover.new_from_model(self._menu, pop_menu) popover.connect('closed', self._on_closed) self.get_style_context().add_class('album-menu-selected') popover.show() """ Remove selected style @param widget as Gtk.Popover """ def _on_closed(self, widget): self.get_style_context().remove_class('album-menu-selected') """ Add tracks for to tracks widget @param tracks as [(track_id, title, length, [artist ids])] @param widget as TracksWidget @param i as int """ def _add_tracks(self, tracks, widget, i): if not tracks or self._stop: self._stop = False return track = tracks.pop(0) track_id = track[0] title = escape(track[1]) length = track[2] tracknumber = track[3] artist_ids = track[4] # If we are listening to a compilation, prepend artist name if self._artist_id == Type.COMPILATIONS or\ len(artist_ids) > 1 or\ self._artist_id not in artist_ids: artist_name = "" for artist_id in artist_ids: artist_name += translate_artist_name( Lp.artists.get_name(artist_id)) + ", " title = "<b>%s</b>\n%s" % (escape(artist_name[:-2]), title) # Get track position in queue pos = None if Lp.player.is_in_queue(track_id): pos = Lp.player.get_track_position(track_id) if Lp.settings.get_value('show-tag-tracknumber'): widget.add_track(track_id, tracknumber, title, length, pos) else: widget.add_track(track_id, i, title, length, pos) GLib.idle_add(self._add_tracks, tracks, widget, i+1) """ On track activation, play track @param widget as TracksWidget @param track id as int """ def _on_activated(self, widget, track_id): Lp.player.context.next = NextContext.NONE if not Lp.player.is_party(): Lp.player.set_albums(track_id, self._artist_id, self._genre_id) Lp.player.load(Track(track_id)) if self._button_state & Gdk.ModifierType.CONTROL_MASK: Lp.player.context.next = NextContext.STOP_TRACK """ Keep track of mask @param widget as TrackWidget @param event as Gdk.Event """ def _on_button_press_event(self, widget, event): self._button_state = event.get_state() """ Change cursor over eventbox @param eventbox as Gdk.Eventbox """ def _on_eventbox_realize(self, eventbox): eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.PENCIL)) """ Change pointer on label @param eventbox as Gtk.EventBox """ def _on_label_realize(self, eventbox): if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS: eventbox.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND1)) """ On clicked label, show artist informations in a popover @param eventbox as Gtk.EventBox @param event as Gdk.Event """ def _on_label_button_release(self, eventbox, event): if Lp.lastfm is not None and self._artist_id != Type.COMPILATIONS: self._popover.set_relative_to(eventbox) self._popover.populate() self._popover.show() """ Popover with album art downloaded from the web (in fact google :-/) @param: widget as eventbox @param: data as unused """ def _show_web_art(self, widget, data): popover = CoversPopover(self._artist_id, self._album_id) popover.set_relative_to(widget) popover.populate() popover.show() """ On enter notify, change star opacity @param widget as Gtk.EventBox @param event as Gdk.Event """ def _on_enter_notify(self, widget, event): event_star = widget.get_children()[0] # First star is hidden (used to clear score) if event_star.get_property("opacity") == 0.0: found = True else: found = False for star in self._stars: if found: star.set_property("opacity", 0.2) else: star.set_property("opacity", 0.8) if star == event_star: found = True """ On leave notify, change star opacity @param widget as Gtk.EventBox (can be None) @param event as Gdk.Event (can be None) """ def _on_leave_notify(self, widget, event): avg_popularity = Lp.albums.get_avg_popularity() if avg_popularity > 0: popularity = Lp.albums.get_popularity(self._album_id) stars = popularity*5/avg_popularity+0.5 if stars < 1: for i in range(5): self._stars[i].set_property("opacity", 0.2) else: if stars >= 1: self._stars[0].set_property("opacity", 0.8) else: self._stars[0].set_property("opacity", 0.2) if stars >= 2: self._stars[1].set_property("opacity", 0.8) else: self._stars[1].set_property("opacity", 0.2) if stars >= 3: self._stars[2].set_property("opacity", 0.8) else: self._stars[2].set_property("opacity", 0.2) if stars >= 4: self._stars[3].set_property("opacity", 0.8) else: self._stars[3].set_property("opacity", 0.2) if stars >= 4.75: self._stars[4].set_property("opacity", 0.8) else: self._stars[4].set_property("opacity", 0.2) else: for i in range(5): self._stars[i].set_property("opacity", 0.2) """ On button press, set album popularity @param widget as Gtk.EventBox @param event as Gdk.Event """ def _on_button_press(self, widget, event): if Lp.scanner.is_locked(): return event_star = widget.get_children()[0] try: position = self._stars.index(event_star) avg_popularity = Lp.albums.get_avg_popularity() popularity = int(((position+1)*avg_popularity/5)+0.5) Lp.albums.set_popularity(self._album_id, popularity) except: Lp.albums.set_popularity(self._album_id, 0) Lp.sql.commit()