moving panels... possible or imposible

hi

I’m still learning python and I want to move panel between UI sections… for example:

I’m pull apart the code of diffuse material and slots:

the code is:

class MaterialPanelX(bpy.types.Panel):    bl_idname = "MATERIAL_PANELX"
    bl_label = "Material Presets"
    #bl_space_type = 'VIEW_3D'
    #bl_region_type = 'TOOLS'
    #bl_category = "z basic"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "material"


    bl_options = {'HIDE_HEADER'}
    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}


    @classmethod
    def poll(cls, context):
        # An exception, don't call the parent poll func because
        # this manages materials for all engine types


        engine = context.scene.render.engine
        return (context.material or context.object) and (engine in cls.COMPAT_ENGINES)


    def draw(self, context):
        layout = self.layout
        
        
        mat = context.material
        ob = context.object
        slot = context.material_slot
        space = context.space_data
#imagen previa material
        self.layout.template_preview(context.material)
        
#cajones de lista de materiales
        if ob:
            row = layout.row()
            row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1)
     
    #cambio de color dinamico   


        mat = active_node_mat(context.material)


        split = layout.split()


        col = split.column()
        col.prop(mat, "diffuse_color", text="color activo")
            

the idea is move that seccion for example:


I thought at this moment that was so simple that change this part of the code… but not!:

  bl_idname = "MATERIAL_PANELX"    bl_label = "Material Presets"
    #bl_space_type = 'VIEW_3D'
    #bl_region_type = 'TOOLS'
    #bl_category = "z basic"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "material"

some ideas?? or are impossible?

thanks for help

Diego

some required context members are missing - .material and .material_slot. They are available in the Properties Editor context, but not in 3D View. There’s a function context_pointer_set(), to point to a datablock, but it requires that the member already exists.

Thus, you can either rewrite the draw code to work without these context members, or money-patch in the context members and use the original draw functions, e.g.:

import bpy


class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel 2"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = 'Tools'

    def draw(self, context):
        layout = self.layout
        ob = context.object
        
        bpy.types.Context.material = ob.active_material
        try:
            idx = ob.material_slots[ob.active_material_index]
        except IndexError:
            idx = 0
        bpy.types.Context.material_slot = idx
        
        if bpy.types.MATERIAL_PT_context_material.poll(context):
            bpy.types.MATERIAL_PT_context_material.draw(self, context)
            
        layout.separator()
        layout.label("Preview")
        
        if bpy.types.MATERIAL_PT_preview.poll(context):
            bpy.types.MATERIAL_PT_preview.draw(self, context)

        layout.separator()
        layout.label("Diffuse")

        if bpy.types.MATERIAL_PT_diffuse.poll(context):
            bpy.types.MATERIAL_PT_diffuse.draw(self, context)

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


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


if __name__ == "__main__":
    register()


import bpy


class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_categoy = 'TOOLS'

    @classmethod
    def poll(cls, context):
        # An exception, don't call the parent poll func because
        # this manages materials for all engine types

        engine = context.scene.render.engine
        return (context.object is not None and
                #context.object.active_material is not None and
                engine in cls.COMPAT_ENGINES)

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

        ob = context.object
        mat = ob.active_material
        slot = ob.material_slots[ob.active_material_index]
        space = context.space_data

        if ob:
            row = layout.row()

            row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1)

            col = row.column(align=True)
            col.operator("object.material_slot_add", icon='ZOOMIN', text="")
            col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")

            col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")

            if ob.mode == 'EDIT':
                row = layout.row(align=True)
                row.operator("object.material_slot_assign", text="Assign")
                row.operator("object.material_slot_select", text="Select")
                row.operator("object.material_slot_deselect", text="Deselect")

        split = layout.split(percentage=0.65)

        if ob:
            split.template_ID(ob, "active_material", new="material.new")
            row = split.row()
            if mat:
                row.prop(mat, "use_nodes", icon='NODETREE', text="")

            if slot:
                row.prop(slot, "link", text="")
            else:
                row.label()
        elif mat:
            split.template_ID(space, "pin_id")
            split.separator()

        if mat:
            layout.prop(mat, "type", expand=True)
            if mat.use_nodes:
                row = layout.row()
                row.label(text="", icon='NODETREE')
                if mat.active_node_material:
                    row.prop(mat.active_node_material, "name", text="")
                else:
                    row.label(text="No material node selected")


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


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


if __name__ == "__main__":
    register()


Note that above code works with Blender Internal only.

really thanks @CoDEmanX thanks … sorry for last answere… I was so sick!.. now I’m going to study your code… thanks for that… Later I’m going to show you my advance :smiley:

thanks again

Diego

hi again

woooww!! this things are really amazing mr CoDEmanX!!!. After check that I made some good stuff

in the properties_material.py I add a new class with only the things and options that I use:

class MATERIAL_PT_Oridiffuse(MaterialButtonsPanel, Panel):    bl_label = "OriDiffuse"
    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}


    @classmethod
    def poll(cls, context):
        mat = context.material
        engine = context.scene.render.engine
        return check_material(mat) and (mat.type in {'SURFACE', 'WIRE'}) and (engine in cls.COMPAT_ENGINES)


    def draw(self, context):
        layout = self.layout
        #self.layout.template_preview(context.material)
        mat = active_node_mat(context.material)


        split = layout.split()


        col = split.column()
        col.prop(mat, "diffuse_color", text="")
        sub = col.column()
        
        col = split.column()
        col.prop(mat, "use_shadeless", text="sin sombra")
        sub = col.column()
        sub.active = not mat.use_shadeless
        
        layout = self.layout


        mat = context.material
        ob = context.object
        slot = context.material_slot
        space = context.space_data


        if ob:
            row = layout.row()


            row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=1)


            col = row.column(align=True)
            col.operator("object.material_slot_add", icon='ZOOMIN', text="")
            col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")

and then I add the new panel using similar (iqual :p) coDEmanX’s code:



class MaterialPanel(bpy.types.Panel):
    bl_idname = "OBJECT_PT_OriMaterial"
    bl_category = "Objetos"
    bl_label = "Material"
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"


    def draw(self, context):
        layout = self.layout
        ob = context.object
        
        bpy.types.Context.material = ob.active_material
        try:
            idx = ob.material_slots[ob.active_material_index]
        except IndexError:
            idx = 0
        bpy.types.Context.material_slot = idx
        
        
        layout.label("Color activo")


        if bpy.types.MATERIAL_PT_Oridiffuse.poll(context):
            bpy.types.MATERIAL_PT_Oridiffuse.draw(self, context)

I decided to create a new class in order to avoid damaging the original code and to provide what I need

Now, I will test this with new sections :smiley:

best regards

Diego