Compare commits

..

9 Commits

Author SHA1 Message Date
da4d4df5fb Bumped version to 1.5.1 2016-11-11 09:28:10 +01:00
9c3098cc0d Attract: Added some poll methods 2016-11-11 09:26:52 +01:00
98beaf7fb7 Unlinking a single shot copies the shot ID to the clipboard.
This allows you to easily unlink one strip, and relink another. This cannot
be done for multiple shots simultaneously.
2016-11-11 09:23:39 +01:00
3364371ac6 Use '{nr of shots} Shots' instead of 'Selected Shots'
This is a bit shorter, and more concrete.
2016-11-11 09:22:59 +01:00
2723b07fa2 Nicer button layout for unlink & delete
This makes 'delete' harder to hit accidentally.
2016-11-11 09:17:25 +01:00
c2a037ca89 Added button to copy a shot ID to the clipboard 2016-11-11 09:15:04 +01:00
d3451d4de3 Icon tweaks 2016-11-11 09:14:51 +01:00
5094977614 Attract: "delete shots" now works on all selected Attract strips 2016-11-11 09:06:59 +01:00
Dalai Felinto
a11a55be22 Implement attract "Trim End" 2016-11-10 18:49:13 +01:00
3 changed files with 79 additions and 16 deletions

View File

@@ -21,7 +21,7 @@
bl_info = {
'name': 'Blender Cloud',
"author": "Sybren A. Stüvel, Francesco Siddi, Inês Almeida, Antony Riakiotakis",
'version': (1, 5, 0),
'version': (1, 5, 1),
'blender': (2, 77, 0),
'location': 'Addon Preferences panel, and Ctrl+Shift+Alt+A anywhere for texture browser',
'description': 'Texture library browser and Blender Sync. Requires the Blender ID addon '

View File

@@ -170,7 +170,7 @@ class ToolsPanel(Panel):
selshots = list(selected_shots(context))
if strip and strip.type in strip_types and strip.atc_object_id:
if len(selshots) > 1:
noun = 'Selected Shots'
noun = '%i Shots' % len(selshots)
else:
noun = 'This Shot'
@@ -193,20 +193,29 @@ class ToolsPanel(Panel):
sub = layout.column(align=True)
row = sub.row(align=True)
if bpy.ops.attract.submit_selected.poll():
row.operator('attract.submit_selected', text='Submit %s' % noun)
row.operator('attract.submit_selected',
text='Submit %s' % noun,
icon='MOVE_UP_VEC')
else:
row.operator(ATTRACT_OT_submit_all.bl_idname)
row.operator(AttractShotFetchUpdate.bl_idname,
text='', icon='FILE_REFRESH')
row.operator(ATTRACT_OT_shot_open_in_browser.bl_idname,
text='', icon='WORLD')
row.operator(ATTRACT_OT_copy_id_to_clipboard.bl_idname,
text='', icon='COPYDOWN')
sub.operator(ATTRACT_OT_make_shot_thumbnail.bl_idname,
text='Render Thumbnail for %s' % noun)
text='Render Thumbnail for %s' % noun,
icon='RENDER_STILL')
# Group more dangerous operations.
dangerous_sub = layout.column(align=True)
dangerous_sub.operator(AttractShotDelete.bl_idname)
dangerous_sub.operator('attract.strip_unlink')
dangerous_sub = layout.split(0.6, align=True)
dangerous_sub.operator('attract.strip_unlink',
text='Unlink %s' % noun,
icon='PANEL_CLOSE')
dangerous_sub.operator(AttractShotDelete.bl_idname,
text='Delete %s' % noun,
icon='CANCEL')
elif context.selected_sequences:
if len(context.selected_sequences) > 1:
@@ -272,6 +281,7 @@ class AttractOperatorMixin:
'notes': '',
'used_in_edit': True,
'trim_start_in_frames': strip.frame_offset_start,
'trim_end_in_frames': strip.frame_offset_end,
'duration_in_edit_in_frames': strip.frame_final_duration,
'cut_in_timeline_in_frames': strip.frame_final_start},
'order': 0,
@@ -306,6 +316,7 @@ class AttractOperatorMixin:
'$set': {
'name': strip.atc_name,
'properties.trim_start_in_frames': strip.frame_offset_start,
'properties.trim_end_in_frames': strip.frame_offset_end,
'properties.duration_in_edit_in_frames': strip.frame_final_duration,
'properties.cut_in_timeline_in_frames': strip.frame_final_start,
'properties.status': strip.atc_status,
@@ -411,6 +422,10 @@ class ATTRACT_OT_shot_open_in_browser(AttractOperatorMixin, Operator):
bl_label = 'Open in Browser'
bl_description = 'Opens a webbrowser to show the shot on Attract'
@classmethod
def poll(cls, context):
return bool(context.selected_sequences and active_strip(context))
def execute(self, context):
from ..blender import PILLAR_WEB_SERVER_URL
import webbrowser
@@ -433,6 +448,10 @@ class AttractShotDelete(AttractOperatorMixin, Operator):
confirm = bpy.props.BoolProperty(name='confirm')
@classmethod
def poll(cls, context):
return bool(context.selected_sequences)
def execute(self, context):
from .. import pillar
@@ -440,13 +459,22 @@ class AttractShotDelete(AttractOperatorMixin, Operator):
self.report({'WARNING'}, 'Delete aborted.')
return {'CANCELLED'}
strip = active_strip(context)
node = pillar.sync_call(Node.find, strip.atc_object_id)
if not pillar.sync_call(node.delete):
print('Unable to delete the strip node on Attract.')
return {'CANCELLED'}
removed = kept = 0
for strip in selected_shots(context):
node = pillar.sync_call(Node.find, strip.atc_object_id)
if not pillar.sync_call(node.delete):
self.report({'ERROR'}, 'Unable to delete shot %s on Attract.' % strip.atc_name)
kept += 1
continue
remove_atc_props(strip)
removed += 1
if kept:
self.report({'ERROR'}, 'Removed %i shots, but was unable to remove %i' %
(removed, kept))
else:
self.report({'INFO'}, 'Removed all %i shots from Attract' % removed)
remove_atc_props(strip)
draw.tag_redraw_all_sequencer_editors()
return {'FINISHED'}
@@ -457,7 +485,14 @@ class AttractShotDelete(AttractOperatorMixin, Operator):
def draw(self, context):
layout = self.layout
col = layout.column()
col.prop(self, 'confirm', text="I hereby confirm: delete this shot from The Edit.")
selshots = list(selected_shots(context))
if len(selshots) > 1:
noun = '%i shots' % len(selshots)
else:
noun = 'this shot'
col.prop(self, 'confirm', text="I hereby confirm: delete %s from The Edit." % noun)
class AttractStripUnlink(AttractOperatorMixin, Operator):
@@ -465,6 +500,10 @@ class AttractStripUnlink(AttractOperatorMixin, Operator):
bl_label = 'Unlink Shot From This Strip'
bl_description = 'Remove Attract props from the selected strip(s)'
@classmethod
def poll(cls, context):
return bool(context.selected_sequences)
def execute(self, context):
unlinked_ids = set()
@@ -487,7 +526,13 @@ class AttractStripUnlink(AttractOperatorMixin, Operator):
node = Node({'_id': oid})
pillar.sync_call(node.patch, {'op': 'unlink'})
self.report({'INFO'}, 'Shot %s has been marked as Unused.' % oid)
if len(unlinked_ids) == 1:
shot_id = unlinked_ids.pop()
context.window_manager.clipboard = shot_id
self.report({'INFO'}, 'Copied unlinked shot ID %s to clipboard' % shot_id)
else:
self.report({'INFO'}, '%i shots have been marked as Unused.' % len(unlinked_ids))
draw.tag_redraw_all_sequencer_editors()
return {'FINISHED'}
@@ -813,6 +858,23 @@ class ATTRACT_OT_make_shot_thumbnail(AttractOperatorMixin,
return file_id
class ATTRACT_OT_copy_id_to_clipboard(AttractOperatorMixin, Operator):
bl_idname = 'attract.copy_id_to_clipboard'
bl_label = 'Copy shot ID to clipboard'
@classmethod
def poll(cls, context):
return bool(context.selected_sequences and active_strip(context))
def execute(self, context):
strip = active_strip(context)
context.window_manager.clipboard = strip.atc_object_id
self.report({'INFO'}, 'Shot ID %s copied to clipboard' % strip.atc_object_id)
return {'FINISHED'}
def draw_strip_movie_meta(self, context):
strip = active_strip(context)
if not strip:
@@ -869,6 +931,7 @@ def register():
bpy.utils.register_class(ATTRACT_OT_open_meta_blendfile)
bpy.utils.register_class(ATTRACT_OT_shot_open_in_browser)
bpy.utils.register_class(ATTRACT_OT_make_shot_thumbnail)
bpy.utils.register_class(ATTRACT_OT_copy_id_to_clipboard)
bpy.app.handlers.scene_update_post.append(scene_update_post_handler)
draw.callback_enable()

View File

@@ -196,7 +196,7 @@ setup(
'wheels': BuildWheels},
name='blender_cloud',
description='The Blender Cloud addon allows browsing the Blender Cloud from Blender.',
version='1.5.0',
version='1.5.1',
author='Sybren A. Stüvel',
author_email='sybren@stuvel.eu',
packages=find_packages('.'),