X-Git-Url: http://git.maemo.org/git/?p=watersofshiloah;a=blobdiff_plain;f=src%2Fpresenter.py;h=e549c66f412d5bc4c1af1472d3c3f75f45220efd;hp=9b8e07aa47af4f2e8324535683378de2bf678fc0;hb=d0799512e99e286826e555b6cfa56fc2200c13a5;hpb=e4b9d028aa9583735e8252eeebe255b4a438d30c diff --git a/src/presenter.py b/src/presenter.py index 9b8e07a..e549c66 100644 --- a/src/presenter.py +++ b/src/presenter.py @@ -2,9 +2,9 @@ import logging import gobject import pango -import cairo import gtk +import util.go_utils as go_utils import util.misc as misc_utils @@ -59,16 +59,10 @@ class NavigationBox(gobject.GObject): if self._clickPosition == self._NO_POSITION: return "" - if self._isPortrait: - delta = ( - newCoord[0] - self._clickPosition[0], - - (newCoord[1] - self._clickPosition[1]) - ) - else: - delta = ( - newCoord[1] - self._clickPosition[1], - - (newCoord[0] - self._clickPosition[0]) - ) + delta = ( + newCoord[0] - self._clickPosition[0], + - (newCoord[1] - self._clickPosition[1]) + ) absDelta = (abs(delta[0]), abs(delta[1])) if max(*absDelta) < self.MINIMUM_MOVEMENT: return "clicking" @@ -131,6 +125,7 @@ class StreamPresenter(object): self._subtitle = "" self._buttonImage = None self._imageName = "" + self._dims = 0, 0 @property def toplevel(self): @@ -144,10 +139,7 @@ class StreamPresenter(object): else: raise NotImplementedError(orientation) - cairoContext = self._image.window.cairo_create() - if not self._isPortrait: - cairoContext.transform(cairo.Matrix(0, 1, 1, 0, 0, 0)) - self._draw_presenter(cairoContext) + self._image.queue_draw() def set_state(self, stateImage): if stateImage == self._imageName: @@ -155,37 +147,29 @@ class StreamPresenter(object): self._imageName = stateImage self._buttonImage = self._store.get_surface_from_store(stateImage) - cairoContext = self._image.window.cairo_create() - if not self._isPortrait: - cairoContext.transform(cairo.Matrix(0, 1, 1, 0, 0, 0)) - self._draw_presenter(cairoContext) + self._image.queue_draw() def set_context(self, backgroundImage, title, subtitle): self._backgroundImage = self._store.get_surface_from_store(backgroundImage) + self._title = title + self._subtitle = subtitle - if self._isPortrait: - backWidth = self._backgroundImage.get_width() - backHeight = self._backgroundImage.get_height() - else: - backHeight = self._backgroundImage.get_width() - backWidth = self._backgroundImage.get_height() + backWidth = self._backgroundImage.get_width() + backHeight = self._backgroundImage.get_height() self._image.set_size_request(backWidth, backHeight) - cairoContext = self._image.window.cairo_create() - if not self._isPortrait: - cairoContext.transform(cairo.Matrix(0, 1, 1, 0, 0, 0)) - self._draw_presenter(cairoContext) + self._image.queue_draw() @misc_utils.log_exception(_moduleLogger) def _on_expose(self, widget, event): cairoContext = self._image.window.cairo_create() - if not self._isPortrait: - cairoContext.transform(cairo.Matrix(0, 1, 1, 0, 0, 0)) self._draw_presenter(cairoContext) def _draw_presenter(self, cairoContext): - # Blank things rect = self._image.get_allocation() + self._dims = rect.width, rect.height + + # Blank things cairoContext.rectangle( 0, 0, @@ -194,7 +178,6 @@ class StreamPresenter(object): ) cairoContext.set_source_rgb(0, 0, 0) cairoContext.fill() - cairoContext.paint() # Draw Background if self._backgroundImage is not None: @@ -205,42 +188,54 @@ class StreamPresenter(object): ) cairoContext.paint() - # title - if self._title or self._subtitle: - backWidth = self._backgroundImage.get_width() - backHeight = self._backgroundImage.get_height() + pangoContext = self._image.create_pango_context() + + titleLayout = pango.Layout(pangoContext) + titleLayout.set_markup("%s" % self._subtitle) + textWidth, textHeight = titleLayout.get_pixel_size() + subtitleTextX = self._dims[0] / 2 - textWidth / 2 + subtitleTextY = self._dims[1] - textHeight - self._buttonImage.get_height() + 10 - pangoContext = self._image.create_pango_context() - textLayout = pango.Layout(pangoContext) + subtitleLayout = pango.Layout(pangoContext) + subtitleLayout.set_markup("%s" % self._title) + textWidth, textHeight = subtitleLayout.get_pixel_size() + textX = self._dims[0] / 2 - textWidth / 2 + textY = subtitleTextY - textHeight - textLayout.set_markup(self._subtitle) - textWidth, textHeight = textLayout.get_pixel_size() - subtitleTextX = backWidth / 2 - textWidth / 2 - subtitleTextY = backHeight - textHeight - self._buttonImage.get_height() + xPadding = min((self._dims[0] - textWidth) / 2 - 5, 5) + yPadding = 5 + startContent = xPadding, textY - yPadding + endContent = self._dims[0] - xPadding, self._dims[1] - yPadding + + # Control background + cairoContext.rectangle( + startContent[0], + startContent[1], + endContent[0] - startContent[0], + endContent[1] - startContent[1], + ) + cairoContext.set_source_rgba(0.9, 0.9, 0.9, 0.75) + cairoContext.fill() + + # title + if self._title or self._subtitle: cairoContext.move_to(subtitleTextX, subtitleTextY) cairoContext.set_source_rgb(0, 0, 0) - cairoContext.show_layout(textLayout) + cairoContext.show_layout(titleLayout) - textLayout.set_markup(self._title) - textWidth, textHeight = textLayout.get_pixel_size() - textX = backWidth / 2 - textWidth / 2 - textY = subtitleTextY - textHeight cairoContext.move_to(textX, textY) cairoContext.set_source_rgb(0, 0, 0) - cairoContext.show_layout(textLayout) + cairoContext.show_layout(subtitleLayout) self._draw_state(cairoContext) def _draw_state(self, cairoContext): if self._backgroundImage is None or self._buttonImage is None: return - backWidth = self._backgroundImage.get_width() - backHeight = self._backgroundImage.get_height() - cairoContext.set_source_surface( self._buttonImage, - backWidth / 2 - self._buttonImage.get_width() / 2, - backHeight - self._buttonImage.get_height() + 5, + self._dims[0] / 2 - self._buttonImage.get_width() / 2, + self._dims[1] - self._buttonImage.get_height() + 5, ) cairoContext.paint() @@ -264,3 +259,144 @@ class StreamMiniPresenter(object): def set_context(self, backgroundImage, title, subtitle): pass + + +class NavControl(gobject.GObject, go_utils.AutoSignal): + + __gsignals__ = { + 'home' : ( + gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (), + ), + 'jump-to' : ( + gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT, ), + ), + } + + def __init__(self, player, store): + gobject.GObject.__init__(self) + self._layout = gtk.HBox() + go_utils.AutoSignal.__init__(self, self.toplevel) + + self._store = store + + self._controlButton = store.get_image_from_store(store.STORE_LOOKUP["play"]) + + self._controlBox = NavigationBox() + self._controlBox.toplevel.add(self._controlButton) + self.connect_auto(self._controlBox, "action", self._on_nav_action) + self.connect_auto(self._controlBox, "navigating", self._on_navigating) + + self._titleButton = gtk.Label() + + self._displayBox = NavigationBox() + self._displayBox.toplevel.add(self._titleButton) + self.connect_auto(self._displayBox, "action", self._on_nav_action) + self.connect_auto(self._displayBox, "navigating", self._on_navigating) + + self._layout.pack_start(self._controlBox.toplevel, False, False) + self._layout.pack_start(self._displayBox.toplevel, True, True) + self._player = player + self.connect_auto(self._player, "state-change", self._on_player_state_change) + self.connect_auto(self._player, "title-change", self._on_player_title_change) + self._titleButton.set_label(self._player.title) + + def refresh(self): + self._titleButton.set_label(self._player.title) + self._set_context(self._player.state) + + def _set_context(self, state): + if state == self._player.STATE_PLAY: + stateImage = self._store.STORE_LOOKUP["pause"] + self._store.set_image_from_store(self._controlButton, stateImage) + self.toplevel.show() + elif state == self._player.STATE_PAUSE: + stateImage = self._store.STORE_LOOKUP["play"] + self._store.set_image_from_store(self._controlButton, stateImage) + self.toplevel.show() + elif state == self._player.STATE_STOP: + self._titleButton.set_label("") + self.toplevel.hide() + else: + _moduleLogger.info("Unhandled player state %s" % state) + stateImage = self._store.STORE_LOOKUP["pause"] + self._store.set_image_from_store(self._controlButton, stateImage) + + @property + def toplevel(self): + return self._layout + + def set_orientation(self, orientation): + pass + + @misc_utils.log_exception(_moduleLogger) + def _on_player_state_change(self, player, newState): + if self._controlBox.is_active() or self._displayBox.is_active(): + return + + self._set_context(newState) + + @misc_utils.log_exception(_moduleLogger) + def _on_player_title_change(self, player, node): + _moduleLogger.info("Title change: %s" % self._player.title) + self._titleButton.set_label(self._player.title) + + @misc_utils.log_exception(_moduleLogger) + def _on_navigating(self, widget, navState): + if navState == "down": + imageName = "home" + elif navState == "clicking": + if widget is self._controlBox: + if self._player.state == self._player.STATE_PLAY: + imageName = "pause_pressed" + else: + imageName = "play_pressed" + else: + if self._player.state == self._player.STATE_PLAY: + imageName = "pause" + else: + imageName = "play" + elif self._player.can_navigate: + if navState == "up": + imageName = "play" + elif navState == "left": + imageName = "next" + elif navState == "right": + imageName = "prev" + else: + if self._player.state == self._player.STATE_PLAY: + imageName = "pause" + else: + imageName = "play" + + imagePath = self._store.STORE_LOOKUP[imageName] + self._store.set_image_from_store(self._controlButton, imagePath) + + @misc_utils.log_exception(_moduleLogger) + def _on_nav_action(self, widget, navState): + self._set_context(self._player.state) + + if navState == "clicking": + if widget is self._controlBox: + if self._player.state == self._player.STATE_PLAY: + self._player.pause() + else: + self._player.play() + elif widget is self._displayBox: + self.emit("jump-to", self._player.node) + else: + raise NotImplementedError() + elif navState == "down": + self.emit("home") + elif navState == "up": + pass + elif navState == "left": + self._player.next() + elif navState == "right": + self._player.back() + + +gobject.type_register(NavControl)