Be more explicit in strip ObjectID conflicts.

Shows more warnings in the UI, and the conflict status is now saved on
an RNA property atc_object_id_conflict.
This commit is contained in:
Sybren A. Stüvel 2016-11-04 12:04:38 +01:00
parent d332e1e50a
commit a58bfe9a76
2 changed files with 61 additions and 13 deletions

View File

@ -79,6 +79,18 @@ def selected_shots(context):
yield strip yield strip
def shown_strips(context):
"""Returns the strips from the current meta-strip-stack, or top-level strips.
What is returned depends on what the user is currently editing.
"""
if context.scene.sequence_editor.meta_stack:
return context.scene.sequence_editor.meta_stack[-1].sequences
return context.scene.sequence_editor.sequences
def remove_atc_props(strip): def remove_atc_props(strip):
"""Resets the attract custom properties assigned to a VSE strip""" """Resets the attract custom properties assigned to a VSE strip"""
@ -88,6 +100,38 @@ def remove_atc_props(strip):
strip.atc_is_synced = False strip.atc_is_synced = False
def shot_id_use(strips):
"""Returns a mapping from shot Object ID to a list of strips that use it."""
import collections
# Count the number of uses per Object ID, so that we can highlight double use.
ids_in_use = collections.defaultdict(list)
for strip in strips:
if not getattr(strip, 'atc_is_synced', False):
continue
ids_in_use[strip.atc_object_id].append(strip)
return ids_in_use
def compute_strip_conflicts(context):
"""Sets the strip property atc_object_id_conflict for each strip."""
# FIXME: this only considers the currently shown strips, so only draws conflicts either within
# the same metastrip or not in metastrips. Cross-metastrip boundaries are not crossed to check.
all_strips = shown_strips(context)
ids_in_use = shot_id_use(all_strips)
for strips in ids_in_use.values():
is_conflict = len(strips) > 1
for strip in strips:
strip.atc_object_id_conflict = is_conflict
return ids_in_use
class ToolsPanel(Panel): class ToolsPanel(Panel):
bl_label = 'Attract' bl_label = 'Attract'
bl_space_type = 'SEQUENCE_EDITOR' bl_space_type = 'SEQUENCE_EDITOR'
@ -110,6 +154,12 @@ class ToolsPanel(Panel):
else: else:
noun = 'This Shot' noun = 'This Shot'
if strip.atc_object_id_conflict:
warnbox = layout.box()
warnbox.alert = True
warnbox.label('Warning: This shot is linked to multiple sequencer strips.',
icon='ERROR')
layout.prop(strip, 'atc_name', text='Name') layout.prop(strip, 'atc_name', text='Name')
layout.prop(strip, 'atc_status', text='Status') layout.prop(strip, 'atc_status', text='Status')
@ -222,6 +272,7 @@ class AttractOperatorMixin:
strip.atc_notes = node['properties']['notes'] strip.atc_notes = node['properties']['notes']
strip.atc_status = node['properties']['status'] strip.atc_status = node['properties']['status']
compute_strip_conflicts(bpy.context)
draw.tag_redraw_all_sequencer_editors() draw.tag_redraw_all_sequencer_editors()
def submit_update(self, strip): def submit_update(self, strip):
@ -266,6 +317,7 @@ class AttractOperatorMixin:
strip.atc_notes = node.properties.notes or '' strip.atc_notes = node.properties.notes or ''
strip.atc_description = node.description or '' strip.atc_description = node.description or ''
compute_strip_conflicts(bpy.context)
draw.tag_redraw_all_sequencer_editors() draw.tag_redraw_all_sequencer_editors()
@ -699,6 +751,10 @@ def draw_strip_movie_meta(self, context):
def register(): def register():
bpy.types.Sequence.atc_is_synced = bpy.props.BoolProperty(name="Is Synced") bpy.types.Sequence.atc_is_synced = bpy.props.BoolProperty(name="Is Synced")
bpy.types.Sequence.atc_object_id = bpy.props.StringProperty(name="Attract Object ID") bpy.types.Sequence.atc_object_id = bpy.props.StringProperty(name="Attract Object ID")
bpy.types.Sequence.atc_object_id_conflict = bpy.props.BoolProperty(
name='Object ID Conflict',
description='Attract Object ID used multiple times',
default=False)
bpy.types.Sequence.atc_name = bpy.props.StringProperty(name="Shot Name") bpy.types.Sequence.atc_name = bpy.props.StringProperty(name="Shot Name")
bpy.types.Sequence.atc_description = bpy.props.StringProperty(name="Shot Description") bpy.types.Sequence.atc_description = bpy.props.StringProperty(name="Shot Description")
bpy.types.Sequence.atc_notes = bpy.props.StringProperty(name="Shot Notes") bpy.types.Sequence.atc_notes = bpy.props.StringProperty(name="Shot Notes")
@ -734,6 +790,7 @@ def unregister():
bpy.utils.unregister_module(__name__) bpy.utils.unregister_module(__name__)
del bpy.types.Sequence.atc_is_synced del bpy.types.Sequence.atc_is_synced
del bpy.types.Sequence.atc_object_id del bpy.types.Sequence.atc_object_id
del bpy.types.Sequence.atc_object_id_conflict
del bpy.types.Sequence.atc_name del bpy.types.Sequence.atc_name
del bpy.types.Sequence.atc_description del bpy.types.Sequence.atc_description
del bpy.types.Sequence.atc_notes del bpy.types.Sequence.atc_notes

View File

@ -108,29 +108,20 @@ def draw_strip_conflict(strip_coords, pixel_size_x):
def draw_callback_px(): def draw_callback_px():
import collections
context = bpy.context context = bpy.context
if not context.scene.sequence_editor: if not context.scene.sequence_editor:
return return
from . import shown_strips
region = context.region region = context.region
xwin1, ywin1 = region.view2d.region_to_view(0, 0) xwin1, ywin1 = region.view2d.region_to_view(0, 0)
xwin2, ywin2 = region.view2d.region_to_view(region.width, region.height) xwin2, ywin2 = region.view2d.region_to_view(region.width, region.height)
one_pixel_further_x, one_pixel_further_y = region.view2d.region_to_view(1, 1) one_pixel_further_x, one_pixel_further_y = region.view2d.region_to_view(1, 1)
pixel_size_x = one_pixel_further_x - xwin1 pixel_size_x = one_pixel_further_x - xwin1
pixel_size_y = one_pixel_further_y - ywin1
if context.scene.sequence_editor.meta_stack: strips = shown_strips(context)
strips = context.scene.sequence_editor.meta_stack[-1].sequences
else:
strips = context.scene.sequence_editor.sequences
# Count the number of uses per Object ID, so that we can highlight double use.
ids_in_use = collections.defaultdict(int)
for strip in strips:
ids_in_use[strip.atc_object_id] += bool(getattr(strip, 'atc_is_synced', False))
for strip in strips: for strip in strips:
if not strip.atc_object_id: if not strip.atc_object_id:
@ -154,7 +145,7 @@ def draw_callback_px():
alpha = 1.0 if strip.atc_is_synced else 0.5 alpha = 1.0 if strip.atc_is_synced else 0.5
draw_underline_in_strip(strip_coords, pixel_size_x, color + (alpha,)) draw_underline_in_strip(strip_coords, pixel_size_x, color + (alpha,))
if strip.atc_is_synced and ids_in_use[strip.atc_object_id] > 1: if strip.atc_is_synced and strip.atc_object_id_conflict:
draw_strip_conflict(strip_coords, pixel_size_x) draw_strip_conflict(strip_coords, pixel_size_x)