~mblayman/entertainer/clean-up-1.0

« back to all changes in this revision

Viewing changes to entertainerlib/gui/tabs/albums_tab.py

  • Committer: Paul Hummer
  • Date: 2008-06-21 06:10:59 UTC
  • mto: This revision was merged to the branch mainline in revision 256.
  • Revision ID: paul@ubuntu.com-20080621061059-a55dg8p5hlr0k1jr
Moves many files and directories

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (c) 2009 Entertainer Developers - See COPYING - GPLv2
2
 
'''Albums tab which displays albums and allows users to select them'''
3
 
# pylint: disable-msg=W1001
4
 
 
5
 
import clutter
6
 
import gobject
7
 
import pango
8
 
 
9
 
from entertainerlib.gui.tabs.tab import Tab
10
 
from entertainerlib.gui.widgets.image_menu import ImageMenu
11
 
from entertainerlib.gui.widgets.image_menu_item import ImageMenuItem
12
 
from entertainerlib.gui.widgets.label import Label
13
 
from entertainerlib.gui.widgets.list_indicator import ListIndicator
14
 
from entertainerlib.gui.widgets.loading_animation import (
15
 
    LoadingAnimation)
16
 
from entertainerlib.gui.widgets.texture import Texture
17
 
 
18
 
class AlbumsTab(Tab):
19
 
    '''Tab to show album listings'''
20
 
 
21
 
    def __init__(self, albums, move_to_new_screen_callback, name="albums",
22
 
        tab_title=_("Albums")):
23
 
        Tab.__init__(self, name, tab_title, move_to_new_screen_callback)
24
 
 
25
 
        # Start the loading animation while the menu is loading
26
 
        self.throbber = LoadingAnimation(40,
27
 
            clutter.Color(255, 255, 255, 255),
28
 
            clutter.Color(128, 128, 128, 128))
29
 
        self.throbber.set_position(self.get_abs_x(0.1), self.get_abs_y(0.1))
30
 
        self.throbber.show()
31
 
        self.add(self.throbber)
32
 
 
33
 
        if len(albums) < 4:
34
 
            # XXX: laymansterms - This is "less than elegant." I'm not fixing
35
 
            # ImageMenu right now so we can't get rid of tex_size_x and y yet.
36
 
            # We really need to eliminate the concept tex_size_y, but it will
37
 
            # have to wait for now.
38
 
            x_percent = 0.2928
39
 
            tex_size_x = self.get_abs_x(x_percent)
40
 
            tex_size_y = self.get_abs_y(0.5208)
41
 
            row_count = 1
42
 
            visible = 3
43
 
        elif len(albums) < 13:
44
 
            x_percent = 0.1464
45
 
            tex_size_x = self.get_abs_x(x_percent)
46
 
            tex_size_y = self.get_abs_y(0.2604)
47
 
            row_count = 2
48
 
            visible = 6
49
 
        else:
50
 
            x_percent = 0.1098
51
 
            tex_size_x = self.get_abs_x(x_percent)
52
 
            tex_size_y = self.get_abs_y(0.1953)
53
 
            row_count = 3
54
 
            visible = 8
55
 
 
56
 
        # Create albums menu
57
 
        self.menu = ImageMenu(self.theme)
58
 
        self.menu.set_row_count(row_count)
59
 
        self.menu.set_visible_column_count(visible)
60
 
        self.menu.set_item_size(tex_size_x, tex_size_y)
61
 
 
62
 
        # Default texture
63
 
        self.default_cover = Texture(self.theme.getImage("default_album_art"))
64
 
 
65
 
        gobject.timeout_add(50, self._async_menu_build, albums, x_percent)
66
 
 
67
 
        self.menu.set_position(self.get_abs_x(0.0586), self.get_abs_y(0.1823))
68
 
        self.menu.set_active(False)
69
 
        self.menu.show()
70
 
 
71
 
        if self.config.show_effects():
72
 
            self.menu.set_animate(True)
73
 
 
74
 
        self.add(self.menu)
75
 
 
76
 
        self.li = ListIndicator(0.18, 0.045, ListIndicator.HORIZONTAL)
77
 
        self.li.set_position(self.get_abs_x(0.9297) - self.li.get_width(),
78
 
            self.get_abs_y(0.7943))
79
 
        self.li.set_delimiter(" | ")
80
 
        self.li.set_maximum(len(albums))
81
 
        self.li.set_current(1)
82
 
        self.li.show()
83
 
        self.add(self.li)
84
 
 
85
 
        # Create album information (displays current menuitem information)
86
 
        self.album_title = Label(0.045, "title", 0.22, 0.79, "")
87
 
        self.album_title.set_ellipsize(pango.ELLIPSIZE_END)
88
 
        self.album_title.width = 0.366
89
 
        self.add(self.album_title)
90
 
 
91
 
        self.album_artist = Label(0.037, "subtitle", 0.22, 0.86, "")
92
 
        self.album_artist.set_ellipsize(pango.ELLIPSIZE_END)
93
 
        self.album_artist.width = 0.366
94
 
        self.add(self.album_artist)
95
 
 
96
 
        self.album_tracks = Label(0.037, "subtitle", 0.22, 0.91, "")
97
 
        self.add(self.album_tracks)
98
 
 
99
 
        self._selected_album = None
100
 
        gobject.timeout_add(50, self._init_selected_album)
101
 
 
102
 
    def _async_menu_build(self, albums, item_size_percent):
103
 
        """
104
 
        This function is called as an async callback. It is also a recursive
105
 
        function. This allows us to load menu items in the background without
106
 
        blocking the user interface.
107
 
        """
108
 
 
109
 
        # Check if we should stop recursive calls (menu is complete)
110
 
        if len(albums) > 0:
111
 
            album = albums[0]
112
 
            if album.has_album_art():
113
 
                texture = Texture(album.get_album_art_url())
114
 
            else:
115
 
                texture = clutter.CloneTexture(self.default_cover)
116
 
 
117
 
            item = ImageMenuItem(item_size_percent, 1, texture)
118
 
            item.set_userdata(album)
119
 
            self.menu.add_actor(item)
120
 
            # Recursive call, remove first album from the list
121
 
            gobject.timeout_add(25, self._async_menu_build, albums[1:],
122
 
                item_size_percent)
123
 
            return False
124
 
        else:
125
 
            self.throbber.hide()
126
 
            # Done loading the albums, notify gobject to stop calling menu build
127
 
            return False
128
 
 
129
 
    def _init_selected_album(self):
130
 
        '''The menu is loaded dynamically so the current menu item may not be
131
 
        available initially. Keep trying until the value is available'''
132
 
        try:
133
 
            self._selected_album = \
134
 
                self.menu.get_current_menuitem().get_userdata()
135
 
            # Stop gobject
136
 
            return False
137
 
        except IndexError:
138
 
            # Item must not be available yet, continue to call
139
 
            return True
140
 
 
141
 
    def _get_selected_album(self):
142
 
        '''Get the currently selected album from the menu'''
143
 
        return self.menu.get_current_menuitem().get_userdata()
144
 
 
145
 
    selected_album = property(_get_selected_album)
146
 
 
147
 
    def can_activate(self):
148
 
        '''Albums tab will always be created from an existing artist with at
149
 
        least one album'''
150
 
        return True
151
 
 
152
 
    def set_active(self, boolean):
153
 
        """
154
 
        Override method from parent class.
155
 
        @param boolean: True to set this tab active, False to set inactive
156
 
        """
157
 
        Tab.set_active(self, boolean)
158
 
        if boolean:
159
 
            self._update_album_info(
160
 
                self.menu.get_current_menuitem().get_userdata())
161
 
            self.menu.set_active(True)
162
 
        else:
163
 
            self.menu.set_active(False)
164
 
 
165
 
    def _update_album_info(self, album):
166
 
        '''Update the album information labels'''
167
 
        self.album_title.set_text(album.get_title())
168
 
        self.album_artist.set_text(album.get_artist())
169
 
        self.album_tracks.set_text(_("%(total)s tracks") % \
170
 
            {'total': album.get_number_of_tracks()})
171
 
 
172
 
    def _update_menu(self, direction):
173
 
        '''Update the menu based on the provided menu direction'''
174
 
        self.menu.move(direction)
175
 
        self._update_album_info(self.menu.get_current_menuitem().get_userdata())
176
 
        self.li.set_current(self.menu.get_current_position() + 1)
177
 
        return False
178
 
 
179
 
    def _handle_up(self):
180
 
        '''Handle the up user event'''
181
 
        if self.menu.get_cursor_position()[1] == 0:
182
 
            return True # Move control back to tab bar
183
 
        else:
184
 
            return self._update_menu(self.menu.UP)
185
 
 
186
 
    def _handle_down(self):
187
 
        '''Handle the down user event'''
188
 
        return self._update_menu(self.menu.DOWN)
189
 
 
190
 
    def _handle_left(self):
191
 
        '''Handle the left user event'''
192
 
        return self._update_menu(self.menu.LEFT)
193
 
 
194
 
    def _handle_right(self):
195
 
        '''Handle the right user event'''
196
 
        return self._update_menu(self.menu.RIGHT)
197
 
 
198
 
    def _handle_select(self):
199
 
        '''Handle the select user event'''
200
 
        album = self.menu.get_current_menuitem().get_userdata()
201
 
        kwargs = { 'album' : album }
202
 
        self.callback("album", kwargs)
203
 
        return False
204