How to Turn Toolbar Items to Pie Menus

I’m trying to get toolbar items to be repurposed for custom pie menus. Currently, there’s no clear way to do this, except to rebuild the tools’ access (such as: Move, Rotate, Scale, etc.) from scratch using the builtin GIZMO_GT primitives.

Edit: After a lot of trial and error and re-purposing of bits of code by other devs and artists, I cobbled together the following:

import bpy
from bpy.types import (
    GizmoGroup,
    Operator
)


class VIEW3D_OT_gizmo_translate(Operator):
    """Show Translate Gizmo"""
    bl_idname = "view3d.gizmo_translate"
    bl_label = "gizmo translate"
    bl_options = {'REGISTER', 'UNDO'}
    
    
    def execute(self, context):
        areas = context.workspace.screens[0].areas

        for area in areas:
            for space in area.spaces:
                if space.type == 'VIEW_3D':
                    space.show_gizmo_object_translate^= True
                    if space.show_gizmo== False:
                         space.show_gizmo= True
                    if space.show_gizmo_context== False:
                         space.show_gizmo_context= True
                    if space.show_gizmo_tool== False:
                         space.show_gizmo_tool= True  
                                             
        return{'FINISHED'}

From what I can gather, however, this toggles the transform gizmos, as in the pop-over method (in fact, you can see the Move checkbox checked in the Show Gizmo pop-over, when you invoke this code). Again, it’s a toggle, so execute once, it comes on; execute again, it turns off.

What I’m after is the exact behaviour of the tools from the toolbar. By looking at the toolbar’s code, however, I can’t see any definitive signs that point to how that’s done. Again, what I’m looking to do is mimic the exact behaviour of the transform gizmo tools from the toolbar, in a custom pie menu. Is this even possible using Blender Python’s API?

The other question is how do I get the icon names of the NEW TOOLBAR ICONS? Currently, there’s no obvious way of finding out how to use them in a pie menu, such as the following:

import bpy
from bpy.types import Menu


class VIEW3D_MT_PIE_template(Menu):
    
    bl_label = "Transform Tools"

    def draw(self, context):
        layout = self.layout
        row = layout.row()

        pie = layout.menu_pie()
        pie.operator("view3d.gizmo_translate", text="Translate", icon='GIZMO')
        pie.operator("view3d.gizmo_rotate", text="Rotate", icon='PHYSICS')
        pie.operator("view3d.gizmo_scale", text="Scale", icon='MOD_MESHDEFORM')

Guidance would be appreciated.

Well, well, well… what a difference a day makes. I discovered the following operator:

bpy.ops.wm.tool_set_by_id(name="builtin.move", space_type="VIEW_3D")

And — voila! — you get the same behaviour as the toolbar version of the tool.

Edit: So, I hacked the following script together:

import bpy
from bpy.types import (
    Menu, 
    Operator, 
)

class VIEW3D_OT_gizmo_translate(Operator):
    bl_idname = "view3d.gizmo_translate"
    bl_label = "gizmo translate"
    bl_options = {'REGISTER', 'UNDO'}
    
    
    def execute(self, context):
        bpy.ops.wm.tool_set_by_id(name='builtin.move', space_type='VIEW_3D')

        return {'FINISHED'}

class VIEW3D_MT_PIE_template(Menu):
    
    bl_label = "Transform Tools"

    def draw(self, context):
        layout = self.layout
        row = layout.row()

        pie = layout.menu_pie()
        pie.operator("view3d.gizmo_translate", text='Translate', icon='GIZMO')


def register():
    bpy.utils.register_class(VIEW3D_OT_gizmo_translate)
    bpy.utils.register_class(VIEW3D_MT_PIE_template)


def unregister():
    bpy.utils.register_class(VIEW3D_OT_gizmo_translate)
    bpy.utils.unregister_class(VIEW3D_MT_PIE_template)


if __name__ == "__main__":
    register()
    bpy.ops.wm.call_menu_pie(name="VIEW3D_MT_PIE_template")

Got very promising results. After some rookie errors and omissions, I got it to work. Hope this helps other people, too.

NOW… about accessing those NEW TOOLBAR ICONS…

This is far from elegant, but if anyone is interested in a decent starting point. Hoping this helps others, as well.

import bpy
from bpy.types import (
    Menu, 
    Operator, 
)

class VIEW3D_OT_gizmo_translate(Operator):
    bl_idname = "view3d.gizmo_translate"
    bl_label = "Pie Translate"
    bl_options = {'REGISTER', 'UNDO'}
    
    
    def execute(self, context):
        bpy.ops.wm.tool_set_by_id(name='builtin.move', space_type='VIEW_3D')
        
        return {'FINISHED'}


class VIEW3D_OT_gizmo_rotate(Operator):
    bl_idname = "view3d.gizmo_rotate"
    bl_label = "Pie Rotate"
    bl_options = {'REGISTER', 'UNDO'}
    
    
    def execute(self, context):
        bpy.ops.wm.tool_set_by_id(name='builtin.rotate', space_type='VIEW_3D')
        
        return {'FINISHED'}


class VIEW3D_OT_gizmo_scale(Operator):
    bl_idname = "view3d.gizmo_scale"
    bl_label = "Pie Scale"
    bl_options = {'REGISTER', 'UNDO'}
    
    
    def execute(self, context):
        bpy.ops.wm.tool_set_by_id(name='builtin.scale', space_type='VIEW_3D')
        
        return {'FINISHED'}
    
    
class VIEW3D_OT_gizmo_select_box(Operator):
    bl_idname = "view3d.gizmo_select_box"
    bl_label = "Pie Box Select"
    bl_options = {'REGISTER', 'UNDO'}
    
    
    def execute(self, context):
        bpy.ops.wm.tool_set_by_id(name='builtin.select_box', space_type='VIEW_3D')
        
        return {'FINISHED'}


class VIEW3D_MT_PIE_template(Menu):
    
    bl_label = "Transform Tools"

    def draw(self, context):
        layout = self.layout
        row = layout.row()

        pie = layout.menu_pie()
        pie.operator("view3d.gizmo_translate", text='Translate', icon='GIZMO')
        pie.operator("view3d.gizmo_rotate", text='Rotate', icon='PHYSICS')
        pie.operator("view3d.gizmo_scale", text='Scale', icon='FULLSCREEN_ENTER')
        pie.operator("view3d.gizmo_select_box", text='Box Select', icon='PIVOT_BOUNDBOX')
 

def register():
    bpy.utils.register_class(VIEW3D_OT_gizmo_translate)
    bpy.utils.register_class(VIEW3D_OT_gizmo_rotate)
    bpy.utils.register_class(VIEW3D_OT_gizmo_scale)
    bpy.utils.register_class(VIEW3D_OT_gizmo_select_box)
    bpy.utils.register_class(VIEW3D_MT_PIE_template)


def unregister():
    bpy.utils.unregister_class(VIEW3D_OT_gizmo_translate)
    bpy.utils.unregister_class(VIEW3D_OT_gizmo_rotate)
    bpy.utils.unregister_class(VIEW3D_OT_gizmo_scale)
    bpy.utils.unregister_class(VIEW3D_OT_gizmo_select_box)
    bpy.utils.unregister_class(VIEW3D_MT_PIE_template)


if __name__ == "__main__":
    register()
    bpy.ops.wm.call_menu_pie(name="VIEW3D_MT_PIE_template")

Thank you for that, I too have experienced the old “Post a question here then solve the problem yourself before anyone responds” syndrome. :rofl::rofl::rofl::rofl::rofl:

I have bookmarked this as I want to use it later in my own work.

Cheers, Clock.