c7859958773b8d12d7bf5f45fdd3e2f385a854d5
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

1) #! /usr/bin/env python
2) 
3) import os
4) from gi.repository import Gtk
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

5) import gobject
Stefan Schuermans show current playlist item...

Stefan Schuermans authored 10 years ago

6) import pango
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

7) import time
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

8) 
Stefan Schuermans reading playlist

Stefan Schuermans authored 10 years ago

9) import playlist
Stefan Schuermans show current position as h:...

Stefan Schuermans authored 10 years ago

10) import time_fmt
11) 
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

12) scriptdir = os.path.dirname(os.path.abspath(__file__))
13) 
14) class SyncGui:
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

15) 
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

16)   def __init__(self):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

17)     """construct a SyncGui object"""
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

18)     self.builder = Gtk.Builder()
19)     self.builder.add_from_file(scriptdir + "/sync_gui.glade")
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

20)     self.widPlaylistView = self.builder.get_object("PlaylistView")
21)     self.widPlaylistStore = self.builder.get_object("PlaylistStore")
22)     self.widPosition = self.builder.get_object("Position")
23)     self.widPositionScale = self.builder.get_object("PositionScale")
24)     self.widPositionAt = self.builder.get_object("PositionAt")
25)     self.widPositionRemaining = self.builder.get_object("PositionRemaining")
26)     self.widBtnPause = self.builder.get_object("Pause")
27)     self.widBtnPlay = self.builder.get_object("Play")
28)     self.widStatus = self.builder.get_object("Status")
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

29)     handlers = {
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

30)       "onDestroy":          self.onDestroy,
31)       "onPlaylistDblClick": self.onPlaylistDblClick,
32)       "onNewPosition":      self.onNewPosition,
33)       "onPrevious":         self.onPrevious,
34)       "onStop":             self.onStop,
35)       "onPause":            self.onPause,
36)       "onPlay":             self.onPlay,
37)       "onNext":             self.onNext,
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

38)     }
39)     self.builder.connect_signals(handlers)
Stefan Schuermans reading playlist

Stefan Schuermans authored 10 years ago

40)     self.playlist = playlist.Playlist()
41)     self.playlist.read("playlist.txt")
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

42)     self.playlist.update(self.widPlaylistStore)
43)     self.widStatus.push(0, "TODO...")
44)     self.stEntryIdx = -1 # no entry selected
45)     self.stName = "" # no current entry name
46)     self.stDuration = 0 # current entry has zero size
47)     self.stPosition = 0 # at begin of current entry
48)     self.stPlaying = False # not playing
49)     gobject.timeout_add(10, self.onTimer10ms)
Stefan Schuermans show current playlist item...

Stefan Schuermans authored 10 years ago

50)     self.updateEntry()
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

51)     self.updateButtonVisibility()
Stefan Schuermans show current position as h:...

Stefan Schuermans authored 10 years ago

52) 
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

53)   def showPosition(self):
54)     """update the position texts next to the position slider"""
55)     # format current time and remaining time
56)     posAt = time_fmt.sec2str(self.stPosition)
57)     posRemaining = time_fmt.sec2str(self.stDuration - self.stPosition)
58)     self.widPositionAt.set_text(posAt)
59)     self.widPositionRemaining.set_text(posRemaining)
60) 
61)   def updatePositionState(self):
62)     """update the position in the state, but not the slider"""
63)     # calculate (virtual) start time of playing
64)     # i.e. the time the playing would have had started to arrive at the
65)     # current position now if it had played continuosly
66)     self.stPlayStart = time.time() - self.stPosition
67)     # update position texts
68)     self.showPosition()
69) 
70)   def updatePosition(self):
71)     """update the position including the position slider"""
72)     # update GUI slider
73)     self.widPositionScale.set_value(self.stPosition)
74)     # update position state
75)     self.updatePositionState()
76) 
77)   def updateDuration(self):
78)     """update the duration (i.e. range for the slider) based on the current
79)        playlist entry"""
80)     # get duration of new playlist entry
81)     self.stDuration = 0
82)     if self.stEntryIdx >= 0:
83)       entry = self.playlist.entries[self.stEntryIdx]
84)       if entry["type"] == "normal":
85)         self.stDuration = entry["duration"]
86)     # set position to begin
87)     self.stPosition = 0
88)     # update value range
89)     self.widPosition.set_upper(self.stDuration)
90)     # update position of slider
91)     self.updatePosition()
92) 
Stefan Schuermans show current playlist item...

Stefan Schuermans authored 10 years ago

93)   def updateEntry(self):
94)     """update current entry of playlist and duration, position, ..."""
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

95)     # clear selection of playlist
96)     sel = self.widPlaylistView.get_selection()
97)     if sel:
98)       sel.unselect_all()
Stefan Schuermans show current playlist item...

Stefan Schuermans authored 10 years ago

99)     # sanity check for entry index
100)     if self.stEntryIdx < -1 or self.stEntryIdx >= len(self.playlist.entries):
101)       self.stEntryIdx = -1
102)     # make current entry bold, all others non-bold
103)     def update(model, path, it, user_data):
104)       (idx,) = model.get(it, 0)
105)       if idx == self.stEntryIdx:
106)         weight = pango.WEIGHT_BOLD
107)       else:
108)         weight = pango.WEIGHT_NORMAL
109)       model.set(it, 1, weight)
110)     self.widPlaylistStore.foreach(update, None)
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

111)     # playing and (no entry or stop entry)
112)     # -> stop playing and update button visibility
113)     if self.stPlaying and (self.stEntryIdx < 0 or \
114)        self.playlist.entries[self.stEntryIdx]["type"] == "stop"):
115)       self.stPlaying = False
116)       self.updateButtonVisibility()
Stefan Schuermans show current playlist item...

Stefan Schuermans authored 10 years ago

117)     # update duration, position, ...
118)     self.updateDuration()
119) 
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

120)   def updateButtonVisibility(self):
121)     """update the visibility of the buttons based on if playing or not"""
122)     self.widBtnPause.set_visible(self.stPlaying)
123)     self.widBtnPlay.set_visible(not self.stPlaying)
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

124) 
125)   def onDestroy(self, widget):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

126)     """window will be destroyed"""
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

127)     Gtk.main_quit()
128) 
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

129)   def onPlaylistDblClick(self, widget, row, col):
130)     """playlist entry has been double-clicked"""
131)     # get index of selected entry
132)     idx = -1
133)     sel = self.widPlaylistView.get_selection()
134)     if sel is not None:
135)       (model, it) = sel.get_selected()
136)       if it is not None:
Stefan Schuermans show current playlist item...

Stefan Schuermans authored 10 years ago

137)         (idx,) = model.get(it, 0)
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

138)     #print("DEBUG sync_gui playlist double-click idx=%d" % (idx))
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

139)     # update playlist entry
140)     self.stEntryIdx = idx
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

141)     # set position to zero if playing
142)     if self.stPlaying:
143)       self.stPosition = 0
Stefan Schuermans show current playlist item...

Stefan Schuermans authored 10 years ago

144)     # update entry
145)     self.updateEntry()
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

146) 
Stefan Schuermans show current position as h:...

Stefan Schuermans authored 10 years ago

147)   def onNewPosition(self, widget, scroll, value):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

148)     """slider has been moved to a new position"""
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

149)     #print("DEBUG sync_gui new position " + str(value));
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

150)     # clamp position to valid range
151)     if value < 0:
152)       value = 0
153)     if value > self.stDuration:
154)       value = self.stDuration
155)     # update current position - and play start time if playing
156)     self.stPosition = value
157)     # update position state (do not touch the slider)
158)     self.updatePositionState()
Stefan Schuermans show current position as h:...

Stefan Schuermans authored 10 years ago

159) 
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

160)   def onPrevious(self, widget):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

161)     """previous button as been pressed"""
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

162)     #print("DEBUG sync_gui previous")
163)     # go to begin of previous entry (with wrap around)
164)     self.stPosition = 0
165)     self.stEntryIdx = self.stEntryIdx - 1
166)     if self.stEntryIdx < 0:
167)       self.stEntryIdx = len(self.playlist.entries) - 1
168)     self.updateEntry()
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

169) 
170)   def onStop(self, widget):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

171)     """stop button has been pressed"""
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

172)     #print("DEBUG sync_gui stop")
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

173)     self.stPlaying = False
174)     self.stPosition = 0 # stop goes back to begin
175)     self.updatePosition()
176)     self.updateButtonVisibility()
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

177) 
178)   def onPause(self, widget):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

179)     """pause button has been pressed"""
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

180)     #print("DEBUG sync_gui pause")
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

181)     self.stPlaying = False
182)     self.updateButtonVisibility()
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

183) 
184)   def onPlay(self, widget):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

185)     """play button has been pressed"""
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

186)     #print("DEBUG sync_gui play")
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

187)     self.stPlaying = True
188)     self.updatePosition()
189)     self.updateButtonVisibility()
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

190) 
191)   def onNext(self, widget):
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

192)     """next button has been pressed"""
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

193)     #print("DEBUG sync_gui next")
194)     # go to begin of next entry (with wrap around)
195)     self.stPosition = 0
196)     self.stEntryIdx = self.stEntryIdx + 1
197)     if self.stEntryIdx >= len(self.playlist.entries):
198)       self.stEntryIdx = 0
199)     self.updateEntry()
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

200) 
201)   def onTimer10ms(self):
202)     """timer callback, every 10ms"""
203)     # update position if playing
204)     if self.stPlaying:
205)       self.stPosition = time.time() - self.stPlayStart
Stefan Schuermans remove forward and backward...

Stefan Schuermans authored 10 years ago

206)       if self.stPosition >= self.stDuration:
207)         # end of entry reached --> go to begin of next entry (with wrap around)
208)         self.stPosition = 0
209)         self.stEntryIdx = self.stEntryIdx + 1
210)         if self.stEntryIdx >= len(self.playlist.entries):
211)           self.stEntryIdx = 0
212)         self.updateEntry()
213)       else:
214)         self.updatePosition()
Stefan Schuermans start making player work -...

Stefan Schuermans authored 10 years ago

215)     return True
216) 
217) # main application entry point
Stefan Schuermans initial PyGtk window

Stefan Schuermans authored 10 years ago

218) if __name__ == "__main__":
219)   app = SyncGui()
220)   Gtk.main()
221)