diff options
-rw-r--r-- | record.py | 271 | ||||
-rw-r--r-- | toolbarcombobox.py | 59 |
2 files changed, 198 insertions, 132 deletions
@@ -33,9 +33,7 @@ import pygst pygst.require('0.10') import gst -import sugar.profile from sugar.activity import activity -from sugar.graphics.icon import Icon from model import Model from button import RecdButton @@ -43,10 +41,17 @@ import constants from instance import Instance import utils from tray import HTray -from toolbarcombobox import ToolComboBox +from sugar.graphics.toolcombobox import ToolComboBox from mediaview import MediaView import hw +from sugar.graphics.toolbarbox import ToolbarBox +from sugar.graphics.toolbarbox import ToolbarButton +from sugar.graphics.toolbutton import ToolButton +from sugar.activity.widgets import StopButton +from sugar.activity.widgets import ActivityToolbarButton +from sugar.activity.widgets import CopyButton + logger = logging.getLogger('record.py') COLOR_BLACK = gdk.color_parse('#000000') COLOR_WHITE = gdk.color_parse('#ffffff') @@ -58,6 +63,7 @@ if logging.getLogger().level <= logging.DEBUG: else: gst.debug_set_default_threshold(gst.LEVEL_ERROR) + class Record(activity.Activity): def __init__(self, handle): super(Record, self).__init__(handle) @@ -81,7 +87,7 @@ class Record(activity.Activity): self._media_view.realize_video() # Changing to the first toolbar kicks off the rest of the setup - self._toolbox.set_current_toolbar(1) + self.model.change_mode(constants.MODE_PHOTO) def read_file(self, path): self.model.read_file(path) @@ -111,31 +117,81 @@ class Record(activity.Activity): self.connect_after('key-press-event', self._key_pressed) self._active_toolbar_idx = 0 - self._toolbox = activity.ActivityToolbox(self) - self.set_toolbox(self._toolbox) - self._toolbar_modes = [None] - # remove Toolbox's hardcoded grey separator - self._toolbox.remove(self._toolbox._separator) + self._toolbar_box = ToolbarBox() + self.activity_button = ActivityToolbarButton(self) + self._toolbar_box.toolbar.insert(self.activity_button, 0) + self.set_toolbar_box(self._toolbar_box) + self._toolbar = self.get_toolbar_box().toolbar + + edit_button = ToolbarButton() + self._edit_toolbar = EditToolbar(self) + edit_button.set_page(self._edit_toolbar) + edit_button.props.icon_name = 'toolbar-edit' + edit_button.props.label = _('Edit') + self._toolbar.insert(edit_button, -1) + + view_button = ToolbarButton() + self._view_toolbar = ViewToolbar(self) + view_button.set_page(self._view_toolbar) + view_button.props.icon_name = 'toolbar-view' + view_button.props.label = _('View') + self._toolbar.insert(view_button, -1) + + self._toolbar.insert(gtk.SeparatorToolItem(), -1) + + self._toolbar_modes = [None] if self.model.get_has_camera(): self._photo_toolbar = PhotoToolbar() - self._toolbox.add_toolbar(_('Photo'), self._photo_toolbar) - self._toolbar_modes.append(constants.MODE_PHOTO) + photo_button = ToolbarButton() + photo_button.set_page(self._photo_toolbar) + photo_button.props.icon_name = 'camera-external' + photo_button.props.label = _('Photo') + photo_button.mode = constants.MODE_PHOTO + photo_button.connect('clicked', self.__mode_button_clicked) + # disable auto popup + photo_button.get_child().disconnect( + photo_button._palette_invoker._enter_hid) + self._toolbar.insert(photo_button, -1) self._video_toolbar = VideoToolbar() - self._toolbox.add_toolbar(_('Video'), self._video_toolbar) + video_button = ToolbarButton() + video_button.set_page(self._video_toolbar) + video_button.props.icon_name = 'media-video' + video_button.props.label = _('Video') + video_button.mode = constants.MODE_VIDEO + video_button.connect('clicked', self.__mode_button_clicked) + # disable auto popup + video_button.get_child().disconnect( + video_button._palette_invoker._enter_hid) + self._toolbar.insert(video_button, -1) + + self._toolbar_modes.append(constants.MODE_PHOTO) self._toolbar_modes.append(constants.MODE_VIDEO) else: self._photo_toolbar = None self._video_toolbar = None self._audio_toolbar = AudioToolbar() - self._toolbox.add_toolbar(_('Audio'), self._audio_toolbar) + audio_button = ToolbarButton() + audio_button.set_page(self._audio_toolbar) + audio_button.props.icon_name = 'media-audio' + audio_button.props.label = _('Audio') + audio_button.mode = constants.MODE_AUDIO + audio_button.connect('clicked', self.__mode_button_clicked) + # disable auto popup + audio_button.get_child().disconnect( + audio_button._palette_invoker._enter_hid) + self._toolbar.insert(audio_button, -1) self._toolbar_modes.append(constants.MODE_AUDIO) - self._toolbox.show_all() - self._toolbox.connect("current-toolbar-changed", self._toolbar_changed) + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_expand(True) + self._toolbar.insert(separator, -1) + self._toolbar.insert(StopButton(self), -1) + self.get_toolbar_box().show_all() main_box = gtk.VBox() self.set_canvas(main_box) @@ -143,11 +199,16 @@ class Record(activity.Activity): 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.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() @@ -155,29 +216,34 @@ class Record(activity.Activity): 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._controls_hbox.pack_start(self._shutter_button, expand=True, + fill=False) self._countdown_image = CountdownImage() - self._controls_hbox.pack_start(self._countdown_image, expand=True, fill=False) + self._controls_hbox.pack_start(self._countdown_image, expand=True, + fill=False) self._play_button = PlayButton() self._play_button.connect('clicked', self._play_pause_clicked) self._controls_hbox.pack_start(self._play_button, expand=False) self._playback_scale = PlaybackScale(self.model) - self._controls_hbox.pack_start(self._playback_scale, expand=True, fill=True) + self._controls_hbox.pack_start(self._playback_scale, expand=True, + fill=True) self._progress = ProgressInfo() self._controls_hbox.pack_start(self._progress, expand=True, fill=True) self._title_label = gtk.Label() - self._title_label.set_markup("<b><span foreground='white'>"+_('Title:')+'</span></b>') + 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) + 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(container, expand=True, fill=True, padding=6) @@ -222,11 +288,11 @@ class Record(activity.Activity): key = event.keyval - if key == gtk.keysyms.KP_Page_Up: # game key O + if key == gtk.keysyms.KP_Page_Up: # game key O if self._shutter_button.props.visible: if self._shutter_button.props.sensitive: self._shutter_button.clicked() - else: # return to live mode + else: # return to live mode self.model.set_state(constants.STATE_READY) elif key == gtk.keysyms.c and event.state == gdk.CONTROL_MASK: self._copy_to_clipboard(self._active_recd) @@ -287,7 +353,8 @@ class Record(activity.Activity): self._active_recd.setTitle(self._title_entry.get_text()) def _media_view_media_clicked(self, widget): - if self._play_button.props.visible and self._play_button.props.sensitive: + if self._play_button.props.visible and \ + self._play_button.props.sensitive: self._play_button.clicked() def _media_view_pip_clicked(self, widget): @@ -307,7 +374,8 @@ class Record(activity.Activity): return self._showing_info = True - if self.model.get_mode() in (constants.MODE_PHOTO, constants.MODE_AUDIO): + if self.model.get_mode() in (constants.MODE_PHOTO, + constants.MODE_AUDIO): func = self._media_view.show_info_photo else: func = self._media_view.show_info_video @@ -319,38 +387,41 @@ class Record(activity.Activity): self._title_entry.show() self._title_label.show() - func(recd.recorderName, recd.colorStroke, recd.colorFill, utils.getDateString(recd.time), recd.tags) + func(recd.recorderName, recd.colorStroke, recd.colorFill, + utils.getDateString(recd.time), recd.tags) def _media_view_full_clicked(self, widget): self._toggle_fullscreen() def _media_view_tags_changed(self, widget, tbuffer): - text = tbuffer.get_text(tbuffer.get_start_iter(), tbuffer.get_end_iter()) + text = tbuffer.get_text(tbuffer.get_start_iter(), + tbuffer.get_end_iter()) self._active_recd.setTags(text) def _toggle_fullscreen(self): if not self._fullscreen: - self._toolbox.hide() + self._toolbar_box.hide() self._thumb_tray.hide() else: - self._toolbox.show() + self._toolbar_box.show() self._thumb_tray.show() self._fullscreen = not self._fullscreen self._media_view.set_fullscreen(self._fullscreen) - def _toolbar_changed(self, toolbox, num): - if num == 0: # Activity tab - return - + def __mode_button_clicked(self, button): # Prevent mode/tab changing under certain conditions by immediately # changing back to the previously-selected toolbar + """ if self.model.ui_frozen(): self._toolbox.set_current_toolbar(self._active_toolbar_idx) return self._active_toolbar_idx = num self.model.change_mode(self._toolbar_modes[num]) + """ + if not self.model.ui_frozen(): + self.model.change_mode(button.mode) def _shutter_clicked(self, arg): self.model.do_shutter() @@ -368,13 +439,15 @@ class Record(activity.Activity): self._play_button.hide() self._playback_scale.hide() self._progress.hide() - self._controls_hbox.set_child_packing(self._shutter_button, expand=True, fill=False, padding=0, pack_type=gtk.PACK_START) + self._controls_hbox.set_child_packing(self._shutter_button, + expand=True, fill=False, padding=0, pack_type=gtk.PACK_START) self._shutter_button.set_normal() self._shutter_button.show() self._media_view.show_live() elif state == constants.STATE_RECORDING: self._shutter_button.set_recording() - self._controls_hbox.set_child_packing(self._shutter_button, expand=False, fill=False, padding=0, pack_type=gtk.PACK_START) + self._controls_hbox.set_child_packing(self._shutter_button, + expand=False, fill=False, padding=0, pack_type=gtk.PACK_START) self._progress.show() elif state == constants.STATE_PROCESSING: self._set_cursor_busy() @@ -399,10 +472,13 @@ class Record(activity.Activity): def add_thumbnail(self, recd, scroll_to_end): button = RecdButton(recd) - clicked_handler = button.connect("clicked", self._thumbnail_clicked, 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)) + 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: @@ -417,7 +493,8 @@ class Record(activity.Activity): 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) + gtk.Clipboard().set_with_data([('text/uri-list', 0, 0)], + self._clipboard_get, self._clipboard_clear, tmp_path) def _clipboard_get(self, clipboard, selection_data, info, path): selection_data.set("text/uri-list", 8, "file://" + path) @@ -493,7 +570,7 @@ class Record(activity.Activity): #downloading = self.ca.requestMeshDownload(recd) #self.MESHING = downloading - if True: #not downloading: + if True: # not downloading: #self.progressWindow.updateProgress(0, "") return recd.getMediaFilepath() @@ -536,6 +613,7 @@ class Record(activity.Activity): def _set_cursor_default(self): self.window.set_cursor(None) + class RecordContainer(gtk.Container): """ A custom Container that contains a media view area, and a controls hbox. @@ -573,7 +651,8 @@ class RecordContainer(gtk.Container): height=self.allocation.height, wclass=gdk.INPUT_OUTPUT, colormap=self.get_colormap(), - event_mask=self.get_events() | gdk.VISIBILITY_NOTIFY_MASK | gdk.EXPOSURE_MASK) + 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)) @@ -603,8 +682,9 @@ class RecordContainer(gtk.Container): @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 + 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: @@ -614,7 +694,7 @@ class RecordContainer(gtk.Container): height = (height / 3) * 3 width = int(ratio * height) - return width, height + return width, height @staticmethod def _center_in_plane(plane_size, size): @@ -627,9 +707,12 @@ class RecordContainer(gtk.Container): 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) + 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() @@ -655,11 +738,13 @@ class RecordContainer(gtk.Container): for widget in (self._media_view, self._controls_hbox): callback(widget, data) + class PlaybackScale(gtk.HScale): def __init__(self, model): self.model = model self._change_handler = None - self._playback_adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, 1.0, 1.0) + self._playback_adjustment = gtk.Adjustment(0.0, 0.00, 100.0, 0.1, \ + 1.0, 1.0) super(PlaybackScale, self).__init__(self._playback_adjustment) self.set_draw_value(False) @@ -675,7 +760,8 @@ class PlaybackScale(gtk.HScale): def _button_press(self, widget, event): self.model.start_seek() - self._change_handler = self.connect('value-changed', self._value_changed) + self._change_handler = self.connect('value-changed', + self._value_changed) def _button_release(self, widget, event): self.disconnect(self._change_handler) @@ -816,19 +902,6 @@ class RecordToolbar(gtk.Toolbar): def __init__(self, icon_name, with_quality, with_timer, with_duration): super(RecordToolbar, self).__init__() - img = Icon(icon_name=icon_name) - color = sugar.profile.get_color() - img.set_property('fill-color', color.get_fill_color()) - img.set_property('stroke-color', color.get_stroke_color()) - toolitem = gtk.ToolItem() - toolitem.add(img) - self.insert(toolitem, -1) - - separator = gtk.SeparatorToolItem() - separator.set_draw(False) - separator.set_expand(True) - self.insert(separator, -1) - if with_quality: combo = gtk.combo_box_new_text() self.quality = ToolComboBox(combo=combo, label_text=_('Quality:')) @@ -847,6 +920,7 @@ class RecordToolbar(gtk.Toolbar): if with_duration: self._duration_combo = DurationCombo() self.insert(self._duration_combo, -1) + self.show_all() def get_timer(self): return self._timer_combo.get_value() @@ -872,19 +946,23 @@ class RecordToolbar(gtk.Toolbar): def set_quality(self, idx): self.quality.combo.set_active(idx) + class PhotoToolbar(RecordToolbar): def __init__(self): - super(PhotoToolbar, self).__init__('media-photo', with_quality=False, with_timer=True, with_duration=False) + super(PhotoToolbar, self).__init__('media-photo', with_quality=False, + with_timer=True, with_duration=False) class VideoToolbar(RecordToolbar): def __init__(self): - super(VideoToolbar, self).__init__('media-video', with_quality=True, with_timer=True, with_duration=True) + super(VideoToolbar, self).__init__('media-video', with_quality=True, + with_timer=True, with_duration=True) class AudioToolbar(RecordToolbar): def __init__(self): - super(AudioToolbar, self).__init__('media-audio', with_quality=False, with_timer=True, with_duration=True) + super(AudioToolbar, self).__init__('media-audio', with_quality=False, + with_timer=True, with_duration=True) class TimerCombo(ToolComboBox): @@ -892,8 +970,9 @@ class TimerCombo(ToolComboBox): def __init__(self): self._combo_box_text = gtk.combo_box_new_text() - super(TimerCombo, self).__init__(combo=self._combo_box_text, label_text=_('Timer:')) - + super(TimerCombo, self).__init__(combo=self._combo_box_text, + label_text=_('Timer:')) + for i in self.TIMERS: if i == 0: self._combo_box_text.append_text(_('Immediate')) @@ -903,7 +982,7 @@ class TimerCombo(ToolComboBox): self._combo_box_text.set_active(0) def get_value(self): - return TimerCombo.TIMERS[self._combo_box_text.get_active()] + return TimerCombo.TIMERS[self._combo_box_text.get_active()] def get_value_idx(self): return self._combo_box_text.get_active() @@ -921,7 +1000,8 @@ class DurationCombo(ToolComboBox): def __init__(self): self._combo_box_text = gtk.combo_box_new_text() - super(DurationCombo, self).__init__(combo=self._combo_box_text, label_text=_('Duration:')) + super(DurationCombo, self).__init__(combo=self._combo_box_text, + label_text=_('Duration:')) for i in self.DURATIONS: string = DurationCombo._minutes_string(i) @@ -941,3 +1021,48 @@ class DurationCombo(ToolComboBox): def _minutes_string(x): return ngettext('%s minute', '%s minutes', x) % x + +class EditToolbar(gtk.Toolbar): + + def __init__(self, record_activity): + gtk.Toolbar.__init__(self) + self._activity = record_activity + self.copy = CopyButton() + self.insert(self.copy, -1) + self.copy.show() + self.copy.connect('clicked', self.__copy_clicked) + + def __copy_clicked(self, button): + self._activity._copy_to_clipboard(self._activity._active_recd) + + +class ViewToolbar(gtk.Toolbar): + + def __init__(self, record_activity): + gtk.Toolbar.__init__(self) + self._activity = record_activity + + full_screen_button = ToolButton('view-fullscreen') + full_screen_button.props.label = _('Fullscreen') + self.insert(full_screen_button, -1) + full_screen_button.connect('clicked', self.__fullscreen_clicked) + + tray_button = ToolButton('tray-hide') + tray_button.props.label = _('Hide tray') + tray_button.connect('clicked', self.__tray_clicked_cb) + self.insert(tray_button, -1) + + self.show_all() + + def __fullscreen_clicked(self, button): + self._activity._toggle_fullscreen() + + def __tray_clicked_cb(self, button): + if self._activity._thumb_tray.props.visible is False: + self._activity._thumb_tray.show() + button.set_icon('tray-hide') + button.set_tooltip(_('Hide Tray')) + else: + self._activity._thumb_tray.hide() + button.set_icon('tray-show') + button.set_tooltip(_('Show Tray')) diff --git a/toolbarcombobox.py b/toolbarcombobox.py deleted file mode 100644 index e455414..0000000 --- a/toolbarcombobox.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2007, Red Hat, Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -import gtk -import gobject - -from sugar.graphics.combobox import ComboBox -from sugar.graphics import style - -class ToolComboBox(gtk.ToolItem): - __gproperties__ = { - 'label-text' : (str, None, None, None, - gobject.PARAM_WRITABLE), - } - - def __init__(self, combo=None, **kwargs): - self.label = None - self._label_text = '' - - gobject.GObject.__init__(self, **kwargs) - - self.set_border_width(int(style.DEFAULT_PADDING*3.5)) - - hbox = gtk.HBox(False, style.DEFAULT_SPACING) - - self.label = gtk.Label(self._label_text) - hbox.pack_start(self.label, False) - self.label.show() - - if combo: - self.combo = combo - else: - self.combo = ComboBox() - - hbox.pack_start(self.combo) - self.combo.show() - - self.add(hbox) - hbox.show() - - def do_set_property(self, pspec, value): - if pspec.name == 'label-text': - self._label_text = value - if self.label: - self.label.set_text(self._label_text) |