1
$\begingroup$

I'm making an operator that has the bl_options = {'REGISTER','UNDO'} in order to call the undo menu.

Since my menu's draw() is getting cluttered with lots of properties, I thought about making an enum that served as some kind of tab-system so, depending on which option is selected, I draw X or Y:

enter image description here

My problem is that when I change that enum, the execute() in my operator is triggered. I don't want that (my operator is a bit heavy, and that enum has nothing to do with its calculations, so I would like the user to change """tabs""" without the lag of waiting the operator to finish.

Is it possible to achieve?

Thank you so much.


Code with Gorgious' idea:

import bpy


# def main(context):
    # for ob in context.scene.objects:
        # print(ob)


class TestOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.test"
    bl_label = "Simple Object Operator"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        # main(context)
        # for i in range(1000):
        #     print(f"executed! ", i)
        print(f"operator finished!")
        # print(f"{context.scene.test_tab = }")
        return {'FINISHED'}
    
    def draw(self, context):
        layout = self.layout
        layout.label(text="Hello!")
        
        # # Scene
        # _selected_tab = context.scene.test_tab
        # layout.prop(context.scene, "test_tab")
        
        # # GreasPencil
        # _selected_tab = context.gpencil_data.test_tab
        # layout.prop(context.gpencil_data, "test_tab")
        
        # # Object
        _selected_tab = context.active_object.test_tab
        layout.prop(context.active_object, "test_tab")
        
        if _selected_tab == "GRAVITY":
            layout.label(text="     Gravity selected!")
        elif _selected_tab == "FX":
            layout.label(text="     FX selected!")
            
        



# def menu_func(self, context):
#     self.layout.operator(TestOperator.bl_idname, text=TestOperator.bl_label)


# Register and add to the "object" menu (required to also use F3 search "Simple Object Operator" for quick access).
def register():
    bpy.utils.register_class(TestOperator)
    # bpy.types.Scene.test_tab = bpy.props.EnumProperty(
    # bpy.types.GreasePencil.test_tab = bpy.props.EnumProperty(
    bpy.types.Object.test_tab = bpy.props.EnumProperty(
        name="Draw tab",
        items=(
            ('GRAVITY', "Gravity & Rotation", "", "GREASEPENCIL", 0),
            ('FX', "FX", "", "GREASEPENCIL", 1),
        ),
        default='GRAVITY',
        )
    # bpy.types.VIEW3D_MT_object.append(menu_func)


def unregister():
    bpy.utils.unregister_class(TestOperator)
    # del bpy.types.Scene.test_tab
    # del bpy.types.GreasePencil.test_tab
    del bpy.types.Object.test_tab
    # bpy.types.VIEW3D_MT_object.remove(menu_func)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.test()
$\endgroup$
6
  • $\begingroup$ Hello ! If this property doesn't affect the operator whatsoever, I think you should store it somewhere else and put it in a panel somewhere else in the interface so it doesn't interact with the redo system $\endgroup$
    – Gorgious
    Dec 7, 2023 at 11:15
  • $\begingroup$ Hello Gorgious! Thank you so much for the idea, much appreciated! To be honest I was hyped and thought it was going to work, but sadly no (damn haha). I registered the enum in the Scene rather than in the OT (also tried other types like Object and GreasePencil (just in case)), but seems that even if the enum is not part of the operator's properties, it stills get triggered when I change it (I edited the answer with the code). Do you mean to place the property outside the Undo panel? (If so, I think that when we change it, it will close the OT's Undo panel) $\endgroup$
    – Ommadawn
    Dec 7, 2023 at 12:34
  • $\begingroup$ Ah yes I think any property changing in the undo panel will triggeer a redo, and changing a property outisde of the undo panel will close the panel. Maybe you want to change the way you're going about it ? it's maybe an XY problem and it can be solved by other means ? $\endgroup$
    – Gorgious
    Dec 8, 2023 at 10:58
  • 1
    $\begingroup$ Maybe you want to check inside execute() if any property that actually matters has been changed (by storing the values of previous settings)? This would still pollute the undo history, but would at least save CPU cycles. $\endgroup$ Dec 8, 2023 at 11:11
  • $\begingroup$ @Gorgious Yeah, probably there is a better way. I thought that maybe Blender had somekind of method for a folding panel in the UILayout or something similar to achieve what I want, but I wasn't able to find anything. I guess it would be easier to simply add the operator as a panel in the N menu. $\endgroup$
    – Ommadawn
    Dec 8, 2023 at 19:06

0

You must log in to answer this question.

Browse other questions tagged .