Integrating and testing of playback
[watersofshiloah] / src / playcontrol.py
1 import logging
2
3 import gobject
4 import gtk
5
6 import gtk_toolbox
7 import hildonize
8 import util.misc as misc_utils
9
10 import presenter
11
12
13 _moduleLogger = logging.getLogger(__name__)
14
15
16 class NavControl(gobject.GObject):
17
18
19         __gsignals__ = {
20                 'home' : (
21                         gobject.SIGNAL_RUN_LAST,
22                         gobject.TYPE_NONE,
23                         (),
24                 ),
25                 'jump-to' : (
26                         gobject.SIGNAL_RUN_LAST,
27                         gobject.TYPE_NONE,
28                         (gobject.TYPE_PYOBJECT, ),
29                 ),
30         }
31
32         def __init__(self, player, store):
33                 gobject.GObject.__init__(self)
34
35                 self._store = store
36
37                 self._player = player
38                 self._player.connect("state-change", self._on_player_state_change)
39                 self._player.connect("title-change", self._on_player_title_change)
40
41                 self._controlButton = store.get_image_from_store(store.STORE_LOOKUP["small_play"])
42
43                 self._controlBox = presenter.NavigationBox()
44                 self._controlBox.toplevel.add(self._controlButton)
45                 self._controlBox.connect("action", self._on_nav_action)
46                 self._controlBox.connect("navigating", self._on_navigating)
47
48                 self._titleButton = gtk.Label(self._player.title)
49
50                 self._displayBox = presenter.NavigationBox()
51                 self._displayBox.toplevel.add(self._titleButton)
52                 self._displayBox.connect("action", self._on_nav_action)
53                 self._displayBox.connect("navigating", self._on_navigating)
54
55                 self._layout = gtk.HBox()
56                 self._layout.pack_start(self._controlBox.toplevel, False, False)
57                 self._layout.pack_start(self._displayBox.toplevel, True, True)
58
59         def refresh(self):
60                 self._titleButton.set_label(self._player.title)
61                 self._set_context(self._player.state)
62
63         def _set_context(self, state):
64                 if state == self._player.STATE_PLAY:
65                         stateImage = self._store.STORE_LOOKUP["small_pause"]
66                         self._store.set_image_from_store(self._controlButton, stateImage)
67                         self.toplevel.show()
68                 elif state == self._player.STATE_PAUSE:
69                         stateImage = self._store.STORE_LOOKUP["small_play"]
70                         self._store.set_image_from_store(self._controlButton, stateImage)
71                         self.toplevel.show()
72                 elif state == self._player.STATE_STOP:
73                         self._titleButton.set_label("")
74                         self.toplevel.hide()
75                 else:
76                         _moduleLogger.info("Unhandled player state %s" % state)
77                         stateImage = self._store.STORE_LOOKUP["small_pause"]
78                         self._store.set_image_from_store(self._controlButton, stateImage)
79
80         @property
81         def toplevel(self):
82                 return self._layout
83
84         def set_orientation(self, orientation):
85                 pass
86
87         @misc_utils.log_exception(_moduleLogger)
88         def _on_player_state_change(self, player, newState):
89                 if self._controlBox.is_active() or self._displayBox.is_active():
90                         return
91
92                 self._set_context(newState)
93
94         @misc_utils.log_exception(_moduleLogger)
95         def _on_player_title_change(self, player, node):
96                 _moduleLogger.info("Title change: %s" % self._player.title)
97                 self._titleButton.set_label(self._player.title)
98
99         @misc_utils.log_exception(_moduleLogger)
100         def _on_navigating(self, widget, navState):
101                 if navState == "down":
102                         imageName = "small_home"
103                 elif navState == "clicking" or not self._player.can_navigate:
104                         if widget is self._controlBox:
105                                 if self._player.state == "play":
106                                         imageName = "small_play"
107                                 else:
108                                         imageName = "small_pause"
109                         elif widget is self._displayBox:
110                                 if self._player.state == self._player.STATE_PLAY:
111                                         imageName = "small_pause"
112                                 else:
113                                         imageName = "small_play"
114                         else:
115                                 raise NotImplementedError()
116                 elif navState == "up":
117                         imageName = "small_play"
118                 elif navState == "left":
119                         imageName = "small_next"
120                 elif navState == "right":
121                         imageName = "small_prev"
122
123                 imagePath = self._store.STORE_LOOKUP[imageName]
124                 self._store.set_image_from_store(self._controlButton, imagePath)
125
126         @misc_utils.log_exception(_moduleLogger)
127         def _on_nav_action(self, widget, navState):
128                 self._set_context(self._player.state)
129
130                 if navState == "clicking":
131                         if widget is self._controlBox:
132                                 if self._player.state == self._player.STATE_PLAY:
133                                         self._player.pause()
134                                 else:
135                                         self._player.play()
136                         elif widget is self._displayBox:
137                                 self.emit("jump-to", self._player.node)
138                         else:
139                                 raise NotImplementedError()
140                 elif navState == "down":
141                         self.emit("home")
142                 elif navState == "up":
143                         pass
144                 elif navState == "left":
145                         self._player.next()
146                 elif navState == "right":
147                         self._player.back()
148
149
150 gobject.type_register(NavControl)
151
152
153 class PlayControl(object):
154
155         def __init__(self, player, store):
156                 self._isPortrait = True
157
158                 self._store = store
159
160                 self._player = player
161                 self._player.connect("state-change", self._on_player_state_change)
162                 self._player.connect("title-change", self._on_player_nav_change)
163
164                 img = store.get_image_from_store(store.STORE_LOOKUP["small_prev"])
165                 self._back = gtk.Button()
166                 self._back.set_image(img)
167                 self._back.connect("clicked", self._on_back_clicked)
168
169                 img = store.get_image_from_store(store.STORE_LOOKUP["small_stop"])
170                 self._stop = gtk.Button()
171                 self._stop.set_image(img)
172                 self._stop.connect("clicked", self._on_stop_clicked)
173
174                 img = store.get_image_from_store(store.STORE_LOOKUP["small_pause"])
175                 self._pause = gtk.Button()
176                 self._pause.set_image(img)
177                 self._pause.connect("clicked", self._on_pause_clicked)
178
179                 img = store.get_image_from_store(store.STORE_LOOKUP["small_play"])
180                 self._play = gtk.Button()
181                 self._play.set_image(img)
182                 self._play.connect("clicked", self._on_play_clicked)
183
184                 img = store.get_image_from_store(store.STORE_LOOKUP["small_next"])
185                 self._next = gtk.Button()
186                 self._next.set_image(img)
187                 self._next.connect("clicked", self._on_next_clicked)
188
189                 self._controls = gtk.HBox()
190                 self._controls.pack_start(self._back)
191                 self._controls.pack_start(self._stop)
192                 self._controls.pack_start(self._pause)
193                 self._controls.pack_start(self._play)
194                 self._controls.pack_start(self._next)
195
196                 self._layout = gtk.VBox()
197                 self._layout.pack_start(self._controls)
198
199         def refresh(self):
200                 if not self._player.title:
201                         self.toplevel.hide()
202                 self._set_navigate(self._player.can_navigate)
203                 self._set_state(self._player.state)
204
205         @property
206         def toplevel(self):
207                 return self._layout
208
209         def set_orientation(self, orientation):
210                 if orientation == gtk.ORIENTATION_VERTICAL:
211                         if self._isPortrait:
212                                 return
213                         self._isPortrait = True
214
215                         self._controls.remove(self._back)
216                         self._controls.remove(self._stop)
217                         self._controls.remove(self._pause)
218                         self._controls.remove(self._play)
219                         self._controls.remove(self._next)
220                         self._layout.remove(self._controls)
221
222                         self._controls = gtk.HBox()
223                         self._controls.pack_start(self._back)
224                         self._controls.pack_start(self._stop)
225                         self._controls.pack_start(self._pause)
226                         self._controls.pack_start(self._play)
227                         self._controls.pack_start(self._next)
228                         self._layout.pack_start(self._controls)
229                 elif orientation == gtk.ORIENTATION_HORIZONTAL:
230                         if not self._isPortrait:
231                                 return
232                         self._isPortrait = False
233
234                         self._controls.remove(self._back)
235                         self._controls.remove(self._stop)
236                         self._controls.remove(self._pause)
237                         self._controls.remove(self._play)
238                         self._controls.remove(self._next)
239                         self._layout.remove(self._controls)
240
241                         self._controls = gtk.VBox()
242                         self._controls.pack_start(self._back)
243                         self._controls.pack_start(self._stop)
244                         self._controls.pack_start(self._pause)
245                         self._controls.pack_start(self._play)
246                         self._controls.pack_start(self._next)
247                         self._layout.pack_start(self._controls)
248                 else:
249                         raise NotImplementedError(orientation)
250
251         def _set_navigate(self, canNavigate):
252                 if canNavigate:
253                         self._back.show()
254                         self._next.show()
255                 else:
256                         self._back.hide()
257                         self._next.hide()
258
259         def _set_state(self, newState):
260                 if newState == "play":
261                         self._pause.show()
262                         self._play.hide()
263                         self.toplevel.show()
264                 elif newState == "pause":
265                         self._pause.hide()
266                         self._play.show()
267                         self.toplevel.show()
268                 elif newState == "stop":
269                         self._pause.hide()
270                         self._play.show()
271                         self.toplevel.hide()
272
273         @misc_utils.log_exception(_moduleLogger)
274         def _on_player_state_change(self, player, newState):
275                 self._set_state(newState)
276
277         @misc_utils.log_exception(_moduleLogger)
278         def _on_player_nav_change(self, player, node):
279                 self._set_navigate(player.can_navigate)
280
281         @misc_utils.log_exception(_moduleLogger)
282         def _on_back_clicked(self, *args):
283                 self._player.back()
284
285                 parent = gtk_toolbox.find_parent_window(self._layout)
286                 hildonize.show_information_banner(parent, self._player.title)
287
288         @misc_utils.log_exception(_moduleLogger)
289         def _on_stop_clicked(self, *args):
290                 self._pause.hide()
291                 self._play.show()
292                 self._player.stop()
293
294         @misc_utils.log_exception(_moduleLogger)
295         def _on_pause_clicked(self, *args):
296                 self._pause.show()
297                 self._play.hide()
298                 self._player.pause()
299
300         @misc_utils.log_exception(_moduleLogger)
301         def _on_play_clicked(self, *args):
302                 self._pause.hide()
303                 self._play.show()
304                 self._player.play()
305
306         @misc_utils.log_exception(_moduleLogger)
307         def _on_next_clicked(self, *args):
308                 self._player.next()
309
310                 parent = gtk_toolbox.find_parent_window(self._layout)
311                 hildonize.show_information_banner(parent, self._player.title)