def __set_prop(self, prop, value): assert self.source if self.__source_uses_keyframes(): try: position = self._project.pipeline.getPosition() start = self.source.props.start in_point = self.source.props.in_point duration = self.source.props.duration if position < start or position > start + duration: return source_position = position - start + in_point with self.app.action_log.started( "Transformation property change", finalizing_action=CommitTimelineFinalizingAction( self._project.pipeline), toplevel=True): self.__control_bindings[prop].props.control_source.set( source_position, value) except PipelineError: self.warning("Could not get pipeline position") return else: with self.app.action_log.started( "Transformation property change", finalizing_action=CommitTimelineFinalizingAction( self._project.pipeline), toplevel=True): self.source.set_child_property(prop, value)
def __init__(self, focus, timeline, mode, edge, app, log_actions): GObject.Object.__init__(self) Loggable.__init__(self) if isinstance(focus, GES.TrackElement): self.focus = focus.get_parent() else: self.focus = focus self.with_video = GES.TrackType.VIDEO & self.focus.get_track_types() self.old_position = self.focus.get_start() if edge == GES.Edge.EDGE_END and mode == GES.EditMode.EDIT_TRIM: self.old_position += self.focus.get_duration() self.old_priority = self.focus.get_priority() self.new_position = None self.new_priority = None self.timeline = timeline self.app = app self.edge = edge self.mode = mode from pitivi.undo.timeline import CommitTimelineFinalizingAction self.__log_actions = log_actions if log_actions: self.app.action_log.begin( "move-clip", finalizing_action=CommitTimelineFinalizingAction( self.timeline.get_asset().pipeline), toplevel=True)
def create_title_clip_cb(self, unused_button): title_clip = GES.TitleClip() duration = self.app.settings.titleClipLength * Gst.MSECOND title_clip.set_duration(duration) with self.app.action_log.started( "add title clip", finalizing_action=CommitTimelineFinalizingAction( self._project.pipeline), toplevel=True): self.app.gui.editor.timeline_ui.insert_clips_on_first_layer( [title_clip]) # Now that the clip is inserted in the timeline, it has a source which # can be used to set its properties. source = title_clip.get_children(False)[0] properties = { "text": DEFAULT_TEXT, "foreground-color": BACKGROUND_DEFAULT_COLOR, "color": FOREGROUND_DEFAULT_COLOR, "font-desc": DEFAULT_FONT_DESCRIPTION, "valignment": DEFAULT_VALIGNMENT, "halignment": DEFAULT_HALIGNMENT } for prop, value in properties.items(): res = source.set_child_property(prop, value) assert res, prop self._selection.set_selection([title_clip], SELECT)
def _dragDataReceivedCb(self, treeview, drag_context, x, y, selection_data, unused_info, timestamp): if not self.clip: # Indicate that a drop will not be accepted. Gdk.drag_status(drag_context, 0, timestamp) return dest_row = treeview.get_dest_row_at_pos(x, y) if drag_context.get_suggested_action() == Gdk.DragAction.COPY: # An effect dragged probably from the effects list. factory_name = str(selection_data.get_data(), "UTF-8") drop_index = self.__get_new_effect_index(dest_row) effect_info = self.app.effects.getInfo(factory_name) pipeline = self._project.pipeline with self.app.action_log.started( "add effect", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): effect = self.clip.ui.add_effect(effect_info) if effect: self.clip.set_top_effect_priority(effect, drop_index) elif drag_context.get_suggested_action() == Gdk.DragAction.MOVE: # An effect dragged from the same treeview to change its position. # Source source_index, drop_index = self.__get_move_indexes( dest_row, treeview.get_model()) self.__move_effect(self.clip, source_index, drop_index) drag_context.finish(True, False, timestamp)
def _remove_effect(self, effect): pipeline = self.app.project_manager.current_project.pipeline with self.app.action_log.started( "remove effect", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): effect.get_parent().remove(effect)
def __dragDropCb(self, unused_widget, context, x, y, timestamp): success = False target = self.drag_dest_find_target(context, None) if not target: return False if target.name() == EFFECT_TARGET_ENTRY.target: self.info("Adding effect %s", self.timeline.dropData) self.timeline.resetSelectionGroup() self.timeline.current_group.add(self.ges_clip) self.timeline.selection.setSelection([self.ges_clip], SELECT) self.app.gui.switchContextTab(self.ges_clip) effect_info = self.app.effects.getInfo(self.timeline.dropData) pipeline = self.timeline.ges_timeline.get_parent() with self.app.action_log.started( "add effect", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): self.add_effect(effect_info) self.timeline.cleanDropData() success = True Gtk.drag_finish(context, success, False, timestamp) return success
def addEffectToClip(self, clip, factory_name, priority=None): """Adds the specified effect if it can be applied to the clip.""" if factory_name in ALLOWED_ONLY_ONCE_EFFECTS: for effect in clip.find_track_elements(None, GES.TrackType.VIDEO, GES.BaseEffect): for elem in effect.get_nleobject().iterate_recurse(): if elem.get_factory().get_name() == factory_name: self.error( "Not adding %s as it would be duplicate" " and this is not allowed.", factory_name) # TODO Let the user know about why it did not work. return effect model = self.treeview.get_model() media_type = self.app.effects.getInfo(factory_name).media_type for track_element in clip.get_children(False): track_type = track_element.get_track_type() if track_type == GES.TrackType.AUDIO and media_type == AUDIO_EFFECT or \ track_type == GES.TrackType.VIDEO and media_type == VIDEO_EFFECT: # Actually add the effect pipeline = self._project.pipeline with self.app.action_log.started( "add effect", CommitTimelineFinalizingAction(pipeline)): effect = GES.Effect.new(bin_description=factory_name) clip.add(effect) if priority is not None and priority < len(model): clip.set_top_effect_priority(effect, priority) break return None
def _removeEffect(self, effect): pipeline = self._project.pipeline with self.app.action_log.started( "remove effect", CommitTimelineFinalizingAction(pipeline)): self.__remove_configuration_widget() self.effects_properties_manager.cleanCache(effect) effect.get_parent().remove(effect) self._updateTreeview()
def _effect_active_toggle_cb(self, toggle, row): effect = row.effect pipeline = self.app.project_manager.current_project.pipeline with self.app.action_log.started( "change active state", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): effect.props.active = toggle.props.active
def _set_child_property(self, name, value): with self.app.action_log.started( "Color change property", finalizing_action=CommitTimelineFinalizingAction( self.app.project_manager.current_project.pipeline), toplevel=True): res = self.source.set_child_property(name, value) assert res
def __delete_layer_cb(self, unused_action, unused_parameter): pipeline = self.ges_timeline.get_asset().pipeline with self.app.action_log.started("delete layer", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): self.ges_timeline.remove_layer(self.ges_layer) removed_priority = self.ges_layer.props.priority for ges_layer in self.ges_timeline.get_layers(): if ges_layer.props.priority > removed_priority: ges_layer.props.priority -= 1
def _defaultValuesCb(self, unused_widget): with self.app.action_log.started("Transformation properties reset default", finalizing_action=CommitTimelineFinalizingAction(self._project.pipeline), toplevel=True): if self.__source_uses_keyframes(): self.__remove_control_bindings() for prop in ["posx", "posy", "width", "height"]: self.source.set_child_property(prop, self.source.ui.default_position[prop]) self.__update_keyframes_ui()
def __alignment_editor_align_cb(self, widget): """Callback method to align a clip from the AlignmentEditor widget.""" x, y = self.alignment_editor.get_clip_position(self._project, self.source) with self.app.action_log.started( "Position change", finalizing_action=CommitTimelineFinalizingAction( self._project.pipeline), toplevel=True): self.__set_prop("posx", x) self.__set_prop("posy", y)
def _effectActiveToggleCb(self, cellrenderertoggle, path): _iter = self.storemodel.get_iter(path) effect = self.storemodel.get_value(_iter, COL_TRACK_EFFECT) pipeline = self._project.ges_timeline.get_parent() with self.app.action_log.started("change active state", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): effect.props.active = not effect.props.active # This is not strictly necessary, but makes sure # the UI reflects the current status. cellrenderertoggle.set_active(effect.is_active())
def color_picker_value_changed_cb(unused_color_picker_button): """Handles the selection of a color with the color picker button.""" from pitivi.undo.timeline import CommitTimelineFinalizingAction pipeline = effect_prop_manager.app.project_manager.current_project.pipeline action_log = effect_prop_manager.app.action_log with action_log.started("Color Picker Change", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): element.set_child_property("target-r", color_picker.color_r) element.set_child_property("target-g", color_picker.color_g) element.set_child_property("target-b", color_picker.color_b)
def op_picker_value_changed_cb(unused): """Handles the selection of op via combobox.""" v = op_list[op_picker.get_active()][1] from pitivi.undo.timeline import CommitTimelineFinalizingAction pipeline = effect_prop_manager.app.project_manager.current_project.pipeline action_log = effect_prop_manager.app.action_log with action_log.started( "Effect property change", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): element.set_child_property("operation", v)
def _onValueChangedCb(self, unused_widget, effect_widget, prop, effect): value = effect_widget.getWidgetValue() # FIXME Workaround in order to make aspectratiocrop working if isinstance(value, Gst.Fraction): value = Gst.Fraction(int(value.num), int(value.denom)) from pitivi.undo.timeline import CommitTimelineFinalizingAction pipeline = self.app.project_manager.current_project.pipeline with self.app.action_log.started("Effect property change", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): effect.set_child_property(prop.name, value)
def color_wheel_changed_cb(color_wheel, prop_r, prop_g, prop_b): """Handles the selection of a color with a color wheel.""" hsv_color = color_wheel.get_color() rgb_color = color_wheel.to_rgb(hsv_color.h, hsv_color.s, hsv_color.v) from pitivi.undo.timeline import CommitTimelineFinalizingAction pipeline = effect_prop_manager.app.project_manager.current_project.pipeline action_log = effect_prop_manager.app.action_log with action_log.started( "Effect property change", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=False): element.set_child_property(prop_r, rgb_color.r) element.set_child_property(prop_g, rgb_color.g) element.set_child_property(prop_b, rgb_color.b)
def create_color_clip_cb(self, unused_widget): color_clip = GES.TestClip.new() duration = self.app.settings.ColorClipLength * Gst.MSECOND color_clip.set_duration(duration) color_clip.set_vpattern(GES.VideoTestPattern.SOLID_COLOR) color_clip.set_supported_formats(GES.TrackType.VIDEO) with self.app.action_log.started( "add color clip", finalizing_action=CommitTimelineFinalizingAction( self._project.pipeline), toplevel=True): self.app.gui.editor.timeline_ui.insert_clips_on_first_layer( [color_clip]) self._selection.set_selection([color_clip], SELECT)
def _onValueChangedCb(self, spinbtn, prop): if not self.source: return value = spinbtn.get_value() res, cvalue = self.source.get_child_property(prop) assert res if value != cvalue: with self.app.action_log.started( "Transformation property change", CommitTimelineFinalizingAction(self._project.pipeline)): self.source.set_child_property(prop, value) self.app.gui.viewer.overlay_stack.update(self.source)
def __move_effect(self, clip, source_index, drop_index): if source_index == drop_index: # Noop. return # The paths are different. effects = clip.get_top_effects() effect = effects[source_index] pipeline = self._project.ges_timeline.get_parent() with self.app.action_log.started( "move effect", CommitTimelineFinalizingAction(pipeline)): clip.set_top_effect_priority(effect, drop_index) new_path = Gtk.TreePath.new() new_path.append_index(drop_index) self.__updateAll(path=new_path)
def color_button_color_set_cb(color_button): """Handles the selection of a color with the color button.""" color = color_button.get_rgba() red = int(color.red * 255) green = int(color.green * 255) blue = int(color.blue * 255) from pitivi.undo.timeline import CommitTimelineFinalizingAction pipeline = effect_prop_manager.app.project_manager.current_project.pipeline action_log = effect_prop_manager.app.action_log with action_log.started("Effect property change", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): element.set_child_property("target-r", red) element.set_child_property("target-g", green) element.set_child_property("target-b", blue)
def _addSelectedEffect(self): """Adds the selected effect to the single selected clip, if any.""" effect = self.getSelectedEffect() effect_info = self.app.effects.getInfo(effect) if not effect_info: return timeline = self.app.gui.timeline_ui.timeline clip = timeline.selection.getSingleClip() if not clip: return pipeline = timeline.ges_timeline.get_parent() from pitivi.undo.timeline import CommitTimelineFinalizingAction with self.app.action_log.started("add effect", CommitTimelineFinalizingAction(pipeline)): clip.ui.add_effect(effect_info)
def color_picker_value_changed_cb(color_picker_button, prop_r, prop_g, prop_b): """Handles the selection of a color with the color picker button.""" from pitivi.undo.timeline import CommitTimelineFinalizingAction pipeline = effect_prop_manager.app.project_manager.current_project.pipeline action_log = effect_prop_manager.app.action_log with action_log.started( "Effect property change", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): element.set_child_property(prop_r, color_picker_button.color_r / 255) element.set_child_property(prop_g, color_picker_button.color_g / 255) element.set_child_property(prop_b, color_picker_button.color_b / 255)
def apply_effect(self, effect_name): """Adds the selected effect to the single selected clip, if any.""" effect_info = self.app.effects.get_info(effect_name) if not effect_info: return timeline = self.app.gui.editor.timeline_ui.timeline clip = timeline.selection.get_single_clip() if not clip: return pipeline = timeline.ges_timeline.get_parent() from pitivi.undo.timeline import CommitTimelineFinalizingAction with self.app.action_log.started("add effect", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): clip.ui.add_effect(effect_info)
def _on_value_changed_cb(self, spinbtn, prop): if not self.source: return value = spinbtn.get_value() res, cvalue = self.__get_source_property(prop) if not res: return if value != cvalue: with self.app.action_log.started( "Transformation property change", finalizing_action=CommitTimelineFinalizingAction( self._project.pipeline), toplevel=True): self.__set_prop(prop, value) self.app.gui.editor.viewer.overlay_stack.update(self.source)
def on_button_press(self): disconnectAllByFunc(self._source, self.__source_property_changed_cb) self.click_source_position = self.__get_source_position() self.__clicked_handle = None self.__action_log.begin( "Video position change", CommitTimelineFinalizingAction( self._source.get_timeline().get_parent())) if self.hovered_handle: self.hovered_handle.on_click() self.__clicked_handle = self.hovered_handle elif self.__box_hovered: self._select() self.stack.set_cursor("grabbing") self.stack.selected_overlay = self elif self._is_selected(): self._deselect() self.hovered_handle = None
def _move_effect(self, clip, source_index, drop_index): # Handle edge cases if drop_index < 0: drop_index = 0 if drop_index > len(clip.get_top_effects()) - 1: drop_index = len(clip.get_top_effects()) - 1 if source_index == drop_index: # Noop. return effects = clip.get_top_effects() effect = effects[source_index] pipeline = self.app.project_manager.current_project.pipeline with self.app.action_log.started( "move effect", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): clip.set_top_effect_index(effect, drop_index)
def _drag_data_received_cb(self, widget, drag_context, x, y, selection_data, unused_info, timestamp): if not self.clip: # Indicate that a drop will not be accepted. Gdk.drag_status(drag_context, 0, timestamp) return if self.effects_listbox.get_row_at_y(y): # Drop happened inside the lisbox drop_index = widget.get_index() else: drop_index = len(self.effects_listbox.get_children()) - 1 if drag_context.get_suggested_action() == Gdk.DragAction.COPY: # An effect dragged probably from the effects list. factory_name = str(selection_data.get_data(), "UTF-8") top_effect_index = drop_index + len(self.__get_time_effects()) self.debug( "Effect dragged at position %s - computed top effect index %s", drop_index, top_effect_index) effect_info = self.app.effects.get_info(factory_name) pipeline = self.app.project_manager.current_project.pipeline with self.app.action_log.started( "add effect", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): effect = self.clip.ui.add_effect(effect_info) if effect: self.clip.set_top_effect_index(effect, top_effect_index) elif drag_context.get_suggested_action() == Gdk.DragAction.MOVE: # An effect dragged from the same listbox to change its position. source_eventbox = Gtk.drag_get_source_widget(drag_context) source_row = source_eventbox.get_parent() source_index = source_row.get_index() self._move_effect(self.clip, source_index, drop_index) drag_context.finish(True, False, timestamp)
def _on_widget_value_changed_cb(self, unused_widget, prop_widget, prop, effect, effect_widget): if effect_widget.updating_property: # The widget is updated as a side-effect of setting one of its # properties. Ignore. return effect_widget.updating_property = True try: value = prop_widget.get_widget_value() # FIXME Workaround in order to make aspectratiocrop working if isinstance(value, Gst.Fraction): value = Gst.Fraction(int(value.num), int(value.denom)) from pitivi.undo.timeline import CommitTimelineFinalizingAction pipeline = self.app.project_manager.current_project.pipeline with self.app.action_log.started("Effect property change", finalizing_action=CommitTimelineFinalizingAction(pipeline), toplevel=True): effect.set_child_property(prop.name, value) finally: effect_widget.updating_property = False