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 ?
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.