1 # debugging hack - add . to path
3 local_module_dir = os.path.join(os.path.dirname(sys.argv[0]), '..')
4 if os.path.isdir(local_module_dir):
5 sys.path.append(local_module_dir)
13 # we don't use the local DB...
15 from jamaui.player import Player, Playlist
16 from util import jsonprint
20 gobject.threads_init()
22 log = logging.getLogger(__name__)
27 if util.platform == 'maemo':
28 log.critical('Using GTK widgets, install "python2.5-hildon" '
29 'for this to work properly.')
31 log.critical('This ui only works in maemo')
34 from dbus.mainloop.glib import DBusGMainLoop
36 DBusGMainLoop(set_as_default=True)
38 _the_playerwindow = None
40 class PlayerWindow(hildon.StackableWindow):
41 def __init__(self, playlist=None):
42 hildon.StackableWindow.__init__(self)
43 self.set_title("jamaendo")
45 self.connect('hide', self.on_hide)
46 self.connect('destroy', self.on_destroy)
48 self.playlist = Playlist(playlist)
49 self.player = Player()
55 self.cover = gtk.Image()
56 self.cover.set_size_request(200, 200)
57 self.cover.set_from_stock(gtk.STOCK_CDROM, gtk.ICON_SIZE_DIALOG)
61 self.playlist_pos = gtk.Label()
62 self.track = gtk.Label()
63 self.progress = hildon.GtkHScale()
64 self.artist = gtk.Label()
65 self.album = gtk.Label()
67 self.set_labels('track name', 'artist', 'album', 0, 0)
69 vbox2.pack_start(self.track, True)
70 vbox2.pack_start(self.artist, False)
71 vbox2.pack_start(self.album, False)
72 vbox2.pack_start(self.playlist_pos, False)
73 vbox2.pack_start(self.progress, False)
75 hbox.pack_start(self.cover, True, True, 0)
76 hbox.pack_start(vbox2, True, True, 0)
78 vbox.pack_start(hbox, True, True, 0)
80 btns = gtk.HButtonBox()
81 btns.set_property('layout-style', gtk.BUTTONBOX_SPREAD)
83 vbox.pack_end(btns, False, True, 0)
85 self.add_stock_button(btns, gtk.STOCK_MEDIA_PREVIOUS, self.on_prev)
86 self.add_stock_button(btns, gtk.STOCK_MEDIA_PLAY, self.on_play)
87 self.add_stock_button(btns, gtk.STOCK_MEDIA_PAUSE, self.on_pause)
88 self.add_stock_button(btns, gtk.STOCK_MEDIA_STOP, self.on_stop)
89 self.add_stock_button(btns, gtk.STOCK_MEDIA_NEXT, self.on_next)
93 print "Created player window, playlist: %s" % (self.playlist)
95 def on_hide(self, wnd):
96 print "Hiding player window"
98 def on_destroy(self, wnd):
99 print "Destroying player window"
102 global _the_playerwindow
103 _the_playerwindow = None
105 def add_stock_button(self, btns, stock, cb):
106 btn = hildon.GtkButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
107 btn.set_relief(gtk.RELIEF_NONE)
108 btn.set_image(gtk.image_new_from_stock(stock, gtk.ICON_SIZE_SMALL_TOOLBAR))
109 btn.connect('clicked', cb)
112 def set_labels(self, track, artist, album, playlist_pos, playlist_size):
113 self.playlist_pos.set_markup('<span size="small">%s/%s songs</span>'%(playlist_pos, playlist_size))
114 self.track.set_markup('<span size="x-large">%s</span>'%(track))
115 self.artist.set_markup('<span size="large">%s</span>'%(artist))
116 self.album.set_markup('<span foreground="#aaaaaa">%s</span>'%(album))
118 def update_state(self):
119 item = self.playlist.current()
123 print "current:", item
124 self.set_labels(item.name, item.artist_name, item.album_name,
125 self.playlist.current_index(), self.playlist.size())
126 coverfile = jamaendo.get_album_cover(int(item.album_id), size=200)
127 print "coverfile:", coverfile
128 self.cover.set_from_file(coverfile)
130 def play_tracks(self, tracks):
131 self.playlist = Playlist(playlist)
132 self.player.play(self.playlist)
135 def on_play(self, button):
136 self.player.play(self.playlist)
138 def on_pause(self, button):
140 def on_prev(self, button):
143 def on_next(self, button):
146 def on_stop(self, button):
149 def open_playerwindow(tracks):
150 global _the_playerwindow
151 if _the_playerwindow:
152 hildon.WindowStack.push_1(_the_playerwindow)
153 _the_playerwindow.play_tracks(tracks)
155 _the_playerwindow = PlayerWindow(tracks)
156 _the_playerwindow.show_all()
157 return _the_playerwindow
159 class SearchWindow(hildon.StackableWindow):
161 hildon.StackableWindow.__init__(self)
162 self.set_title("Search")
164 vbox = gtk.VBox(False, 0)
167 self.entry = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT)
168 self.entry.set_placeholder("Search")
169 self.entry.connect('activate', self.on_search)
170 btn = hildon.GtkButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
172 btn.connect('clicked', self.on_search)
173 hbox.pack_start(self.entry, True, True, 0)
174 hbox.pack_start(btn, False)
177 playbtn = hildon.GtkButton(gtk.HILDON_SIZE_FINGER_HEIGHT)
178 playbtn.set_label("Play selected")
179 playbtn.connect('clicked', self.play_selected)
180 btnbox.pack_start(playbtn, False)
182 self.results = hildon.TouchSelector(text=True)
183 self.results.connect("changed", self.selection_changed)
184 self.results.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
186 vbox.pack_start(hbox, False)
187 vbox.pack_start(self.results, True, True, 0)
188 vbox.pack_start(btnbox, False)
196 def on_search(self, w):
197 txt = self.entry.get_text()
198 for album in jamaendo.search_albums(query=txt):
199 title = "%s - %s" % (album.artist_name, album.name)
200 self.idmap[title] = album
201 self.results.append_text(title)
203 def selection_changed(self, results, userdata):
206 def play_selected(self, btn):
207 current_selection = self.results.get_current_text()
209 album = self.idmap[current_selection]
210 tracks = jamaendo.get_tracks(album.ID)
212 wnd = open_playerwindow(tracks)
215 class RadiosWindow(hildon.StackableWindow):
217 hildon.StackableWindow.__init__(self)
218 self.set_title("Radios")
220 label = gtk.Label("Radios")
221 vbox = gtk.VBox(False, 0)
222 vbox.pack_start(label, True, True, 0)
225 class FeaturedWindow(hildon.StackableWindow):
227 hildon.StackableWindow.__init__(self)
228 self.set_title("Featured")
230 label = gtk.Label("featured")
231 vbox = gtk.VBox(False, 0)
232 vbox.pack_start(label, True, True, 0)
235 class PlaylistsWindow(hildon.StackableWindow):
237 hildon.StackableWindow.__init__(self)
238 self.set_title("Playlists")
240 label = gtk.Label("playlists")
241 vbox = gtk.VBox(False, 0)
242 vbox.pack_start(label, True, True, 0)
245 class FavoritesWindow(hildon.StackableWindow):
247 hildon.StackableWindow.__init__(self)
248 self.set_title("Favorites")
250 label = gtk.Label("favorites")
251 vbox = gtk.VBox(False, 0)
252 vbox.pack_start(label, True, True, 0)
255 class Jamaui(object):
256 _BG = 'bg.png' # /opt/jamaendo/data/bg.png
263 def create_window(self):
264 self.app = hildon.Program()
265 self.window = hildon.StackableWindow()
266 self.app.add_window(self.window)
268 self.window.set_title("jamaendo")
269 self.window.connect("destroy", self.destroy)
271 def create_menu(self):
272 self.menu = hildon.AppMenu()
274 #search = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
275 #search.set_label("Search")
276 #search.connect("clicked", self.on_search)
277 #self.menu.append(search)
279 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
280 player.set_label("Open player")
281 player.connect("clicked", self.on_player)
282 self.menu.append(player)
284 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
285 player.set_label("Favorites")
286 player.connect("clicked", self.on_favorites)
287 self.menu.append(player)
289 player = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
290 player.set_label("Playlists")
291 player.connect("clicked", self.on_playlists)
292 self.menu.append(player)
294 # Don't use localdb ATM
295 #refresh = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
296 #refresh.set_label("Refresh")
297 #refresh.connect("clicked", self.on_refresh)
298 #self.menu.append(refresh)
300 menu_about = hildon.GtkButton(gtk.HILDON_SIZE_AUTO)
301 menu_about.set_label("About")
302 menu_about.connect("clicked", self.show_about, self.window)
303 self.menu.append(menu_about)
304 gtk.about_dialog_set_url_hook(self.open_link, None)
307 self.window.set_app_menu(self.menu)
309 def find_resource(self, name):
310 if os.path.isfile(os.path.join('data', name)):
311 return os.path.join('data', name)
312 elif os.path.isfile(os.path.join('/opt/jaemendo', name)):
313 return os.path.join('/opt/jaemendo', name)
314 elif os.path.isfile(os.path.join('/usr/share/jaemendo', name)):
315 return os.path.join('/usr/share/jaemendo', name)
319 def setup_widgets(self):
320 bgimg = self.find_resource(self._BG)
322 background, mask = gtk.gdk.pixbuf_new_from_file(bgimg).render_pixmap_and_mask()
323 self.window.realize()
324 self.window.window.set_back_pixmap(background, False)
326 bbox = gtk.HButtonBox()
327 alignment = gtk.Alignment(xalign=0.0, yalign=0.8, xscale=1.0)
329 bbox.set_property('layout-style', gtk.BUTTONBOX_SPREAD)
331 self.window.add(alignment)
333 self.add_mainscreen_button("Featured", "Most listened to", self.on_featured)
334 self.add_mainscreen_button("Radios", "The best in free music", self.on_radios)
335 self.add_mainscreen_button("Search", "Search for artists/albums", self.on_search)
337 self.window.show_all()
339 def add_mainscreen_button(self, title, subtitle, callback):
340 btn = hildon.Button(gtk.HILDON_SIZE_THUMB_HEIGHT,
341 hildon.BUTTON_ARRANGEMENT_VERTICAL)
342 btn.set_text(title, subtitle)
343 btn.set_property('width-request', 225)
344 btn.connect('clicked', callback)
347 def destroy(self, widget):
350 def show_about(self, w, win):
351 dialog = gtk.AboutDialog()
352 dialog.set_website("http://github.com/krig")
353 dialog.set_website_label("http://github.com/krig")
354 dialog.set_authors(("Kristoffer Gronlund (Purple Scout AB)",))
355 dialog.set_comments("""Jamaendo plays music from the music catalog of JAMENDO.
357 JAMENDO is an online platform that distributes musical works under Creative Commons licenses.""")
358 dialog.set_version('')
362 def open_link(self, d, url, data):
364 webbrowser.open_new(url)
367 #def on_refresh(self, button):
368 # dialog = RefreshDialog()
373 def on_featured(self, button):
374 self.featuredwnd = FeaturedWindow()
375 self.featuredwnd.show_all()
377 def on_radios(self, button):
378 self.radiownd = RadioWindow()
379 self.radiownd.show_all()
381 def on_search(self, button):
382 self.searchwnd = SearchWindow()
383 self.searchwnd.show_all()
385 def on_playlists(self, button):
386 self.playlistswnd = PlaylistsWindow()
387 self.playlistswnd.show_all()
389 def on_favorites(self, button):
390 self.favoriteswnd = FavoritesWindow()
391 self.favoriteswnd.show_all()
393 def on_player(self, button):
394 open_playerwindow([])
397 def on_search(self, button):
399 self.searchbar.show()
401 self.searchstore = gtk.ListStore(gobject.TYPE_STRING)
402 iter = self.searchstore.append()
403 self.searchstore.set(iter, 0, "Test1")
404 iter = self.searchstore.append()
405 self.searchstore.set(iter, 0, "Test2")
406 self.searchbar = hildon.FindToolbar("Search", self.searchstore, 0)
407 self.searchbar.set_active(0)
408 self.window.add_toolbar(self.searchbar)
409 self.searchbar.show()
413 ossohelper.application_init('org.jamaendo', '0.1')
417 self.window.show_all()
419 ossohelper.application_exit()
421 if __name__=="__main__":