How to detect that you are in gpencil mode and switch between draw and edit mode?

Hy everyone,

I would like to make a srcipt with an operator that allows you to switch to the edit and draw mode of the grease pencil but I can’t find in the bleder doc how to tell that we are in Gpencil mode and also how to switch to the draw and edit mode.

import bpy

# -----------------------------------------------------------------------------------
# creation of an addon that will switch select to draw in Grease Pencil
# -----------------------------------------------------------------------------------
         
# ---------------------------------------------------
#  OP_Switch_GP : switch between select and draw of the grease pencil


def Switch() :
    print("def Switch start")
    
    context = bpy.context
    scene = context.scene

   #I would like to check here that we are in gpencil mode before doing the tests in "if".
  
    if bpy.ops.object.mode_set(mode='PAINT_GPENCIL') :
    
        bpy.ops.gpencil.editmode_toggle()
        bpy.ops.wm.tool_set_by_id(name='builtin.select_box')
        return
    
    bpy.ops.gpencil.paintmode_toggle() //don't work
    bpy.ops.wm.tool_set_by_id(name='builtin.brush.Draw')
    
            
class OP_Switch_GP (bpy.types.Operator) :
    
    bl_idname = "object.oper_select_draw"
    bl_label = "switch"
    bl_description = "switch select to draw in Grease Pencil"
    
    def execute(self, context) :
        
        Switch()
        
        return {'FINISHED'}

    
# ---------------------------------------------------
#  PANEL GREASE PENCIL SWITCH : SELECT <--> DRAW

class InterfacePanel (bpy.types.Panel) :
    
    bl_label = "Switch Draw <-> select"
    bl_idname = "VIEW_3D_PT_SELECT_DRAW"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "GP select-draw"
    bl_description = "Grease Pencil switch Draw <-> select"
                                
     # --- draw --- #
        
    def draw(self, context) :
        
        l = self.layout
        c=l.column(align = False)
        
        c.operator(OP_Switch_GP.bl_idname)
                    
# ---------------------------------------------------
# REGISTER
classes = (InterfacePanel, OP_Switch_GP)

        
def register() :
   
    for cls in classes:
        bpy.utils.register_class(cls)
     
def unregister() :
    
    for cls in classes:
        bpy.utils.unregister_class(cls)
     
if __name__ == "__main__" :
    register()

Good night,

context.mode will tell you what mode you’re in. for example, if you’re in edit mode it will return EDIT_GPENCIL

to change to different modes, use the object.mode_set operator:

bpy.ops.object.mode_set(mode='PAINT_GPENCIL')
bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
bpy.ops.object.mode_set(mode='SCULPT_GPENCIL')
bpy.ops.object.mode_set(mode='WEIGHT_GPENCIL')
bpy.ops.object.mode_set(mode='OBJECT')

Thanks, I managed to make a code that works. There’s just one thing I don’t understand. I want to make it automatically select a specific tool when it enters each mode. For edit mode it works but for draw it doesn’t select the pencil. But I put the right line of code. What’s my mistake, I don’t understand?

import bpy

# -----------------------------------------------------------------------------------
# creation of an addon that will switch select to draw in Grease Pencil
# -----------------------------------------------------------------------------------
         
# ---------------------------------------------------
#  OP_Switch_GP : switch between select and draw of the grease pencil


def Switch() :
    print("def Switch start")
    
    context = bpy.context
    scene = context.scene
  
    if context.mode == 'EDIT_GPENCIL':
        bpy.ops.object.mode_set(mode='PAINT_GPENCIL')
        
        bpy.ops.wm.tool_set_by_id(name='builtin.brush.Draw')// don't work
        return
        
    if context.mode == 'PAINT_GPENCIL':
        bpy.ops.object.mode_set(mode='EDIT_GPENCIL')

        bpy.ops.wm.tool_set_by_id(name='builtin.select_box')// work
        return

I’ve tried a lot of things, but it doesn’t work. Even this post doesn’t seem to be working :
choose active tool

def set_active_tool(tool_name):
    for area in bpy.context.screen.areas:
        if area.type == '2D Animation':
            override = bpy.context.copy()
            override["space_data"] = area.spaces[0]
            override["area"] = area
            bpy.ops.wm.tool_set_by_id(override, name=tool_name)


def Switch() :
    print("def Switch start")
    
    context = bpy.context
    scene = context.scene
  
    if context.mode == 'EDIT_GPENCIL':
#        print("EDIT_GPENCIL active")
        bpy.ops.object.mode_set(mode='PAINT_GPENCIL')
        
        set_active_tool('builtin.brush.Draw')
        
#        bpy.ops.wm.tool_set_by_id(name='builtin.brush.Draw')
        return
        
    if context.mode == 'PAINT_GPENCIL':
#        print("PAINT_GPENCIL active")
        bpy.ops.object.mode_set(mode='EDIT_GPENCIL')
        
        set_active_tool('builtin.select_box')
        
#        bpy.ops.wm.tool_set_by_id(name='builtin.select_box')
        return

well, you have at least two problems that I can see at a glance:

  • There is no such thing as an area type called “2D Animation”. Here is a valid list of area types. You’re looking for VIEW_3D.

  • There is no tool with the name “builtin.brush.Draw”, you’re looking for builtin_brush.Draw. You can find the correct names of tools by turning on python tooltips in the interface settings and you’ll see them like this:
    image

Thank you,
I still have to get it clean, but it works.