refactor: use generic type in EnumPropHelper
- use typing.Generic in EnumPropHelper and its child classes. - change Doxygen docstring into reStructedText docstring.
This commit is contained in:
@ -572,13 +572,13 @@ _g_Helper_MtlPreset: UTIL_functions.EnumPropHelper = UTIL_functions.EnumPropHelp
|
|||||||
#region Fix Material
|
#region Fix Material
|
||||||
|
|
||||||
def fix_material(mtl: bpy.types.Material) -> bool:
|
def fix_material(mtl: bpy.types.Material) -> bool:
|
||||||
"""!
|
"""
|
||||||
Fix single Blender material.
|
Fix single Blender material.
|
||||||
|
|
||||||
@remark The implementation of this function is copied from BallanceVirtoolsHelper/bvh/features/mapping/bmfile_fix_texture.cpp
|
The implementation of this function is copied from `BallanceVirtoolsHelper/bvh/features/mapping/bmfile_fix_texture.cpp`
|
||||||
|
|
||||||
@param mtl[in] The blender material need to be processed.
|
:param mtl: The blender material need to be processed.
|
||||||
@return True if we do a fix, otherwise return False.
|
:return: True if we do a fix, otherwise return False.
|
||||||
"""
|
"""
|
||||||
# prepare return value first
|
# prepare return value first
|
||||||
ret: bool = False
|
ret: bool = False
|
||||||
|
@ -64,12 +64,10 @@ def set_raw_virtools_texture(img: bpy.types.Image, rawdata: RawVirtoolsTexture)
|
|||||||
|
|
||||||
#region Virtools Texture Drawer
|
#region Virtools Texture Drawer
|
||||||
|
|
||||||
"""!
|
# YYC MARK:
|
||||||
@remark
|
# Because Image do not have its unique properties window,
|
||||||
Because Image do not have its unique properties window
|
# so we only can draw Virtools Texture properties in other window.
|
||||||
so we only can draw virtools texture properties in other window
|
# We provide various functions to help draw properties.
|
||||||
we provide various function to help draw property.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def draw_virtools_texture(img: bpy.types.Image, layout: bpy.types.UILayout):
|
def draw_virtools_texture(img: bpy.types.Image, layout: bpy.types.UILayout):
|
||||||
props: BBP_PG_virtools_texture = get_virtools_texture(img)
|
props: BBP_PG_virtools_texture = get_virtools_texture(img)
|
||||||
|
@ -187,15 +187,14 @@ class PrototypeShowcaseCfgDescriptor():
|
|||||||
def get_default(self) -> typing.Any:
|
def get_default(self) -> typing.Any:
|
||||||
return _eval_showcase_cfgs_default(self.__mRawCfg[TOKEN_SHOWCASE_CFGS_DEFAULT])
|
return _eval_showcase_cfgs_default(self.__mRawCfg[TOKEN_SHOWCASE_CFGS_DEFAULT])
|
||||||
|
|
||||||
class EnumPropHelper(UTIL_functions.EnumPropHelper):
|
class EnumPropHelper(UTIL_functions.EnumPropHelper[str]):
|
||||||
"""
|
"""
|
||||||
The BME specialized Blender EnumProperty helper.
|
The BME specialized Blender EnumProperty helper.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# init parent class
|
# init parent class
|
||||||
UTIL_functions.EnumPropHelper.__init__(
|
super().__init__(
|
||||||
self,
|
|
||||||
self.get_bme_identifiers(),
|
self.get_bme_identifiers(),
|
||||||
lambda x: x,
|
lambda x: x,
|
||||||
lambda x: x,
|
lambda x: x,
|
||||||
|
@ -2,19 +2,17 @@ import bpy, mathutils
|
|||||||
import math, typing, enum, sys
|
import math, typing, enum, sys
|
||||||
|
|
||||||
class BBPException(Exception):
|
class BBPException(Exception):
|
||||||
"""
|
""" The exception thrown by Ballance Blender Plugin"""
|
||||||
The exception thrown by Ballance Blender Plugin
|
|
||||||
"""
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def clamp_float(v: float, min_val: float, max_val: float) -> float:
|
def clamp_float(v: float, min_val: float, max_val: float) -> float:
|
||||||
"""!
|
"""
|
||||||
@brief Clamp a float value
|
Clamp a float value
|
||||||
|
|
||||||
@param v[in] The value need to be clamp.
|
:param v: The value need to be clamp.
|
||||||
@param min_val[in] The allowed minium value, including self.
|
:param min_val: The allowed minium value (inclusive).
|
||||||
@param max_val[in] The allowed maxium value, including self.
|
:param max_val: The allowed maxium value (inclusive).
|
||||||
@return Clamped value.
|
:return: Clamped value.
|
||||||
"""
|
"""
|
||||||
if (max_val < min_val): raise BBPException("Invalid range of clamp_float().")
|
if (max_val < min_val): raise BBPException("Invalid range of clamp_float().")
|
||||||
|
|
||||||
@ -23,13 +21,13 @@ def clamp_float(v: float, min_val: float, max_val: float) -> float:
|
|||||||
else: return v
|
else: return v
|
||||||
|
|
||||||
def clamp_int(v: int, min_val: int, max_val: int) -> int:
|
def clamp_int(v: int, min_val: int, max_val: int) -> int:
|
||||||
"""!
|
"""
|
||||||
@brief Clamp a int value
|
Clamp a int value
|
||||||
|
|
||||||
@param v[in] The value need to be clamp.
|
:param v: The value need to be clamp.
|
||||||
@param min_val[in] The allowed minium value, including self.
|
:param min_val: The allowed minium value (inclusive).
|
||||||
@param max_val[in] The allowed maxium value, including self.
|
:param max_val: The allowed maxium value (inclusive).
|
||||||
@return Clamped value.
|
:return: Clamped value.
|
||||||
"""
|
"""
|
||||||
if (max_val < min_val): raise BBPException("Invalid range of clamp_int().")
|
if (max_val < min_val): raise BBPException("Invalid range of clamp_int().")
|
||||||
|
|
||||||
@ -41,9 +39,9 @@ def message_box(message: tuple[str, ...], title: str, icon: str):
|
|||||||
"""
|
"""
|
||||||
Show a message box in Blender. Non-block mode.
|
Show a message box in Blender. Non-block mode.
|
||||||
|
|
||||||
@param message[in] The text this message box displayed. Each item in this param will show as a single line.
|
:param message: The text this message box displayed. Each item in this param will show as a single line.
|
||||||
@param title[in] Message box title text.
|
:param title: Message box title text.
|
||||||
@param icon[in] The icon this message box displayed.
|
:param icon: The icon this message box displayed.
|
||||||
"""
|
"""
|
||||||
def draw(self, context: bpy.types.Context):
|
def draw(self, context: bpy.types.Context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@ -53,24 +51,48 @@ def message_box(message: tuple[str, ...], title: str, icon: str):
|
|||||||
bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)
|
bpy.context.window_manager.popup_menu(draw, title = title, icon = icon)
|
||||||
|
|
||||||
def add_into_scene(obj: bpy.types.Object):
|
def add_into_scene(obj: bpy.types.Object):
|
||||||
|
"""
|
||||||
|
Add given object into active scene.
|
||||||
|
|
||||||
|
:param obj: The 3d object to be added.
|
||||||
|
"""
|
||||||
view_layer = bpy.context.view_layer
|
view_layer = bpy.context.view_layer
|
||||||
collection = view_layer.active_layer_collection.collection
|
collection = view_layer.active_layer_collection.collection
|
||||||
collection.objects.link(obj)
|
collection.objects.link(obj)
|
||||||
|
|
||||||
def move_to_cursor(obj: bpy.types.Object):
|
def move_to_cursor(obj: bpy.types.Object):
|
||||||
# use obj.matrix_world to move, not obj.location because this bug:
|
"""
|
||||||
|
Move given object to the position of cursor.
|
||||||
|
|
||||||
|
:param obj: The 3d object to be moved.
|
||||||
|
"""
|
||||||
|
# YYC MARK:
|
||||||
|
# Use `obj.matrix_world` to move, not `obj.location`, because this bug:
|
||||||
# https://blender.stackexchange.com/questions/27667/incorrect-matrix-world-after-transformation
|
# https://blender.stackexchange.com/questions/27667/incorrect-matrix-world-after-transformation
|
||||||
# the update of matrix_world after setting location is not immediately.
|
# The update of `matrix_world` after setting `location` is not immediately.
|
||||||
# and calling update() function for view_layer for the translation of each object is not suit for too much objects.
|
# And it is inviable that calling `update()` function for `view_layer` to update these fields,
|
||||||
|
# because it involve too much objects and cost too much time.
|
||||||
|
|
||||||
# obj.location = bpy.context.scene.cursor.location
|
# obj.location = bpy.context.scene.cursor.location
|
||||||
obj.matrix_world = obj.matrix_world @ mathutils.Matrix.Translation(bpy.context.scene.cursor.location - obj.location)
|
obj.matrix_world = obj.matrix_world @ mathutils.Matrix.Translation(bpy.context.scene.cursor.location - obj.location)
|
||||||
|
|
||||||
def add_into_scene_and_move_to_cursor(obj: bpy.types.Object):
|
def add_into_scene_and_move_to_cursor(obj: bpy.types.Object):
|
||||||
|
"""
|
||||||
|
Add given object into active scene and move it to cursor position.
|
||||||
|
|
||||||
|
This function is just a simple combination of previous functions.
|
||||||
|
|
||||||
|
:param obj: The 3d object to be processed.
|
||||||
|
"""
|
||||||
add_into_scene(obj)
|
add_into_scene(obj)
|
||||||
move_to_cursor(obj)
|
move_to_cursor(obj)
|
||||||
|
|
||||||
def select_certain_objects(objs: tuple[bpy.types.Object, ...]) -> None:
|
def select_certain_objects(objs: tuple[bpy.types.Object, ...]) -> None:
|
||||||
|
"""
|
||||||
|
Deselect all objects and then select given 3d objects.
|
||||||
|
|
||||||
|
:param objs: The tuple of 3d objects to be selected.
|
||||||
|
"""
|
||||||
# deselect all objects first
|
# deselect all objects first
|
||||||
bpy.ops.object.select_all(action = 'DESELECT')
|
bpy.ops.object.select_all(action = 'DESELECT')
|
||||||
# if no objects, return
|
# if no objects, return
|
||||||
@ -83,6 +105,11 @@ def select_certain_objects(objs: tuple[bpy.types.Object, ...]) -> None:
|
|||||||
bpy.context.view_layer.objects.active = objs[0]
|
bpy.context.view_layer.objects.active = objs[0]
|
||||||
|
|
||||||
def is_in_object_mode() -> bool:
|
def is_in_object_mode() -> bool:
|
||||||
|
"""
|
||||||
|
Check whether we are in Blender Object Mode.
|
||||||
|
|
||||||
|
:return: True if we are in object mode which suit for exporting something.
|
||||||
|
"""
|
||||||
# get active object from context
|
# get active object from context
|
||||||
obj = bpy.context.active_object
|
obj = bpy.context.active_object
|
||||||
|
|
||||||
@ -92,51 +119,53 @@ def is_in_object_mode() -> bool:
|
|||||||
# simply check active object mode
|
# simply check active object mode
|
||||||
return obj.mode == 'OBJECT'
|
return obj.mode == 'OBJECT'
|
||||||
|
|
||||||
class EnumPropHelper():
|
#region Blender Enum Property Helper
|
||||||
|
|
||||||
|
_TRawEnum = typing.TypeVar('_TRawEnum')
|
||||||
|
|
||||||
|
_TFctToStr = typing.Callable[[_TRawEnum], str]
|
||||||
|
_TFctFromStr = typing.Callable[[str], _TRawEnum]
|
||||||
|
_TFctName = typing.Callable[[_TRawEnum], str]
|
||||||
|
_TFctDesc = typing.Callable[[_TRawEnum], str]
|
||||||
|
_TFctIcon = typing.Callable[[_TRawEnum], str | int]
|
||||||
|
|
||||||
|
class EnumPropHelper(typing.Generic[_TRawEnum]):
|
||||||
"""
|
"""
|
||||||
These class contain all functions related to EnumProperty, including generating `items`,
|
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.
|
parsing data from EnumProperty string value and getting EnumProperty acceptable string format from data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# define some type hint
|
__mCollections: typing.Iterable[_TRawEnum]
|
||||||
_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
|
|
||||||
|
|
||||||
__mCollections: typing.Iterable[typing.Any]
|
|
||||||
__mFctToStr: _TFctToStr
|
__mFctToStr: _TFctToStr
|
||||||
__mFctFromStr: _TFctFromStr
|
__mFctFromStr: _TFctFromStr
|
||||||
__mFctName: _TFctName
|
__mFctName: _TFctName
|
||||||
__mFctDesc: _TFctDesc
|
__mFctDesc: _TFctDesc
|
||||||
__mFctIcon: _TFctIcon
|
__mFctIcon: _TFctIcon
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, collections: typing.Iterable[typing.Any],
|
||||||
self,
|
fct_to_str: _TFctToStr, fct_from_str: _TFctFromStr,
|
||||||
collections_: typing.Iterable[typing.Any],
|
fct_name: _TFctName, fct_desc: _TFctDesc,
|
||||||
fct_to_str: _TFctToStr,
|
fct_icon: _TFctIcon):
|
||||||
fct_from_str: _TFctFromStr,
|
|
||||||
fct_name: _TFctName,
|
|
||||||
fct_desc: _TFctDesc,
|
|
||||||
fct_icon: _TFctIcon):
|
|
||||||
"""
|
"""
|
||||||
Initialize a EnumProperty helper.
|
Initialize an EnumProperty helper.
|
||||||
|
|
||||||
@param collections_ [in] The collection all available enum property entries contained.
|
:param collections: The collection containing all available enum property entries.
|
||||||
It can be enum.Enum or a simple list/tuple/dict.
|
It can be `enum.Enum` or a simple list/tuple.
|
||||||
@param fct_to_str [in] A function pointer converting data collection member to its string format.
|
:param fct_to_str: A function pointer converting data collection member to its string format.
|
||||||
For enum.IntEnum, it can be simply `lambda x: str(x.value)`
|
You must make sure that each members built name is unique in collection!
|
||||||
@param fct_from_str [in] A function pointer getting data collection member from its string format.
|
For `enum.IntEnum`, it can be simple `lambda x: str(x.value)`
|
||||||
For enum.IntEnum, it can be simply `lambda x: TEnum(int(x))`
|
:param fct_from_str: A function pointer getting data collection member from its string format.
|
||||||
@param fct_name [in] A function pointer converting data collection member to its display name.
|
This class promise that given string must can be parsed.
|
||||||
@param fct_desc [in] Same as `fct_name` but return description instead. Return empty string, not None if no description.
|
For `enum.IntEnum`, it can be simple `lambda x: TEnum(int(x))`
|
||||||
@param fct_icon [in] Same as `fct_name` but return the used icon instead. Return empty string if no icon.
|
:param fct_name: A function pointer converting data collection member to its display name which shown in Blender.
|
||||||
|
:param fct_desc: Same as `fct_name` but return description instead which shown in Blender
|
||||||
|
If no description, return empty string, not None.
|
||||||
|
:param fct_icon: Same as `fct_name` but return the used icon instead which shown in Blender.
|
||||||
|
It can be a Blender builtin icon string, or any loaded icon integer ID.
|
||||||
|
If no icon, return empty string.
|
||||||
"""
|
"""
|
||||||
# assign member
|
# assign member
|
||||||
self.__mCollections = collections_
|
self.__mCollections = collections
|
||||||
self.__mFctToStr = fct_to_str
|
self.__mFctToStr = fct_to_str
|
||||||
self.__mFctFromStr = fct_from_str
|
self.__mFctFromStr = fct_from_str
|
||||||
self.__mFctName = fct_name
|
self.__mFctName = fct_name
|
||||||
@ -159,20 +188,22 @@ class EnumPropHelper():
|
|||||||
) for idx, member in enumerate(self.__mCollections)
|
) for idx, member in enumerate(self.__mCollections)
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_selection(self, prop: str) -> typing.Any:
|
def get_selection(self, prop: str) -> _TRawEnum:
|
||||||
"""
|
"""
|
||||||
Return collection member from given Blender EnumProp string data.
|
Return collection member from given Blender EnumProp string data.
|
||||||
"""
|
"""
|
||||||
# call from_str fct ptr
|
# call from_str fct ptr
|
||||||
return self.__mFctFromStr(prop)
|
return self.__mFctFromStr(prop)
|
||||||
|
|
||||||
def to_selection(self, val: typing.Any) -> str:
|
def to_selection(self, val: _TRawEnum) -> str:
|
||||||
"""
|
"""
|
||||||
Parse collection member to Blender EnumProp acceptable string format.
|
Parse collection member to Blender EnumProp acceptable string format.
|
||||||
"""
|
"""
|
||||||
# call to_str fct ptr
|
# call to_str fct ptr
|
||||||
return self.__mFctToStr(val)
|
return self.__mFctToStr(val)
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Blender Collection Visitor
|
#region Blender Collection Visitor
|
||||||
|
|
||||||
_TPropertyGroup = typing.TypeVar('_TPropertyGroup', bound = bpy.types.PropertyGroup)
|
_TPropertyGroup = typing.TypeVar('_TPropertyGroup', bound = bpy.types.PropertyGroup)
|
||||||
@ -190,30 +221,33 @@ class CollectionVisitor(typing.Generic[_TPropertyGroup]):
|
|||||||
self.__mSrcProp = src_prop
|
self.__mSrcProp = src_prop
|
||||||
|
|
||||||
def add(self) -> _TPropertyGroup:
|
def add(self) -> _TPropertyGroup:
|
||||||
"""!
|
"""
|
||||||
@brief Adds a new item to the collection.
|
Adds a new item to the collection.
|
||||||
@return The instance of newly created item.
|
|
||||||
|
:return: The instance of newly created item.
|
||||||
"""
|
"""
|
||||||
return self.__mSrcProp.add()
|
return self.__mSrcProp.add()
|
||||||
|
|
||||||
def remove(self, index: int) -> None:
|
def remove(self, index: int) -> None:
|
||||||
"""!
|
"""
|
||||||
@brief Removes the item at the specified index from the collection.
|
Removes the item at the specified index from the collection.
|
||||||
@param[in] index The index of the item to remove.
|
|
||||||
|
:param index: The index of the item to remove.
|
||||||
"""
|
"""
|
||||||
self.__mSrcProp.remove(index)
|
self.__mSrcProp.remove(index)
|
||||||
|
|
||||||
def move(self, from_index: int, to_index: int) -> None:
|
def move(self, from_index: int, to_index: int) -> None:
|
||||||
"""!
|
"""
|
||||||
@brief Moves an item from one index to another within the collection.
|
Moves an item from one index to another within the collection.
|
||||||
@param[in] from_index The current index of the item to move.
|
|
||||||
@param[in] to_index The target index where the item should be moved.
|
:param from_index: The current index of the item to move.
|
||||||
|
:param to_index: The target index where the item should be moved.
|
||||||
"""
|
"""
|
||||||
self.__mSrcProp.move(from_index, to_index)
|
self.__mSrcProp.move(from_index, to_index)
|
||||||
|
|
||||||
def clear(self) -> None:
|
def clear(self) -> None:
|
||||||
"""!
|
"""
|
||||||
@brief Clears all items from the collection.
|
Clears all items from the collection.
|
||||||
"""
|
"""
|
||||||
self.__mSrcProp.clear()
|
self.__mSrcProp.clear()
|
||||||
|
|
||||||
@ -238,8 +272,8 @@ _TMutexObject = typing.TypeVar('_TMutexObject')
|
|||||||
|
|
||||||
class TinyMutex(typing.Generic[_TMutexObject]):
|
class TinyMutex(typing.Generic[_TMutexObject]):
|
||||||
"""
|
"""
|
||||||
In this plugin, some class have "with" context feature.
|
In this plugin, some classes have "with" context feature.
|
||||||
However, it is essential to block any futher visiting if some "with" context are operating on some object.
|
However, in some cases, it is essential to block any futher visiting if some "with" context are operating on some object.
|
||||||
This is the reason why this tiny mutex is designed.
|
This is the reason why this tiny mutex is designed.
|
||||||
|
|
||||||
Please note this class is not a real MUTEX.
|
Please note this class is not a real MUTEX.
|
||||||
@ -253,17 +287,35 @@ class TinyMutex(typing.Generic[_TMutexObject]):
|
|||||||
self.__mProtectedObjects = set()
|
self.__mProtectedObjects = set()
|
||||||
|
|
||||||
def lock(self, obj: _TMutexObject) -> None:
|
def lock(self, obj: _TMutexObject) -> None:
|
||||||
|
"""
|
||||||
|
Lock given object.
|
||||||
|
|
||||||
|
:raise BBPException: Raised if given object has been locked.
|
||||||
|
:param obj: The resource to be locked.
|
||||||
|
"""
|
||||||
if obj in self.__mProtectedObjects:
|
if obj in self.__mProtectedObjects:
|
||||||
raise BBPException('It is not allowed that operate multiple "with" contexts on a single object.')
|
raise BBPException('It is not allowed that operate multiple "with" contexts on a single object.')
|
||||||
self.__mProtectedObjects.add(obj)
|
self.__mProtectedObjects.add(obj)
|
||||||
|
|
||||||
def try_lock(self, obj: _TMutexObject) -> bool:
|
def try_lock(self, obj: _TMutexObject) -> bool:
|
||||||
|
"""
|
||||||
|
Try lock given object.
|
||||||
|
|
||||||
|
:param obj: The resource to be locked.
|
||||||
|
:return: True if we successfully lock it, otherwise false.
|
||||||
|
"""
|
||||||
if obj in self.__mProtectedObjects:
|
if obj in self.__mProtectedObjects:
|
||||||
return False
|
return False
|
||||||
self.__mProtectedObjects.add(obj)
|
self.__mProtectedObjects.add(obj)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def unlock(self, obj: _TMutexObject) -> None:
|
def unlock(self, obj: _TMutexObject) -> None:
|
||||||
|
"""
|
||||||
|
Unlock given object.
|
||||||
|
|
||||||
|
:raise BBPException: Raised if given object is not locked.
|
||||||
|
:param obj: The resource to be unlocked.
|
||||||
|
"""
|
||||||
if obj not in self.__mProtectedObjects:
|
if obj not in self.__mProtectedObjects:
|
||||||
raise BBPException('It is not allowed that unlock an non-existent object.')
|
raise BBPException('It is not allowed that unlock an non-existent object.')
|
||||||
self.__mProtectedObjects.remove(obj)
|
self.__mProtectedObjects.remove(obj)
|
||||||
|
@ -235,21 +235,28 @@ _g_Annotation: dict[type, dict[int, EnumAnnotation]] = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EnumPropHelper(UTIL_functions.EnumPropHelper):
|
_TRawEnum = typing.TypeVar('_TRawEnum', bound = enum.Enum)
|
||||||
|
|
||||||
|
class EnumPropHelper(UTIL_functions.EnumPropHelper[_TRawEnum]):
|
||||||
"""
|
"""
|
||||||
Virtools type specified Blender EnumProp helper.
|
Virtools type specified Blender EnumProp helper.
|
||||||
"""
|
"""
|
||||||
__mAnnotationDict: dict[int, EnumAnnotation]
|
__mAnnotationDict: dict[int, EnumAnnotation]
|
||||||
__mEnumTy: type[enum.Enum]
|
__mEnumTy: type[_TRawEnum]
|
||||||
|
|
||||||
def __init__(self, ty: type[enum.Enum]):
|
def __init__(self, ty: type[_TRawEnum]):
|
||||||
# set enum type and annotation ref first
|
# set enum type and annotation ref first
|
||||||
self.__mEnumTy = ty
|
self.__mEnumTy = ty
|
||||||
self.__mAnnotationDict = _g_Annotation[ty]
|
self.__mAnnotationDict = _g_Annotation[ty]
|
||||||
# init parent data
|
|
||||||
UTIL_functions.EnumPropHelper.__init__(
|
# YYC MARK:
|
||||||
self,
|
# It seems that Pylance has bad generic analyse ability in there.
|
||||||
self.__mEnumTy, # enum.Enum it self is iterable
|
# It can not deduce the correct generic type in lambda.
|
||||||
|
# I gave up.
|
||||||
|
|
||||||
|
# Init parent data
|
||||||
|
super().__init__(
|
||||||
|
self.__mEnumTy, # enum.Enum its self is iterable
|
||||||
lambda x: str(x.value), # convert enum.Enum's value to string
|
lambda x: str(x.value), # convert enum.Enum's value to string
|
||||||
lambda x: self.__mEnumTy(int(x)), # use stored enum type and int() to get enum member
|
lambda x: self.__mEnumTy(int(x)), # use stored enum type and int() to get enum member
|
||||||
lambda x: self.__mAnnotationDict[x.value].mDisplayName,
|
lambda x: self.__mAnnotationDict[x.value].mDisplayName,
|
||||||
@ -265,11 +272,11 @@ def virtools_name_regulator(name: str | None) -> str:
|
|||||||
if name: return name
|
if name: return name
|
||||||
else: return bpy.app.translations.pgettext_data('annoymous', 'BME/UTIL_virtools_types.virtools_name_regulator()')
|
else: return bpy.app.translations.pgettext_data('annoymous', 'BME/UTIL_virtools_types.virtools_name_regulator()')
|
||||||
|
|
||||||
## Default Encoding for PyBMap
|
# YYC MARK:
|
||||||
# Use semicolon split each encodings. Support Western European and Simplified Chinese in default.
|
# There are default encodings for PyBMap. We support Western European and Simplified Chinese in default.
|
||||||
# Since LibCmo 0.2, the encoding name of LibCmo become universal encoding which is platfoorm independent.
|
# Since LibCmo 0.2, the encoding name of LibCmo become universal encoding which is platfoorm independent.
|
||||||
# So no need set it according to different platform.
|
# So no need set it according to different platform.
|
||||||
# Use universal encoding name (like Python).
|
# Use universal encoding name (like Python).
|
||||||
g_PyBMapDefaultEncodings: tuple[str, ...] = (
|
g_PyBMapDefaultEncodings: tuple[str, ...] = (
|
||||||
'cp1252',
|
'cp1252',
|
||||||
'gbk'
|
'gbk'
|
||||||
|
Reference in New Issue
Block a user