Run modal operator while tool is selected

For my addon in 2.8 I need to have a modal operator running while my custom toolbar tool is selected, or at least know when it is selected/deselected so that I can invoke/stop a modal operator. I have not been able to find any way to do both these things. Is it possible with the current python API?

2 Likes

I’m not sure if this is what you’re looking for.
I use something like this to check if the move or scale tools are selected:

current_tool = bpy.context.workspace.tools.from_space_view3d_mode(mode, create=False).idname
if current_tool == "builtin.move" or current_tool== "builtin.scale":
	print (current_tool)
1 Like

Thanks! Not exactly what I was looking for, but being able to check the currently selected tool will certainly be useful.

1 Like

@Oskar That’s some helpful code, thanks! I have a related question. Is there a way to know what ‘mode’ a tool was left in?

So for example, I click and hold on the Scale tool to open the dropdown menu (or cycle through with a hotkey) and choose Scale Cage. Then I switch over to the Move tool. Is there I way I can find out what mode or state the no-longer-selected Scale tool was left in?

image

Just wanted to bump this again. I still haven’t figured out how to tell what ‘mode’ an active tool was left in.

current_tool = bpy.context.workspace.tools.from_space_view3d_mode(mode, create=False).idname

The above code only gives you the currently selected tool. I haven’t figured out how to access the rest of the tools on the panel. Does anyone know how?

unfortunately I don’t think it’s possible. you can loop through all the areas to find the toolbar’s region, but once you have a toolbar region I’m not aware of any way to extract the UILayout (which you could then use to divine which buttons are on the toolbar, and what state they were left in).

this would probably be a good Python API papercut to add, seeing as the functionality doesn’t seem to exist

Check out bpy.types.VIEW3D_PT_tools_active and its methods for getting all tool definitions based on context mode.

That will give you the all of the tools for a given context, but does it have a way to get the last known state of a particular tooldef (even if it’s not the active tool)? I haven’t found that to be the case, but it would be super useful if it does

I’m probably just a bit dense atm, but it’s unclear to me what is meant by “last known state” of an active tool.

Are we talking about last used operator properties or last activated tool?
Or are we talking about getting the last known active tool in a different context?

Could you give some context to what the “last known state” would be useful for?

I’m looking for last activated tool. Say I cycled the Scale tool to Scale Cage, then switched my active tool to Select. I want to find out which mode the Scale tool was left in.

With the Scale Tool selected:
bpy.context.workspace.tools.from_space_view3d_mode('OBJECT', create=False).idname
returns ‘builtin.scale_cage’
bpy.context.workspace.tools.from_space_view3d_mode('OBJECT', create=False).index
returns 1

But if I switch to a different tool I can’t find out anymore which idname, what index, etc. the Scale tool has been cycled to. Now I only have access to the current Select Tool info.

Knowing this would be useful for a bunch of stuff I would think. Like maybe I have an addon or operator that I want to do a certain thing dependent on what mode an active tool was last in, even if that tool is not currently selected.

Say I have an operator that creates an object and then invokes the annotate tool for whatever reason, for tagging it or making notes or whatever. The annotation tool is not selected or active, but I want to invoke it in the mode it was last left in, so annotate polygon for example.

It’s a dumb example, I know, but you get the idea. Annotate Polygon is currently being displayed on the button in the panel. So surely Blender must have a way of accessing that information, right?

Makes sense.

You can get the state of sub menus which have been accessed since blender was launched using _tool_group_active from the same class in my previous post.

It returns a dict containing the groups that have sub menus, and last accessed sub menu index.
If the user hasn’t accessed the tool since blender started, it wont appear in the dictionary.

>>> bpy.types.VIEW3D_PT_tools_active._tool_group_active
{'builtin.annotate': 0, 'builtin.scale': 1, 'builtin.extrude_region': 1, 'builtin.loop_cut': 1, 'builtin.select': 3, 'builtin.knife': 1, 'builtin.spin': 1}
2 Likes