diff options
Diffstat (limited to 'activity.py')
-rw-r--r-- | activity.py | 338 |
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) |