Hello, I’m struggling to check if the operator bpy.ops.anim.previewrange_set is in effect in the Video Sequencer.
I’m trying to make myself a custom addon where I want to merge the 2 following operators into one button: bpy.ops.anim.previewrange_set bpy.ops.anim.previewrange_clear
The idea is that if there is no preview range, the button is normal and I can click to make one.
If there is a preview range, the button is red (alert) and I can click it so clears the preview range.
operators are fire-and-forget, you can’t query them. bpy.ops.anim.previewrange_set will never be “None” because it will resolve to a pointer to the built-in function.
import bpy
# operator that displays the menu
class ShowMenu(bpy.types.Operator):
bl_idname = "object.show_menu"
bl_label = "Show Menu"
def execute(self, context):
return bpy.ops.wm.call_menu(name=CustomMenu.bl_idname)
# menu with UI
class CustomMenu(bpy.types.Menu):
bl_label = "Custom Menu"
bl_idname = "OBJECT_MT_custom_menu"
def draw(self, context):
layout = self.layout
# get all spaces
for space in context.area.spaces:
# get only view3D
if space.type != 'VIEW_3D': continue;
# if it has no render border -> exec operator with renderborder
if not space.use_render_border:
layout.operator('object.exec_operator', text='draw border').action='renderborder'
return
# it has render border -> exec operator with 'clearborder'
else:
layout.operator('object.exec_operator', text='clear border').action='clearborder'
# is only a wrapper operator that will call the real operators
class ExecOperator(bpy.types.Operator):
bl_idname = "object.exec_operator"
bl_label = "Show Menu"
bl_options = {'INTERNAL'} # this operator is hidden from user
action : bpy.props.StringProperty()
def execute(self, context):
# can execute only two actions
if self.action == 'renderborder':
# INVOKE_DEFAULT is used to override BLENDER's default context
# --> now blender will be confused and assume
# that the user wants to call the operator
# instead of how by default Blender/Operator calls the oper
bpy.ops.view3d.render_border('INVOKE_DEFAULT')
elif self.action == 'clearborder':
# since this does not involve user-level-interaction
# INVOKE_DEFAULT is not needed essentially
# (either you use it or not makes not so much of a differnce)
bpy.ops.view3d.clear_render_border()
return {'FINISHED'}
def register():
bpy.utils.register_class(ShowMenu) # to begin display the menu
bpy.utils.register_class(CustomMenu) # to draw the menu
bpy.utils.register_class(ExecOperator) # to execute the operators (CustomMenu->ExecOperator)
def unregister():
bpy.utils.register_class(ShowMenu)
bpy.utils.unregister_class(CustomMenu)
bpy.utils.register_class(ExecOperator)
# while testing unregister/register all of the time
# (first time ever will fail for sure, so exception is used)
try: unregister()
except: pass
register()
So I tried your script and changed a few things as I wanted this to be in the Sequence Editor and for the anim.previewrange_set and anim.previewrange_clear operators.
I changed, in class CustomMenu: if space.type != 'SEQUENCE_EDITOR': continue;
and in class ExecOperator: bpy.ops.anim.previewrange_set('INVOKE_DEFAULT') bpy.ops.anim.previewrange_clear()
But it’s that line here that is causing me a problem: if not space.use_render_border: