ocarina/trunk/src/contentPane.py

369 lines
9.3 KiB
Python

import gtk
import gobject
import os
import thread
from label import Label
from queue import Queue
from playlist import Playlist
from liblist import LibList
from image import Image
from check import CheckButton
from button import Button
from scrobbler import Scrobbler
from controlPanel import ControlPanel
# This is the main content area
class ContentPane(gtk.HBox):
def __init__(self,data):
gtk.HBox.__init__(self,False,0)
self.data = data
self.divider = gtk.HPaned()
self.divider.set_position(self.data.divider)
self.divider.connect("notify",self.moveDivider)
self.divider.show()
self.add(self.divider)
self.makeLeftSide()
self.makeRightSide()
self.show()
# Load up the last saved song
try:
self.library.loadSong(self.data.library.files[self.data.curSong])
except:
True == True
self.gotoCurSong()
# Left side is scrobbler, album art, maybe others at some point?
def makeLeftSide(self):
vbox = gtk.VBox(False,0)
vbox.show()
self.albumArt = Image(None,None)
vbox.pack_start(self.albumArt,False,False,0)
self.data.scrobbler = Scrobbler(self.data)
vbox.pack_start(self.data.scrobbler,False,False,0)
self.divider.add(vbox)
# Right side has tabs, current song info, controls, and more
def makeRightSide(self):
vbox = gtk.VBox(False,0)
vbox.show()
self.divider.add2(vbox)
self.makeInfoArea(vbox)
self.makeTabs(vbox)
self.makeControls(vbox)
hbox = gtk.HBox(False,0)
hbox.pack_start(self.library.pbaralign,False,False,0)
hbox.pack_end(self.playlist.align,False,False,0)
hbox.pack_end(self.queue.align,False,False,0)
hbox.pack_end(self.library.align,False,False,0)
vbox.pack_start(hbox,False,False,0)
hbox.show()
#self.changedTab(None,None,0)
self.status = ""
self.filterCount = 0
def setLabels(self):
title = ""
album = ""
artist = ""
if self.data.song:
title = self.data.song.info.title
album = "from "+self.data.song.info.album
artist = "by "+self.data.song.info.artist
self.title.set_text(title)
self.album.set_text(album)
self.artist.set_text(artist)
# This is the upper end of the right side of the divider
# Current song labels, and the filter entry
def makeInfoArea(self,box):
# Make the labels
self.title = Label("",13000,700)
self.album = Label("",10000,400)
self.artist = Label("",10000,400)
self.setLabels()
infobox = gtk.HBox(False,0)
infobox.show()
infolabels = gtk.VBox(False,0)
infolabels.show()
infobox.pack_start(infolabels,False,False,0)
# Pack the labels into a vbox
infolabels.pack_start(self.title,False,False,0)
infolabels.pack_start(self.album,False,False,0)
infolabels.pack_start(self.artist,False,False,0)
# Make the filter bar
self.searchBar = gtk.Entry()
self.searchBar.show()
self.searchBar.connect("changed",self.textTyped)
searchalign = gtk.Alignment(1,1,0,0)
searchalign.show()
searchalign.add(self.searchBar)
infobox.pack_end(searchalign,False,False,0)
# Pack it all in
box.pack_start(infobox,False,False,0)
# Makes the playlist/queue/library tabs
def makeTabs(self,box):
self.tabs = gtk.Notebook()
box.add(self.tabs)
self.tabs.show()
# Ann array of function pointers that gets passed to List
funcs = (self.next,self.setLabels,self.plause,self.setAlbumArt)
self.queue = Queue(self.data,funcs)
self.playlist = Playlist(self.data,self.queue,funcs)
self.playlist.visible("show")
self.library = LibList(self.data,self.playlist,self.queue,funcs)
self.data.library.libview = self.library
self.tabs.append_page(self.playlist,self.playlist.label)
self.tabs.append_page(self.queue,self.queue.label)
self.tabs.append_page(self.library,self.library.label)
self.curTab = 0
self.tabs.connect("switch-page",self.changedTab)
#self.filter("")
# Makes buttons and progress bar
def makeControls(self,vbox):
box = gtk.HBox(False,0)
box.show()
self.pauseImg = Image(None,gtk.STOCK_MEDIA_PAUSE)
box.pack_start(CheckButton("Random",self.toggleRand,self.data.random),False,False,0)
hbox = gtk.VBox()
hbox.show()
pbar = gtk.ProgressBar()
pbar.show()
pbar.set_fraction(0)
event = gtk.EventBox()
event.show()
event.add(pbar)
hbox.pack_start(event,True,False,0)
event.connect("button_release_event",self.pbarclick,pbar)
box.pack_start(hbox,True,True,0)
gobject.timeout_add(500,self.updatePBar,pbar)
(self.playImg,self.plauseBtn) = self.makeButton("plause",gtk.STOCK_MEDIA_PLAY,self.plause,box)
(self.stopImg,self.stopBtn) = self.makeButton("stop",gtk.STOCK_MEDIA_STOP,self.stop,box)
(self.nextImg,self.nextBtn) = self.makeButton("next",gtk.STOCK_MEDIA_NEXT,self.next,box)
vbox.pack_start(box,False,False,0)
def makeButton(self,name,img,func,box):
image = Image(None,img)
button = Button(name,image,None,func)
box.pack_start(button,False,False,0)
return image,button
# Turn shuffle on/off
def toggleRand(self,widgit):
self.data.random = not self.data.random
# A callback for when the user seeks into the song
def pbarclick(self,widgit,data,pbar):
if data.button==1:
prcnt = float(data.x) / float(pbar.get_allocation()[2])
self.data.song.seek(int(prcnt * self.data.song.info.duration * 1000000000))
# Updates the progress bar to the current % of song
def updatePBar(self,pbar):
time = 0
if not self.data.song:
return True
try:
time = self.data.song.curTime()
except:
time = 0
if self.data.song.info.duration > 0:
pbar.set_fraction(float(time)/self.data.song.info.duration)
pbar.set_text(self.data.song.info.fixTime(time) + " / " + self.data.song.info.length)
return True
# Called when the play/pause button is clicked
def plause(self,widgit,data):
self.data.song.plause()
self.changeImg()
# Stop the song, change plause button
def stop(self,widgit,data):
self.data.song.stop()
self.changeImg()
# Advance to the next song, save updates
def next(self,widgit,data):
loaded = self.queue.getNext()
#print loaded
if loaded == False:
loaded = self.playlist.getNext()
if not (self.status == "pafter") and (loaded==True):
self.plause(None,None)
self.data.scrobbler.nowPlaying(self.data.song.info)
#self.gotoCurSong()
self.changeImg()
self.status = ""
self.data.dump(True)
# Scroll to the current song
def gotoCurSong(self):
self.playlist.gotoCurSong()
self.queue.gotoCurSong()
self.library.gotoCurSong()
# Change the state of the play/pause button
def changeImg(self):
self.plauseBtn.set_image(self.playImg)
if self.data.song.playing == True:
self.plauseBtn.set_image(self.pauseImg)
# Load album art
def setAlbumArt(self,file):
file = file.rsplit(os.path.sep,1)[0]
file = os.path.join(file,"AlbumArt.jpg")
self.albumArt.hide()
# Fetch album art if we don't have it yet
if not os.path.exists(file):
info = self.data.song.info
thread.start_new_thread(self.fetchAlbumArt,(info.artist,info.album,file))
else:
self.albumArt.set(file)
self.resizeAlbumArt()
self.albumArt.show()
def fetchAlbumArt(self,artist,album,file):
info = self.data.song.info
self.data.scrobbler.fetchAlbumArt(artist,album,file)
if os.path.exists(file):
self.albumArt.set(file)
self.resizeAlbumArt()
self.albumArt.show()
def resizeAlbumArt(self):
self.albumArt.scale(self.data.divider)
# This is called when a user changes tabs
# Do nothing if the user selects the same tab
# Otherwise, hide objects on the old visible tab and show the new visible tab
# Also updates self.curTab
def changedTab(self,widgit,page,pagenum):
if self.curTab == pagenum:
return
if self.curTab == 0:
self.playlist.visible("hide")
elif self.curTab == 1:
self.queue.visible("hide")
else:
self.library.visible("hide")
self.curTab = pagenum
if pagenum == 0:
self.playlist.visible("show")
elif pagenum == 1:
self.queue.visible("show")
else:
self.library.visible("show")
self.textTyped(self.searchBar)
def dumpLib(self):
self.library.drop()
self.playlist.drop()
self.queue.drop()
# text was typed, refilter rows
# Arrange to filter rows in 250ms, as long as no additional text has been typed
def textTyped(self,entry):
search = entry.get_text().lower()
self.filterCount+=1
gobject.timeout_add(250,self.filter,search)
# Filter the rows of the current tab
# Do a quickFilter on nonvisible tabs
# Decrements self.filterCount
def filter(self,search):
# If filterCount is 0, no additional text has been typed
self.filterCount -= 1
if self.filterCount > 0:
return
# It is ok to filter rows
if self.curTab == 0:
self.playlist.filterRows(search)
tabs = [1,2]
elif self.curTab == 1:
self.queue.filterRows(search)
tabs = [0,2]
else:
self.library.filterRows(search)
tabs = [0,1]
for tab in tabs:
if tab == 0:
self.playlist.filterQuick(search)
elif tab == 1:
self.queue.filterQuick(search)
else:
self.library.filterQuick(search)
# Coose to pause after the current song or not
def setStatus(self,status):
if status == "pafter":
self.status = "pafter"
else:
print status
# Store the width of the current tabs columns
def storeCols(self):
if self.curTab == 0:
self.playlist.storeCols()
elif self.curTab == 1:
self.queue.storeCols()
else:
self.library.storeCols()
# This is called whenever the divider changes
def moveDivider(self,pane,event):
if event.name=="position":
self.data.divider = pane.get_position()
self.resizeAlbumArt()