def __init__(self, music_library, track, name="lyrics", tab_title=_("Lyrics")): Tab.__init__(self, name, tab_title) self.track = track self.lyrics_area = None self.library = music_library self.lyrics_text = "" if self.track.has_lyrics(): self.lyrics_text = self.track.lyrics lyrics = Label(0.037, "subtitle", 0, 0, self.lyrics_text) lyrics.set_line_wrap_mode(pango.WRAP_WORD) lyrics.width = 0.366 self.lyrics_area = ScrollArea(0.5, 0.23, 0.4, 0.57, lyrics) self.lyrics_area.connect("activated", self._on_activated) self.add(self.lyrics_area) self.connect('activated', self._on_activated) self.connect('deactivated', self._on_deactivated) else: # Display throbber animation while searching for lyrics self.throbber = LoadingAnimation(0.7, 0.5, 0.1) self.throbber.show() self.add(self.throbber) self.track.fetch_lyrics(self._lyrics_search_callback)
def _create_episode_info_box(self): """ Create a texture that is displayed next to track list. This texture displays album cover art. """ self._create_thumbnail_texture() # Title self.title = Label(0.04, "title", 0.05, 0.55, self.menu.selected_userdata.title, font_weight="bold") self.title.set_ellipsize(pango.ELLIPSIZE_END) self.title.set_line_wrap(False) self.title.width = 0.4 self.add(self.title) # Plot plot = Label(0.029, "subtitle", 0, 0, self.menu.selected_userdata.plot) plot.width = 0.4 self.scroll_area = ScrollArea(0.05, 0.63, 0.4, 0.15, plot) self.scroll_area.connect("activated", self._on_scroll_area_activated) self.add(self.scroll_area)
def setUp(self): """Set up the test.""" EntertainerTest.setUp(self) # Get a workable amount of text text = "Here is the start. " # pylint: disable-msg=W0612 for i in range(0, 100): text += "Here is sentence number " self.label = Label(0.1, "screentitle", 0.1, 0.2, text) self.scroll_area = ScrollArea(0.5, 0.6, 0.1, 0.1, self.label)
def _lyrics_search_callback(self, lyrics_text): '''This function is called when lyrics search is over.''' self.throbber.hide() # Save the results to help determine if the tab can activate. self.lyrics_text = lyrics_text if lyrics_text == "": no_lyrics = Label(0.037, "title", 0.7, 0.5, _("No lyrics found for this track")) no_lyrics.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self.add(no_lyrics) else: lyrics = Label(0.037, "subtitle", 0, 0, lyrics_text) lyrics.set_line_wrap_mode(pango.WRAP_WORD) lyrics.width = 0.366 self.lyrics_area = ScrollArea(0.5, 0.23, 0.4, 0.57, lyrics) self.lyrics_area.connect("activated", self._on_activated) self.add(self.lyrics_area) self.library.save_lyrics(self.track, lyrics_text)
class ScrollAreaTest(EntertainerTest): """Test for entertainerlib.gui.widgets.scroll_area""" def setUp(self): """Set up the test.""" EntertainerTest.setUp(self) # Get a workable amount of text text = "Here is the start. " # pylint: disable-msg=W0612 for i in range(0, 100): text += "Here is sentence number " self.label = Label(0.1, "screentitle", 0.1, 0.2, text) self.scroll_area = ScrollArea(0.5, 0.6, 0.1, 0.1, self.label) def test_create(self): """Test correct ScrollArea initialization.""" self.assertTrue(isinstance(self.scroll_area, ScrollArea)) def test_active(self): '''Test the use of the active property.''' self.scroll_area.active = True self.assertTrue(self.scroll_area.active) self.scroll_area.active = False self.assertFalse(self.scroll_area.active) def test_on_top_bottom(self): '''Test the use of the on_top, on_bottom properties.''' self.scroll_area.offset = 0 self.scroll_area.stop_animation() self.assertTrue(self.scroll_area.on_top) self.assertFalse(self.scroll_area.on_bottom) self.scroll_area.scroll_to_bottom() self.scroll_area.stop_animation() self.assertFalse(self.scroll_area.on_top) self.assertTrue(self.scroll_area.on_bottom) def test_offset(self): '''Test the use of the offset property.''' self.scroll_area.scroll_to_bottom() offset = self.scroll_area.offset self.scroll_area.offset = 0 self.assertTrue(self.scroll_area.offset != offset) def test_set_content(self): '''Test the use of the set_content method.''' self.scroll_area.set_content(Label(0.1, "screentitle", 0.1, 0.2, "foo")) self.assertFalse(self.scroll_area.content == self.label) self.scroll_area.set_content(self.label) self.assertTrue(self.scroll_area.content == self.label) def test_scroll(self): '''Test the use of scroll methods.''' self.scroll_area.scroll_to_bottom() self.scroll_area.stop_animation() self.assertTrue(self.scroll_area.on_bottom) self.scroll_area.scroll_to_top() self.scroll_area.stop_animation() self.assertTrue(self.scroll_area.on_top) self.assertTrue(self.scroll_area.offset == 0) self.scroll_area.scroll_down() self.scroll_area.stop_animation() self.assertFalse(self.scroll_area.offset == 0) self.scroll_area.scroll_up() self.scroll_area.stop_animation() self.assertTrue(self.scroll_area.offset == 0)
class TvEpisodes(Screen): '''Screen contains list of all episodes of one specific season.''' def __init__(self, media_player, move_to_new_screen_callback, episodes, tv_series): Screen.__init__(self, 'TvEpisodes', move_to_new_screen_callback) self.episodes = episodes self.media_player = media_player self.theme = self.config.theme self.tv_series = tv_series # Screen Title (Displayed at the bottom left corner) screen_title = Label(0.13, "screentitle", 0, 0.87, self.tv_series.title) self.add(screen_title) self.scroll_area = None self.title = None self.thumb = None self.menu = self._create_episode_menu() self.add(self.menu) self._create_episode_info_box() #List indicator self.li = ListIndicator(0.8, 0.9, 0.2, 0.045, ListIndicator.VERTICAL) self.li.set_maximum(len(self.episodes)) self.add(self.li) self.menu.connect("moved", self._update_episode_info) self.menu.connect("selected", self._handle_select) self.menu.connect("activated", self._on_menu_activated) def _create_episode_menu(self): """Create a list of available seasons.""" menu = TextMenu(0.4978, 0.1563, 0.4393, 0.0781) episodes_list = [[_("%(num)d. %(title)s") % \ {'num': episode.number, 'title': episode.title}, None, episode] for episode in self.episodes] menu.async_add(episodes_list) menu.active = True return menu def _create_thumbnail_texture(self): """Create a thumbnail texture. This is called as menu is scrolled.""" if self.thumb: self.thumb.hide() # Thumbnail. Use cover art if thumbnail doesn't exist thumbnail = self.menu.selected_userdata.thumbnail_url if(thumbnail is not None): pixbuf = gtk.gdk.pixbuf_new_from_file(thumbnail) thumb_width = 0.2928 thumb_height = 0.2799 thumb_x = 0.05 thumb_y = 0.2 else: thumb_width = 0.1098 thumb_height = 0.2799 thumb_x = 0.20 thumb_y = 0.15 if(self.tv_series.has_cover_art()): pixbuf = gtk.gdk.pixbuf_new_from_file( self.tv_series.cover_art_url) else: pixbuf = gtk.gdk.pixbuf_new_from_file( self.theme.getImage("default_movie_art")) self.thumb = EyeCandyTexture(thumb_x, thumb_y, thumb_width, thumb_height, pixbuf) self.add(self.thumb) def _create_episode_info_box(self): """ Create a texture that is displayed next to track list. This texture displays album cover art. """ self._create_thumbnail_texture() # Title self.title = Label(0.04, "title", 0.05, 0.55, self.menu.selected_userdata.title, font_weight="bold") self.title.set_ellipsize(pango.ELLIPSIZE_END) self.title.set_line_wrap(False) self.title.width = 0.4 self.add(self.title) # Plot plot = Label(0.029, "subtitle", 0, 0, self.menu.selected_userdata.plot) plot.width = 0.4 self.scroll_area = ScrollArea(0.05, 0.63, 0.4, 0.15, plot) self.scroll_area.connect("activated", self._on_scroll_area_activated) self.add(self.scroll_area) def _update_episode_info(self, event=None): '''Update information from this episode.''' self.li.set_current(self.menu.selected_index + 1) self._create_thumbnail_texture() self.title.set_text(self.menu.selected_userdata.title) self.title.width = 0.4 plot = Label(0.029, "subtitle", 0, 0, self.menu.selected_userdata.plot) plot.width = 0.4 self.scroll_area.set_content(plot) def _handle_up(self): '''Handle UserEvent.NAVIGATE_UP.''' if self.menu.active: self.menu.up() else: self.scroll_area.scroll_up() def _handle_down(self): '''Handle UserEvent.NAVIGATE_DOWN.''' if self.menu.active: self.menu.down() else: self.scroll_area.scroll_down() def _handle_left(self): '''Handle UserEvent.NAVIGATE_LEFT.''' self.menu.active = False self.scroll_area.active = True def _handle_right(self): '''Handle UserEvent.NAVIGATE_RIGHT.''' self.menu.active = True self.scroll_area.active = False def _handle_select(self, event=None): '''Handle UserEvent.NAVIGATE_SELECT.''' episode = self.menu.selected_userdata self.media_player.set_media(episode) self.media_player.play() self.callback("video_osd") def _on_menu_activated(self, event=None): '''Handle menu activation.''' self.scroll_area.active = False def _on_scroll_area_activated(self, event=None): '''Handle scroll_area activation.''' self.menu.active = False
class TvEpisodes(Screen): '''Screen contains list of all episodes of one specific season.''' def __init__(self, media_player, move_to_new_screen_callback, episodes, tv_series): Screen.__init__(self, 'TvEpisodes', move_to_new_screen_callback) self.episodes = episodes self.media_player = media_player self.theme = self.config.theme self.tv_series = tv_series # Screen Title (Displayed at the bottom left corner) screen_title = Label(0.13, "screentitle", 0, 0.87, self.tv_series.title) self.add(screen_title) self.scroll_area = None self.title = None self.thumb = None self.menu = self._create_episode_menu() self.add(self.menu) self._create_episode_info_box() #List indicator self.li = ListIndicator(0.8, 0.9, 0.2, 0.045, ListIndicator.VERTICAL) self.li.set_maximum(len(self.episodes)) self.add(self.li) self.menu.connect("moved", self._update_episode_info) self.menu.connect("selected", self._handle_select) self.menu.connect("activated", self._on_menu_activated) def _create_episode_menu(self): """Create a list of available seasons.""" menu = TextMenu(0.4978, 0.1563, 0.4393, 0.0781) episodes_list = [[_("%(num)d. %(title)s") % \ {'num': episode.number, 'title': episode.title}, None, episode] for episode in self.episodes] menu.async_add(episodes_list) menu.active = True return menu def _create_thumbnail_texture(self): """Create a thumbnail texture. This is called as menu is scrolled.""" if self.thumb: self.thumb.hide() # Thumbnail. Use cover art if thumbnail doesn't exist thumbnail = self.menu.selected_userdata.thumbnail_url if (thumbnail is not None): pixbuf = gtk.gdk.pixbuf_new_from_file(thumbnail) thumb_width = 0.2928 thumb_height = 0.2799 thumb_x = 0.05 thumb_y = 0.2 else: thumb_width = 0.1098 thumb_height = 0.2799 thumb_x = 0.20 thumb_y = 0.15 if (self.tv_series.has_cover_art()): pixbuf = gtk.gdk.pixbuf_new_from_file( self.tv_series.cover_art_url) else: pixbuf = gtk.gdk.pixbuf_new_from_file( self.theme.getImage("default_movie_art")) self.thumb = EyeCandyTexture(thumb_x, thumb_y, thumb_width, thumb_height, pixbuf) self.add(self.thumb) def _create_episode_info_box(self): """ Create a texture that is displayed next to track list. This texture displays album cover art. """ self._create_thumbnail_texture() # Title self.title = Label(0.04, "title", 0.05, 0.55, self.menu.selected_userdata.title, font_weight="bold") self.title.set_ellipsize(pango.ELLIPSIZE_END) self.title.set_line_wrap(False) self.title.width = 0.4 self.add(self.title) # Plot plot = Label(0.029, "subtitle", 0, 0, self.menu.selected_userdata.plot) plot.width = 0.4 self.scroll_area = ScrollArea(0.05, 0.63, 0.4, 0.15, plot) self.scroll_area.connect("activated", self._on_scroll_area_activated) self.add(self.scroll_area) def _update_episode_info(self, event=None): '''Update information from this episode.''' self.li.set_current(self.menu.selected_index + 1) self._create_thumbnail_texture() self.title.set_text(self.menu.selected_userdata.title) self.title.width = 0.4 plot = Label(0.029, "subtitle", 0, 0, self.menu.selected_userdata.plot) plot.width = 0.4 self.scroll_area.set_content(plot) def _handle_up(self): '''Handle UserEvent.NAVIGATE_UP.''' if self.menu.active: self.menu.up() else: self.scroll_area.scroll_up() def _handle_down(self): '''Handle UserEvent.NAVIGATE_DOWN.''' if self.menu.active: self.menu.down() else: self.scroll_area.scroll_down() def _handle_left(self): '''Handle UserEvent.NAVIGATE_LEFT.''' self.menu.active = False self.scroll_area.active = True def _handle_right(self): '''Handle UserEvent.NAVIGATE_RIGHT.''' self.menu.active = True self.scroll_area.active = False def _handle_select(self, event=None): '''Handle UserEvent.NAVIGATE_SELECT.''' episode = self.menu.selected_userdata self.media_player.set_media(episode) self.media_player.play() self.callback("video_osd") def _on_menu_activated(self, event=None): '''Handle menu activation.''' self.scroll_area.active = False def _on_scroll_area_activated(self, event=None): '''Handle scroll_area activation.''' self.menu.active = False
def create_movie_information(self): '''Create clutter parts related to movie information''' # Movie art texture if self.movie.has_cover_art(): pixbuf = gtk.gdk.pixbuf_new_from_file(self.movie.cover_art_url) else: pixbuf = gtk.gdk.pixbuf_new_from_file( self.theme.getImage("default_movie_art")) movie_art = EyeCandyTexture(0.33, 0.1, 0.1, 0.25, pixbuf) self.add(movie_art) # Movie title title = Label(0.04, "title", 0.47, 0.1, self.movie.title, font_weight="bold") title.set_ellipsize(pango.ELLIPSIZE_END) title.set_size(0.5124, 0.05208) self.add(title) # Movie release year year_text = _("Released in %(year)s") % {'year': self.movie.year} year = Label(0.032, "subtitle", 0.47, 0.3, year_text) year.set_ellipsize(pango.ELLIPSIZE_END) year.set_size(0.5124, 0.05208) self.add(year) # Show only 2 genres (or one if there is only one) genres_list = self.movie.genres if len(genres_list) == 0: genres_text = _("Unknown") else: genres_text = "/".join(genres_list[:2]) # Runtime and genres info_text = _("%(runtime)s min, %(genre)s") % \ {'runtime': self.movie.runtime, 'genre': genres_text} info = Label(0.032, "subtitle", 0.47, 0.24, info_text) info.set_ellipsize(pango.ELLIPSIZE_END) info.set_size(0.5124, 0.05208) self.add(info) # Stars (rating) star = Texture(self.theme.getImage("star")) star.hide() self.add(star) star2 = Texture(self.theme.getImage("star2")) star2.hide() self.add(star2) for i in range(self.movie.rating): tex = clutter.Clone(star) tex.set_position( self.get_abs_x(0.47) + (self.get_abs_x(0.0366) * i), self.get_abs_y(0.17)) tex.set_size(self.get_abs_x(0.024), self.get_abs_y(0.04)) self.add(tex) dark_star = 5 - self.movie.rating for i in range(dark_star): tex = clutter.Clone(star2) tex.set_position(self.get_abs_x(0.47) + (self.get_abs_x(0.0366) * \ (i + self.movie.rating)), self.get_abs_y(0.17)) tex.set_size(self.get_abs_x(0.024), self.get_abs_y(0.04)) self.add(tex) # Plot plot = Label(0.029, "subtitle", 0, 0, self.movie.plot) plot.set_justify(True) plot.set_line_wrap_mode(pango.WRAP_WORD) plot.set_line_wrap(True) plot.width = 0.5124 self.scroll_area = ScrollArea(0.33, 0.38, 0.5124, 0.3516, plot) self.add(self.scroll_area) # Actors self.add(Label(0.032, "title", 0.33, 0.8, _("Starring"))) actors_list = self.movie.actors if len(actors_list) == 0: actors_text = _("Unknown") else: actors_text = ", ".join(actors_list[:5]) actors = Label(0.032, "subtitle", 0.46, 0.8, actors_text) actors.set_ellipsize(pango.ELLIPSIZE_END) actors.set_size(0.5124, 0.05208) self.add(actors) # Directors self.add(Label(0.032, "title", 0.33, 0.86, _("Directed by"))) directors_list = self.movie.directors if len(directors_list) == 0: directors_text = _("Unknown") else: directors_text = ", ".join(directors_list[:2]) directors = Label(0.032, "subtitle", 0.46, 0.86, directors_text) directors.set_ellipsize(pango.ELLIPSIZE_END) directors.set_size(0.5124, 0.05208) self.add(directors) # Writers self.add(Label(0.032, "title", 0.33, 0.92, _("Written by"))) writers_list = self.movie.writers if len(directors_list) == 0: writers_text = _("Unknown") else: writers_text = ", ".join(writers_list[:2]) writers = Label(0.032, "subtitle", 0.46, 0.92, writers_text) writers.set_ellipsize(pango.ELLIPSIZE_END) writers.set_size(0.5124, 0.05208) self.add(writers)
class Movie(Screen): '''Screen contains information of one movie.''' def __init__(self, media_player, movie, move_to_new_screen_callback): Screen.__init__(self, 'Movie', move_to_new_screen_callback) self.theme = self.config.theme self.media_player = media_player self.movie = movie # Screen Title (Displayed at the bottom left corner) screen_title = Label(0.13, "screentitle", 0, 0.87, _("Movie")) self.add(screen_title) # Add the additional actions that are needed but not handled by default self.event_handlers.update({ UserEvent.NAVIGATE_FIRST_PAGE : self._handle_first_page, UserEvent.NAVIGATE_LAST_PAGE : self._handle_last_page, UserEvent.NAVIGATE_PREVIOUS_PAGE : self._handle_previous_page, UserEvent.NAVIGATE_NEXT_PAGE : self._handle_next_page }) self.menu = None self.scroll_area = None self.create_menu() self.create_movie_information() def create_movie_information(self): '''Create clutter parts related to movie information''' # Movie art texture if self.movie.has_cover_art(): pixbuf = gtk.gdk.pixbuf_new_from_file(self.movie.cover_art_url) else: pixbuf = gtk.gdk.pixbuf_new_from_file( self.theme.getImage("default_movie_art")) movie_art = EyeCandyTexture(0.33, 0.1, 0.1, 0.25, pixbuf) self.add(movie_art) # Movie title title = Label(0.04, "title", 0.47, 0.1, self.movie.title, font_weight="bold") title.set_ellipsize(pango.ELLIPSIZE_END) title.set_size(0.5124, 0.05208) self.add(title) # Movie release year year_text = _("Released in %(year)s") % {'year': self.movie.year} year = Label(0.032, "subtitle", 0.47, 0.3, year_text) year.set_ellipsize(pango.ELLIPSIZE_END) year.set_size(0.5124, 0.05208) self.add(year) # Show only 2 genres (or one if there is only one) genres_list = self.movie.genres if len(genres_list) == 0: genres_text = _("Unknown") else: genres_text = "/".join(genres_list[:2]) # Runtime and genres info_text = _("%(runtime)s min, %(genre)s") % \ {'runtime': self.movie.runtime, 'genre': genres_text} info = Label(0.032, "subtitle", 0.47, 0.24, info_text) info.set_ellipsize(pango.ELLIPSIZE_END) info.set_size(0.5124, 0.05208) self.add(info) # Stars (rating) star = Texture(self.theme.getImage("star")) star.hide() self.add(star) star2 = Texture(self.theme.getImage("star2")) star2.hide() self.add(star2) for i in range(self.movie.rating): tex = clutter.Clone(star) tex.set_position( self.get_abs_x(0.47) + (self.get_abs_x(0.0366) * i), self.get_abs_y(0.17)) tex.set_size(self.get_abs_x(0.024), self.get_abs_y(0.04)) self.add(tex) dark_star = 5 - self.movie.rating for i in range(dark_star): tex = clutter.Clone(star2) tex.set_position(self.get_abs_x(0.47) + (self.get_abs_x(0.0366) * \ (i + self.movie.rating)), self.get_abs_y(0.17)) tex.set_size(self.get_abs_x(0.024), self.get_abs_y(0.04)) self.add(tex) # Plot plot = Label(0.029, "subtitle", 0, 0, self.movie.plot) plot.set_justify(True) plot.set_line_wrap_mode(pango.WRAP_WORD) plot.set_line_wrap(True) plot.width = 0.5124 self.scroll_area = ScrollArea(0.33, 0.38, 0.5124, 0.3516, plot) self.add(self.scroll_area) # Actors self.add(Label(0.032, "title", 0.33, 0.8, _("Starring"))) actors_list = self.movie.actors if len(actors_list) == 0: actors_text = _("Unknown") else: actors_text = ", ".join(actors_list[:5]) actors = Label(0.032, "subtitle", 0.46, 0.8, actors_text) actors.set_ellipsize(pango.ELLIPSIZE_END) actors.set_size(0.5124, 0.05208) self.add(actors) # Directors self.add(Label(0.032, "title", 0.33, 0.86, _("Directed by"))) directors_list = self.movie.directors if len(directors_list) == 0: directors_text = _("Unknown") else: directors_text = ", ".join(directors_list[:2]) directors = Label(0.032, "subtitle", 0.46, 0.86, directors_text) directors.set_ellipsize(pango.ELLIPSIZE_END) directors.set_size(0.5124, 0.05208) self.add(directors) # Writers self.add(Label(0.032, "title", 0.33, 0.92, _("Written by"))) writers_list = self.movie.writers if len(directors_list) == 0: writers_text = _("Unknown") else: writers_text = ", ".join(writers_list[:2]) writers = Label(0.032, "subtitle", 0.46, 0.92, writers_text) writers.set_ellipsize(pango.ELLIPSIZE_END) writers.set_size(0.5124, 0.05208) self.add(writers) def create_menu(self): """ Create menu of the screen. This displayed the left side of the screen. """ self.menu = TextMenu(0.07, 0.1, 0.2196, 0.0781) self.menu.add_item(_("Watch"), None, "watch") self.menu.active = True self.add(self.menu) def _handle_up(self): '''Handle UserEvent.NAVIGATE_UP.''' if self.menu.active: self.menu.up() else: self.scroll_area.scroll_up() def _handle_down(self): '''Handle UserEvent.NAVIGATE_DOWN.''' if self.menu.active: self.menu.down() else: self.scroll_area.scroll_down() def _handle_left(self): '''Handle UserEvent.NAVIGATE_LEFT.''' self.menu.active = True self.scroll_area.active = False def _handle_right(self): '''Handle UserEvent.NAVIGATE_RIGHT.''' self.menu.active = False self.scroll_area.active = True def _handle_select(self, event=None): '''Handle UserEvent.NAVIGATE_SELECT.''' if self.menu.active: item = self.menu.selected_userdata if item == "watch": self.media_player.set_media(self.movie) self.media_player.play() self.callback("video_osd") def _handle_first_page(self): '''Handle UserEvent.NAVIGATE_FIRST_PAGE.''' self.scroll_area.scroll_to_top() def _handle_last_page(self): '''Handle UserEvent.NAVIGATE_LAST_PAGE.''' self.scroll_area.scroll_to_bottom() def _handle_previous_page(self): '''Handle UserEvent.NAVIGATE_PREVIOUS_PAGE.''' self.scroll_area.scroll_page_up() def _handle_next_page(self): '''Handle UserEvent.NAVIGATE_NEXT_PAGE.''' self.scroll_area.scroll_page_down()
class LyricsTab(Tab): '''Tab for the audio play screen to show lyrics''' def __init__(self, music_library, track, name="lyrics", tab_title=_("Lyrics")): Tab.__init__(self, name, tab_title) self.track = track self.lyrics_area = None self.library = music_library self.lyrics_text = "" if self.track.has_lyrics(): self.lyrics_text = self.track.lyrics lyrics = Label(0.037, "subtitle", 0, 0, self.lyrics_text) lyrics.set_line_wrap_mode(pango.WRAP_WORD) lyrics.width = 0.366 self.lyrics_area = ScrollArea(0.5, 0.23, 0.4, 0.57, lyrics) self.lyrics_area.connect("activated", self._on_activated) self.add(self.lyrics_area) self.connect('activated', self._on_activated) self.connect('deactivated', self._on_deactivated) else: # Display throbber animation while searching for lyrics self.throbber = LoadingAnimation(0.7, 0.5, 0.1) self.throbber.show() self.add(self.throbber) self.track.fetch_lyrics(self._lyrics_search_callback) def _lyrics_search_callback(self, lyrics_text): '''This function is called when lyrics search is over.''' self.throbber.hide() # Save the results to help determine if the tab can activate. self.lyrics_text = lyrics_text if lyrics_text == "": no_lyrics = Label(0.037, "title", 0.7, 0.5, _("No lyrics found for this track")) no_lyrics.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self.add(no_lyrics) else: lyrics = Label(0.037, "subtitle", 0, 0, lyrics_text) lyrics.set_line_wrap_mode(pango.WRAP_WORD) lyrics.width = 0.366 self.lyrics_area = ScrollArea(0.5, 0.23, 0.4, 0.57, lyrics) self.lyrics_area.connect("activated", self._on_activated) self.add(self.lyrics_area) self.library.save_lyrics(self.track, lyrics_text) def can_activate(self): ''' Lyrics tab can scroll the lyrics listing only if lyrics were found. ''' if self.lyrics_text == "": return False else: return True def _handle_up(self): '''Handle the up user event.''' if self.lyrics_area.on_top: return True # Move control back to tab bar else: return self.lyrics_area.scroll_up() def _handle_down(self): '''Handle the down user event.''' return self.lyrics_area.scroll_down() def _on_activated(self, event=None): '''Tab activated.''' if self.tab_group is not None: self.tab_group.active = False self.lyrics_area.active = True self.active = True return False def _on_deactivated(self, event=None): '''Tab deactivated.''' self.active = False self.lyrics_area.active = False return False