Skip to content

Instantly share code, notes, and snippets.

@tin2tin
Created November 24, 2024 04:54
Show Gist options
  • Save tin2tin/78d9fb3f732a2bfa4326264213de103e to your computer and use it in GitHub Desktop.
Save tin2tin/78d9fb3f732a2bfa4326264213de103e to your computer and use it in GitHub Desktop.
Update text strip content, when changing text-block
import bpy
# Store the last synced text block content to detect changes
LAST_SYNCED_TEXT = {"content": None, "name": None}
# Add properties to the Text Strip
def add_text_strip_properties():
bpy.types.Sequence.text_sync_enabled = bpy.props.BoolProperty(
name="Sync with Text Block",
description="Enable syncing with a specific text block",
default=False,
update=on_sync_toggle_update
)
bpy.types.Sequence.text_sync_text_block = bpy.props.PointerProperty(
name="Text Block",
type=bpy.types.Text,
description="Select the text block to sync with this text strip",
update=on_sync_toggle_update
)
def remove_text_strip_properties():
del bpy.types.Sequence.text_sync_enabled
del bpy.types.Sequence.text_sync_text_block
def on_sync_toggle_update(self, context):
"""
Callback for the on/off toggle to enable or disable syncing.
"""
if self.text_sync_enabled:
setup_text_block_timer()
sync_text_strip()
else:
remove_text_block_timer()
def get_textblock_from_strip(strip):
"""
Get the text block selected in the strip's custom property.
"""
if strip and strip.text_sync_enabled and strip.text_sync_text_block:
return strip.text_sync_text_block
return None
def get_active_textstrip():
"""
Retrieve the active text strip from the Video Sequence Editor.
"""
sequence_editor = bpy.context.scene.sequence_editor
if not sequence_editor:
return None
active_text_strip = sequence_editor.active_strip
# Ensure the active strip is a text strip
if not active_text_strip or active_text_strip.type != 'TEXT':
return None
return active_text_strip
def sync_text_strip():
"""
Synchronize the content of the selected text block with the active text strip.
"""
active_text_strip = get_active_textstrip()
if not active_text_strip:
return
# Get the text block from the strip's property
text_block = get_textblock_from_strip(active_text_strip)
if not text_block:
return
# Update the text strip content with the text block content
content = text_block.as_string()
active_text_strip.text = content
LAST_SYNCED_TEXT["content"] = content
#LAST_SYNCED_TEXT["name"] = text_block.name
def check_text_block_update():
"""
Check if the content of the selected text block has changed.
If it has, synchronize it with the active text strip.
"""
active_text_strip = get_active_textstrip()
if not active_text_strip or not active_text_strip.text_sync_enabled:
return None
# Get the selected text block
text_block = get_textblock_from_strip(active_text_strip)
if not text_block:
return None
if text_block.name != LAST_SYNCED_TEXT["name"]:
return None
# Compare the current content with the last synced content
current_content = text_block.as_string()
if current_content != LAST_SYNCED_TEXT["content"]:
sync_text_strip()
# Continue checking every 1 second
return 1.0
def setup_text_block_timer():
"""
Set up a timer to periodically check if the text block has changed.
"""
if not bpy.app.timers.is_registered(check_text_block_update):
bpy.app.timers.register(check_text_block_update, first_interval=1.0)
def remove_text_block_timer():
"""
Remove the timer that checks for text block updates.
"""
if bpy.app.timers.is_registered(check_text_block_update):
bpy.app.timers.unregister(check_text_block_update)
# Extend the SEQUENCER_PT_effect Panel
def draw_sync_ui(self, context):
layout = self.layout
strip = context.scene.sequence_editor.active_strip
if strip and strip.type == 'TEXT':
# Create a row for the toggle and the text-block selector
row = layout.row(align=True, heading="")
row.use_property_decorate = False
# Add the toggle button
sub = row.row(align=True)
sub.prop(strip, "text_sync_enabled", text="")
# Add the text-block selector, activating only if the toggle is enabled
subsub = sub.row(align=True)
subsub.active = strip.text_sync_enabled
subsub.prop(strip, "text_sync_text_block", text="")
# Optional decorator (useful for UI consistency and showing relationships)
row.prop_decorator(strip, "text_sync_text_block")
def prepend_sync_ui():
bpy.types.SEQUENCER_PT_effect.prepend(draw_sync_ui)
def remove_sync_ui():
bpy.types.SEQUENCER_PT_effect.remove(draw_sync_ui)
# Registration
def register():
"""
Register the script's functionality.
"""
add_text_strip_properties()
prepend_sync_ui()
def unregister():
"""
Unregister the script's functionality.
"""
remove_text_strip_properties()
remove_sync_ui()
remove_text_block_timer()
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment