1
$\begingroup$

I have a property that I'm trying to use to set the current context.area.type

Using the property as it is now, the set_space function crashes Blender. If I use the property with just an update function it works, but I need the property to also get updated when the context.area.type is changed in another manner by the user (using a get).

Can anyone please help me create this property so that its set method sets the current space? Thank you!

import bpy
from bpy.types import PropertyGroup
from bpy.props import EnumProperty

def set_space(self,value):
    if value == 0:
        bpy.context.area.type = "GRAPH_EDITOR"
    elif value == 1:
        bpy.context.area.type = "DOPESHEET_EDITOR"

class SWITCH_PG_switcher_props(PropertyGroup):
    space: EnumProperty(
        name="Space Target",
        description="Switch to space",
        items=(
            ('GRAPH_EDITOR', "", "Graph Editor", "GRAPH", 0),
            ('DOPESHEET_EDITOR', "", "Dopesheet Editor", "ACTION", 1),
        ),
        default='GRAPH_EDITOR',
        set = set_space
        )

def draw_enum(self, context):
    layout = self.layout
    scene = context.scene
    layout.prop(scene.switcher, "space", icon_only=True, expand=True)

def register():
    bpy.utils.register_class(SWITCH_PG_switcher_props)
    bpy.types.Scene.switcher = bpy.props.PointerProperty(type=SWITCH_PG_switcher_props)
    bpy.types.DOPESHEET_HT_header.append(draw_enum)
    bpy.types.GRAPH_HT_header.append(draw_enum)

def unregister():
    del bpy.types.Scene.switcher
    bpy.types.DOPESHEET_HT_header.remove(draw_enum)
    bpy.types.GRAPH_HT_header.remove(draw_enum)
    bpy.utils.unregister_class(SWITCH_PG_switcher_props)

if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ Side effects in property callback methods is AFAIK not really supported in Blender, so the crash is not really surprising, especially since it concerns the context which is needed for pretty much every element of the UI. In this case what you want to achieve should be done with an operator which are allowed to modify the data outside of their scope. $\endgroup$
    – Gorgious
    Commented Aug 20, 2022 at 18:00

1 Answer 1

1
$\begingroup$

I'll expand on my comment so it's more clear hopefully.

Side effects in property callback methods is AFAIK not really supported in Blender, so the crash is not really surprising, especially since it concerns the context which is needed for pretty much every element of the UI. What I mean is property callbacks are not meant to be used to modify the state of other properties, especially not of Blender internal constructs. In this case what you want to achieve should be done with an operator which are allowed to modify the data outside of their scope.

import bpy
from bpy.types import PropertyGroup


class SimpleOperator(bpy.types.Operator):
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"
    space: bpy.props.StringProperty()

    def execute(self, context):
        context.area.type = self.space
        return {'FINISHED'}

def draw_enum(self, context):
    layout = self.layout
    row = layout.row(align=True)
    for area_type, icon in zip (
        ("GRAPH_EDITOR", "DOPESHEET_EDITOR"), 
        ("GRAPH", "ACTION")):
            op = row.operator(
                "object.simple_operator", 
                text="", 
                icon=icon, 
                depress=context.area.type==area_type)
            op.space = area_type

def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.types.DOPESHEET_HT_header.append(draw_enum)
    bpy.types.GRAPH_HT_header.append(draw_enum)

def unregister():
    bpy.types.DOPESHEET_HT_header.remove(draw_enum)
    bpy.types.GRAPH_HT_header.remove(draw_enum)
    bpy.utils.unregister_class(SimpleOperator)

if __name__ == "__main__":
    register()

enter image description here

$\endgroup$
3
  • $\begingroup$ Hi Gorgious, thank you for the reply. I'd explored the method you're suggesting (thank you!), but opted for the other because it showed the active Space in the Header with a blue background. It sounds like it's acknowledged as a bug in Blender: developer.blender.org/T100519 For now I'm going with the method you mentioned, but hopeful that someone can explain how to work around this bug. Thank you, again, for your help! $\endgroup$ Commented Aug 20, 2022 at 19:45
  • $\begingroup$ @Dr.Pontchartrain you can indeed draw the buttons as pressed with the depress argument. I've updated the code in my answer :) $\endgroup$
    – Gorgious
    Commented Aug 21, 2022 at 7:24
  • $\begingroup$ very nice! Thank you so much :D $\endgroup$ Commented Aug 21, 2022 at 17:33

You must log in to answer this question.

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