First try at starting on the UI
authorEd Page <eopage@byu.net>
Sun, 2 May 2010 05:10:11 +0000 (00:10 -0500)
committerEd Page <eopage@byu.net>
Tue, 4 May 2010 03:15:17 +0000 (22:15 -0500)
src/banners.py [new file with mode: 0644]
src/imagestore.py
src/mormonchannel_gtk.py
src/playcontrol.py
src/player.py [new file with mode: 0644]
src/presenter.py
src/windows.py [new file with mode: 0644]

diff --git a/src/banners.py b/src/banners.py
new file mode 100644 (file)
index 0000000..328029a
--- /dev/null
@@ -0,0 +1,91 @@
+import sys
+import logging
+
+import gtk
+
+import util.misc as misc_utils
+
+
+_moduleLogger = logging.getLogger(__name__)
+
+
+class GenericBanner(object):
+
+       def __init__(self):
+               self._label = gtk.Label()
+
+               self._layout = gtk.VBox()
+               self._layout.pack_start(self._label)
+
+       @property
+       def toplevel(self):
+               return self._layout
+
+       def show(self, message):
+               assert not self._label.get_text(), self._label.get_text()
+               self._label.set_text(message)
+               self.toplevel.show()
+
+       def hide(self):
+               assert self._label.get_text(), self._label.get_text()
+               self._label.set_text("")
+               self.toplevel.hide()
+
+
+class StackingBanner(object):
+
+       ICON_SIZE = 32
+
+       def __init__(self):
+               self._indicator = gtk.Image()
+
+               self._message = gtk.Label()
+
+               self._closeImage = gtk.Image()
+               self._closeImage.set_from_stock("gtk-close", self.ICON_SIZE)
+
+               self._layout = gtk.HBox()
+               self._layout.pack_start(self._indicator, False, False)
+               self._layout.pack_start(self._message, True, True)
+               self._layout.pack_start(self._closeImage, False, False)
+
+               self._events = gtk.EventBox()
+               self._events.add(self._layout)
+               self._events.connect("button_release_event", self._on_close)
+
+               self._messages = []
+
+       @property
+       def toplevel(self):
+               return self._events
+
+       def push_message(self, message, icon=""):
+               self._messages.append((message, icon))
+               if 1 == len(self.__messages):
+                       self._update_message()
+
+       def push_exception(self):
+               userMessage = str(sys.exc_info()[1])
+               self.push_message(userMessage, "gtk-dialog-error")
+               _moduleLogger.exception(userMessage)
+
+       def pop_message(self):
+               del self.__messages[0]
+               self._update_message()
+
+       def _update_message(self):
+               if 0 == len(self.__messages):
+                       self.toplevel.hide()
+               else:
+                       message, icon = self._message[0]
+                       self._message.set_text(message)
+                       if icon:
+                               self._indicator.set_from_stock(icon)
+                               self._indicator.show()
+                       else:
+                               self._indicator.hide()
+                       self.toplevel.show()
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_close(self, *args):
+               self.pop_message()
index e5e351c..cc2ea55 100644 (file)
@@ -12,12 +12,14 @@ class ImageStore(object):
                "pause": "pause.png",
                "play": "play.png",
                "stop": "stop.png",
+
                "generic_background": "radiobackground_01.png",
                "night_temple_background": "radiobackground_02.png",
                "day_temple_background": "radiobackground_03.png",
                "presidency_background": "radiobackground_04.png",
                "scriptures_background": "radiobackground_05.png",
-               "conference": "conference.png",
+
+               "conferences": "conference.png",
                "magazines": "magazines.png",
                "more": "more.png",
                "mormonmessages": "mormonmessages.png",
index ddcd8f3..09ebb5d 100755 (executable)
@@ -23,6 +23,10 @@ import constants
 import hildonize
 import gtk_toolbox
 
+import imagestore
+import player
+import windows
+
 
 _moduleLogger = logging.getLogger(__name__)
 PROFILE_STARTUP = False
@@ -113,6 +117,12 @@ class MormonChannelProgram(hildonize.get_app_class()):
                self._window.connect("window-state-event", self._on_window_state_change)
 
                self._window.show_all()
+
+               self._player = player.Player()
+               self._store = imagestore.ImageStore("../data", "../data")
+               self._windowStack = [windows.SourceSelector(self._player, self._store)]
+               vbox.pack_start(self._windowStack[0].toplevel, True, True)
+
                self._load_settings()
 
        def _save_settings(self):
index 2e31d0a..0802ebe 100644 (file)
@@ -21,27 +21,27 @@ class PlayControl(object):
                self._player.connect("state-change", self._on_player_state_change)
                self._player.connect("navigate-change", self._on_player_nav_change)
 
-               img = store.get_image_from_store("prev.png")
+               img = store.get_image_from_store(store.STORE_LOOKUP["prev"])
                self._back = gtk.Button()
                self._back.set_image(img)
                self._back.connect("clicked", self._on_back_clicked)
 
-               img = store.get_image_from_store("stop.png")
+               img = store.get_image_from_store(store.STORE_LOOKUP["stop"])
                self._stop = gtk.Button()
                self._stop.set_image(img)
                self._stop.connect("clicked", self._on_stop_clicked)
 
-               img = store.get_image_from_store("pause.png")
+               img = store.get_image_from_store(store.STORE_LOOKUP["pause"])
                self._pause = gtk.Button()
                self._pause.set_image(img)
                self._pause.connect("clicked", self._on_pause_clicked)
 
-               img = store.get_image_from_store("play.png")
+               img = store.get_image_from_store(store.STORE_LOOKUP["play"])
                self._play = gtk.Button()
                self._play.set_image(img)
                self._play.connect("clicked", self._on_play_clicked)
 
-               img = store.get_image_from_store("next.png")
+               img = store.get_image_from_store(store.STORE_LOOKUP["next"])
                self._next = gtk.Button()
                self._next.set_image(img)
                self._next.connect("clicked", self._on_next_clicked)
diff --git a/src/player.py b/src/player.py
new file mode 100644 (file)
index 0000000..b99d1c6
--- /dev/null
@@ -0,0 +1,64 @@
+import logging
+
+import gobject
+
+
+_moduleLogger = logging.getLogger(__name__)
+
+
+class Player(gobject.GObject):
+
+       __gsignals__ = {
+               'state_change' : (
+                       gobject.SIGNAL_RUN_LAST,
+                       gobject.TYPE_NONE,
+                       (gobject.TYPE_PYOBJECT, ),
+               ),
+               'navigate_change' : (
+                       gobject.SIGNAL_RUN_LAST,
+                       gobject.TYPE_NONE,
+                       (gobject.TYPE_PYOBJECT, ),
+               ),
+               'title_change' : (
+                       gobject.SIGNAL_RUN_LAST,
+                       gobject.TYPE_NONE,
+                       (gobject.TYPE_PYOBJECT, ),
+               ),
+       }
+
+       def __init__(self):
+               gobject.GObject.__init__(self)
+
+       @property
+       def title(self):
+               return ""
+
+       @property
+       def can_navigate(self):
+               return True
+
+       @property
+       def state(self):
+               return "play"
+
+       @property
+       def background(self):
+               return "night_temple_background"
+
+       def play(self):
+               _moduleLogger.info("play")
+
+       def pause(self):
+               _moduleLogger.info("pause")
+
+       def stop(self):
+               _moduleLogger.info("stop")
+
+       def back(self):
+               _moduleLogger.info("back")
+
+       def next(self):
+               _moduleLogger.info("next")
+
+
+gobject.type_register(Player)
index 20359af..335d118 100644 (file)
@@ -42,9 +42,6 @@ class StreamPresenter(object):
                self._image.connect("expose_event", self._on_expose)
                self._imageEvents = gtk.EventBox()
                self._imageEvents.connect("motion_notify_event", self._on_motion_notify)
-               #self._imageEvents.connect("leave_notify_event", self._on_leave_notify)
-               #self._imageEvents.connect("proximity_in_event", self._on_motion_notify)
-               #self._imageEvents.connect("proximity_out_event", self._on_leave_notify)
                self._imageEvents.connect("button_press_event", self._on_button_press)
                self._imageEvents.connect("button_release_event", self._on_button_release)
                self._imageEvents.add(self._image)
diff --git a/src/windows.py b/src/windows.py
new file mode 100644 (file)
index 0000000..6ad1192
--- /dev/null
@@ -0,0 +1,62 @@
+import gtk
+
+import banners
+import playcontrol
+
+
+class SourceSelector(object):
+
+       def __init__(self, player, store):
+               self._player = player
+               self._store = store
+
+               self._errorBanner = banners.StackingBanner()
+
+               self._radioButton = self._create_button("radio", "Radio")
+               self._radioWrapper = gtk.VBox()
+               self._radioWrapper.pack_start(self._radioButton, False, True)
+               self._conferenceButton = self._create_button("conferences", "Conferences")
+               self._conferenceWrapper = gtk.VBox()
+               self._conferenceWrapper.pack_start(self._conferenceButton, False, True)
+               self._magazineButton = self._create_button("magazines", "Magazines")
+               self._magazineWrapper = gtk.VBox()
+               self._magazineWrapper.pack_start(self._magazineButton, False, True)
+               self._scriptureButton = self._create_button("scriptures", "Scriptures")
+               self._scriptureWrapper = gtk.VBox()
+               self._scriptureWrapper.pack_start(self._scriptureButton, False, True)
+
+               self._buttonLayout = gtk.VBox(True, 5)
+               self._buttonLayout.set_property("border-width", 5)
+               self._buttonLayout.pack_start(self._radioWrapper, True, True)
+               self._buttonLayout.pack_start(self._conferenceWrapper, True, True)
+               self._buttonLayout.pack_start(self._magazineWrapper, True, True)
+               self._buttonLayout.pack_start(self._scriptureWrapper, True, True)
+
+               self._playcontrol = playcontrol.PlayControl(player, store)
+
+               self._layout = gtk.VBox()
+               self._layout.pack_start(self._errorBanner.toplevel, False, True)
+               self._layout.pack_start(self._buttonLayout, True, True)
+               self._layout.pack_start(self._playcontrol.toplevel, False, True)
+
+               self._layout.show_all()
+               self._errorBanner.toplevel.hide()
+               self._playcontrol.toplevel.hide()
+
+       @property
+       def toplevel(self):
+               return self._layout
+
+       def _create_button(self, icon, message):
+               image = self._store.get_image_from_store(self._store.STORE_LOOKUP[icon])
+
+               label = gtk.Label()
+               label.set_text(message)
+
+               buttonLayout = gtk.HBox(False, 5)
+               buttonLayout.pack_start(image, False, False)
+               buttonLayout.pack_start(label, False, True)
+               button = gtk.Button()
+               button.add(buttonLayout)
+
+               return button