Tool selection vs Blender area types

Hey there!

I try to create tool selection shortcut, and it works as intended in view3d area, but can’t get any reaction in “uv editor mode”.
What am i doing wrong please :slight_smile:

import bpy

# Function to switch the active selection tool based on mode
def switch_selection_tool():
    # Check the area type
    area_type = bpy.context.area.type

    if area_type == 'VIEW_3D':
        switch_selection_tool_3d_view()
    elif area_type in {'IMAGE_EDITOR', 'UV_EDITOR'}:
        switch_selection_tool_image_editor()
    else:
        print("Unsupported editor type")

# Function to switch the active selection tool in 3D Viewport mode
def switch_selection_tool_3d_view():
    # Get the current mode
    mode = bpy.context.mode

    # Get the active tool ID
    active_tool_id = bpy.context.workspace.tools.from_space_view3d_mode(mode, create=False).idname

    # Switch selection tool based on the active tool ID
    if active_tool_id == 'builtin.select_circle':
        bpy.ops.wm.tool_set_by_id(name="builtin.select_box")
        print("Switched to Box Selection Tool in 3D Viewport")
    elif active_tool_id == 'builtin.select_box':
        bpy.ops.wm.tool_set_by_id(name="builtin.select_lasso")
        print("Switched to Lasso Selection Tool in 3D Viewport")
    elif active_tool_id == 'builtin.select_lasso':
        bpy.ops.wm.tool_set_by_id(name="builtin.select_box")
        print("Switched to Box Selection Tool in 3D Viewport")

# Function to switch the active selection tool in Image Editor or UV Editor mode
def switch_selection_tool_image_editor():  
    # Get the current mode
    mode = bpy.context.mode

    # Get the active tool ID for UV Editor mode
    active_tool_id = bpy.context.workspace.tools.from_space_uv_mode(mode, create=False).idname

    # Switch selection tool based on the active tool ID
    if active_tool_id == 'builtin.select_circle':
        bpy.ops.wm.tool_set_by_id(name="builtin.select_box")
        print("Switched to Box Selection Tool in UV Editor")
    elif active_tool_id == 'builtin.select_box':
        bpy.ops.wm.tool_set_by_id(name="builtin.select_lasso")
        print("Switched to Lasso Selection Tool in UV Editor")
    elif active_tool_id == 'builtin.select_lasso':
        bpy.ops.wm.tool_set_by_id(name="builtin.select_box")
        print("Switched to Box Selection Tool in UV Editor")

# Call the function to switch the selection tool
switch_selection_tool()

There are two small errors in your switch_selection_tool_image_editor function:

  1. Instead of getting the current mode: mode = bpy.context.mode, you should be checking for the space’s mode, which looks like: mode = bpy.context.space_data.mode

This is because the context.mode will return OBJECT, whereas the context.space_data.mode will give you VIEW, UV, PAINT, or MASK, which are the modes you need in this case.

  1. Instead of getting workspace tools from_space_uv_mode you should be getting them from_space_image_mode.

It makes sense to grab from the uv_mode in the UV Editor, but that is not actually an option.
The Image Editor and UV Editor share the same space, but operate in different modes, so you need to grab tools from_space_image_mode, and fill in the mode with one of the options from part 1.

2 more things that I noticed that may not be mistakes, but I felt were worth mentioning:

  1. in order to call the switch_selection_tool function I had to pass in the other two functions as arguments. Depending on how and where you’re calling the function that might be something to keep in mind.

  2. You’re looping through 3 tools - circle, box, lasso, but your logic only allows you to access box and lasso:

  • if Circle is active, switch to Box
  • if Box is active, switch to Lasso
  • if Lasso is active, switch to Box <= This should switch to Circle if you want to loop through all available tools
1 Like

Thank You, it is working perfectly now!
I kept the “first half” of the script as it were since it is working in view3d, but change the image editor part, and now it is working as it should.

“1. You’re looping through 3 tools - circle, box, lasso, but your logic only allows you to access box and lasso:”
Yep, should work like that way :slight_smile:

I just love this community, You are so supportive and helpful! :slight_smile:

1 Like