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
    $\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 '17 at 6:26
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$
  • $\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 '17 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 '17 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.