Area type change via script not working

solved

(loscotec) #1

Hi!

I am creating a custom screen via script. I’ve managed to create a new screen duplicating the current one, reduce the areas to one and split this to create the areas I need. So far so good.

I have then tried to change the area types to my desired ones using the code :

bpy.data.screens['My screen'].areas[2].type = 'TIMELINE'

That works perfectly from the console.

This kind of works as the area type is effectively changed but the content of the area is not. in other words if was moving from an info area to a timeline, I would see the timeline icon as expected, but the content of the area would still be that of the info area.

This happens both in the 2.79 and in the current 2.80 !!!

Any idea on how to solve this?


(loscotec) #2

Found myself a way to solve this.

I’ve used a Modal operator.

Please find below a 2.79 working example.

It is very dirty the way I call the modal operator… timer and counter feels horrible, but I couldnt’t come up with any other solution which didn’t involve events requiring user input. If anyone knows of a better way, please tell me! :slight_smile:

import bpy
from bpy.props import IntProperty, FloatProperty


class ModalOperator(bpy.types.Operator):
    """Covnerts all areas of a given screen to graph editors"""
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    

    def modal(self, context, event):
        if event.type == 'TIMER':
            print("inside modal : ", bpy.context.screen, self.count)
            for area in bpy.context.screen.areas:
                area.type = 'GRAPH_EDITOR'
            self.count += 1
            if self.count < 1:
                return {'RUNNING_MODAL'}
            else:
                self.cancel(context)
                return {'FINISHED'}
        else:
            return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        print("\n#####\n")
        self.count = 0
        print(bpy.context.screen)
        bpy.context.window.screen = bpy.data.screens['Compositing']
        print(bpy.context.screen)
        wm = context.window_manager
        self._timer = wm.event_timer_add(0.1, context.window)
        wm.modal_handler_add(self)
        return {'RUNNING_MODAL'}
    
    def cancel(self, context):
        wm = context.window_manager
        wm.event_timer_remove(self._timer)


def register():
    bpy.utils.register_class(ModalOperator)
    
if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.modal_operator('INVOKE_DEFAULT')

Hope this will help you all.