Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/activity.py
diff options
context:
space:
mode:
Diffstat (limited to 'activity.py')
-rw-r--r--activity.py338
1 files changed, 338 insertions, 0 deletions
diff --git a/activity.py b/activity.py
new file mode 100644
index 0000000..65ed37d
--- /dev/null
+++ b/activity.py
@@ -0,0 +1,338 @@
+import pygst
+pygst.require("0.10")
+# Load GTK
+import gtk
+from gtk import gdk
+import pygst
+import os, sys
+import time
+import gobject
+gobject.threads_init()
+from mediaview import MediaView
+import constants
+import gst
+import pygtk
+from treeview import TreeView
+from model import Model
+from button import RecdButton
+import utils
+from instance import Instance
+from tray import HTray
+import shutil
+# Load sugar libraries
+from sugar.activity import activity
+import logging
+
+COLOR_BLACK = gdk.color_parse('#000000')
+COLOR_WHITE = gdk.color_parse('#ffffff')
+
+class littleTrampActivity(activity.Activity):
+
+ def callback(self, widget, data=None):
+ print "Hello again"
+
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+ self._name = handle
+
+ # Set title for our Activity
+ self.set_title('Little Tramp')
+
+ # Attach sugar toolbox (Share, ...)
+ #toolbox = activity.ActivityToolbox(self)
+ #self.set_toolbox(toolbox)
+ #toolbox.show()
+ Instance(self)
+
+ #self.set_canvas(self._main_view)
+ self.show_all()
+ self.model = Model(self)
+ self.ui_init()
+ self._media_view.realize_video()
+
+ # Changing to the first toolbar kicks off the rest of the setup
+ if self.model.get_has_camera():
+ self.model.change_mode(constants.MODE_PHOTO)
+ #else:
+ #self.model.change_mode(constants.MODE_AUDIO)
+
+ def _shutter_clicked(self, arg):
+ self.model.do_shutter()
+
+ def _remove_thumbnail(self, recdbutton):
+ handlers = recdbutton.get_data('handler-ids')
+ for handler in handlers:
+ recdbutton.disconnect(handler)
+
+ self._thumb_tray.remove_item(recdbutton)
+ recdbutton.cleanup()
+
+ def remove_all_thumbnails(self):
+ for child in self._thumb_tray.get_children():
+ self._remove_thumbnail(child)
+
+ def add_thumbnail(self, recd, scroll_to_end):
+ button = RecdButton(recd)
+ clicked_handler = button.connect("clicked", self._thumbnail_clicked, recd)
+ remove_handler = button.connect("remove-requested", self._remove_recd)
+ clipboard_handler = button.connect("copy-clipboard-requested", self._thumbnail_copy_clipboard)
+ button.set_data('handler-ids', (clicked_handler, remove_handler, clipboard_handler))
+ self._thumb_tray.add_item(button)
+ button.show()
+ if scroll_to_end:
+ self._thumb_tray.scroll_to_end()
+
+
+ def ui_init(self):
+ self._fullscreen = False
+ self._showing_info = False
+
+ # FIXME: if _thumb_tray becomes some kind of button group, we wouldn't
+ # have to track which recd is active
+ self._active_recd = None
+ toolbox = activity.ActivityToolbox(self)
+ activity_toolbar = toolbox.get_activity_toolbar()
+ activity_toolbar.keep.props.visible = False
+ activity_toolbar.share.props.visible = False
+ self.set_toolbox(toolbox)
+ toolbox.show()
+
+ self.tView = TreeView()
+
+ main_box = gtk.VBox()
+ self.set_canvas(main_box)
+ main_box.get_parent().modify_bg(gtk.STATE_NORMAL, COLOR_BLACK)
+ main_box.show()
+
+ self._media_view = MediaView()
+ #self._media_view.connect('media-clicked', self._media_view_media_clicked)
+ #self._media_view.connect('pip-clicked', self._media_view_pip_clicked)
+ #self._media_view.connect('info-clicked', self._media_view_info_clicked)
+ #self._media_view.connect('full-clicked', self._media_view_full_clicked)
+ #self._media_view.connect('tags-changed', self._media_view_tags_changed)
+ self._media_view.show()
+
+ self._controls_hbox = gtk.HBox()
+ self._controls_hbox.show()
+ self._treeview_vbox = gtk.VBox()
+ self._treeview_vbox.show()
+ self._treeview_vbox.pack_start(self.tView)
+ self._shutter_button = ShutterButton()
+ self._shutter_button.connect("clicked", self._shutter_clicked)
+ self._controls_hbox.pack_start(self._shutter_button, expand=True, fill=False)
+ self._shutter_button.show()
+
+ self._title_label = gtk.Label()
+ self._title_label.set_markup("<b><span foreground='white'>"+('Title:')+'</span></b>')
+ self._controls_hbox.pack_start(self._title_label, expand=False)
+
+ self._title_entry = gtk.Entry()
+ self._title_entry.modify_bg(gtk.STATE_INSENSITIVE, COLOR_BLACK)
+ self._title_entry.connect('changed', self._title_changed)
+ self._controls_hbox.pack_start(self._title_entry, expand=True, fill=True, padding=10)
+
+ container = RecordContainer(self._media_view, self._controls_hbox)
+ main_box.pack_start(self._treeview_vbox, expand=True)
+ main_box.pack_start(container, expand=True, fill=True, padding=6)
+ container.show()
+
+ self._thumb_tray = HTray()
+ self._thumb_tray.set_size_request(-1, 150)
+ main_box.pack_end(self._thumb_tray, expand=False)
+ self._thumb_tray.show_all()
+
+ def set_glive_sink(self, sink):
+ return self._media_view.set_video_sink(sink)
+
+ # can be called from gstreamer thread, so must not do any GTK+ stuff
+ def set_gplay_sink(self, sink):
+ return self._media_view.set_video2_sink(sink)
+
+ def _title_changed(self, widget):
+ self._active_recd.setTitle(self._title_entry.get_text())
+
+ def _thumbnail_clicked(self, button, recd):
+ if self.model.ui_frozen():
+ return
+
+ self._active_recd = recd
+ self._show_recd(recd)
+
+ def _show_recd(self, recd, play=True):
+ self._showing_info = False
+
+ def _remove_recd(self, recdbutton):
+ recd = recdbutton.get_recd()
+ self.model.delete_recd(recd)
+ if self._active_recd == recd:
+ self.model.set_state(constants.STATE_READY)
+
+ self._remove_thumbnail(recdbutton)
+
+ def _thumbnail_copy_clipboard(self, recdbutton):
+ self._copy_to_clipboard(recdbutton.get_recd())
+
+
+ def _copy_to_clipboard(self, recd):
+ if recd == None:
+ return
+ if not recd.isClipboardCopyable():
+ return
+
+ media_path = recd.getMediaFilepath()
+ tmp_path = utils.getUniqueFilepath(media_path, 0)
+ shutil.copyfile(media_path, tmp_path)
+ gtk.Clipboard().set_with_data([('text/uri-list', 0, 0)], self._clipboard_get, self._clipboard_clear, tmp_path)
+
+ def set_shutter_sensitive(self, value):
+ self._shutter_button.set_sensitive(value)
+
+
+class ShutterButton(gtk.Button):
+ def __init__(self):
+ gtk.Button.__init__(self)
+ self.set_relief(gtk.RELIEF_NONE)
+ self.set_focus_on_click(False)
+ self.modify_bg(gtk.STATE_ACTIVE, COLOR_BLACK)
+
+ path = os.path.join(constants.GFX_PATH, 'media-record.png')
+ self._rec_image = gtk.image_new_from_file(path)
+
+ path = os.path.join(constants.GFX_PATH, 'media-record-red.png')
+ self._rec_red_image = gtk.image_new_from_file(path)
+
+ path = os.path.join(constants.GFX_PATH, 'media-insensitive.png')
+ self._insensitive_image = gtk.image_new_from_file(path)
+
+ self.set_normal()
+
+ def set_sensitive(self, sensitive):
+ if sensitive:
+ self.set_image(self._rec_image)
+ else:
+ self.set_image(self._insensitive_image)
+ super(ShutterButton, self).set_sensitive(sensitive)
+
+ def set_normal(self):
+ self.set_image(self._rec_image)
+
+ def set_recording(self):
+ self.set_image(self._rec_red_image)
+class RecordContainer(gtk.Container):
+ """
+ A custom Container that contains a media view area, and a controls hbox.
+
+ The controls hbox is given the first height that it requests, locked in
+ for the duration of the widget.
+ The media view is given the remainder of the space, but is constrained to
+ a strict 4:3 ratio, therefore deducing its width.
+ The controls hbox is given the same width, and both elements are centered
+ horizontall.y
+ """
+ __gtype_name__ = 'RecordContainer'
+
+ def __init__(self, media_view, controls_hbox):
+ self._media_view = media_view
+ self._controls_hbox = controls_hbox
+ self._controls_hbox_height = 0
+ super(RecordContainer, self).__init__()
+
+ for widget in (self._media_view, self._controls_hbox):
+ if widget.flags() & gtk.REALIZED:
+ widget.set_parent_window(self.window)
+
+ widget.set_parent(self)
+
+ def do_realize(self):
+ self.set_flags(gtk.REALIZED)
+
+ self.window = gdk.Window(
+ self.get_parent_window(),
+ window_type=gdk.WINDOW_CHILD,
+ x=self.allocation.x,
+ y=self.allocation.y,
+ width=self.allocation.width,
+ height=self.allocation.height,
+ wclass=gdk.INPUT_OUTPUT,
+ colormap=self.get_colormap(),
+ event_mask=self.get_events() | gdk.VISIBILITY_NOTIFY_MASK | gdk.EXPOSURE_MASK)
+ self.window.set_user_data(self)
+
+ self.set_style(self.style.attach(self.window))
+
+ for widget in (self._media_view, self._controls_hbox):
+ widget.set_parent_window(self.window)
+ self.queue_resize()
+
+ # GTK+ contains on exit if remove is not implemented
+ def do_remove(self, widget):
+ pass
+
+ def do_size_request(self, req):
+ # always request 320x240 (as a minimum for video)
+ req.width = 320
+ req.height = 240
+
+ self._media_view.size_request()
+
+ w, h = self._controls_hbox.size_request()
+
+ # add on height requested by controls hbox
+ if self._controls_hbox_height == 0:
+ self._controls_hbox_height = h
+
+ req.height += self._controls_hbox_height
+
+ @staticmethod
+ def _constrain_4_3(width, height):
+ if (width % 4 == 0) and (height % 3 == 0) and ((width / 4) * 3) == height:
+ return width, height # nothing to do
+
+ ratio = 4.0 / 3.0
+ if ratio * height > width:
+ width = (width / 4) * 4
+ height = int(width / ratio)
+ else:
+ height = (height / 3) * 3
+ width = int(ratio * height)
+
+ return width, height
+
+ @staticmethod
+ def _center_in_plane(plane_size, size):
+ return (plane_size - size) / 2
+
+ def do_size_allocate(self, allocation):
+ self.allocation = allocation
+
+ # give the controls hbox the height that it requested
+ remaining_height = self.allocation.height - self._controls_hbox_height
+
+ # give the mediaview the rest, constrained to 4/3 and centered
+ media_view_width, media_view_height = self._constrain_4_3(self.allocation.width, remaining_height)
+ media_view_x = self._center_in_plane(self.allocation.width, media_view_width)
+ media_view_y = self._center_in_plane(remaining_height, media_view_height)
+
+ # send allocation to mediaview
+ alloc = gdk.Rectangle()
+ alloc.width = media_view_width
+ alloc.height = media_view_height
+ alloc.x = media_view_x
+ alloc.y = media_view_y
+ self._media_view.size_allocate(alloc)
+
+ # position hbox at the bottom of the window, with the requested height,
+ # and the same width as the media view
+ alloc = gdk.Rectangle()
+ alloc.x = media_view_x
+ alloc.y = self.allocation.height - self._controls_hbox_height
+ alloc.width = media_view_width
+ alloc.height = self._controls_hbox_height
+ self._controls_hbox.size_allocate(alloc)
+
+ if self.flags() & gtk.REALIZED:
+ self.window.move_resize(*allocation)
+
+ def do_forall(self, include_internals, callback, data):
+ for widget in (self._media_view, self._controls_hbox):
+ callback(widget, data)