def init_tool_for_clip(clip, track): clip_index = track.clips.index(clip) # Save data needed to do the keyframe edits. global edit_data #, pressed_on_selected, drag_disabled edit_data = { "draw_function": _tline_overlay, "clip_index": clip_index, "clip_start_in_timeline": track.clip_start(clip_index), "clip": clip, "track": track, "initializing": True } # Init for volume editing if volume filter available for i in range(0, len(clip.filters)): filter_object = clip.filters[i] if filter_object.info.mlt_service_id == "volume": editable_properties = propertyedit.get_filter_editable_properties( clip, filter_object, i, track, clip_index) for ep in editable_properties: # Volume is one of these MLT multipart filters, so we chose this way to find the editable property in filter. try: if ep.args["exptype"] == "multipart_keyframe": edit_data["editable_property"] = ep global _kf_editor _kf_editor = TLineKeyFrameEditor(ep, True) except: pass tlinewidgets.set_edit_mode_data(edit_data) updater.repaint_tline()
def _get_multipart_keyframe_ep_from_service(clip, track, clip_index, mlt_service_id): for i in range(0, len(clip.filters)): filter_object = clip.filters[i] if filter_object.info.mlt_service_id == mlt_service_id: editable_properties = propertyedit.get_filter_editable_properties( clip, filter_object, i, track, clip_index) for ep in editable_properties: try: if ep.args["exptype"] == "multipart_keyframe": return ep except: pass return None
def _get_brightness_editable_property(clip, track, clip_index): for i in range(0, len(clip.filters)): filter_object = clip.filters[i] if filter_object.info.mlt_service_id == "brightness": editable_properties = propertyedit.get_filter_editable_properties( clip, filter_object, i, track, clip_index) for ep in editable_properties: # Volume is one of these MLT multipart filters, so we chose this way to find the editable property in filter. try: if ep.name == "level": return ep except: pass return None
def effect_selection_changed(): global keyframe_editor_widgets # Check we have clip if clip == None: keyframe_editor_widgets = [] return # Check we actually have filters so we can display one. # If not, clear previous filters from view. if len(clip.filters) == 0: vbox = Gtk.VBox(False, 0) vbox.pack_start(Gtk.Label(), False, False, 0) widgets.value_edit_frame.remove(widgets.value_edit_box) widgets.value_edit_frame.add(vbox) vbox.show_all() widgets.value_edit_box = vbox keyframe_editor_widgets = [] return # "changed" get's called twice when adding filter and selecting last # so we use this do this only once if block_changed_update == True: return keyframe_editor_widgets = [] # Get selected row which is also index of filter in clip.filters treeselection = widgets.effect_stack_view.treeview.get_selection() (model, rows) = treeselection.get_selected_rows() # If we don't get legal selection select first filter try: row = rows[0] filter_index = max(row) except: filter_index = 0 filter_object = clip.filters[filter_index] global current_filter_index current_filter_index = filter_index # Create EditableProperty wrappers for properties editable_properties = propertyedit.get_filter_editable_properties( clip, filter_object, filter_index, track, clip_index) # Get editors and set them displayed vbox = Gtk.VBox(False, 0) try: filter_name = translations.filter_names[filter_object.info.name] except KeyError: filter_name = filter_object.info.name filter_name_label = Gtk.Label(label="<b>" + filter_name + "</b>") filter_name_label.set_use_markup(True) vbox.pack_start(filter_name_label, False, False, 0) vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) if len(editable_properties) > 0: # Create editor row for each editable property for ep in editable_properties: editor_row = propertyeditorbuilder.get_editor_row(ep) if editor_row == None: continue # Set keyframe editor widget to be updated for frame changes if such is created try: editor_type = ep.args[propertyeditorbuilder.EDITOR] except KeyError: editor_type = propertyeditorbuilder.SLIDER # this is the default value if ((editor_type == propertyeditorbuilder.KEYFRAME_EDITOR) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_RELEASE) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_CLIP)): keyframe_editor_widgets.append(editor_row) # if slider property is being dedited as keyrame property if hasattr(editor_row, "is_kf_editor"): keyframe_editor_widgets.append(editor_row) vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) # Create NonMltEditableProperty wrappers for properties non_mlteditable_properties = propertyedit.get_non_mlt_editable_properties( clip, filter_object, filter_index) # Extra editors. Editable properties may have already been created # with "editor=no_editor" and now extra editors may be created to edit those # Non mlt properties are added as these are only need with extraeditors editable_properties.extend(non_mlteditable_properties) editor_rows = propertyeditorbuilder.get_filter_extra_editor_rows( filter_object, editable_properties) for editor_row in editor_rows: vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) vbox.pack_start(guiutils.pad_label(12, 12), False, False, 0) hamburger_launcher_surface = cairo.ImageSurface.create_from_png( respaths.IMAGE_PATH + "hamburger_big.png") hamburger_launcher = guicomponents.PressLaunch( _hamburger_launch_pressed, hamburger_launcher_surface, 24, 24) sl_row = guiutils.get_left_justified_box([hamburger_launcher.widget]) vbox.pack_start(sl_row, False, False, 0) vbox.pack_start(Gtk.Label(), True, True, 0) else: vbox.pack_start(Gtk.Label(label=_("No editable parameters")), True, True, 0) vbox.show_all() scroll_window = Gtk.ScrolledWindow() scroll_window.add_with_viewport(vbox) scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scroll_window.show_all() widgets.value_edit_frame.remove(widgets.value_edit_box) widgets.value_edit_frame.add(scroll_window) widgets.value_edit_box = scroll_window
def change_animation(self): # global _animation_instance has been set elsewhere self.animation_label.set_text(_animation_instance.info.name) # We are using existing property edit code to create value editors. # We will need present a lot of dummy data and monkeypatch objects to make that # pipeline do our bidding for natron animations value editing. clip = None filter_index = -1 track = None clip_index = -1 editable_properties = propertyedit.get_filter_editable_properties( clip, _animation_instance, filter_index, track, clip_index, compositor_filter=False) self.editable_properties = editable_properties edit_panel = Gtk.VBox(False, 2) edit_panel.set_size_request(EDIT_PANEL_WIDTH, EDIT_PANEL_HEIGHT) guiutils.set_margins(edit_panel, 4, 4, 4, 4) if len(editable_properties) > 0: # Create editor row for each editable property for ep in editable_properties: # We are not interfacing with mlt objects or clip's filter arrays # and we need make functions accessing those no-ops. # We are only interested in saving value as string and then later interpreting # it somehow to use as input when modifying natron project. self.modify_editable_properties(ep) editor_row = propertyeditorbuilder.get_editor_row(ep) if editor_row == None: continue # Set keyframe editor widget to be updated for frame changes if such is created try: editor_type = ep.args[propertyeditorbuilder.EDITOR] except KeyError: editor_type = propertyeditorbuilder.SLIDER # this is the default value edit_panel.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): edit_panel.pack_start( guicomponents.EditorSeparator().widget, False, False, 0) edit_panel.pack_start(Gtk.Label(), True, True, 0) edit_panel.show_all() scroll_window = Gtk.ScrolledWindow() scroll_window.add_with_viewport(edit_panel) scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scroll_window.show_all() if self.value_edit_box != None: self.value_edit_frame.remove(self.value_edit_box) self.value_edit_frame.add(scroll_window) self.value_edit_box = scroll_window
def effect_selection_changed(use_current_filter_index=False): global keyframe_editor_widgets, current_filter_index # Check we have clip if clip == None: keyframe_editor_widgets = [] show_text_in_edit_area(_("No Clip")) return # Check we actually have filters so we can display one. # If not, clear previous filters from view. if len(clip.filters) == 0: show_text_in_edit_area(_("Clip Has No Filters")) keyframe_editor_widgets = [] return # "changed" get's called twice when adding filter and selecting last # so we use this do this only once if block_changed_update == True: return # We need this update on clip load into editor if _clip_has_filter_mask_filter() == True: widgets.add_filter_mask.set_sensitive(False) else: widgets.add_filter_mask.set_sensitive(True) keyframe_editor_widgets = [] # Get selected row which is also index of filter in clip.filters treeselection = widgets.effect_stack_view.treeview.get_selection() (model, rows) = treeselection.get_selected_rows() # If we don't get legal selection select first filter try: row = rows[0] filter_index = max(row) except: filter_index = 0 # use_current_filter_index == False is used when user changes edited filter or clip. if use_current_filter_index == True: filter_index = current_filter_index filter_object = clip.filters[filter_index] current_filter_index = filter_index # Create EditableProperty wrappers for properties editable_properties = propertyedit.get_filter_editable_properties( clip, filter_object, filter_index, track, clip_index) # Get editors and set them displayed vbox = Gtk.VBox(False, 0) try: filter_name = translations.filter_names[filter_object.info.name] except KeyError: filter_name = filter_object.info.name filter_name_label = Gtk.Label(label="<b>" + filter_name + "</b>") filter_name_label.set_use_markup(True) vbox.pack_start(filter_name_label, False, False, 0) vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) if len(editable_properties) > 0: # Create editor row for each editable property for ep in editable_properties: editor_row = propertyeditorbuilder.get_editor_row(ep) if editor_row == None: continue # Set keyframe editor widget to be updated for frame changes if such is created try: editor_type = ep.args[propertyeditorbuilder.EDITOR] except KeyError: editor_type = propertyeditorbuilder.SLIDER # this is the default value if ((editor_type == propertyeditorbuilder.KEYFRAME_EDITOR) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_RELEASE) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_CLIP) or (editor_type == propertyeditorbuilder.FILTER_RECT_GEOM_EDITOR)): keyframe_editor_widgets.append(editor_row) # if slider property is being dedited as keyrame property if hasattr(editor_row, "is_kf_editor"): keyframe_editor_widgets.append(editor_row) vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) # Create NonMltEditableProperty wrappers for properties non_mlteditable_properties = propertyedit.get_non_mlt_editable_properties( clip, filter_object, filter_index) # Extra editors. Editable properties may have already been created # with "editor=no_editor" and now extra editors may be created to edit those # Non mlt properties are added as these are only need with extraeditors editable_properties.extend(non_mlteditable_properties) editor_rows = propertyeditorbuilder.get_filter_extra_editor_rows( filter_object, editable_properties) for editor_row in editor_rows: vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) vbox.pack_start(guiutils.pad_label(12, 12), False, False, 0) vbox.pack_start(Gtk.Label(), True, True, 0) else: vbox.pack_start(Gtk.Label(label=_("No editable parameters")), True, True, 0) vbox.show_all() scroll_window = Gtk.ScrolledWindow() scroll_window.add_with_viewport(vbox) scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scroll_window.show_all() widgets.value_edit_frame.remove(widgets.value_edit_box) widgets.value_edit_frame.add(scroll_window) widgets.value_edit_box = scroll_window
def effect_selection_changed(use_current_filter_index=False): global keyframe_editor_widgets # Check we have clip if clip == None: keyframe_editor_widgets = [] show_text_in_edit_area(_("No Clip")) return # Check we actually have filters so we can display one. # If not, clear previous filters from view. if len(clip.filters) == 0: show_text_in_edit_area(_("Clip Has No Filters")) keyframe_editor_widgets = [] return # "changed" get's called twice when adding filter and selecting last # so we use this do this only once if block_changed_update == True: return keyframe_editor_widgets = [] # Get selected row which is also index of filter in clip.filters treeselection = widgets.effect_stack_view.treeview.get_selection() (model, rows) = treeselection.get_selected_rows() # If we don't get legal selection select first filter try: row = rows[0] filter_index = max(row) except: filter_index = 0 # use_current_filter_index == False is used when user changes edited filter or clip. if use_current_filter_index == True: filter_index = current_filter_index filter_object = clip.filters[filter_index] global current_filter_index current_filter_index = filter_index # Create EditableProperty wrappers for properties editable_properties = propertyedit.get_filter_editable_properties( clip, filter_object, filter_index, track, clip_index) # Get editors and set them displayed vbox = Gtk.VBox(False, 0) try: filter_name = translations.filter_names[filter_object.info.name] except KeyError: filter_name = filter_object.info.name filter_name_label = Gtk.Label(label= "<b>" + filter_name + "</b>") filter_name_label.set_use_markup(True) vbox.pack_start(filter_name_label, False, False, 0) vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) if len(editable_properties) > 0: # Create editor row for each editable property for ep in editable_properties: editor_row = propertyeditorbuilder.get_editor_row(ep) if editor_row == None: continue # Set keyframe editor widget to be updated for frame changes if such is created try: editor_type = ep.args[propertyeditorbuilder.EDITOR] except KeyError: editor_type = propertyeditorbuilder.SLIDER # this is the default value if ((editor_type == propertyeditorbuilder.KEYFRAME_EDITOR) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_RELEASE) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_CLIP)): keyframe_editor_widgets.append(editor_row) # if slider property is being dedited as keyrame property if hasattr(editor_row, "is_kf_editor"): keyframe_editor_widgets.append(editor_row) vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) # Create NonMltEditableProperty wrappers for properties non_mlteditable_properties = propertyedit.get_non_mlt_editable_properties( clip, filter_object, filter_index) # Extra editors. Editable properties may have already been created # with "editor=no_editor" and now extra editors may be created to edit those # Non mlt properties are added as these are only need with extraeditors editable_properties.extend(non_mlteditable_properties) editor_rows = propertyeditorbuilder.get_filter_extra_editor_rows(filter_object, editable_properties) for editor_row in editor_rows: vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) vbox.pack_start(guiutils.pad_label(12,12), False, False, 0) vbox.pack_start(Gtk.Label(), True, True, 0) else: vbox.pack_start(Gtk.Label(label=_("No editable parameters")), True, True, 0) vbox.show_all() scroll_window = Gtk.ScrolledWindow() scroll_window.add_with_viewport(vbox) scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scroll_window.show_all() widgets.value_edit_frame.remove(widgets.value_edit_box) widgets.value_edit_frame.add(scroll_window) widgets.value_edit_box = scroll_window
def _get_filter_panel(clip, filter_object, filter_index, track, clip_index): # Create EditableProperty wrappers for properties editable_properties = propertyedit.get_filter_editable_properties( clip, filter_object, filter_index, track, clip_index) # Get editors and set them displayed vbox = Gtk.VBox(False, 0) try: filter_name = translations.filter_names[filter_object.info.name] except KeyError: filter_name = filter_object.info.name filter_keyframe_editor_widgets = [] vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) if len(editable_properties) > 0: # Create editor row for each editable property for ep in editable_properties: editor_row = propertyeditorbuilder.get_editor_row(ep) if editor_row == None: continue # Set keyframe editor widget to be updated for frame changes if such is created try: editor_type = ep.args[propertyeditorbuilder.EDITOR] except KeyError: editor_type = propertyeditorbuilder.SLIDER # this is the default value if ((editor_type == propertyeditorbuilder.KEYFRAME_EDITOR) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_RELEASE) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_CLIP) or (editor_type == propertyeditorbuilder.FILTER_RECT_GEOM_EDITOR) or (editor_type == propertyeditorbuilder.KEYFRAME_EDITOR_CLIP_FADE_FILTER)): keyframe_editor_widgets.append(editor_row) filter_keyframe_editor_widgets.append(editor_row) # if slider property is being edited as keyrame property if hasattr(editor_row, "is_kf_editor"): keyframe_editor_widgets.append(editor_row) filter_keyframe_editor_widgets.append(editor_row) vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) # Create NonMltEditableProperty wrappers for properties non_mlteditable_properties = propertyedit.get_non_mlt_editable_properties( clip, filter_object, filter_index) # Extra editors. Editable properties may have already been created # with "editor=no_editor" and now extra editors may be created to edit those # Non mlt properties are added as these are only needed with extraeditors editable_properties.extend(non_mlteditable_properties) editor_rows = propertyeditorbuilder.get_filter_extra_editor_rows( filter_object, editable_properties) for editor_row in editor_rows: vbox.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): vbox.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) else: vbox.pack_start(Gtk.Label(label=_("No editable parameters")), True, True, 0) vbox.show_all() return (vbox, filter_keyframe_editor_widgets)
def change_animation(self): # ---------------- PROPERTY EDITING # We are using existing property edit code to create value editors. # We will need present a lot of dummy data and monkeypatch objects to make that # pipeline do our bidding for natron animations value editing. clip = None filter_index = -1 track = None clip_index = -1 editable_properties = propertyedit.get_filter_editable_properties(clip, _animation_instance, filter_index, track, clip_index, compositor_filter=False) self.editable_properties = editable_properties edit_panel = Gtk.VBox(False, 2) edit_panel.set_size_request(EDIT_PANEL_WIDTH, EDIT_PANEL_HEIGHT) guiutils.set_margins(edit_panel, 4, 4, 4, 4) if len(editable_properties) > 0: # Create editor row for each editable property for ep in editable_properties: # We are not interfacing with mlt objects or clip's filter arrays # and we need make functions accessing those no-ops. # We are only interested in saving value as string and then later interpreting # it somehow to use as input when modifying natron project. self.modify_editable_properties(ep) editor_row = propertyeditorbuilder.get_editor_row(ep) if editor_row == None: continue # Set keyframe editor widget to be updated for frame changes if such is created try: editor_type = ep.args[propertyeditorbuilder.EDITOR] except KeyError: editor_type = propertyeditorbuilder.SLIDER # this is the default value edit_panel.pack_start(editor_row, False, False, 0) if not hasattr(editor_row, "no_separator"): edit_panel.pack_start(guicomponents.EditorSeparator().widget, False, False, 0) edit_panel.pack_start(Gtk.Label(), True, True, 0) edit_panel.show_all() scroll_window = Gtk.ScrolledWindow() scroll_window.add_with_viewport(edit_panel) scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scroll_window.show_all() if self.value_edit_box != None: self.value_edit_frame.remove(self.value_edit_box) self.value_edit_frame.add(scroll_window) self.value_edit_box = scroll_window # ---------------- GUI UPDATES global _current_preview_surface _current_preview_surface = None self.animation_label.set_text(_animation_instance.info.name) self.render_status_info.set_markup("<small>" + self.status_no_render + "</small>") self.pos_bar.update_display_from_producer(_animation_instance) # duck typing as mlt.Producer for pos bar, need data methods are in NatronAnimationInstance self.range_in.set_value(_animation_instance.range_in) self.range_out.set_value(_animation_instance.range_out) _animation_instance.current_frame = _animation_instance.range_in self.set_position(_animation_instance.range_in) self.preview_monitor.queue_draw()