From 920ce35570143728a4477d4350ab5afaae10ec00 Mon Sep 17 00:00:00 2001 From: bjschuma Date: Mon, 29 Jun 2009 03:13:12 +0000 Subject: [PATCH] buttons, images, checkboxes, scrolling to current track,toggling random git-svn-id: file:///home/anna/Desktop/ocarina-legacy/mithos/ocarina@36 1daee41c-8060-4895-b1f0-2197c00d777a --- trunk/images/next.png | Bin 1845 -> 1148 bytes trunk/images/pause.png | Bin 894 -> 667 bytes trunk/images/play.png | Bin 1546 -> 956 bytes trunk/images/stop.png | Bin 740 -> 505 bytes trunk/src/GuiObjects/__init__.py | 3 +- trunk/src/GuiObjects/button.py | 21 +++++ trunk/src/GuiObjects/check.py | 12 +++ trunk/src/GuiObjects/controlPanel.py | 80 +++++++++++++++++++ trunk/src/GuiObjects/image.py | 9 +++ trunk/src/GuiObjects/libView.py | 2 +- trunk/src/GuiObjects/menuItem.py | 2 + trunk/src/GuiObjects/plistView.py | 86 +++++++++++++++----- trunk/src/libdata.py | 8 -- trunk/src/library.py | 41 +++++----- trunk/src/ocarina.py | 47 ++--------- trunk/src/saveddata.py | 7 +- trunk/src/song.py | 91 ++++++--------------- trunk/src/songInfo.py | 22 +++-- trunk/src/window.py | 115 +++------------------------ 19 files changed, 273 insertions(+), 273 deletions(-) create mode 100644 trunk/src/GuiObjects/button.py create mode 100644 trunk/src/GuiObjects/check.py create mode 100644 trunk/src/GuiObjects/controlPanel.py create mode 100644 trunk/src/GuiObjects/image.py delete mode 100644 trunk/src/libdata.py diff --git a/trunk/images/next.png b/trunk/images/next.png index e13146f0348f0728598ed8b0c670d230ce4eec9b..58be8152ae1464d9df6f6f51aed6072fcb4edbf7 100644 GIT binary patch delta 1140 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 DRl*yX delta 846 zcmV-U1F`&@1^xz*7YY~<1^@s6u;<~skuEBK33hNnX8-^I7ytkO7yx)orKSJ?0|`k) zK~z}7?UqYR>p&F8XOfvV&7*m=Ng84)U04v@`Zc5!-&;X9B7P)6inx*D=kP;#r3ght ze56fn$=t&EN5QdkR z-R{*DZ#2LE^z`iPdAB+34Mf8X!l-64cA#t0$gd9E7-pM{r7jEOklC_?@I!^59HXnv6?7^v%?8-|hkx{>cWx~}VgKMNNM zFiq1mO~!b`yzTTq0Pt)RS>Yfc-w5aMk;;-pdD#$-5EqbjOqOMt5QHQN8pxiAt{aA7 zqn<=twOXxKt8oBhya0E8_JuZExKgQ9DwVWh;Cwwol%}IJD-UCYf*=Tgf?$DLC=A0e z4D$fXGELhS1L5dX=j!!(yHyVvbqrq5`BuSFIz3uMq?{9C5zlAKzvTS=ag1nzcNcbv&`&rY* z-B7k?561^@s6LF^u$00001b5ch_0Itp)=>Px#24YJ`L;(K){{a7> zy{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXQ40XQ_{Kfl}n00TTpL_t(I z%dOPQZyQw<2Jr9Px#O`te#BHH_JpR%ICc}tQ?!zkRIE}NH-CVT@=!|KC5sXk6)J2h z7D!0EB2fv!hC&KWkoY4KUP1^_*pW(sR;dFq>4VsK?3p{B8MCmlMD2#sa-<_&%`ASJ z@18jl+AE#S9eOSr>FO#J3RM6CfQvgUsl&5f`wu+!Swf4?r1z!=s}=K7u~>8gSOC2L z1$f}0eJ4IVyMLgB!)m%%Djx0IvzxB0=ku=Xq6yt4@Zi1^volAyt|wXUiJY%oDesR) z!n0kwqMP~kjbbx0aaX|9B<{FNy^srMGQOTQR~L4P|9LL1=s`|lYV-uwLD000mO zHOGdq1+;`lPe1jH9FB&E%9Zl5zP|gcKW=RQ$~k9&KtKo~>N^7IbUGG~_smUAPIF6G zkQf7#7#L$90%|oIuIplW=zeJ;cUUPKMkb&tlim0BT;`mYHBGB)nr0UYh0Z`Glj-s) z@(WXw(|=sp0*pyujJ2AG;Cc?KW(7oqvC)I_NMSnq!YfBEh(>>#dmh%|J4l z^sZiSd>#V>F$P8iA_Ax>*XxjF9|Ha$HVd0LJ%4}NEdIIu_3qx@R|W@%F9I-b2@DJj zc;9~aO&tIv&Kq~ojERUq#30KugeCCa`|p}R{CHtA7LA=cI(z&p##m{5eEc8N)CQzd zsn$ARM9u6aNRkAZ%K(7om1X;r^BgTYcNm9jgHX&cbr-`@f}&jS%b zmVYJqWFOXkUi0SX-x87}oj>;M@i(&B>=qGKcly!V07X$+XT})RU~mln;H&sVM`dU{Ts{a|4kK$(bYx4Z0a0o3uu zmn+V~xpP)1q`v<4oAV!acXyYF$o#MCx-280DE^<8K3!U!ojLMaE|>fLcH`(&e*pwd VGfylL<^uo#002ovPDHLkV1i@1u_pik delta 1541 zcmV+g2KxED2Z{`k7k?NK1^@s6u;<~s00006VoOIv|NsC0|NjYC_uK#g010qNS#tmY z07w7;07w8v$!k6U000Sga6xAP000;O000;Ocub|H000GNNkl>rc~e6vv;o z>$RW5Fd7Ypf&!f`8jVJy(Nqe)7le&qe;hzjQEhEq-M)SI z@7rv4yVcs!L4VVgl{8&ZkxC_#95*w=vMkH83INYTFG+t4z>XcecGcAM_TIWRJUlW& z5EMmGBuUdO8;h}QSC_+4R#sYyAoKHcbK!6}oXuvlxqc`>zZGET&YGIu-p+FGO0V4$eZ&VquXB7dVX5($Ur<`x!M7OtZpDU$mQ z0PXEgvkM6DPg~Pz*ufmC1-=It_pzq|<@`fZcAh+3g5&`0$}aM~>h)MH!70RaFHg z*WK-KI2_xy@%*PxtE+2k@883YqNrA@)oQiEXMdCB9|oXlnx<)!$!fJ)EtbAM1%T%T zf#(6hFcd{m08kW)1V!OJg21X~GMP*|4S=$#tE;Q3wr|I<)>ejTX(5PsJdsEwyk4!A zBnhIe&1^0%wpeCoAxJ!Kx7+P@yDUSWPQ&B-I{>_1uh;7>C{U{j0>@9DQ~;C;qbQ1E zSbr|@uRVf5lx$X#L=k{gisO>W-1CNp`ufI39QXOWUZ2lsoSmJUo0(x4k|ar;uC7k6 zCrOH$nlhP8CX-2$LZMJ76w37;%?IFexm+%nBte1XOp!{?!%8b&5MYPWX$UHcq9}?0 zNRlK;5&%3e2&q&q&StY(Z8iW}TU%QX9)Hwm;JWqo27|$%(^;)BkIhn2ECYb!IIdO$pw((LIvoI!NHiLW05CWh2n-H# z9Luh+udO|KQd(M4Qc`mEY(+&yMRoO?H*k$Fcik2N%FD~k%gZI{*|X=*pFYi10Dr^a z@tNBL8>OUxAP9n>C`=s30T2Y97X$#VU%zqV+BJ@Q`SR7Psi{cBWHK5}rh$R3uFlS$ zp2v^jIi*VotA z-=EVmO#J7Ey}SV522-oGS^&n!Cnm$IV0ifE&5@DGNf;fE z!-Ri)WcVcjvJAk(hmRfwgQ7SxGCDds%JX`?UQd!2E?l{C=~5tY`?lF^Hk-|{7)+Ss zes#h>3_uVBq0zj4Juz|b-hRYHCdhHrNJO5L3!r00000NkvXXu0mjf8erQL diff --git a/trunk/images/stop.png b/trunk/images/stop.png index 1b2515e4d1e1b51150346072bd5f311ec9e8268b..f48c81fe8d9494941230dd54abe55195a9a832f9 100644 GIT binary patch delta 492 zcmVPx#24YJ`L;(K){{a7> zy{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iXQ40XZ4J`_kwD00DVPL_t(I z%e_?1O2a@9{$_SJjkQf_L;o;{1z*IQAl^iZuP5RwsQ5A(i+_l>iU_uu@sK8sQtevM zxn#3hzQ36)@W(|Pe*3P}7o-oMwE@8^fJt@3t~wQl;nvad;T5wPc}o|a++5!tOs7+< zB^VBe%4~Kn&M)Dd^CCDMpX{_+E%74gbUJ0050g7&B6*&)I^o@94*)P23^YyC^#r|M zPf7?P5c%~xj(=nMy2q;ycDr5OWF)K3e{>K{qmkq-Brr1!GYnf;V_}VhwHD4gI2#~vwNJvl z9K>;~#gGIpKxPb3sD@UYmu3nUK zwJJ~nlyh*FWy(pC_&I1a8l{q`8F`Osyqlt!J?ZW^Ix33e<93~8S(ar= zRaI40m4O73BuSE_OR*)2P-{&gilQir*3Vl7?i(1Q-&-0Y} z_?S$l)3!wjA%s!@0EC42Qv{`y+WatX^7Sp)w-b1Kn}1ARUo~Nb0A{oKd^Q7EEQDAr zG)*bB)r8yiGL5cZ%CC24i697qATZcMWm%SG*#^{o4}dYo7y}T}T1o*Z)yhyx2x9=0 zQc5WRW0W$cE$0B7Gd37(FPJd}^rh+s)Gfq0W1IsBK?otb#$PMF{MHre`d6V_Xtx62 z9AxcLOMeA8=X@{#5JCtc)(J|vN?gh=aVfQb6~-^|Y6~r)2U}ZtDV0K~TiKSlUSZrN zjpEH z=Q#iX03v!+SaefwW^{L9a%BJjc-kv3FW1Y=%Pvk%EJ)SMFG>dhHrNJO5L3!r00000 LNkvXXu0mjfNa{)m diff --git a/trunk/src/GuiObjects/__init__.py b/trunk/src/GuiObjects/__init__.py index 249786ac..82625f3d 100644 --- a/trunk/src/GuiObjects/__init__.py +++ b/trunk/src/GuiObjects/__init__.py @@ -1,2 +1,3 @@ +# Used for initializing things in the GuiObjects directory -__all__ = ['menuItem','libView','plistView'] +__all__ = ['button','menuItem','libView','plistView'] diff --git a/trunk/src/GuiObjects/button.py b/trunk/src/GuiObjects/button.py new file mode 100644 index 00000000..7551b89a --- /dev/null +++ b/trunk/src/GuiObjects/button.py @@ -0,0 +1,21 @@ +import pygtk +pygtk.require('2.0') +import gtk + +from image import Image + +class Button(gtk.Button): + def __init__(self,name,image,text,func): + gtk.Button.__init__(self) + box = gtk.HBox(True,0) + if image!= None: + box.pack_start(image,True,True,0) + #box.add(image) + if text != None: + label = gtk.Label(text) + label.show() + box.pack_start(label,False,False,0) + box.show() + self.add(box) + self.connect("clicked",func,name) + self.show() diff --git a/trunk/src/GuiObjects/check.py b/trunk/src/GuiObjects/check.py new file mode 100644 index 00000000..c99fb9c3 --- /dev/null +++ b/trunk/src/GuiObjects/check.py @@ -0,0 +1,12 @@ +import pygtk +pygtk.require('2.0') +import gtk + + +class CheckButton(gtk.CheckButton): + def __init__(self,label,func,active): + gtk.CheckButton.__init__(self,label) + if active==True: + self.set_active(1) + self.connect("toggled",func) + self.show() diff --git a/trunk/src/GuiObjects/controlPanel.py b/trunk/src/GuiObjects/controlPanel.py new file mode 100644 index 00000000..b08b8dc4 --- /dev/null +++ b/trunk/src/GuiObjects/controlPanel.py @@ -0,0 +1,80 @@ +import os +import gobject +import pygtk +pygtk.require('2.0') +import gtk + +from button import Button +from image import Image +from check import CheckButton + +class ControlPanel(gtk.HBox): + def __init__(self,data,plist): + gtk.HBox.__init__(self,False,0) + self.pauseImg = Image(os.path.join("images","pause.png")) + self.data = data + self.next = plist.next + self.pack_start(CheckButton("Random",self.toggleRand,self.data.random),False,False,0) + self.makeProgressBar() + (self.nextImg,self.nextBtn) = self.makeButton("next","next.png",None,self.next) + (self.stopImg,self.stopBtn) = self.makeButton("stop","stop.png",None,self.stop) + (self.playImg,self.plauseBtn) = self.makeButton("plause","play.png",None,self.plause) + self.show() + + + # Everything for making and adding a button + def makeButton(self,name,img,text,func): + image = None + if img: + image = Image(os.path.join("images",img)) + button = Button(name,image,text,func) + self.pack_end(button,False,False,0) + return (image,button) + + + # Make the progress bar, and set updates + def makeProgressBar(self): + vbox = gtk.VBox() + pbar = gtk.ProgressBar() + pbar.set_fraction(0) + vbox.pack_start(pbar,True,False,0) + self.pack_start(vbox,True,True,0) + vbox.show() + pbar.show() + gobject.timeout_add(1000,self.updatePBar,pbar) + + + # Play/Pause function + def plause(self,widgit,data): + self.data.song.plause() + self.changeImg() + + + # Stop function + def stop(self,widgit,data): + self.data.song.stop() + self.changeImg() + + + # Change the image on the play button + def changeImg(self): + self.plauseBtn.set_image(self.playImg) + if self.data.song.playing == True: + self.plauseBtn.set_image(self.pauseImg) + + + # Update time/progress of the progress bar + def updatePBar(self,pbar): + try: + (success,time) = self.data.song.curTime() + except: + success = False + if success == True: + time = time/1000000000 + 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 + + + def toggleRand(self,widgit): + self.data.random = not self.data.random diff --git a/trunk/src/GuiObjects/image.py b/trunk/src/GuiObjects/image.py new file mode 100644 index 00000000..b1474462 --- /dev/null +++ b/trunk/src/GuiObjects/image.py @@ -0,0 +1,9 @@ +import pygtk +pygtk.require('2.0') +import gtk + +class Image(gtk.Image): + def __init__(self,path): + gtk.Image.__init__(self) + self.set_from_file(path) + self.show() diff --git a/trunk/src/GuiObjects/libView.py b/trunk/src/GuiObjects/libView.py index 4aa6452f..0fa53ca5 100644 --- a/trunk/src/GuiObjects/libView.py +++ b/trunk/src/GuiObjects/libView.py @@ -48,7 +48,7 @@ class LibView(gtk.VBox): tree.set_sort_column_id(0,gtk.SORT_ASCENDING) self.treeview = gtk.TreeView(tree) self.treeview.connect("button_release_event",self.clicked) - self.col = gtk.TreeViewColumn('Library') + self.col = gtk.TreeViewColumn('Library ('+str(self.data.library.count)+')') self.treeview.append_column(self.col) cell = gtk.CellRendererText() self.col.pack_start(cell,True) diff --git a/trunk/src/GuiObjects/menuItem.py b/trunk/src/GuiObjects/menuItem.py index eb9b3e3c..27fa60d9 100644 --- a/trunk/src/GuiObjects/menuItem.py +++ b/trunk/src/GuiObjects/menuItem.py @@ -1,3 +1,5 @@ +import pygtk +pygtk.require('2.0') import gtk class MenuItem(gtk.MenuItem): diff --git a/trunk/src/GuiObjects/plistView.py b/trunk/src/GuiObjects/plistView.py index a5294b0f..756f2faf 100644 --- a/trunk/src/GuiObjects/plistView.py +++ b/trunk/src/GuiObjects/plistView.py @@ -1,3 +1,4 @@ +import random import gobject import pygtk pygtk.require('2.0') @@ -10,12 +11,15 @@ class PlistView(gtk.ScrolledWindow): self.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) self.data = data self.data.song.next = self.next + self.controls = None self.tree = None self.label = gtk.Label("") self.makeList() + self.loadSong() gobject.timeout_add(1000,self.checkUpdate) - - + + + # Check if the playlist has been updated def checkUpdate(self): if self.data.updateList == True: self.data.updateList = False @@ -23,19 +27,20 @@ class PlistView(gtk.ScrolledWindow): return True + # Make the playlist and show it def makeList(self): - trackList= gtk.ListStore(int,str,str,str,str,int) + self.trackList= gtk.ListStore(int,str,str,str,str,int) if self.tree: self.remove(self.tree) time = 0 for index in self.data.curList: track = self.data.library.files[index] - trackList.append([track.id,track.title,track.length,track.artist,track.album,track.count]) + self.trackList.append([track.id,track.title,track.length,track.artist,track.album,track.count]) time+=track.duration - self.tree = gtk.TreeView(trackList) + self.tree = gtk.TreeView(self.trackList) cell = gtk.CellRendererText() cols = ["Id","Title","Length","Artist","Album","#"] - trackList.set_sort_column_id(self.data.sortedCol,gtk.SORT_ASCENDING) + self.trackList.set_sort_column_id(self.data.sortedCol,gtk.SORT_ASCENDING) lenSaved = len(self.data.colSizes) for i in range(len(cols)): col = gtk.TreeViewColumn(cols[i],cell) @@ -48,7 +53,7 @@ class PlistView(gtk.ScrolledWindow): if cols[i] != "Id": self.tree.append_column(col) self.tree.set_rules_hint(True) - self.tree.connect("row-activated",self.selectSong,"clicked",trackList) + self.tree.connect("row-activated",self.selectSong,"clicked",self.trackList) self.tree.show() self.resizeCols() self.add(self.tree) @@ -63,26 +68,32 @@ class PlistView(gtk.ScrolledWindow): self.data.colSizes +=[col.get_width()] + # Uses saved column settings def resizeCols(self): cols = self.tree.get_columns() for i in range(len(self.data.colSizes)): cols[i].set_fixed_width(self.data.colSizes[i]) - def makeTimeLabel(self,time): - day = time/86500 - time = time-(day*86500) - hour = time/3600 - time = time-(hour*3600) - min = time/60 - time = time-(min*60) - + # Shows total running time of the playlist + def makeTimeLabel(self,sec): + day = 0 + hour = 0 + min = 0 + day = sec/86500 + sec = sec-(day*86500) + hour = sec/3600 + sec = sec-(hour*3600) + min = sec/60 + sec = sec-(min*60) + string = "" string = self.toStr(day,"day")+self.toStr(hour,"hour") - string += self.toStr(min,"minute")+self.toStr(time,"second") + string += self.toStr(min,"minute")+self.toStr(sec,"second") self.label.set_text(string) self.label.show() + # Make a string for the amount of time def toStr(self,time,label): if time > 0: string=str(time) + " "+label @@ -90,15 +101,48 @@ class PlistView(gtk.ScrolledWindow): string+="s" string += " " return string + return "" + # User selected a song with mouse click def selectSong(self,widgit,iter,path,data,list): - print list[iter][0] + self.data.curSong = self.data.curList.index(list[iter][0]) + self.loadSong() + self.controls.plause(None,None) + + + # Go to the next song in the list + def next(self,widgit,data): + if self.data.random == True: + self.data.curSong = random.randint(0,len(self.data.curList)) + else: + self.data.curSong+=1 + if self.data.curSong >= len(self.data.curList): + self.data.curSong = 0 + self.loadSong() + self.controls.plause(None,None) + + + # Load a song and begin playback + def loadSong(self): + if len(self.data.curList) == 0: + return if self.data.song: self.data.song.close() - self.data.song.passInfo(self.data.library.files[list[iter][0]]) - self.data.song.play(None,None) + self.data.song.passInfo(self.data.library.files[self.data.curList[self.data.curSong]]) + self.gotoCurSong() - def next(self): - self.song.close() + def gotoCurSong(self): + if len(self.data.curList) == 0: + return + selrow = 0 + row = 0 + for i in range(len(self.trackList)): + if self.trackList[i] == self.data.curSong: + if i > 10: + selrow = i - 10 + row = i + break + #self.tree.scroll_to_cell(selrow,None,True,0,0) + self.tree.set_cursor(self.data.curSong,None,False) diff --git a/trunk/src/libdata.py b/trunk/src/libdata.py deleted file mode 100644 index f60a7d62..00000000 --- a/trunk/src/libdata.py +++ /dev/null @@ -1,8 +0,0 @@ -from songInfo import SongInfo - -# This class is used to store all library data -class LibData: - def __init__(self): - self.path = "" - self.files = [] - self.map = dict() diff --git a/trunk/src/library.py b/trunk/src/library.py index 21498429..3e8d6c5d 100644 --- a/trunk/src/library.py +++ b/trunk/src/library.py @@ -2,7 +2,7 @@ import os import re import tagpy import cPickle as pickle -from libdata import LibData +#from libdata import LibData from songInfo import SongInfo import thread @@ -98,8 +98,9 @@ class Library: info.artist = t.artist a = f.audioProperties() - info.duration = a.length - info.fixTime() + info.setTime(a.length) + #info.duration = a.length + #info.fixTime() artist = info.artist.lower() album = info.album.lower() @@ -117,11 +118,11 @@ class Library: # Dump to file - def dump(self): - out = open(self.save,'w') - p = pickle.Pickler(out,2) - p.dump(self.data) - out.close() + #def dump(self): + # out = open(self.save,'w') + # p = pickle.Pickler(out,2) + # p.dump(self.data) + # out.close() # Return true if file is in the library @@ -140,17 +141,17 @@ class Library: return -1 - def nonBanned(self): - list = [] - for i in range(len(self.data.files)): - if self.data.files[i].banned == False: - list += [i] - return list + #def nonBanned(self): + # list = [] + # for i in range(len(self.data.files)): + # if self.data.files[i].banned == False: + # list += [i] + # return list - def translate(self,sid): - #file = self.data.files[sid] - return self.data.files[sid] - #print file.title, file.artist, file.album - return (sid,file.title,file.artist,file.album,file.playCount) - #return (file.artist,file.album) + #def translate(self,sid): + # #file = self.data.files[sid] + # return self.data.files[sid] + # #print file.title, file.artist, file.album + # return (sid,file.title,file.artist,file.album,file.playCount) + # #return (file.artist,file.album) diff --git a/trunk/src/ocarina.py b/trunk/src/ocarina.py index 53ea088b..1236b101 100644 --- a/trunk/src/ocarina.py +++ b/trunk/src/ocarina.py @@ -11,11 +11,11 @@ from options import Options from saveddata import SavedData from song import Song -from duration import Duration -from library import Library -from operations import Operations -from playlist import Playlist -from songInfo import SongInfo +#from duration import Duration +#from library import Library +#from operations import Operations +#from playlist import Playlist +#from songInfo import SongInfo from window import Window #gtk.gdk.threads_init() @@ -34,43 +34,6 @@ class main: self.window = Window(self.quit,self.options,self.data) gtk.main() - ''' - self.ops = Operations(self.quit) - self.library = Library() - self.plist = Playlist() - self.plist.insert(self.library.nonBanned()) - self.plist.translate = self.library.translate - self.plist.opsNext = self.ops.next - self.ops.plist = self.plist - self.ops.library = self.library - - window = Window(self.quit,self.ops) - self.ops.setInfo = window.changeInfo - self.ops.resetInfo = window.resetInfo - self.ops.scrollSong = window.gotoCurSong - - song = None - # If we were given a song as input, check that it exists and begin playback - if len(argv) > 0: - split = argv[0].split(self.library.data.path) - if len(split) > 0: - index = self.library.has(split[len(split)-1]) - #if index != -1: - #info = self.library.data.files[index] - self.plist.queueSong(index) - if index==-1: - file = os.path.expanduser(argv[0]) - if os.path.exists(file): - info = SongInfo() - info.filename = file - song = Song(info,self.next)#,self.commands.printLines) - self.ops.song = song - self.ops.next("","") - window.song = self.ops.song - - # Call gtk main - gtk.main() - ''' # Eventually replace "delete_event" with this diff --git a/trunk/src/saveddata.py b/trunk/src/saveddata.py index 26a7b991..a4fd23b7 100644 --- a/trunk/src/saveddata.py +++ b/trunk/src/saveddata.py @@ -12,11 +12,13 @@ class SavedData: self.divider = 150 self.library = Library() self.curList = [] + self.curSong = 0 self.colSizes = [110,110,110,110,110] self.sortedCol = 3 self.updateList = False self.path = path self.song = None + self.random = False if os.path.exists(path): try: @@ -47,7 +49,10 @@ class SavedData: p = pickle.Unpickler(open(path)) data = p.load() self.size = data.size - self.library = data.library self.divider = data.divider + self.library = data.library self.curList = data.curList + self.curSong = 0 self.colSizes = data.colSizes + self.path = data.path + self.random = data.random diff --git a/trunk/src/song.py b/trunk/src/song.py index 373b62d7..4fa71116 100644 --- a/trunk/src/song.py +++ b/trunk/src/song.py @@ -10,117 +10,74 @@ class Song(): #def __init__(self,info,exitFunc,prnt): def __init__(self,exitFunc): self.quit=exitFunc - #self.prnt=prnt - #self.info = info - #self.info.tags = dict() - #self.setInfo = None - #self.getNext = None - #self.current = 0 # initialize player pipeline self.next = None self.player = gst.Pipeline("player") self.bin = gst.element_factory_make("playbin",None) - #bin.set_property("uri","file://"+self.info.filename) self.player.add(self.bin) # initialize bus bus = self.player.get_bus() bus.add_signal_watch() bus.connect("message",self.onMessage) - - # Pause song - #self.pause() + self.playing = False + self.hasFile = False # Initialize stuff for finding duration self.time_format = gst.Format(gst.FORMAT_TIME) - #self.length = None - #self.taglist = None # Called on bus messages def onMessage(self,bus,message): t = message.type if t == gst.MESSAGE_EOS: - #print "End of stream" - #self.prnt(["End of stream"]) - if self.quit != None: - self.quit("","") + self.next(None,None) + self.plause() elif t == gst.MESSAGE_ERROR: err, debug = message.parse_error() - #if self.prnt != None: - # self.prnt(["Error: "+ str(err) + " " +str(debug)]) self.close() print "Error: %s" % err, debug print "Trying next song" - self.next() - #self.getNext(None,None) - #if self.quit != None: - # self.quit("") - #elif t == gst.MESSAGE_TAG: - # tags = message.parse_tag() - # for tag in tags.keys(): - # self.info.tags[tag] = tags[tag] - # if tag=="title": - # self.info.title = tags[tag] - # elif tag=="album": - # self.info.album = tags[tag] - # elif tag=="artist": - # self.info.artist = tags[tag] - # self.setInfo(tags) - #self.taglist = message.parse_tag() - # return + self.next(None,None) - # Change state to "playing" - def play(self,widgit,data): - self.player.set_state(gst.STATE_PLAYING) - # Start main loop and find duration (if this hasn't been done yet) - #while self.duration() == False: - # time.sleep(0.1) - - - # Change state to "paused" - def pause(self,widgit,data): - self.player.set_state(gst.STATE_PAUSED) + # Toggle between play and pause + def plause(self): + if self.hasFile == False: + return + if self.playing == False: + self.player.set_state(gst.STATE_PLAYING) + self.playing = True + else: + self.player.set_state(gst.STATE_PAUSED) + self.playing = False # Stop playback def stop(self): + if self.hasFile == False: + return self.player.set_state(gst.STATE_PAUSED) + self.playing = False self.current = 0 self.player.seek_simple(self.time_format,gst.SEEK_FLAG_FLUSH,self.current) # Close the song def close(self): + self.playing = False self.player.set_state(gst.STATE_NULL) - # Find the duration of the pipeline - #def duration(self): - # try: - # self.info.length = Duration() - # length = self.player.query_duration(self.time_format,None)[0] - # self.total = length - # self.info.length.setTime(length) - # return True - #except: - # return False - #self.length.disp(self.prnt) - - # Print out current running time def curTime(self): - try: - length = self.player.query_position(self.time_format,None)[0] - self.current = length - dur = Duration() - dur.setTime(length) - return (True,dur) - except: - return (False,None) + if self.playing == False: + return (False,False) + return (True, self.player.query_position(self.time_format,None)[0]) + # Use to load a file path def passInfo(self,info): self.info = info self.bin.set_property("uri","file://"+self.info.filename) + self.hasFile = True diff --git a/trunk/src/songInfo.py b/trunk/src/songInfo.py index 0b81220f..5ee72e49 100644 --- a/trunk/src/songInfo.py +++ b/trunk/src/songInfo.py @@ -13,25 +13,31 @@ class SongInfo: self.artist = "" - def fixTime(self): - time = self.duration + def setTime(self,time): + self.duration = time + self.length = self.fixTime(time) + + def fixTime(self,time): + #time = self.duration # Find hour + length = "" if time >= 3600: hour = time/3600 time = time - (self.hour * 3600) if hour > 0: - self.length=str(hour)+":" + length=str(hour)+":" # Find minute if time >= 60: min = time/60 time = time - (min * 60) if min < 10: - self.length+="0" - self.length+=str(min)+":" + length+="0" + length+=str(min)+":" else: - self.length+="00:" + length+="00:" # Remainder is seconds sec = time if sec < 10: - self.length+="0" - self.length+=str(sec) + length+="0" + length+=str(sec) + return length diff --git a/trunk/src/window.py b/trunk/src/window.py index f379e109..6345ad3a 100644 --- a/trunk/src/window.py +++ b/trunk/src/window.py @@ -9,6 +9,7 @@ from kiwi.ui.objectlist import Column, ObjectList from GuiObjects.menuItem import MenuItem from GuiObjects.libView import LibView from GuiObjects.plistView import PlistView +from GuiObjects.controlPanel import ControlPanel class Window(gtk.Window): @@ -29,31 +30,12 @@ class Window(gtk.Window): self.add(self.mainLayout) self.makeMenuBar() self.makeContentPane() - ''' - self.song = song - self.ops = ops - self.tree = None - self.tooltip = gtk.Tooltips() - self.tagLabels = dict() - self.set_title("Ocarina") - # Call quit function when closed - self.connect("delete_event",onQuit) - self.set_icon_from_file("images/ocarina.png") - - self.mainLayout = gtk.VBox(False,0) - self.add(self.mainLayout) - self.mainLayout.show() - self.makeMenuBar() - self.makeInfoPane() - self.makeList() - self.makeControls() - self.maximize() - ''' self.mainLayout.show() self.show() + ''' # Make initial info pane def makeInfoPane(self): self.infoFrame = gtk.Frame("Current Song:") @@ -134,79 +116,7 @@ class Window(gtk.Window): #self.tree.scroll_to_cell(selrow,None,True,0,0) #treesel = self.tree.get_selection() #treesel.select_path(row) - - - # Use to make play/pause/next/etc buttons - def makeControls(self): - #controls = gtk.VBox(False,0) - row = gtk.HBox(False,0) - topRow = gtk.HBox(False,0) - # Make top row buttons - #self.makeButton("play","images/play.png",None,self.ops.play,topRow) - self.makeButton("play","images/play.png",None,self.song.play,topRow) - - #self.makeButton("pause","images/pause.png",None,self.ops.pause,topRow) - self.makeButton("pause","images/pause.png",None,self.song.pause,topRow) - - self.makeButton("stop","images/stop.png",None,self.ops.stop,topRow) - self.makeButton("next","images/next.png",None,self.ops.next,topRow) - self.makeButton("info",None,"Info",self.ops.info,topRow) - #self.makeButton("plist",None,"Plist",self.ops.plist.showWindow,topRow) - - test = gtk.VBox(False,0) - self.makeCheck("Random",self.ops.random,self.ops.plist.random,True,topRow) - topRow.show() - row.pack_end(topRow,False,False,0) - row.show() - #self.mainLayout.pack_start(topRow,False,False,0) - self.mainLayout.pack_start(row,False,False,0) - # Make progress bar, add below top row - pbar = gtk.ProgressBar() - pbar.set_fraction(0) - gobject.timeout_add(1000,self.ops.markProgress,pbar,"progress") - pbar.show() - self.mainLayout.pack_start(pbar,False,False,0) - # Show completed controls - #controls.show() - #self.add(controls) - - - # Make buttons and add to container - # Path is to an image - # Text is label text - # Func is callback function - def makeButton(self,name,path,text,func,container): - button = gtk.Button() - box = gtk.HBox(False,0) - box.set_border_width(0) - if path != None: - image = gtk.Image() - image.set_from_file(path) - image.show() - box.pack_start(image,False,False,0) - if text != None: - label = gtk.Label(text) - label.show() - box.pack_start(label,False,False,0) - box.show() - button.add(box) - button.connect("clicked",func,name) - button.show() - container.pack_start(button,False,False,0) - return button - - - # Make a checkbox and add to container - # Active is variable to check, status is value it has to mark as active - def makeCheck(self,name,func,active,status,container): - check = gtk.CheckButton(label=name) - if active == status: - check.set_active(1) - check.connect("toggled",func,name) - check.show() - container.pack_start(check,False,False,0) - return check - +''' # Used to make the top row menu bar def makeMenuBar(self): @@ -224,8 +134,8 @@ class Window(gtk.Window): bar.append(plist) # Replace first 'None' with after track functions - pafter = MenuItem("Pause After Current Track",None,"pafter",self.changeFrameTitle,None) - qafter = MenuItem("Quit After Current Track",None,"qafter",self.changeFrameTitle,None) + pafter = MenuItem("Pause After Current Track",None,"pafter",None,None) + qafter = MenuItem("Quit After Current Track",None,"qafter",None,None) playback = MenuItem("Playback",None,None,None,[pafter,qafter]) bar.append(playback) @@ -236,8 +146,7 @@ class Window(gtk.Window): def deleteLib(self,widgit,data,other=None): self.data.library.reset() self.libview.update() - self.data.curList = [] - self.data.updateList = True + self.clearPlist() def clearPlist(self,widgit,data,other=None): @@ -257,13 +166,8 @@ class Window(gtk.Window): dirsel.hide() if response != gtk.RESPONSE_OK: return - #dirsel.destroy() - #dirsel = None self.libview.updates() thread.start_new_thread(func,(data,file)) - #self.libview.updates() - #func(data,file) - #self.libview.update() def makeContentPane(self): @@ -293,10 +197,13 @@ class Window(gtk.Window): def makeBottomRow(self,vbox): box = gtk.HBox(False,0) - box.pack_end(self.libview.label,False,False,10) + #box.pack_end(self.libview.label,False,False,10) + controls = ControlPanel(self.data,self.plistview) + self.plistview.controls = controls + vbox.pack_start(controls,False,False,0) box.pack_end(self.plistview.label) box.show() - align = gtk.Alignment(1,0.5,0,0) + align = gtk.Alignment(1,1,0,0) align.add(box) align.show() vbox.pack_start(align,False,False,0)