UI: Reorganize "Transform" menu

"Transform" menu appears in Object Mode and edit modes, and there are
operators that work in both, and operators that work only in Object
mode, or only in edit modes.

Previously, those operators were mixed, and because of that, navigation
was more difficult. From users POV this was perceived as items jumping
around based on mode.

To avoid this create a clear separation. Have shared operators always
grouped at the top, followed by a separation and mode-specific
operators. This way item order stays the same always.

Images in the PR.

Pull Request: https://projects.blender.org/blender/blender/pulls/159331
This commit is contained in:
Nika Kutsniashvili 2026-05-30 13:29:25 +02:00 • committed by Nika Kutsniashvili
parent 95239df338
commit 78b81795c2

View file

@ -1269,14 +1269,32 @@ class VIEW3D_MT_transform_base:
layout.separator()
layout.operator("transform.tosphere", text="To Sphere")
if context.mode == 'EDIT_MESH':
layout.operator("mesh.circularize", text="To Circle")
layout.operator("mesh.flatten", text="Flatten")
layout.operator("mesh.space_edge_loops_evenly", text="Space Edge Loops Evenly")
layout.operator("transform.shear", text="Shear")
layout.operator("transform.bend", text="Bend")
layout.operator("transform.push_pull", text="Push/Pull")
layout.separator()
# Generic transform menu - geometry types
class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu):
def draw(self, context):
# base menu
VIEW3D_MT_transform_base.draw(self, context)
# generic...
layout = self.layout
if context.mode == 'EDIT_MESH':
layout.operator("mesh.circularize", text="To Circle")
layout.operator("mesh.flatten", text="Flatten")
layout.operator("transform.shrink_fatten", text="Shrink/Fatten")
layout.operator("mesh.space_edge_loops_evenly", text="Space Edge Loops Evenly")
layout.operator("transform.skin_resize")
elif context.mode in {'EDIT_CURVE', 'EDIT_GREASE_PENCIL', 'EDIT_CURVES', 'EDIT_POINTCLOUD'}:
layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
if context.mode == 'EDIT_GREASE_PENCIL':
layout.operator("transform.transform", text="Opacity").mode = 'GPENCIL_OPACITY'
if context.mode in {
'EDIT_MESH',
'EDIT_ARMATURE',
@ -1293,30 +1311,6 @@ class VIEW3D_MT_transform_base:
layout.operator_context = 'INVOKE_REGION_WIN'
# Generic transform menu - geometry types
class VIEW3D_MT_transform(VIEW3D_MT_transform_base, Menu):
def draw(self, context):
# base menu
VIEW3D_MT_transform_base.draw(self, context)
# generic...
layout = self.layout
if context.mode == 'EDIT_MESH':
layout.operator("transform.shrink_fatten", text="Shrink/Fatten")
layout.operator("transform.skin_resize")
elif context.mode in {'EDIT_CURVE', 'EDIT_GREASE_PENCIL', 'EDIT_CURVES', 'EDIT_POINTCLOUD'}:
layout.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
if context.mode == 'EDIT_GREASE_PENCIL':
layout.operator("transform.transform", text="Opacity").mode = 'GPENCIL_OPACITY'
if context.mode != 'EDIT_CURVES' and context.mode != 'EDIT_GREASE_PENCIL':
layout.separator()
props = layout.operator("transform.translate", text="Move Texture Space")
props.texture_space = True
props = layout.operator("transform.resize", text="Scale Texture Space")
props.texture_space = True
# Object-specific extensions to Transform menu
class VIEW3D_MT_transform_object(VIEW3D_MT_transform_base, Menu):
def draw(self, context):