1
$\begingroup$

I have two properties set in my Class:

o_color: FloatVectorProperty(name="Obj Color",subtype='COLOR',default=[0.0,0.0,0.0],set=set_o,update=set_o_color)
mode_o: EnumProperty(name="Mode", items=[("O1", "Randomize", ""),("O2", "Set", "")], default="O1",update=change_mode_o)

I want to set the color of o_color to a specific value when mode_o is switched to O2. In my head it was simple: when mode_o updates, I run the set function of o_color:

# update of EnumProperty
def change_mode_o(self, context):
    if self['mode_o'] == 1: # if switched to O2
        set_o(self, tuple(1, 0.5, 0)) # set o_color to (1, 0.5, 0)

# set of FloatVectorProperty
def set_o(self, value):
    self["o_color"] = value

in reality:

  • my color doesn't update. No errors, just nothing happens.
  • when I try to select color it only allows me to change Saturation. This seems to happen if FloatVectorProperty has set or get function passed:

enter image description here

What am I doing wrong?

$\endgroup$
14
  • $\begingroup$ Does it work if the color property is part of a panel? If so try add a def check(self, context): return True method to the operator. $\endgroup$
    – brockmann
    Mar 26, 2020 at 11:47
  • $\begingroup$ Perhaps you need to copy those attribute and assign them separately? Since the code you did is actually changing the pointer of the List (And you gave him a tuple... not sure it can work) $\endgroup$
    – HikariTW
    Mar 26, 2020 at 11:50
  • $\begingroup$ @brockmann haven't tried as a panel (never made them, seems like a lot of things to change... so maybe later) but adding the check function didn't do anything $\endgroup$ Mar 26, 2020 at 11:57
  • $\begingroup$ @HikariTW yes I've tried that, same result $\endgroup$ Mar 26, 2020 at 11:57
  • 1
    $\begingroup$ oh! setting it via self.o_color in update function of EnumProperty worked! (self['o_color'] didn't) $\endgroup$ Mar 26, 2020 at 13:17

1 Answer 1

2
$\begingroup$

Elaborate From brockmann comment and Blender API:

bpy.props.FloatVectorProperty(
min=sys.float_info.min, 
max=sys.float_info.max, 
soft_min=sys.float_info.min, 
soft_max=sys.float_info.max)
  • min (float) – Hard minimum, trying to assign a value below will silently assign this minimum instead.
  • max (float) – Hard maximum, trying to assign a value above will silently assign this maximum instead.
  • soft_min (float) – Soft minimum (>= min), user won’t be able to drag the widget below this value in the UI.
  • soft_max (float) – Soft maximum (<= max), user won’t be able to drag the widget above this value in the UI.

You need to set min = 0.0 and max=1.0 (or soft min/max) for the color subtype property. So it will look like this:

a_color : bpy.props.FloatVectorProperty(name='Color',subtype='COLOR_GAMMA',size=4,default=(0.5,0.5,0.9,1.0),min = 0.0, max = 1.0)

b_color : bpy.props.FloatVectorProperty(name='Color',subtype='COLOR',min = 0.0, max = 1.0)

It seems like color also support by light system. So the min max wasn't set by default, causing the silder getting a ridiculous range and break the panel


Operator based on this answer:

import bpy


class SimplePropConfirmOperator(bpy.types.Operator):
    """Really?"""
    bl_idname = "my_category.custom_confirm_dialog"
    bl_label = "Do you really want to do that?"
    bl_options = {'REGISTER', 'INTERNAL'}

    def update_func(self, context):
        #print("my test function", self)
        self.my_color = (0.5,0.5,0.9, 1.0) # Alpha

    my_enum : bpy.props.EnumProperty(
        items = (("RND", "Randomize", ""),("SET", "Set", "")),
        update = update_func)

    my_color : bpy.props.FloatVectorProperty(
        subtype='COLOR', 
        min=0.0, 
        max=1.0,
        size=4) # Alpha

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        self.report({'INFO'}, "YES!")
        return {'FINISHED'}

    '''
    def check(self, context): 
        return True
    '''

    def invoke(self, context, event):
        return context.window_manager.invoke_props_dialog(self)

    def draw(self, context):
        row = self.layout
        row.prop(self, "my_enum", text="Property A")
        if self.my_enum == "SET":
            row.prop(self, "my_color", text="Property B")


class OBJECT_PT_CustomPanel(bpy.types.Panel):
    bl_label = "My Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"

    def draw(self, context):
        layout = self.layout
        layout.operator(SimplePropConfirmOperator.bl_idname)

def register():
    bpy.utils.register_class(OBJECT_PT_CustomPanel)
    bpy.utils.register_class(SimplePropConfirmOperator)

def unregister():
    bpy.utils.unregister_class(SimplePropConfirmOperator)
    bpy.utils.unregister_class(OBJECT_PT_CustomPanel)

if __name__ == "__main__":
    register()
$\endgroup$
2
  • $\begingroup$ could you try to add a set function to it? that'd just print values. To see if the colorpicker gets locked $\endgroup$ Mar 26, 2020 at 12:50
  • $\begingroup$ @SergeyKritskiy Yeah, it's locked $\endgroup$
    – HikariTW
    Mar 26, 2020 at 13:12

You must log in to answer this question.

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