Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change Operator's label in Blender 2.63 depending on the context?

I'm writing an exporter for a game my friend and I are making and it involves setting custom properties and tags to objects which are then recognized in the game and dealt with accordingly. Our engine, which is written in C/C++ has been successfully tested with my current version of the export script, and I''m currently working on tidying it up.

The script uses Blender's feature of custom properties to write custom tags to output file. The model typically consists of multiple 'parts' (Blender mesh objects that are parented to form a tree, with one 'parent' and multiple 'child' objects) and some of those parts are simple Blender Empty objects (for only it's X, Y and Z coordinates are needed) with custom properties that mark where things like ship's propulsion (it's a 3D shooter) are placed, or where the flames/explosions appear when ship's been shot. Those empty parts are also parented to either 'root' object or any of it's children. So far it's been working good, I have written a generic Operator class and some extended classes that reside in a panel which set part's properties (pretty handy since you don't have to add those custom properties by hand).

Now I want to speed thing up even more, that is to be able to simply click on an operator of desired type, and it should automatically add it to the scene and parent it to the active/selected object. I know how to do that, but I can't get those operators to change their labels. Basically, what I want is to operator to say 'Bullet point' when an existing empty is selected (I've got that part done), and when there's a mesh object selected to say 'Add bullet point'. So I just need a way to dynamically change operators' labels depending on the context (as the title of the question states clearly :))

This is what I got so far:

class OBJECT_OT_tg_generic (bpy.types.Operator):
    bl_label        =   "Sets Generic Part Type"
    bl_idname       =   "rbm.set_generic_part_type"

    OB_TYPE         =   None

    @classmethod
    def poll (cls, context):
        act = context.active_object
        if 'Type' in act.keys ():
            if act['Type'] == cls.OB_TYPE:
                cls.bl_label = 'foo'
                print (cls.bl_label)
                # this prints foo but doesn't change the label
                return False
        return True

    def execute (self, context):
        # TODO: add code to automatically place empties and parent them to active object
        bpy.context.active_object['Type'] = self.OB_TYPE
        return{"FINISHED"}

And an example of a subclass:

class OBJECT_OT_tg_bullet_point (OBJECT_OT_tg_generic):
    bl_label        =   "Bullet Point"
    bl_idname       =   "rbm.set_bullet_point"

    OB_TYPE         =   OT_BULLET_POINT

Here's how it looks in Blender: https://i.sstatic.net/6OJ4R.png

like image 844
Vladimir Mitrovic Avatar asked Jan 27 '26 08:01

Vladimir Mitrovic


1 Answers

Guess I solved it. When you're adding an operator to a panel, you can do something like this:

def draw (self, context):
    layout = self.layout
    row = layout.row()
    row.operator("foo.bar", text="Whatever you want")

and the "Whatever you want" is going to be your button's label. But what I did was something else. I didn't change the operators' labels, but instead gave them a different icons depending on whether it's a mesh or an empty currently selected/active:

def draw (self, context):
    # (...) we're skipping some code here, obviously
    act = context.active_object
    if act.type == 'MESH':
        op_icon = 'ZOOMIN'
    else:
        op_icon = 'EMPTY_DATA'

    row = layout.column(align=True)
    row.operator('rbm.set_bullet_point', icon=op_icon)
    row.operator('rbm.set_rocket_point', icon=op_icon)
    # (...) rest of the code
like image 163
Vladimir Mitrovic Avatar answered Jan 29 '26 22:01

Vladimir Mitrovic