class ListIndicator(Base, clutter.Group): """ ListIndicator displays 'current / maximum' value label and arrows. """ # Direction # HORIZONTAL layout: ARROW_LEFT current / maximum ARROW_RIGHT # VERITCAL layout: current / maximum ARROW_UP ARROW_DOWN HORIZONTAL = 0 VERTICAL = 1 def __init__(self, x, y, width, height, direction): Base.__init__(self) clutter.Group.__init__(self) self.config = Configuration() # Size self.width = self.get_abs_x(width) self.height = self.get_abs_y(height) self.direction = direction self.delimiter = " | " self.current = 1 self.maximum = 1 self.theme = self.config.theme self.fg = self.theme.get_color("arrow_foreground") self.bg = self.theme.get_color("arrow_background") if direction == ListIndicator.VERTICAL: text_x_pos = width / 3 else: text_x_pos = width / 2 self.text = Label( height * 0.8, "text", text_x_pos, height / 2, str(self.maximum) + self.delimiter + str(self.maximum)) self.text.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self.add(self.text) # Create arrows and calculate positions on screen if direction == ListIndicator.VERTICAL: self.arrow1 = ArrowTexture(5 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.UP) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.DOWN) elif direction == ListIndicator.HORIZONTAL: self.arrow1 = ArrowTexture(height / 2, height / 2, height / 2, self.fg, self.bg, ArrowTexture.LEFT) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.RIGHT) self.add(self.arrow1) self.add(self.arrow2) self.set_position(self.get_abs_x(x), self.get_abs_y(y)) def set_current(self, value): """ Set current value @param number: Current value (between 1 - maximum) """ if value > 0 and value <= self.maximum: self.current = value self._update_text() # Bounce arrow if user has reached the limit if self.current == 1: self.arrow1.bounce() elif self.current == self.maximum: self.arrow2.bounce() def get_current(self): """ Get current value @return Current value (integer) """ return self.current def set_maximum(self, value): """ Set maximum value of the indicator @param number: Set maximum value """ self.maximum = value self._update_text() def get_maximum(self): """ Get maximum value. @return Max value (integer) """ return self.maximum def set_delimiter(self, delimiter): """ Set delimiter text that is displayed between current and maximum value. Default delimiter text is ' / ' spaces included. @param delimiter: delimiter text """ self.delimiter = delimiter self._update_text() def show_position(self): """ Show position text that indicates the current position of the content. """ self.text.show() def hide_position(self): """ Hide position text that indicates the current position of the content. If this is called then indicator shows only arrows. """ self.text.hide() def _update_text(self): """Update the text label""" self.text.set_text( str(self.current) + self.delimiter + str(self.maximum))
class Album(Screen): '''Screen that allows user to browse and play tracks of the music album.''' def __init__(self, media_player, music_library, move_to_new_screen_callback, album): Screen.__init__(self, 'Album', move_to_new_screen_callback) self.media_player = media_player self.theme = self.config.theme self.library = music_library self.album = album self.art = None self.track_menu = None # Create and initialize screen items self.track_menu = self._create_track_menu() self.add(self.track_menu) self._create_album_cover_texture() self._create_album_info() self.screen_title = Label(0.13, "screentitle", 0, 0.87, "") self.screen_title.set_ellipsize(pango.ELLIPSIZE_END) self.screen_title.width = 0.8 self.add(self.screen_title) #List indicator self.li = ListIndicator(0.74, 0.85, 0.2, 0.045, ListIndicator.VERTICAL) self.li.set_maximum(len(self.album.tracks)) self.add(self.li) self.track_menu.active = True self.track_menu.connect('selected', self._on_menu_selected) self.track_menu.connect('moved', self._display_selected_track) def _create_album_cover_texture(self): """ Create a texture that is displayed next to track list. This texture displays album cover art. """ if(self.album.has_album_art()): pixbuf = gtk.gdk.pixbuf_new_from_file(self.album.album_art_url) else: pixbuf = gtk.gdk.pixbuf_new_from_file( self.theme.getImage("default_album_art")) self.art = EyeCandyTexture(0.1, 0.13, 0.3148, 0.5599, pixbuf) self.art.set_rotation(clutter.Y_AXIS, 25, 0, 0, 0) self.add(self.art) def _create_album_info(self): """ Create album info labels. """ if self.album.year != 0: album_text = self.album.title + ", " + str(self.album.year) else: album_text = self.album.title album = Label(0.0416, "text", 0.5, 0.13, album_text, font_weight="bold") album.set_ellipsize(pango.ELLIPSIZE_END) album.set_line_wrap(False) album.width = 0.45 self.add(album) length = str(self.album.length / 60) num_of_tracks_text = _("%(total)s tracks, %(time)s minutes") % \ {'total': len(self.album.tracks), 'time': length} num_of_tracks = Label(0.028, "subtitle", 0.5, 0.18, num_of_tracks_text, font_weight="bold") self.add(num_of_tracks) def _create_track_menu(self): """ Create track menu. This menu contains list of all tracks on album. """ menu = TextMenu(0.4978, 0.2344, 0.4393, 0.0781) tracks = self.album.tracks tracks_list = [[track.title, track.length_string, track] \ for track in tracks] menu.async_add(tracks_list) return menu def is_interested_in_play_action(self): """ Override function from Screen class. See Screen class for better documentation. """ return True def execute_play_action(self): """ Override function from Screen class. See Screen class for better documentation. """ track = self.track_menu.selected_userdata self.media_player.set_media(track) self.media_player.play() def _handle_up(self): '''Handle UserEvent.NAVIGATE_UP.''' self.track_menu.up() def _handle_down(self): '''Handle UserEvent.NAVIGATE_DOWN.''' self.track_menu.down() def _handle_select(self, event=None): '''Handle UserEvent.NAVIGATE_SELECT.''' track = self.track_menu.selected_userdata kwargs = { 'track' : track } self.callback("audio_play", kwargs) def _on_menu_selected(self, actor=None): '''Handle a *select command* if an item was selected.''' self._handle_select() def _display_selected_track(self, actor=None): '''Update of the list indicator and the screen's title''' self.li.set_current(self.track_menu.selected_index + 1) track = self.track_menu.selected_userdata self.screen_title.set_text(track.artist) self.screen_title.show()
class ListIndicator(Base, clutter.Group): """ ListIndicator displays 'current / maximum' value label and arrows. """ # Direction # HORIZONTAL layout: ARROW_LEFT current / maximum ARROW_RIGHT # VERITCAL layout: current / maximum ARROW_UP ARROW_DOWN HORIZONTAL = 0 VERTICAL = 1 def __init__(self, x, y, width, height, direction): Base.__init__(self) clutter.Group.__init__(self) self.config = Configuration() # Size self.width = self.get_abs_x(width) self.height = self.get_abs_y(height) self.direction = direction self.delimiter = " | " self.current = 1 self.maximum = 1 self.theme = self.config.theme self.fg = self.theme.get_color("arrow_foreground") self.bg = self.theme.get_color("arrow_background") if direction == ListIndicator.VERTICAL: text_x_pos = width / 3 else: text_x_pos = width / 2 self.text = Label(height * 0.8, "text", text_x_pos, height / 2, str(self.maximum) + self.delimiter + str(self.maximum)) self.text.set_anchor_point_from_gravity(clutter.GRAVITY_CENTER) self.add(self.text) # Create arrows and calculate positions on screen if direction == ListIndicator.VERTICAL: self.arrow1 = ArrowTexture(5 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.UP) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.DOWN) elif direction == ListIndicator.HORIZONTAL: self.arrow1 = ArrowTexture(height / 2, height / 2, height / 2, self.fg, self.bg, ArrowTexture.LEFT) self.arrow2 = ArrowTexture(6 * width / 7, height / 2, height / 2, self.fg, self.bg, ArrowTexture.RIGHT) self.add(self.arrow1) self.add(self.arrow2) self.set_position(self.get_abs_x(x), self.get_abs_y(y)) def set_current(self, value): """ Set current value @param number: Current value (between 1 - maximum) """ if value > 0 and value <= self.maximum: self.current = value self._update_text() # Bounce arrow if user has reached the limit if self.current == 1: self.arrow1.bounce() elif self.current == self.maximum: self.arrow2.bounce() def get_current(self): """ Get current value @return Current value (integer) """ return self.current def set_maximum(self, value): """ Set maximum value of the indicator @param number: Set maximum value """ self.maximum = value self._update_text() def get_maximum(self): """ Get maximum value. @return Max value (integer) """ return self.maximum def set_delimiter(self, delimiter): """ Set delimiter text that is displayed between current and maximum value. Default delimiter text is ' / ' spaces included. @param delimiter: delimiter text """ self.delimiter = delimiter self._update_text() def show_position(self): """ Show position text that indicates the current position of the content. """ self.text.show() def hide_position(self): """ Hide position text that indicates the current position of the content. If this is called then indicator shows only arrows. """ self.text.hide() def _update_text(self): """Update the text label""" self.text.set_text( str(self.current) + self.delimiter + str(self.maximum))