def do_timeline_filters_paste(): if _timeline_has_focus() == False: return track = current_sequence().get_first_active_track() if track == None: return paste_objs = editorstate.get_copy_paste_objects() if paste_objs == None: return if movemodes.selected_track == -1: return target_clips = [] track = current_sequence().tracks[movemodes.selected_track] for i in range(movemodes.selected_range_in, movemodes.selected_range_out + 1): target_clips.append(track.clips[i]) # First clip of selection is used as filters source source_clip = paste_objs[0] # Currently selected clips are target clips target_clips = [] track = current_sequence().tracks[movemodes.selected_track] for i in range(movemodes.selected_range_in, movemodes.selected_range_out + 1): target_clips.append(track.clips[i]) for target_clip in target_clips: data = {"clip":target_clip,"clone_source_clip":source_clip} action = edit.paste_filters_action(data) action.do_edit()
def sync_all_compositors(): # Pair all compositors with their origin clips and clip data comp_clip_pairings = {} for compositor in current_sequence().compositors: comp_clip_pairings[compositor.origin_clip_id] = compositor for i in range(current_sequence().first_video_index, len(current_sequence().tracks) - 1): # -1, there is a topmost hidden track track = current_sequence().tracks[i] # b_track is source track where origin clip is for j in range(0, len(track.clips)): clip = track.clips[j] if clip.id in comp_clip_pairings: compositor = comp_clip_pairings[clip.id] comp_clip_pairings[clip.id] = (clip, track, j, compositor) # Do sync for origin_clip_id in comp_clip_pairings: try: clip, track, clip_index, compositor = comp_clip_pairings[origin_clip_id] clip_start = track.clip_start(clip_index) clip_end = clip_start + clip.clip_out - clip.clip_in data = {"compositor":compositor,"clip_in":clip_start,"clip_out":clip_end} action = edit.move_compositor_action(data) action.do_edit() except: # Clip is probably already deleted pass
def rotating_geom_keyframes_value_string_to_geom_kf_array(keyframes_str, out_to_in_func): # Parse extraeditor value properties value string into (frame, [x, y, x_scale, y_scale, rotation], opacity) # keyframe tuples. new_keyframes = [] screen_width = current_sequence().profile.width() screen_height = current_sequence().profile.height() keyframes_str = keyframes_str.strip('"') # expression have sometimes quotes that need to go away kf_tokens = keyframes_str.split(';') for token in kf_tokens: sides = token.split('=') values = sides[1].split(':') frame = int(sides[0]) # get values and convert "frei0r.cairoaffineblend" values to editor values # this because all frei0r plugins require values in range 0 - 1 x = _get_pixel_pos_from_frei0r_cairo_pos(float(values[0]), screen_width) y = _get_pixel_pos_from_frei0r_cairo_pos(float(values[1]), screen_height) x_scale = _get_scale_from_frei0r_cairo_scale(float(values[2])) y_scale = _get_scale_from_frei0r_cairo_scale(float(values[3])) rotation = float(values[4]) * 360 opacity = float(values[5]) * 100 source_rect = [x,y,x_scale,y_scale,rotation] add_kf = (frame, source_rect, float(opacity)) new_keyframes.append(add_kf) return new_keyframes
def display_sequence_in_monitor(): """ Sets mltplayer producer to be current sequence tractor and updates GUI. """ if PLAYER() == None: # this method gets called too early when initializing, hack fix. return editorstate._timeline_displayed = True # Clear hidden track that has been displaying monitor clip current_sequence().clear_hidden_track() # Reset timeline pos global saved_timeline_pos if saved_timeline_pos != -1: PLAYER().seek_frame(saved_timeline_pos) saved_timeline_pos = -1 update_seqence_info_text() # Display marks and pos gui.pos_bar.update_display_from_producer(PLAYER().producer) display_marks_tc() gui.monitor_switch.widget.queue_draw() repaint_tline()
def display_sequence_in_monitor(): """ Sets mltplayer producer to be current sequence tractor and updates GUI. """ if PLAYER() == None: # this method gets called too early when initializing, hack fix. return # If this gets called without user having pressed 'Timeline' button we'll # programmatically press it to recall this method to have the correct button down. #if gui.sequence_editor_b.get_active() == False: # gui.sequence_editor_b.set_active(True) # return editorstate._timeline_displayed = True # Clear hidden track that has been displaying monitor clip current_sequence().clear_hidden_track() # Reset timeline pos global saved_timeline_pos if saved_timeline_pos != -1: PLAYER().seek_frame(saved_timeline_pos) saved_timeline_pos = -1 update_seqence_info_text() # Display marks and pos gui.pos_bar.update_display_from_producer(PLAYER().producer) display_marks_tc() gui.monitor_switch.widget.queue_draw() repaint_tline()
def _get_new_clip_from_clip_monitor(): """ Creates and returns new clip from current clip monitor clip with user set in and out points. """ if MONITOR_MEDIA_FILE() == None: # Info window here return if MONITOR_MEDIA_FILE().type != appconsts.PATTERN_PRODUCER: new_clip = current_sequence().create_file_producer_clip(MONITOR_MEDIA_FILE().path) else: new_clip = current_sequence().create_pattern_producer(MONITOR_MEDIA_FILE()) # Set clip in and out points new_clip.mark_in = MONITOR_MEDIA_FILE().mark_in new_clip.mark_out = MONITOR_MEDIA_FILE().mark_out new_clip.name = MONITOR_MEDIA_FILE().name if new_clip.mark_in == -1: new_clip.mark_in = 0 if new_clip.mark_out == -1: new_clip.mark_out = new_clip.get_length() - 1 #-1 == out inclusive return new_clip
def tline_canvas_double_click(frame, x, y): if PLAYER().looping(): return elif PLAYER().is_playing(): PLAYER().stop_playback() if not timeline_visible(): updater.display_sequence_in_monitor() set_default_edit_mode() return hit_compositor = tlinewidgets.compositor_hit(frame, y, current_sequence().compositors) if hit_compositor != None: compositeeditor.set_compositor(hit_compositor) return track = tlinewidgets.get_track(y) if track == None: return clip_index = current_sequence().get_clip_index(track, frame) if clip_index == -1: return clip = track.clips[clip_index] data = (clip, track, None, x) updater.open_clip_in_effects_editor(data)
def _add_autofade(data): clip, track, item_id, item_data = data x, compositor_type = item_data frame = tlinewidgets.get_frame(x) clip_index = track.get_clip_index_at(frame) target_track_index = track.id - 1 clip_length = clip.clip_out - clip.clip_in if compositor_type == "##auto_fade_in": compositor_in = current_sequence().tracks[track.id].clip_start(clip_index) compositor_out = compositor_in + int(utils.fps()) - 1 else: clip_start = current_sequence().tracks[track.id].clip_start(clip_index) compositor_out = clip_start + clip_length compositor_in = compositor_out - int(utils.fps()) + 1 edit_data = {"origin_clip_id":clip.id, "in_frame":compositor_in, "out_frame":compositor_out, "a_track":target_track_index, "b_track":track.id, "compositor_type":compositor_type, "clip":clip} action = edit.add_compositor_action(edit_data) action.do_edit() updater.repaint_tline()
def _move_mode_move(frame, x, y): """ Updates edit data needed for doing edit and drawing overlay based on mouse movement. """ global edit_data # Get frame that is the one where insert is attempted press_frame = edit_data["press_frame"] first_clip_start = edit_data["first_clip_start"] attempt_insert_frame = first_clip_start + (frame - press_frame) edit_data["attempt_insert_frame"] = attempt_insert_frame # Get track where insert is attempted. Track selection forced into range of editable tracks. to_track = tlinewidgets.get_track(y) if to_track == None: if y > tlinewidgets.REF_LINE_Y: to_track = get_track(1) else: to_track = get_track(len(current_sequence().tracks) - 2) if to_track.id < 1: to_track = get_track(1) if to_track.id > len(current_sequence().tracks) - 2: to_track = get_track(len(current_sequence().tracks) - 2) edit_data["to_track_object"] = to_track # Get index for insert in target track insert_index = to_track.get_clip_index_at(attempt_insert_frame) edit_data["insert_index"] = insert_index edit_data["insert_frame"] = to_track.clip_start(insert_index) _set_current_move_frame_and_check_move_start(frame, x, y)
def track_center_pressed(data): if data.event.button == 1: # handle possible mute icon presses press_x = data.event.x press_y = data.event.y track = tlinewidgets.get_track(press_y) if track == None: return y_off = press_y - tlinewidgets._get_track_y(track.id) ICON_WIDTH = 12 if press_x > tlinewidgets.COLUMN_LEFT_PAD and press_x < tlinewidgets.COLUMN_LEFT_PAD + ICON_WIDTH: # Mute icon x area hit ix, iy = tlinewidgets.MUTE_ICON_POS if track.height > appconsts.TRACK_HEIGHT_SMALL: ix, iy = tlinewidgets.MUTE_ICON_POS_NORMAL ICON_HEIGHT = 10 if track.id >= current_sequence().first_video_index: # Video tracks # Test mute switches if y_off > iy and y_off < iy + ICON_HEIGHT: # Video mute icon hit if track.mute_state == appconsts.TRACK_MUTE_NOTHING: new_mute_state = appconsts.TRACK_MUTE_VIDEO elif track.mute_state == appconsts.TRACK_MUTE_VIDEO: new_mute_state = appconsts.TRACK_MUTE_NOTHING elif track.mute_state == appconsts.TRACK_MUTE_AUDIO: new_mute_state = appconsts.TRACK_MUTE_ALL elif track.mute_state == appconsts.TRACK_MUTE_ALL: new_mute_state = appconsts.TRACK_MUTE_AUDIO elif y_off > iy + ICON_HEIGHT and y_off < iy + ICON_HEIGHT * 2: # Audio mute icon hit if track.mute_state == appconsts.TRACK_MUTE_NOTHING: new_mute_state = appconsts.TRACK_MUTE_AUDIO elif track.mute_state == appconsts.TRACK_MUTE_VIDEO: new_mute_state = appconsts.TRACK_MUTE_ALL elif track.mute_state == appconsts.TRACK_MUTE_AUDIO: new_mute_state = appconsts.TRACK_MUTE_NOTHING elif track.mute_state == appconsts.TRACK_MUTE_ALL: new_mute_state = appconsts.TRACK_MUTE_VIDEO else: return else: # Audio tracks # Test mute switches iy = iy + 6 # Mute icon is lower on audio tracks if y_off > iy and y_off < iy + ICON_HEIGHT: if track.mute_state == appconsts.TRACK_MUTE_VIDEO: new_mute_state = appconsts.TRACK_MUTE_ALL else: new_mute_state = appconsts.TRACK_MUTE_VIDEO else: return # Update track mute state current_sequence().set_track_mute_state(track.id, new_mute_state) gui.tline_column.widget.queue_draw() if data.event.button == 3: guicomponents.display_tracks_popup_menu(data.event, data.track, \ _track_menu_item_activated)
def _get_track_above(track): if track == None: return None # Clip is being dragged outside of tracks area if track.id < len(current_sequence().tracks) - 2: return current_sequence().tracks[track.id + 1] else: return None
def _audio_levels_item_activated(widget, msg): if msg == "all": editorstate.display_all_audio_levels = True updater.repaint_tline() else: editorstate.display_all_audio_levels = False current_sequence().drop_audio_levels() updater.repaint_tline()
def init_geom_gui(self, editable_property): self.geom_kf_edit = keyframeeditcanvas.BoxEditCanvas(editable_property, self) self.geom_kf_edit.init_editor(current_sequence().profile.width(), current_sequence().profile.height(), GEOM_EDITOR_SIZE_MEDIUM) editable_property.value.strip('"') self.geom_kf_edit.keyframe_parser = propertyparse.geom_keyframes_value_string_to_geom_kf_array self.geom_kf_edit.set_keyframes(editable_property.value, editable_property.get_in_value)
def _activate_only_current_top_active(): for i in range(0, len(current_sequence().tracks) - 1): if i == current_sequence().get_first_active_track().id: current_sequence().tracks[i].active = True else: current_sequence().tracks[i].active = False gui.tline_column.widget.queue_draw()
def _view_mode_menu_item_item_activated(widget, msg): if msg < 3: editorstate.current_sequence().set_output_mode(msg) gui.editor_window.view_mode_select.set_pixbuf(msg) else: mix_value_index = msg - 3 ## this just done in a bit hackish way, # see guicomponents.get_monitor_view_popupmenu and sequence.SCOPE_MIX_VALUES editorstate.current_sequence().set_scope_overlay_mix(mix_value_index)
def maybe_init_for_mouse_press(event, frame): # See if we actually hit a clip track = tlinewidgets.get_track(event.y) if track == None: return if track.id < 1 or (track.id >= len(current_sequence().tracks) - 1): return False clip_index = current_sequence().get_clip_index(track, frame) if clip_index == -1: return clip = track.clips[clip_index] if clip.is_blanck_clip: return # Now we will in fact enter CLIP_END_DRAG edit mode # See if we're dragging clip end or start cut_frame = current_sequence().get_closest_cut_frame(track.id, frame) editing_clip_end = True if frame >= cut_frame: editing_clip_end = False else: cut_frame = cut_frame - (clip.clip_out - clip.clip_in) if editing_clip_end == True: # clip end drags bound_end = ( cut_frame - clip.clip_in + clip.get_length() - 1 ) # get_length() is available media length, not current clip length bound_start = cut_frame - 1 if clip_index == len(track.clips) - 1: # last clip bound_end = bound_end - 1 else: # clip beginning drags bound_start = cut_frame - clip.clip_in bound_end = cut_frame + (clip.clip_out - clip.clip_in) + 1 global _enter_mode, _enter_draw_func, _edit_data _enter_mode = editorstate.edit_mode editorstate.edit_mode = editorstate.CLIP_END_DRAG _enter_draw_func = tlinewidgets.canvas_widget.edit_mode_overlay_draw_func _edit_data = {} _edit_data["track"] = track _edit_data["clip_index"] = clip_index _edit_data["frame"] = frame _edit_data["press_frame"] = frame _edit_data["editing_clip_end"] = editing_clip_end _edit_data["bound_end"] = bound_end _edit_data["bound_start"] = bound_start _edit_data["track_height"] = track.height _edit_data["orig_in"] = cut_frame - 1 _edit_data["orig_out"] = cut_frame + (clip.clip_out - clip.clip_in) tlinewidgets.set_edit_mode(_edit_data, tlinewidgets.draw_clip_end_drag_overlay) gui.editor_window.set_cursor_to_mode()
def tline_media_drop(media_file, x, y, use_marks=False): track = tlinewidgets.get_track(y) if track == None: return if track.id < 1 or track.id >= (len(current_sequence().tracks) - 1): return if dialogutils.track_lock_check_and_user_info(track): #modesetting.set_default_edit_mode() # TODO: Info return modesetting.stop_looping() frame = tlinewidgets.get_frame(x) # Create new clip. if media_file.type != appconsts.PATTERN_PRODUCER: new_clip = current_sequence().create_file_producer_clip(media_file.path, media_file.name, False, media_file.ttl) else: new_clip = current_sequence().create_pattern_producer(media_file) # Set clip in and out if use_marks == False: new_clip.mark_in = 0 new_clip.mark_out = new_clip.get_length() - 1 # - 1 because out is mark_out inclusive if media_file.type == appconsts.IMAGE_SEQUENCE: new_clip.mark_out = media_file.length else: new_clip.mark_in = media_file.mark_in new_clip.mark_out = media_file.mark_out if new_clip.mark_in == -1: new_clip.mark_in = 0 if new_clip.mark_out == -1: new_clip.mark_out = new_clip.get_length() - 1 # - 1 because out is mark_out inclusive if media_file.type == appconsts.IMAGE_SEQUENCE: new_clip.mark_out = media_file.length # Graphics files get added with their default lengths f_name, ext = os.path.splitext(media_file.name) if utils.file_extension_is_graphics_file(ext) and media_file.type != appconsts.IMAGE_SEQUENCE: # image sequences are graphics files but have own length in_fr, out_fr, l = editorpersistance.get_graphics_default_in_out_length() new_clip.mark_in = in_fr new_clip.mark_out = out_fr # Non-insert DND actions if editorpersistance.prefs.dnd_action == appconsts.DND_OVERWRITE_NON_V1: if track.id != current_sequence().first_video_track().id: drop_done = _attempt_dnd_overwrite(track, new_clip, frame) if drop_done == True: return elif editorpersistance.prefs.dnd_action == appconsts.DND_ALWAYS_OVERWRITE: drop_done = _attempt_dnd_overwrite(track, new_clip, frame) if drop_done == True: return do_clip_insert(track, new_clip, frame)
def cut_mode_pressed(): stop_looping() current_sequence().clear_hidden_track() # Box tool is implemeted as sub mode of OVERWRITE_MOVE editorstate.edit_mode = editorstate.CUT tlinewidgets.set_edit_mode(None, tlinewidgets.draw_cut_overlay) movemodes.clear_selected_clips() # Entering trim edit mode clears selection
def do_timeline_objects_copy(): if movemodes.selected_track != -1: # copying clips track = current_sequence().tracks[movemodes.selected_track] clone_clips = [] for i in range(movemodes.selected_range_in, movemodes.selected_range_out + 1): clone_clip = current_sequence().clone_track_clip(track, i) clone_clips.append(clone_clip) editorstate.set_copy_paste_objects(clone_clips)
def multi_mode_pressed(): stop_looping() current_sequence().clear_hidden_track() editorstate.edit_mode = editorstate.MULTI_MOVE tlinewidgets.set_edit_mode(None, tlinewidgets.draw_multi_overlay) updater.set_move_mode_gui() updater.repaint_tline()
def _get_compositor_clip(compositor): for i in range(current_sequence().first_video_index, len(current_sequence().tracks) - 1): # -1, there is a topmost hidden track track = current_sequence().tracks[i] # b_track is source track where origin clip is for j in range(0, len(track.clips)): clip = track.clips[j] if clip.id == compositor.origin_clip_id: return clip return None
def _all_tracks_snap(track, x, frame, frame_x): snapped_x = -1 for i in range(1, len(current_sequence().tracks) - 1): track = current_sequence().tracks[i] snapped_x = _get_track_snapped_x(track, x, frame, frame_x) if snapped_x != -1: return snapped_x return snapped_x
def _watermark_file_select_callback(dialog, response_id, widgets): add_button, remove_button, file_path_value_label = widgets if response_id == Gtk.ResponseType.ACCEPT: filenames = dialog.get_filenames() current_sequence().add_watermark(filenames[0]) add_button.set_sensitive(False) remove_button.set_sensitive(True) file_path_value_label.set_text(filenames[0]) dialog.destroy()
def init_sequence_gui(): """ Called after project load or changing current sequence to initialize interface. """ # Set initial timeline scale draw params editorstate.current_sequence().update_length() updater.update_pix_per_frame_full_view() updater.init_tline_scale() updater.repaint_tline()
def kftool_mode_pressed(): stop_looping() current_sequence().clear_hidden_track() # Box tool is implemeted as sub mode of OVERWRITE_MOVE editorstate.edit_mode = editorstate.KF_TOOL kftoolmode.enter_mode = None kftoolmode.set_no_clip_edit_data() tlinewidgets.set_edit_mode(None, tlinewidgets.draw_kftool_overlay) movemodes.clear_selected_clips() # Entering trim edit mode clears selection
def cut_all_tracks(frame): tracks_cut_data = [] for i in range(1, len(current_sequence().tracks) - 1): tracks_cut_data.append(get_cut_data(current_sequence().tracks[i], frame)) data = {"tracks_cut_data":tracks_cut_data} action = edit.cut_all_action(data) action.do_edit() updater.repaint_tline()
def insert_move_mode_pressed(): """ User selects insert move mode. """ stop_looping() current_sequence().clear_hidden_track() editorstate.edit_mode = editorstate.INSERT_MOVE tlinewidgets.set_edit_mode(None, tlinewidgets.draw_insert_overlay) _set_move_mode()
def _show_monitor_info_toggled(widget): editorpersistance.prefs.show_sequence_profile = widget.get_active() editorpersistance.save() if editorstate.timeline_visible(): name = editorstate.current_sequence().name profile_desc = editorstate.current_sequence().profile.description() if editorpersistance.prefs.show_sequence_profile: gui.editor_window.monitor_source.set_text(name + " / " + profile_desc) else: gui.editor_window.monitor_source.set_text(name)
def marks_clear_pressed(): if timeline_visible(): trimmodes.set_no_edit_trim_mode() PLAYER().producer.mark_in = -1 PLAYER().producer.mark_out = -1 else: current_sequence().monitor_clip.mark_in = -1 current_sequence().monitor_clip.mark_out = -1 _do_marks_update() updater.display_marks_tc()
def overwrite_move_mode_pressed(): """ User selects overwrite move mode. """ stop_looping() current_sequence().clear_hidden_track() editorstate.edit_mode = editorstate.OVERWRITE_MOVE tlinewidgets.set_edit_mode(None, tlinewidgets.draw_overwrite_overlay) _set_move_mode()
def _set_new_render_mode(new_tline_render_mode): if new_tline_render_mode == get_tline_rendering_mode(): return if new_tline_render_mode == appconsts.TLINE_RENDERING_OFF and get_tline_rendering_mode( ) != appconsts.TLINE_RENDERING_OFF: gui.editor_window.hide_tline_render_strip() elif new_tline_render_mode != appconsts.TLINE_RENDERING_OFF and get_tline_rendering_mode( ) == appconsts.TLINE_RENDERING_OFF: gui.editor_window.show_tline_render_strip() current_sequence().tline_render_mode = new_tline_render_mode update_renderer_to_mode() gui.editor_window.tline_render_mode_launcher.set_pixbuf( new_tline_render_mode) gui.editor_window.init_timeline_rendering_menu()
def clips_drag_out_started(event): # Abort move edit global edit_data, drag_disabled edit_data = None drag_disabled = True tlinewidgets.set_edit_mode_data(None) # Set dnd track = current_sequence().tracks[selected_track] clips = [] for i in range(selected_range_in, selected_range_out + 1): clips.append(track.clips[i]) dnd.start_tline_clips_out_drag(event, clips, gui.tline_canvas.widget) # Update tlione gui updater.repaint_tline()
def _show_preview(self): global _selected_plugin, _current_screenshot_surface frame = int(self.frame_select.get_value()) editor_widgets = self.plugin_editors.editor_widgets new_editors_list = simpleeditors.get_editors_data_as_editors_list(self.plugin_editors.editor_widgets) editors_data_json = json.dumps(new_editors_list) script_file = open(_selected_plugin.get_plugin_script_file()) user_script = script_file.read() profile_file_path = mltprofiles.get_profile_file_path(current_sequence().profile.description()) fctx = fluxity.render_preview_frame(user_script, frame, None, profile_file_path, editors_data_json) _current_screenshot_surface = self._create_preview_surface(fctx.priv_context.frame_surface) self.screenshot_canvas.queue_draw()
def set_slide_mode(track, current_frame): """ Sets two roll mode """ if track == None: return None if current_frame > track.get_length(): return False current_sequence().clear_hidden_track() view_frame, start_frame_being_viewed = _get_trim_edit(track, current_frame) # _get_trim_edit() gives first frame belonging to next clip if press closer to end frame of clip if not start_frame_being_viewed: view_frame = view_frame - 1 try: _set_slide_mode_edit_data(track, view_frame) except: return False if edit_data["clip"].is_blanck_clip: return False clip = edit_data["clip"] clip_start = edit_data["trim_limits"]["clip_start"] edit_data["start_frame_being_viewed"] = start_frame_being_viewed fake_current_frame = clip_start if not start_frame_being_viewed: fake_current_frame = clip_start + clip.clip_out - clip.clip_in # Give timeline widget needed data tlinewidgets.set_edit_mode(edit_data, tlinewidgets.draw_slide_overlay) tlinewidgets.fake_current_frame = fake_current_frame # Set clip as producer on hidden track and display current frame from it. clip = edit_data["clip"] clip_start = 0 # we'll calculate the offset from actual position of clip on timeline to display the frame displayed after sliding if clip.media_type != appconsts.PATTERN_PRODUCER: current_sequence().display_trim_clip(clip.path, clip_start) # File producer else: current_sequence().display_trim_clip( None, clip_start, clip.create_data) # pattern producer if start_frame_being_viewed: PLAYER().seek_frame(clip.clip_in) else: PLAYER().seek_frame(clip.clip_out) updater.repaint_tline() return True
def _get_track_snapped_x(track, x, frame, frame_x): if track == None: # Clip is being dragged outside of tracks area return -1 closest_cut_frame = current_sequence().get_closest_cut_frame(track.id, frame) if closest_cut_frame == -1: return -1 cut_frame_x = _get_x_for_frame_func(closest_cut_frame) if abs(cut_frame_x - frame_x) < _snap_threshold: global _last_snap_x _last_snap_x = cut_frame_x return x - (frame_x - cut_frame_x) else: return -1 # no snapping happened
def tline_effect_drop(x, y): clip, track, index = tlinewidgets.get_clip_track_and_index_for_pos(x, y) if clip == None: return if track == None: return if track.id < 1 or track.id >= (len(current_sequence().tracks) - 1): return if track_lock_check_and_user_info(track): set_default_edit_mode() return if clip != clipeffectseditor.clip: clipeffectseditor.set_clip(clip, track, index) clipeffectseditor.add_currently_selected_effect() # drag start selects the dragged effect
def append_button_pressed(): track = current_sequence().get_first_active_track() if editevent.track_lock_check_and_user_info(track, append_button_pressed, "insert"): return tline_pos = track.get_length() new_clip = _get_new_clip_from_clip_monitor() if new_clip == None: no_monitor_clip_info(gui.editor_window.window) return updater.save_monitor_frame = False # hack to not get wrong value saved in MediaFile.current_frame editevent.do_clip_insert(track, new_clip, tline_pos)
def screenshot_export(): length = current_sequence().tractor.get_length() if length < 2: dialogutils.info_message("Sequence is too short", "Sequence needs to be at least 2 frames long to allow frame export.", None) return frame = PLAYER().current_frame() # Can't get last frame to render easily, so just force range. if frame > length - 2: frame = length - 2 render_screen_shot(frame, get_displayed_image_render_path(), "png") export_screenshot_dialog(_export_screenshot_dialog_callback, frame, gui.editor_window.window, PROJECT().name) PLAYER().seek_frame(frame)
def change_edit_sequence(): selection = gui.sequence_list_view.treeview.get_selection() (model, rows) = selection.get_selected_rows() row = max(rows[0]) current_index = PROJECT().sequences.index(current_sequence()) if row == current_index: dialogutils.warning_message( _("Selected sequence is already being edited"), _("Select another sequence. Press Add -button to create a\nnew sequence if needed." ), gui.editor_window.window) return # Clear clips selection at exit. This is transient user focus state and # therefore is not saved. movemodes.clear_selected_clips() app.change_current_sequence(row)
def mouse_press(event, frame): track = current_sequence().tracks[compositor.transition.b_track - 1] global edit_data, sub_mode compositor_y = tlinewidgets._get_track_y( track.id) - tlinewidgets.COMPOSITOR_HEIGHT_OFF if abs(event.x - tlinewidgets._get_frame_x(compositor.clip_in)) < TRIM_HANDLE_WIDTH: edit_data = { "clip_in": compositor.clip_in, "clip_out": compositor.clip_out, "trim_is_clip_in": True, "orig_clip_in": compositor.clip_in, "compositor_y": compositor_y, "compositor": compositor } tlinewidgets.set_edit_mode(edit_data, tlinewidgets.draw_compositor_trim) sub_mode = TRIM_EDIT elif abs(event.x - tlinewidgets._get_frame_x(compositor.clip_out + 1)) < TRIM_HANDLE_WIDTH: edit_data = { "clip_in": compositor.clip_in, "clip_out": compositor.clip_out, "trim_is_clip_in": False, "orig_clip_out": compositor.clip_out, "compositor_y": compositor_y, "compositor": compositor } tlinewidgets.set_edit_mode(edit_data, tlinewidgets.draw_compositor_trim) sub_mode = TRIM_EDIT else: edit_data = { "press_frame": frame, "current_frame": frame, "clip_in": compositor.clip_in, "clip_length": (compositor.clip_out - compositor.clip_in + 1), "compositor_y": compositor_y, "compositor": compositor } tlinewidgets.set_edit_mode(edit_data, tlinewidgets.draw_compositor_move_overlay) sub_mode = MOVE_EDIT updater.repaint_tline()
def splice_out_button_pressed(): """ Removes 1 - n long continuous clip range from track and closes the created gap. """ if movemodes.selected_track == -1: return # Edit consumes selection, so clear selected from clips movemodes.set_range_selection(movemodes.selected_track, movemodes.selected_range_in, movemodes.selected_range_out, False) track = get_track(movemodes.selected_track) if editevent.track_lock_check_and_user_info(track, splice_out_button_pressed, "splice out"): movemodes.clear_selection_values() return # A single clip delete can trigger a special clip cover delete # See if such delete should be attempted. # Exit if done succesfully, do normal splice out and report if failed cover_delete_failed = False if editorpersistance.prefs.trans_cover_delete == True: if movemodes.selected_range_out == movemodes.selected_range_in: clip = track.clips[movemodes.selected_range_in] if hasattr(clip, "rendered_type") and (track.id >= current_sequence().first_video_index): cover_delete_success = _attempt_clip_cover_delete(clip, track, movemodes.selected_range_in) if cover_delete_success: return # A successful cover delete happened else: cover_delete_failed = True # A successful cover delete failed, do normal delete and gove info # Do delete data = {"track":track, "from_index":movemodes.selected_range_in, "to_index":movemodes.selected_range_out} edit_action = edit.remove_multiple_action(data) edit_action.do_edit() _splice_out_done_update() if cover_delete_failed == True: dialogutils.info_message(_("Fade/Transition cover delete failed!"), _("There wasn't enough material available in adjacent clips.\nA normal Splice Out was done instead."), gui.editor_window.window)
def sync_compositor(compositor): track = current_sequence().tracks[compositor.transition.b_track] # b_track is source track where origin clip is origin_clip = None for clip in track.clips: if clip.id == compositor.origin_clip_id: origin_clip = clip if origin_clip == None: dialogutils.info_message(_("Origin clip not found!"), _("Clip used to create this Compositor has been removed\nor moved to different track."), gui.editor_window.window) return clip_index = track.clips.index(origin_clip) clip_start = track.clip_start(clip_index) clip_end = clip_start + origin_clip.clip_out - origin_clip.clip_in data = {"compositor":compositor,"clip_in":clip_start,"clip_out":clip_end} action = edit.move_compositor_action(data) action.do_edit()
def _fade_render_complete(clip_path): global transition_render_data clip_index, fade_type, clip, track, length = transition_render_data fade_clip = current_sequence().create_rendered_transition_clip(clip_path, fade_type) data = {"fade_clip":fade_clip, "index":clip_index, "track":track, "length":length} if fade_type == mlttransitions.RENDERED_FADE_IN: action = edit.add_rendered_fade_in_action(data) action.do_edit() else: # mlttransitions.RENDERED_FADE_OUT action = edit.add_rendered_fade_out_action(data) action.do_edit()
def select_prev_clip_for_filter_edit(): if not editorstate.timeline_visible(): updater.display_sequence_in_monitor() tline_frame = PLAYER().tracktor_producer.frame() - 1 clip, track = current_sequence().find_prev_editable_clip_and_track( tline_frame) if clip == None: return range_in = track.clips.index(clip) frame = track.clip_start(range_in) movemodes.select_clip(track.id, range_in) PLAYER().seek_frame(frame) clipeffectseditor.set_clip(clip, track, range_in)
def cut_single_track(event, frame): track = tlinewidgets.get_track(event.y) if track == None or track.id == 0 or track.id == len( current_sequence().tracks) - 1: return if dialogutils.track_lock_check_and_user_info(track): return data = get_cut_data(track, frame) if data == None: return action = edit.cut_action(data) action.do_edit() updater.repaint_tline()
def mouse_press(event, frame): print "gggg" x = event.x y = event.y # If we have clip being edited and its edit area is hit, we do not need to init data. if _clip_is_being_edited() and _clip_edit_area_hit(x, y): print "ooooooooooooooooooo" return # Get pressed track track = tlinewidgets.get_track(y) # Selecting empty clears selection if track == None: #clear_selected_clips() #pressed_on_selected = False _set_no_clip_edit_data() updater.repaint_tline() return # Get pressed clip index clip_index = current_sequence().get_clip_index(track, frame) # Selecting empty clears selection if clip_index == -1: #clear_selected_clips() #pressed_on_selected = False _set_no_clip_edit_data() updater.repaint_tline() return print "kkkkkk" global edit_data #, pressed_on_selected, drag_disabled edit_data = { "draw_function": _tline_overlay, "clip_index": clip_index, "track": track, "mouse_start_x": x, "mouse_start_y": y } tlinewidgets.set_edit_mode_data(edit_data) updater.repaint_tline()
def _all_tracks_item_activated(widget, msg): if msg == "min": current_sequence().minimize_tracks_height() _tracks_resize_update() if msg == "max": current_sequence().maximize_tracks_height( gui.tline_canvas.widget.get_allocation()) _tracks_resize_update() if msg == "maxvideo": current_sequence().maximize_video_tracks_height( gui.tline_canvas.widget.get_allocation()) _tracks_resize_update() if msg == "maxaudio": current_sequence().maximize_audio_tracks_height( gui.tline_canvas.widget.get_allocation()) _tracks_resize_update()
def _transition_render_complete(clip_path): print "render complete" global transition_render_data transition_index, from_clip, to_clip, track, from_in, to_out, transition_type = transition_render_data transition_clip = current_sequence().create_rendered_transition_clip(clip_path, transition_type) data = {"transition_clip":transition_clip, "transition_index":transition_index, "from_clip":from_clip, "to_clip":to_clip, "track":track, "from_in":from_in, "to_out":to_out} action = edit.add_centered_transition_action(data) action.do_edit()
def _get_sync_tline_clip(event, frame): sync_track = tlinewidgets.get_track(event.y) if sync_track == None: return None if sync_track == _tline_sync_data.origin_track: dialogutils.warning_message( _("Audio Sync parent clips must be on differnt tracks "), _("Selected audio sync clip is on the sametrack as the sync action origin clip." ), gui.editor_window.window, True) return None sync_clip_index = current_sequence().get_clip_index(sync_track, frame) if sync_clip_index == -1: return None return sync_track.clips[sync_clip_index]
def render_screen_shot(frame, render_path, vcodec): producer = current_sequence().tractor consumer = mlt.Consumer(PROJECT().profile, "avformat", str(render_path)) consumer.set("real_time", -1) consumer.set("rescale", "bicubic") consumer.set("vcodec", str(vcodec)) renderer = renderconsumer.FileRenderPlayer(None, producer, consumer, frame, frame + 1) renderer.wait_for_producer_end_stop = False renderer.consumer_pos_stop_add = 2 # Hack, see FileRenderPlayer renderer.start() while renderer.has_started_running == False: time.sleep(0.05) while renderer.stopped == False: time.sleep(0.05)
def _reload_clip_media(data): clip, track, item_id, item_data = data # TODO: This ain't doing the clip icon update as wished. media_item = PROJECT().get_media_file_for_path(clip.path) media_item.create_icon() clip_index = track.clips.index(clip) new_clip = current_sequence().create_clone_clip(clip) data = { "old_clip": clip, "new_clip": new_clip, "track": track, "index": clip_index } action = edit.reload_replace(data) action.do_edit()
def set_track_normal_height(track_index): track = get_track(track_index) track.height = appconsts.TRACK_HEIGHT_NORMAL # Check that new height tracks can be displayed and cancel if not. new_h = current_sequence().get_tracks_height() x, y, w, h = gui.tline_canvas.widget.allocation if new_h > h: track.height = appconsts.TRACK_HEIGHT_SMALL dialogutils.warning_message( _("Not enough vertical space on Timeline to expand track"), _("Maximize or resize application window to get more\nspace for tracks if possible." ), gui.editor_window.window, True) return tlinewidgets.set_ref_line_y(gui.tline_canvas.widget.allocation) gui.tline_column.init_listeners() updater.repaint_tline()
def _launch_render(self, clip, range_in, range_out, clip_start_offset): self.create_data_dirs_if_needed() self.render_range_in = range_in self.render_range_out = range_out self.clip_start_offset = clip_start_offset mltxmlheadless.clear_flag_files(self.get_container_program_id()) # We need data to be available for render process, # create video_render_data object with default values if not available. if self.container_data.render_data == None: self.container_data.render_data = toolsencoding.create_container_clip_default_render_data_object( current_sequence().profile) mltxmlheadless.set_render_data(self.get_container_program_id(), self.container_data.render_data) job_msg = self.get_job_queue_message() job_msg.text = _("Render Starting...") job_msg.status = jobs.RENDERING jobs.update_job_queue(job_msg) args = ( "session_id:" + self.get_container_program_id(), "clip_path:" + str(self.container_data.unrendered_media).replace( " ", "\ " ), # This is going through Popen shell=True and needs escaped spaces. "range_in:" + str(range_in), "range_out:" + str(range_out), "profile_desc:" + PROJECT().profile.description().replace(" ", "_"), "xml_file_path:" + str(self.container_data.unrendered_media).replace(" ", "\ ") ) # This is going through Popen shell=True and needs escaped spaces. # Run with nice to lower priority if requested (currently hard coded to lower) nice_command = "nice -n " + str(10) + " " + str( respaths.LAUNCH_DIR + "flowblademltxmlheadless").replace( " ", "\ ") for arg in args: nice_command += " " nice_command += arg subprocess.Popen([nice_command], shell=True)
def _add_fluxity_rendered_help_media_complete(created_unrendered_clip_path, container_data): rand_id_str = str(os.urandom(16)) clip_id_str = hashlib.md5(rand_id_str.encode('utf-8')).hexdigest() unrendered_clip_path = userfolders.get_data_dir( ) + appconsts.CONTAINER_CLIPS_UNRENDERED + "/" + clip_id_str + ".mp4" os.replace(created_unrendered_clip_path, unrendered_clip_path) container_data.unrendered_media = unrendered_clip_path container_data.unrendered_type = appconsts.VIDEO throw_away_clip = current_sequence().create_file_producer_clip( unrendered_clip_path, "dummy", False, None) throw_away_clip.container_data = container_data throw_away_clip.container_data.generate_clip_id() action_object = containeractions.get_action_object(container_data) action_object.plugin_create_render_complete_callback = _plugin_create_render_complete_callback action_object.render_full_media(throw_away_clip)
def _get_trim_edit(track, frame): """ Return a trim edit for a frame on a track. """ # Trying to trim from frame after last clip will init from-side trim # for frame where last clip ends. if ((frame >= track.get_length()) and (track.get_length() > 1)): cut_frame = track.get_length() edit_to_side = False return (cut_frame, edit_to_side) # Get cut frame for trim cut_frame = current_sequence().get_closest_cut_frame(track.id, frame) if cut_frame == -1: return (-1, None) edit_to_side = False if frame >= cut_frame: edit_to_side = True return (cut_frame, edit_to_side)
def append_log_events(): clips = [] log_events = get_current_filtered_events() for le in log_events: clips.append(get_log_event_clip(le)) track = editorstate.current_sequence().get_first_active_track() # Can't put audio media on video track for new_clip in clips: if ((new_clip.media_type == appconsts.AUDIO) and (track.type == appconsts.VIDEO)): dialogs.no_audio_dialog(track) return data = {"track": track, "clips": clips} action = edit.append_media_log_action(data) action.do_edit()
def get_log_event_clip(log_event): # pre versions 1.16 do not have this attr in log_event objects if not hasattr(log_event, "ttl"): log_event.ttl = None # currently quaranteed not to be a pattern producer new_clip = editorstate.current_sequence().create_file_producer_clip( log_event.path, None, False, log_event.ttl) # Set clip in and out points new_clip.clip_in = log_event.mark_in new_clip.clip_out = log_event.mark_out if widgets.use_comments_check.get_active() == True: new_clip.name = log_event.comment if len(new_clip.name) == 0: new_clip.name = log_event.name else: new_clip.name = log_event.name return new_clip
def run(self): # Image produceer img_producer = current_sequence().create_file_producer_clip(str(self.image_file)) # , new_clip_name=None, novalidate=False, ttl=None): # Create tractor and track to get right length tractor = mlt.Tractor() multitrack = tractor.multitrack() track0 = mlt.Playlist() multitrack.connect(track0, 0) track0.insert(img_producer, 0, 0, self.length) # Consumer write_file = userfolders.get_cache_dir() + "/unrendered_clip.mp4" # Delete earlier created files if os.path.exists(write_file): os.remove(write_file) consumer = renderconsumer.get_default_render_consumer(write_file, PROJECT().profile) clip_renderer = renderconsumer.FileRenderPlayer(write_file, tractor, consumer, 0, self.length) clip_renderer.wait_for_producer_end_stop = True clip_renderer.start() Gdk.threads_enter() info_text = _("<b>Rendering Placeholder Media For:</b> ") + self.data.get_program_name() + ".blend" progress_bar = Gtk.ProgressBar() dialog = rendergui.clip_render_progress_dialog(None, self.window_text, info_text, progress_bar, gui.editor_window.window, True) motion_progress_update = renderconsumer.ProgressWindowThread(dialog, progress_bar, clip_renderer, self.progress_thread_complete) motion_progress_update.start() Gdk.threads_leave() while clip_renderer.stopped == False: time.sleep(0.5) Gdk.threads_enter() self.callback(write_file, self.data) Gdk.threads_leave()
def init_select_tline_sync_clip(popup_data): clip, track, item_id, x = popup_data frame = tlinewidgets.get_frame(x) clip_index = current_sequence().get_clip_index(track, frame) if not (track.clips[clip_index] == clip): # This should never happen print("big fu at init_select_tline_sync_clip(...)") return gdk_window = gui.tline_display.get_parent_window() gdk_window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.TCROSS)) editorstate.edit_mode = editorstate.SELECT_TLINE_SYNC_CLIP global _tline_sync_data _tline_sync_data = TLineSyncData() _tline_sync_data.origin_clip = clip _tline_sync_data.origin_track = track _tline_sync_data.origin_clip_index = clip_index
def recreate_master_meter_filter_for_new_sequence(): global _level_filters, _audio_levels # We need to be sure that audio level updates are stopped before # detaching and destroying them _update_ticker.stop_ticker() if len(_level_filters) != 0: seq = editorstate.current_sequence() # Only detach master filter if we are displaying audio master meter if _master_volume_meter != None: seq.tractor.detach(_level_filters[0]) _level_filters.pop(0) _audio_levels[0] = 0.0 master_level_filter = _add_audio_level_filter( seq.tractor, seq.profile) _level_filters.insert(0, master_level_filter) if _master_volume_meter != None or _monitor_window != None: _update_ticker.start_ticker()