1
$\begingroup$

I only found a similar question that does not answer mine((Python) How to add items in context menu in 2.8?).

I have this code that adds a menu to the right click context menu when you are in edit mode:

import bpy

class VIEW3D_MT_edit_mesh_context_menu(bpy.types.Menu):
    bl_label = ''

    # Leave empty for compatibility.
    def draw(self, context):
        pass

def draw(self, context):
    layout = self.layout
    layout.separator()
    layout.operator('mesh.flip_normals', text = 'Flip Normals')

if __name__ == '__main__':
    # Register menu only if it doesn't already exist.
    rcmenu = getattr(bpy.types, "VIEW3D_MT_edit_mesh_context_menu", None)
    if rcmenu is None:
        bpy.utils.register_class(VIEW3D_MT_edit_mesh_context_menu)
        rcmenu = VIEW3D_MT_edit_mesh_context_menu

    # Retrieve a python list for inserting draw functions.
    draw_funcs = rcmenu._dyn_ui_initialize()
    draw_funcs.append(draw)

The problem is that the menu is added to the Vertex, Edge and Face Context Menus, but I want it only in the Face Context Menu. How can I restrict that?

$\endgroup$
2
  • 2
    $\begingroup$ See space_view3d.py line 3807. A simple condition does the trick: if is_face_mode: ..., the flag is based on the tool settings and comes from: is_vert_mode, is_edge_mode, is_face_mode = context.tool_settings.mesh_select_mode. $\endgroup$
    – brockmann
    Aug 24, 2021 at 9:36
  • 1
    $\begingroup$ @brockmann sure I've answered soemthing similar before, shrugs spent enough time looking. $\endgroup$
    – batFINGER
    Aug 24, 2021 at 9:48

2 Answers 2

4
$\begingroup$

Use a conditional to draw.

Suggest check if the menu has a module

>>> bpy.types.VIEW3D_MT_edit_mesh_context_menu.__module__
'bl_ui.space_view3d'

and if so

>>> from bl_ui.space_view3d import VIEW3D_MT_edit_mesh_context_menu

another way check if it's registered

>>> VIEW3D_MT_edit_mesh_context_menu.is_registered
True

One of my faves is using draw_funcs. Since usage as above is the equivalent of

VIEW3D_MT_edit_mesh_context_menu.append(draw)

wouldn't bother. _or create your own class methods to manipulate the list, ie could append remove different methods in poll.

Finally to pinch @brockmann's comment above as it saves me typing same

See space_view3d.py line 3807. A simple condition does the trick: if is_face_mode: ..., the flag is based on the tool settings and comes from: is_vert_mode, is_edge_mode, is_face_mode = context.tool_settings.mesh_select_mode.

$\endgroup$
0
$\begingroup$

This aligns with what others have said mostly, but I thought I would give a concrete example of how I did it. I needed a vertex menu instead of the Face menu, but it is simple to change.

I made two menus. They are identical except for the names and that one has a test for checking if we are in Vertex mode.

This is for the normal Vertex top bar menu:

def menu_func(self, context):
 self.layout.separator(factor=1.0)
 self.layout.operator(VertAlign.bl_idname)

This is for the Right-click vertex context menu setup. The "if" statement checks to see if we are in vertex mode, if true, then the menu gets added to the bottom of the vertex context menu (right-click menu). If this wasn't here, the menu would be added to All Edit Mode right-click context menus. The [0] refers to Vertex mode; [1] is Edge mode, [2] is Face mode.

def menu_vert(self, context):
 if bpy.context.tool_settings.mesh_select_mode[0]: 
    self.layout.separator(factor=1.0)
    self.layout.operator(VertAlign.bl_idname)

Then, you just register those like always:

def register():
 bpy.utils.register_class(VertAlign) 
 bpy.types.VIEW3D_MT_edit_mesh_vertices.append(menu_func) # for top menu  
 bpy.types.VIEW3D_MT_edit_mesh_context_menu.append(menu_vert) # for context menu
$\endgroup$

You must log in to answer this question.

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