Simplifying Blender UI from python addon, hiding SpaceProperty panels + other Spaces

HI,
I am the main developer of BlenderFDS Addon (http://www.blenderfds.org), I work as a fire officer.

We use Blender as a 3d modeler for fire simulation in civil buildings, we do not use other Blender features.
I need to simplify Blender UI and hide all the features that are not used and distract our unsavvy users.

  1. I would like to fully hide the following SpaceProperty contexts:
    ‘RENDER’, ‘RENDER_LAYER’, ‘BONE’, ‘BONE_CONSTRAINT’, ‘TEXTURE’, ‘PARTICLES’, ‘PHYSICS’

I succeded in hiding single panels, but, even empty, the context is still there.

For example:
bpy.utils.unregister_class(bpy.types.RENDERLAYER_PT_layer_passes)
bpy.utils.unregister_class(bpy.types.RENDERLAYER_PT_layers)
bpy.utils.unregister_class(bpy.types.RENDERLAYER_PT_layer_options)

The RENDERLAYER context is still there.

  1. I would like to fully hide the following currently unused Space/Editor types:
    ‘TIMELINE’, ‘GRAPH_EDITOR’, ‘DOPESHEET_EDITOR’, ‘NLA_EDITOR’, ‘IMAGE_EDITOR’, ‘SEQUENCE_EDITOR’, ‘CLIP_EDITOR’, ‘NODE_EDITOR’, ‘LOGIC_EDITOR’

I am sorry to add that modifing Blender source is out of question.
I do not want to fork Blender, I want to keep on releasing a pure Python Addon.

Thank you very much in advance for your precious help,
Emanuele

If you do not want any other Blender feature but you want to provide a highly customized user interface you can start modifying the core of the user interface itself.

For example in this directory there is everything you will need to know.
…\Blender\2.73\scripts\startup\bl_ui

One example would be to go this file space_view3d.py and make this change to disable context switching entirely.
row.template_header() at line 39

Then you can go to space_info.py, and make the changes accordingly to disable screen layout.

P.S. This message is edited.

Thank you Const for your quick reply.
Well, it’s template_header() that I should comment out.
mode_string has no effect and is already commented out.

I took a deep look at the bl_ui directory, as I checked what the guys from Fluid Designer did with that,
In fact I would better not to provide a highly customized interface, but just switch off some Property panels…

What about changing the items of context in line 34 of in space_properties.py?
row.prop(view, “context”, expand=True, icon_only=True)
Any idea?

Emanuele

You can modify the UI a great deal with Python script, but it’s NOT possible to do as addon (addons are in a subfolder of the scripts folder, UI is in a sibling directory).

You could do something like this for the properties header:

# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

# <pep8 compliant>
import bpy
from bpy.types import Header

ctx_items = bpy.types.SpaceProperties.bl_rna.properties['context'].enum_items
ctx_exclude = ('RENDER', 'RENDER_LAYER', 'BONE', 'BONE_CONSTRAINT', 'TEXTURE', 'PARTICLES', 'PHYSICS')

def ctx_items_cb(self, context):
    data_icon = "X"
    if context.object is not None:
        data_icon = context.object.type + "_DATA"
    return [(item.identifier, item.name, item.description, data_icon if item.icon == "NONE" else item.icon, item.value) for item in ctx_items if item.identifier not in ctx_exclude]

def ctx_update_cb(self, context):
    context.space_data.context = self.my_context

class PROPERTIES_HT_header(Header):
    bl_space_type = 'PROPERTIES'

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

        #view = context.space_data
        wm = context.window_manager

        row = layout.row()
        row.template_header()
        row.prop(wm, "my_context", expand=True, icon_only=True)


def register():
    bpy.types.WindowManager.my_context = bpy.props.EnumProperty(items=ctx_items_cb, update=ctx_update_cb)
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.WindowManager.my_context


if __name__ == "__main__":
    register()


But it won’t work that well, the data tab icon can’t be determined if scene or world are active, and entries won’t hide appropriately when using the pinning feature.

Oh, my… My brain won’t cooperate.
It’s this: row.template_header() at line 39

Thank you very much, this seems to work good enough for me.

I worked a little on your code and hardcoded the items


import bpy
from bpy.types import Header


ctx_items = (
    ('SCENE','Scene','Scene','SCENE_DATA',1),
    ('OBJECT','Object','Object','OBJECT_DATA',3),
    ('MATERIAL','Material','Material','MATERIAL',5),
    ('MODIFIER','Modifiers','Object modifiers','MODIFIER',10),
)


def ctx_items_cb(self, context):
    if context.object and context.object.type=='MESH':
        return ctx_items
    else:
        return ctx_items[0:2]


def ctx_update_cb(self, context):
    context.space_data.context = self.my_context


class PROPERTIES_HT_header(Header):
    bl_space_type = 'PROPERTIES'


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


        view = context.space_data
        wm = context.window_manager


        row = layout.row()
        row.prop(view, "type", icon_only=True) # Show fixed icon
        row.prop(wm, "my_context", expand=True, icon_only=True)


def register():
    bpy.types.WindowManager.my_context = bpy.props.EnumProperty(items=ctx_items_cb, update=ctx_update_cb)
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.WindowManager.my_context


if __name__ == "__main__":
    register()

Two questions left:

  1. I tried to set my_context in bpy.types.SpaceProperties instead of WindowManager. Why it does not work? readonly?
  2. What do you mean by: “entries won’t hide appropriately when using the pinning feature”?

Thank you all once more,
Emanuele

Sorry, i missed the word “not” in my post (not possible as addon).

  1. SpaceProperties is not an ID type, WindowManager is. Properties work on ID types and Bones only.

  2. Click the pin icon in the properties editor and compare the default behavior with my script, and you’ll see that some icons should go away, but they don’t.

Ok, now I understand. Thank you CoDEmanX, you are awesome and very dedicated to this forum.
Emanuele