X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fwindows%2F_base.py;h=8a144898e6a3508468e207ae700e4727de201478;hb=d0799512e99e286826e555b6cfa56fc2200c13a5;hp=e4396a758bc9d206ccb61a8f977d4b4bda4b9ee2;hpb=137494dc7dabf1d738a3e8e85a469a9c33ea091b;p=watersofshiloah diff --git a/src/windows/_base.py b/src/windows/_base.py index e4396a7..8a14489 100644 --- a/src/windows/_base.py +++ b/src/windows/_base.py @@ -2,6 +2,7 @@ from __future__ import with_statement import ConfigParser import logging +import webbrowser import gobject import gtk @@ -47,11 +48,17 @@ class BasicWindow(gobject.GObject, go_utils.AutoSignal): gobject.TYPE_NONE, (gobject.TYPE_BOOLEAN, ), ), + 'rotate' : ( + gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_PYOBJECT, ), + ), } def __init__(self, app, player, store): gobject.GObject.__init__(self) self._isDestroyed = False + self._isPortrait = hildonize.IS_FREMANTLE_SUPPORTED self._app = app self._player = player @@ -63,7 +70,6 @@ class BasicWindow(gobject.GObject, go_utils.AutoSignal): self._errorBanner = banners.StackingBanner() self._layout = gtk.VBox() - self._layout.pack_start(self._errorBanner.toplevel, False, True) self._window = gtk.Window() self._window.add(self._layout) @@ -75,6 +81,35 @@ class BasicWindow(gobject.GObject, go_utils.AutoSignal): self._window.connect("window-state-event", self._on_window_state_change) self._window.connect("destroy", self._on_destroy) + if hildonize.GTK_MENU_USED: + aboutMenuItem = gtk.MenuItem("About") + aboutMenuItem.connect("activate", self._on_about) + + helpMenu = gtk.Menu() + helpMenu.append(aboutMenuItem) + + helpMenuItem = gtk.MenuItem("Help") + helpMenuItem.set_submenu(helpMenu) + + menuBar = gtk.MenuBar() + menuBar.append(helpMenuItem) + + self._layout.pack_start(menuBar, False, False) + menuBar = hildonize.hildonize_menu( + self._window, + menuBar, + ) + else: + aboutMenuItem = gtk.Button("About") + aboutMenuItem.connect("clicked", self._on_about) + + appMenu = hildonize.hildon.AppMenu() + appMenu.append(aboutMenuItem) + appMenu.show_all() + self._window.set_app_menu(appMenu) + + self._layout.pack_start(self._errorBanner.toplevel, False, True) + @property def window(self): return self._window @@ -97,6 +132,7 @@ class BasicWindow(gobject.GObject, go_utils.AutoSignal): e.section, ) ) + windowInFullscreen = self._windowInFullscreen if windowInFullscreen: self._window.fullscreen() @@ -106,6 +142,45 @@ class BasicWindow(gobject.GObject, go_utils.AutoSignal): def jump_to(self, node): raise NotImplementedError("On %s" % self) + def set_orientation(self, orientation): + oldIsPortrait = self._isPortrait + if orientation == gtk.ORIENTATION_VERTICAL: + hildonize.window_to_portrait(self._window) + self._isPortrait = True + elif orientation == gtk.ORIENTATION_HORIZONTAL: + hildonize.window_to_landscape(self._window) + self._isPortrait = False + else: + raise NotImplementedError(orientation) + didChange = oldIsPortrait != self._isPortrait + if didChange: + self.emit("rotate", orientation) + return didChange + + def _configure_child(self, childWindow): + if not hildonize.IS_FREMANTLE_SUPPORTED: + childWindow.window.set_modal(True) + childWindow.window.set_transient_for(self._window) + childWindow.window.set_default_size(*self._window.get_size()) + if self._windowInFullscreen: + childWindow.window.fullscreen() + else: + childWindow.window.unfullscreen() + childWindow.set_orientation( + gtk.ORIENTATION_VERTICAL if self._isPortrait else gtk.ORIENTATION_HORIZONTAL + ) + childWindow.connect_auto(childWindow, "quit", self._on_quit) + childWindow.connect_auto(childWindow, "home", self._on_home) + childWindow.connect_auto(childWindow, "jump-to", self._on_jump) + childWindow.connect_auto(childWindow, "fullscreen", self._on_child_fullscreen) + childWindow.connect_auto(childWindow, "rotate", self._on_child_rotate) + + @misc_utils.log_exception(_moduleLogger) + def _on_about(self, *args): + sourceWindow = AboutWindow(self._app, self._player, self._store) + self._configure_child(sourceWindow) + sourceWindow.show() + @misc_utils.log_exception(_moduleLogger) def _on_destroy(self, *args): self._isDestroyed = True @@ -135,6 +210,12 @@ class BasicWindow(gobject.GObject, go_utils.AutoSignal): else: self._window.fullscreen () return True + elif event.keyval == gtk.keysyms.o and event.get_state() & gtk.gdk.CONTROL_MASK: + if self._isPortrait: + self.set_orientation(gtk.ORIENTATION_HORIZONTAL) + else: + self.set_orientation(gtk.ORIENTATION_VERTICAL) + return True elif ( event.keyval in (gtk.keysyms.w, ) and event.get_state() & gtk.gdk.CONTROL_MASK @@ -168,6 +249,10 @@ class BasicWindow(gobject.GObject, go_utils.AutoSignal): self._window.unfullscreen() @misc_utils.log_exception(_moduleLogger) + def _on_child_rotate(self, source, orientation): + self.set_orientation(orientation) + + @misc_utils.log_exception(_moduleLogger) def _on_jump(self, source, node): raise NotImplementedError("On %s" % self) @@ -350,7 +435,9 @@ class PresenterWindow(BasicWindow): self._presenter = presenter.StreamPresenter(self._store) self._presenter.set_context( - self._get_background(), + self._get_background( + gtk.ORIENTATION_VERTICAL if self._isPortrait else gtk.ORIENTATION_HORIZONTAL + ), self._node.title, self._node.subtitle, ) @@ -368,7 +455,7 @@ class PresenterWindow(BasicWindow): self._window.set_title(self._node.get_parent().title) - def _get_background(self): + def _get_background(self, orientation): raise NotImplementedError() def show(self): @@ -382,6 +469,16 @@ class PresenterWindow(BasicWindow): def jump_to(self, node): assert self._node is node + def set_orientation(self, orientation): + didChange = BasicWindow.set_orientation(self, orientation) + if didChange: + self._presenter.set_orientation(orientation) + self._presenter.set_context( + self._get_background(orientation), + self._node.title, + self._node.subtitle, + ) + @property def _active(self): return self._playerNode is self._node @@ -533,3 +630,73 @@ class PresenterWindow(BasicWindow): def _on_node_search_error(self, e): self._nextSearch = None self._errorBanner.push_message(str(e)) + + +class AboutWindow(BasicWindow): + + def __init__(self, app, player, store): + BasicWindow.__init__(self, app, player, store) + self._window.set_title(constants.__pretty_app_name__) + + self._titleLabel = gtk.Label() + self._titleLabel.set_markup(""" +Waters of Shiloah +Maemo Edition +Version %s +""" % (constants.__version__, )) + self._titleLabel.set_property("justify", gtk.JUSTIFY_CENTER) + + self._copyLabel = gtk.Label() + self._copyLabel.set_markup(""" +Developed by: Ed Page +Images by: Various Sources, See COPYING for author and license information (mix of various CC licenses, commercial, and non-commercial +This application nor various images are not endorsed by The Church of Jesus Christ of Latter-day Saints +""") + self._copyLabel.set_property("justify", gtk.JUSTIFY_CENTER) + + self._linkButton = gtk.LinkButton("http://watersofshiloah.garage.maemo.org") + self._linkButton.set_label("Waters of Shiloah") + self._linkButton.connect("clicked", self._on_website) + + self._radioLinkButton = gtk.LinkButton("http://radio.lds.org") + self._radioLinkButton.set_label("Mormon Channel") + self._radioLinkButton.connect("clicked", self._on_website) + + self._ldsLinkButton = gtk.LinkButton("http://www.lds.org") + self._ldsLinkButton.set_label("LDS.org") + self._ldsLinkButton.connect("clicked", self._on_website) + + self._spacedLayout = gtk.VBox(True) + self._spacedLayout.pack_start(self._titleLabel, False, False) + self._spacedLayout.pack_start(self._copyLabel, False, False) + self._spacedLayout.pack_start(self._linkButton, False, False) + self._spacedLayout.pack_start(self._radioLinkButton, False, False) + self._spacedLayout.pack_start(self._ldsLinkButton, False, False) + + self._separator = gtk.HSeparator() + self._presenter = presenter.NavControl(self._player, self._store) + self.connect_auto(self._presenter, "home", self._on_home) + self.connect_auto(self._presenter, "jump-to", self._on_jump) + + self._layout.pack_start(self._spacedLayout, True, True) + self._layout.pack_start(self._presenter.toplevel, False, True) + + def show(self): + BasicWindow.show(self) + self._window.show_all() + self._errorBanner.toplevel.hide() + self._presenter.refresh() + + @misc_utils.log_exception(_moduleLogger) + def _on_about(self, *args): + pass + + @misc_utils.log_exception(_moduleLogger) + def _on_website(self, widget): + uri = widget.get_uri() + webbrowser.open(uri) + + @misc_utils.log_exception(_moduleLogger) + def _on_jump(self, source, node): + self.emit("jump-to", node) + self._window.destroy()