refactor EnumPropHelper to improve BME again.
This commit is contained in:
@ -70,37 +70,51 @@ def add_into_scene_and_move_to_cursor(obj: bpy.types.Object):
|
||||
|
||||
class EnumPropHelper():
|
||||
"""
|
||||
These class contain all functions related to EnumProperty creation for Python Enums
|
||||
These class contain all functions related to EnumProperty, including generating `items`,
|
||||
parsing data from EnumProperty string value and getting EnumProperty acceptable string format from data.
|
||||
"""
|
||||
|
||||
# define some type hint
|
||||
|
||||
_TEnumVar = typing.TypeVar('_TEnumVar', bound = enum.Enum) ##< Mean a variable of enum.Enum's children
|
||||
_TEnum = type[_TEnumVar] ##< Mean the type self which is enum.Enum's children.
|
||||
_TFctName = typing.Callable[[_TEnumVar], str]
|
||||
_TFctDesc = typing.Callable[[_TEnumVar], str]
|
||||
_TFctIcon = typing.Callable[[_TEnumVar], str | int]
|
||||
_TFctToStr = typing.Callable[[typing.Any], str]
|
||||
_TFctFromStr = typing.Callable[[str], typing.Any]
|
||||
_TFctName = typing.Callable[[typing.Any], str]
|
||||
_TFctDesc = typing.Callable[[typing.Any], str]
|
||||
_TFctIcon = typing.Callable[[typing.Any], str | int]
|
||||
|
||||
# define class member
|
||||
|
||||
__mTy: _TEnum
|
||||
__mIsIntEnum: bool
|
||||
__mCollections: typing.Iterable[typing.Any]
|
||||
__mFctToStr: _TFctToStr
|
||||
__mFctFromStr: _TFctFromStr
|
||||
__mFctName: _TFctName
|
||||
__mFctDesc: _TFctDesc
|
||||
__mFctIcon: _TFctIcon
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
ty: _TEnum,
|
||||
collections_: typing.Iterable[typing.Any],
|
||||
fct_to_str: _TFctToStr,
|
||||
fct_from_str: _TFctFromStr,
|
||||
fct_name: _TFctName,
|
||||
fct_desc: _TFctDesc,
|
||||
fct_icon: _TFctIcon):
|
||||
# check type
|
||||
if not issubclass(ty, enum.Enum):
|
||||
raise BBPException('invalid type for EnumPropHelper')
|
||||
"""
|
||||
Initialize a EnumProperty helper.
|
||||
|
||||
@param collections_ [in] The collection all available enum property entries contained.
|
||||
It can be enum.Enum or a simple list/tuple/dict.
|
||||
@param fct_to_str [in] A function pointer converting data collection member to its string format.
|
||||
For enum.IntEnum, it can be simply `lambda x: str(x.value)`
|
||||
@param fct_from_str [in] A function pointer getting data collection member from its string format.
|
||||
For enum.IntEnum, it can be simply `lambda x: TEnum(int(x))`
|
||||
@param fct_name [in] A function pointer converting data collection member to its display name.
|
||||
@param fct_desc [in] Same as `fct_name` but return description instead. Return empty string, not None if no description.
|
||||
@param fct_icon [in] Same as `fct_name` but return the used icon instead. Return empty string if no icon.
|
||||
"""
|
||||
# assign member
|
||||
self.__mTy = ty
|
||||
self.__mIsIntEnum = issubclass(ty, enum.IntEnum)
|
||||
self.__mCollections = collections_
|
||||
self.__mFctToStr = fct_to_str
|
||||
self.__mFctFromStr = fct_from_str
|
||||
self.__mFctName = fct_name
|
||||
self.__mFctDesc = fct_desc
|
||||
self.__mFctIcon = fct_icon
|
||||
@ -111,50 +125,27 @@ class EnumPropHelper():
|
||||
"""
|
||||
# blender enum prop item format:
|
||||
# (token, display name, descriptions, icon, index)
|
||||
if self.__mIsIntEnum:
|
||||
# for intenum, we can use its value as index number directly.
|
||||
# and use the string format of index as blender prop token.
|
||||
return tuple(
|
||||
(
|
||||
str(member.value),
|
||||
self.__mFctName(member),
|
||||
self.__mFctDesc(member),
|
||||
self.__mFctIcon(member),
|
||||
member.value
|
||||
) for member in self.__mTy
|
||||
)
|
||||
else:
|
||||
# for non-intenum, we need create number index manually for it.
|
||||
# and directly use its value as blender prop token
|
||||
return tuple(
|
||||
(
|
||||
member.value,
|
||||
self.__mFctName(member),
|
||||
self.__mFctDesc(member),
|
||||
self.__mFctIcon(member),
|
||||
idx
|
||||
) for idx, member in enumerate(self.__mTy)
|
||||
)
|
||||
return tuple(
|
||||
(
|
||||
self.__mFctToStr(member), # call to_str as its token.
|
||||
self.__mFctName(member),
|
||||
self.__mFctDesc(member),
|
||||
self.__mFctIcon(member),
|
||||
idx # use hardcode index, not the collection member self.
|
||||
) for idx, member in enumerate(self.__mCollections)
|
||||
)
|
||||
|
||||
def get_selection(self, prop: str) -> _TEnumVar:
|
||||
def get_selection(self, prop: str) -> typing.Any:
|
||||
"""
|
||||
Return Python enum value from given Blender EnumProp.
|
||||
Return collection member from given Blender EnumProp string data.
|
||||
"""
|
||||
# for intenum, param is its string format, we need use int() to convert it first
|
||||
# for non-intenum, param is just its value, we use it directly
|
||||
# then we parse it to python enum type
|
||||
if self.__mIsIntEnum:
|
||||
return self.__mTy(int(prop))
|
||||
else:
|
||||
return self.__mTy(prop)
|
||||
# call from_str fct ptr
|
||||
return self.__mFctFromStr(prop)
|
||||
|
||||
def to_selection(self, val: _TEnumVar) -> str:
|
||||
def to_selection(self, val: typing.Any) -> str:
|
||||
"""
|
||||
Parse Python enum value to Blender EnumProp acceptable string.
|
||||
Parse collection member to Blender EnumProp acceptable string format.
|
||||
"""
|
||||
# the inversed operation of get_selection().
|
||||
if self.__mIsIntEnum:
|
||||
return str(val.value)
|
||||
else:
|
||||
return val.value
|
||||
# call to_str fct ptr
|
||||
return self.__mFctToStr(val)
|
||||
|
||||
|
Reference in New Issue
Block a user