1
$\begingroup$

I have a custom enum property which defines the colour channels RGB, or RGBA depending on whether a flag in the addon preferences is enabled. Because the only way I could get this to work was to define the enum items dynamically using a function, I cannot set the default value of the enum. However, I'd really like to enable all the channels by default. Is there a way, and a sensible location in my addon's code that I can set the value of the enum after it has been registered and without requiring user interaction?

This is my EnumProperty:

active_channels = EnumProperty(
  name="Active Channels",
  options={'ENUM_FLAG'},
  items=channel_items,
  update=update_rgba,
  )

This is the function I'm using to populate it:

def channel_items(self, context):
  prefs = context.user_preferences.addons[__name__].preferences
  if prefs.alpha_support:
    return ((red_id, "R", ""), (green_id, "G", ""), (blue_id, "B", ""),(alpha_id, "A", ""))
  return ((red_id, "R", ""), (green_id, "G", ""), (blue_id, "B", ""))

Is there some way I can set the value of the enum in the addon's Panel code or on registration?

$\endgroup$
1
  • 1
    $\begingroup$ Do you mean that the addon should return the rgba enum by default, or do you want to set one of the channels, like 'g', by default? $\endgroup$
    – aliasguru
    Oct 21, 2017 at 6:26

1 Answer 1

2
$\begingroup$

Check if a bpy.prop property has been initialized by looking at its custom property "data store".

Have a look at the Getter / Setter examples for bpy.props. The ENUM_FLAG option enum property is saved internally as a custom property of the same name, an integer, calculated from each item having an "internal id" of a power of 2 (aka bitwise). 1, 2, 4, 8... The empty set set() 0, first only 1, first and second 1 | 2, and third 1 | 2 | 4 ...

As an example I've used the items method to show how to alter the data store (the custom property) only if it hasn't been already set. I've used a scene bool to emulate the addon prefs boolean.

import bpy
from bpy.props import BoolProperty, EnumProperty


def channel_items(self, context):
    prefs = context.scene    

    red_id, green_id, blue_id, alpha_id = (c for c in "rgba")
    items = [(red_id, "R", ""),
            (green_id, "G", ""), 
            (blue_id, "B", "")]
    if prefs.alpha_support:
        items.append((alpha_id, "A", ""))

    if not self.get("active_channels"):
        self["active_channels"] = 1 | 2 | 4 #rgb
        if prefs.alpha_support:
            self["active_channels"] |= 8

    return items

def update_rgba(self, context):
    print("enum set", self.active_channels, "int", self["active_channels"])
    return None

active_channels = EnumProperty(
    name="Active Channels",
    options={'ENUM_FLAG'},
    items=channel_items,
    update=update_rgba,
)
bpy.types.Scene.active_channels = active_channels
bpy.types.Scene.alpha_support = BoolProperty(default=False)

Note the above will give all for empty selection, as well as the custom property not being set. To check if bpy.prop is initialized would use

is_init = self.get("active_channels") is not None
$\endgroup$
2
  • $\begingroup$ Thanks for the answer, and sorry I didn't notice I left some irrelevant stuff in my question code snippets. I'll see if I can incorporate it into the add-on and I'll also try to make sure the code I have written adheres to the Blender coding guidelines. $\endgroup$
    – MrFlamey
    Oct 21, 2017 at 14:15
  • $\begingroup$ NP on both. I try to provide a minimal runable solution. Can't see why this wont work wired up in addon. Just remember you cant change properties in restricted context, like in a register method. Should be ok in items and definitely in setter and getter. $\endgroup$
    – batFINGER
    Oct 21, 2017 at 14:31

You must log in to answer this question.

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