0
$\begingroup$

I would like to know why 2D Gizmos disappear when running a modal operator using them?

Here is a trivial example of a code that creates a gizmo in 3d view and by clicking it and dragging we can move the active object in x. As you will see the gizmo will disappear during the dragging. How can we prevent that from happening?

Thanks!

Maciej

enter image description here

Here is an example code that illustrates the problem:

import bpy

from bpy.types import (
    GizmoGroup,
    Gizmo
    )
    
from mathutils import Matrix, Vector


# --------------------------------------------------------------
# Simple Gizmo Button Example that will be drawn in the 3D VIEW
# --------------------------------------------------------------
class GIZMO_example_button(bpy.types.GizmoGroup):
    bl_label = "GIZMO Example"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'WINDOW'
    bl_options = {'PERSISTENT', 'SCALE', 'SHOW_MODAL_ALL'}

    @classmethod
    def poll(cls, context):
        return True  

    @staticmethod
    def set_gizmo_settings(gizmo, icon,
            color=(0.1, 0.1, 0.1),
            color_highlight=(0.5, 0.5, 0.5),
            alpha=0.7,
            alpha_highlight=0.7,
            show_drag=False,
            draw_options={'BACKDROP', 'OUTLINE' },
            scale_basis=24):
        
        gizmo.icon = icon
        gizmo.color = color
        gizmo.color_highlight = color_highlight
        gizmo.alpha = alpha
        gizmo.alpha_highlight = alpha_highlight
        gizmo.show_drag = show_drag
        gizmo.draw_options = draw_options
        gizmo.scale_basis = scale_basis
        gizmo.use_draw_offset_scale = True

    def setup(self, context):
        
        self.object_gizmos = []

        self.gizmo_example = self.gizmos.new("GIZMO_GT_button_2d")
        self.set_gizmo_settings(self.gizmo_example, 'ARROW_LEFTRIGHT', show_drag=False)
        self.gizmo_example.target_set_operator("test.example_operator") 
        self.object_gizmos.append(self.gizmo_example)

    def draw_prepare(self, context):

        self.gizmo_example.matrix_basis = Matrix.Translation((250,250,0))
        self.gizmo_example.scale_basis = 20


# ------------------------------------------------------
# Simple Gizmo Button that will be drawn in the 3D VIEW
# ------------------------------------------------------
class OT_example_modal_operator(bpy.types.Operator):
    """EXAMPLE OPERATOR"""
    
    # This operator will slide the cut point between two realtime edit clips that are next to each other
    #

    bl_idname = "test.example_operator"    
    bl_label = "EXAMPLE OPERATOR"
    bl_options = {'REGISTER', 'UNDO'}

    def move_x(self, context, event):

        # MOVING TO THE RIGHT
        if event.mouse_x > self.init_mouse_x + 15:

            self.init_mouse_x = event.mouse_x
            
            active_object = bpy.context.view_layer.objects.active
            
            if active_object != None:
                
                active_object.location.x += 1

        # MOVING TO THE LEFT
        elif event.mouse_x < self.init_mouse_x - 15:

            self.init_mouse_x = event.mouse_x        

            active_object = bpy.context.view_layer.objects.active
            
            if active_object != None:
                
                active_object.location.x -= 1

    @classmethod
    def poll(cls, context):
        return context    

    def execute(self, context):

        return {'FINISHED'} 

    def invoke(self, context, event):

        # ----------------------------------------
        # Set the init x position of the mouse
        # ----------------------------------------
        self.init_mouse_x = event.mouse_x

        # ----------------------------------------
        # Set the cursor
        # ----------------------------------------
        context.window.cursor_set("SCROLL_X")

        # ----------------------------------------
        # Add Modal Handler to the Window Manager
        # ----------------------------------------
        context.window_manager.modal_handler_add(self)

        # ----------------------------------------
        # Run the move_x function
        # ----------------------------------------
        self.move_x(context, event)

        return {'RUNNING_MODAL'}

    def modal(self, context, event):
        
        self.move_x(context, event)

        if event.type == 'LEFTMOUSE':
            
            # Set the mouse cursor to default
            context.window.cursor_set("DEFAULT")            
            return {'FINISHED'}

        elif event.type in {'RIGHTMOUSE', 'ESC'}:

            # Set the mouse cursor to default
            context.window.cursor_set("DEFAULT")
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}





classes = (
    OT_example_modal_operator,
    GIZMO_example_button,
    
    
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
        
        
        
    bpy.types.Area.show_vision_interface = bpy.props.BoolProperty(default = True)
        

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
        
    del bpy.types.Area.show_vision_interface
        
if __name__ == '__main__':
    register()
$\endgroup$

1 Answer 1

0
$\begingroup$

Thanks to @SpectralVectors on Blender Artists forum I found out that you just need to set this property in set_gizmo_settings function:

gizmo.use_draw_modal = True
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .