Export_3ds: Improved distance cue node search
[blender-addons.git] / power_sequencer / operators / make_hold_frame.py
blobff743b7ec41c0ea3dbf6ed05c331606e4efd7663
1 # SPDX-FileCopyrightText: 2016-2020 by Nathan Lovato, Daniel Oakey, Razvan Radulescu, and contributors
3 # SPDX-License-Identifier: GPL-3.0-or-later
5 import bpy
6 import operator
8 from .utils.global_settings import SequenceTypes
9 from .utils.functions import convert_duration_to_frames
10 from .utils.doc import doc_name, doc_idname, doc_brief, doc_description
13 class POWER_SEQUENCER_OT_make_hold_frame(bpy.types.Operator):
14 """
15 *brief* Make a hold frame from the active strip
17 Converts the image under the cursor to a hold frame, to create a pause effect in the video,
18 using the active sequence
19 """
21 doc = {
22 "name": doc_name(__qualname__),
23 "demo": "",
24 "description": doc_description(__doc__),
25 "shortcuts": [],
26 "keymap": "Sequencer",
28 bl_idname = doc_idname(__qualname__)
29 bl_label = doc["name"]
30 bl_description = doc_brief(doc["description"])
31 bl_options = {"REGISTER", "UNDO"}
33 strip_duration: bpy.props.FloatProperty(
34 name="Strip Duration",
35 description="The duration in seconds of the new strip, if 0.0 it will use the gap as its duration",
36 default=0.0,
37 min=0.0,
40 @classmethod
41 def poll(cls, context):
42 return context.scene.sequence_editor.active_strip.type in SequenceTypes.VIDEO
44 def invoke(self, context, event):
45 window_manager = context.window_manager
46 return window_manager.invoke_props_dialog(self)
48 def execute(self, context):
49 scene = context.scene
50 active = scene.sequence_editor.active_strip
51 sequencer = bpy.ops.sequencer
52 transform = bpy.ops.transform
54 frame_start = scene.frame_current
56 if not active.frame_final_start <= frame_start < active.frame_final_end:
57 return {"FINISHED"}
59 if frame_start == active.frame_final_start:
60 scene.frame_current = frame_start + 1
62 # Detect the gap automatically
63 offset = convert_duration_to_frames(context, self.strip_duration)
64 if self.strip_duration <= 0.0:
65 try:
66 next_strip_start = next(
68 for s in sorted(context.sequences, key=operator.attrgetter("frame_final_start"))
69 if s.frame_final_start > active.frame_final_end
70 ).frame_final_start
71 offset = next_strip_start - active.frame_final_end
72 except Exception:
73 pass
75 active.select = True
76 source_blend_type = active.blend_type
77 sequencer.split(frame=scene.frame_current, type="SOFT", side="RIGHT")
78 transform.seq_slide(value=(offset, 0))
79 sequencer.split(frame=scene.frame_current + offset + 1, type="SOFT", side="LEFT")
80 transform.seq_slide(value=(-offset, 0))
82 sequencer.meta_make()
83 active = scene.sequence_editor.active_strip
84 active.name = "Hold frame"
85 active.blend_type = source_blend_type
86 active.select_right_handle = True
87 transform.seq_slide(value=(offset, 0))
89 scene.frame_current = frame_start
91 active.select = True
92 active.select_right_handle = False
93 active.select_left_handle = False
94 return {"FINISHED"}