custom menu for views

Hi,

I would like to make a custom menu for changing views in blender.

I already have made a custom menu, but for this one, I d’ont find the good python code to use.


Somenone can help me plz ?

import bpy

areas = {t.identifier: (t.name, t.icon) for t in bpy.types.Area.bl_rna.properties['type'].enum_items}

class SimpleCustomMenu(bpy.types.Menu):
    bl_label = "Simple Custom Menu"
    bl_idname = "OBJECT_MT_simple_custom_menu"

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

        for identifier in ('VIEW_3D', 'NODE_EDITOR', 'IMAGE_EDITOR', 'CLIP_EDITOR', 'SEQUENCE_EDITOR'):
            name, icon = areas[identifier]
            props = layout.operator("wm.context_set_enum", text=name, icon=icon)
            props.data_path = "area.type"
            props.value = identifier
            
        layout.separator()
        layout.operator("screen.area_split", text="Split Vertical", icon='PAUSE').direction = 'VERTICAL'
        layout.operator("screen.area_split", text="Split Horizontal", icon='GRIP').direction = 'HORIZONTAL'
        layout.operator("screen.screen_full_area", text="Maximize Area", icon='FULLSCREEN_ENTER')


def register():
    bpy.utils.register_class(SimpleCustomMenu)


def unregister():
    bpy.utils.unregister_class(SimpleCustomMenu)

if __name__ == "__main__":
    register()

    # The menu can also be called from scripts
    bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)

There is no concept of closing an area, you can only join two. But I highly discourage doing that any way, the result would be either random (up to 4 candidates for joining) or even crash Blender - the operators don’t work well when used with python, looks like there are missing update calls and timing issues… Here’s some experimental code, if you decrease the modal timer interval, it will tend to crash:

import bpy

target_area = 'VIEW_3D'

class ModalTimerOperator(bpy.types.Operator):
    """Operator which runs its self from a timer"""
    bl_idname = "wm.modal_timer_operator"
    bl_label = "Modal Timer Operator"

    _timer = None

    def modal(self, context, event):
        if event.type == 'ESC':
            return self.cancel(context)

        if event.type == 'TIMER':
            s = bpy.context.screen
            bpy.context.window.screen = bpy.data.screens[0]
            bpy.context.window.screen = s
            if self.area_count > 1:
                print('TIMER')
                for i, area1 in enumerate(bpy.context.screen.areas):
                    area1.type = target_area
                    for j, area2 in enumerate(bpy.context.screen.areas):
                        if area1 == area2: continue
                        print(area1.type, i, j, area2.type)
                        if (area1.x == area2.x and area1.width == area2.width) or \
                           (area1.y == area2.y and area1.height == area2.height):
                            print(area1.x, area2.x, area1.y, area2.y)
                            ret = bpy.ops.screen.area_join(min_x=area1.x, min_y=area1.y, max_x=area2.x, max_y=area2.y)
                            print(ret)

                            #bpy.ops.screen.screen_full_area()
                            #bpy.ops.screen.back_to_previous()
                            if ret == {'FINISHED'}:
                                self.area_count -= 1
                            print(self.area_count)
                            break
            else:
                context.area.type == 'VIEW_3D'
                print(context.area.type)
                return self.cancel(context)
            
        return {'RUNNING_MODAL'}

    def execute(self, context):
        self.area_count = len(context.screen.areas)
        self._timer = context.window_manager.event_timer_add(0.1, context.window)
        context.window_manager.modal_handler_add(self)
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        return {'CANCELLED'}


def register():
    bpy.utils.register_class(ModalTimerOperator)


def unregister():
    bpy.utils.unregister_class(ModalTimerOperator)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.wm.modal_timer_operator()


Thank you for your help ! )

I’m trying using your code with only the view for starting.