feat: add translation context for operators and their properties.

- add translation context for operator, menu, panel and etc. and their associated properties.
- improve some name and description but not finished.
- move reset BME material function inside BMEMaterialsHelper.
- rename variable of collection visitor in BME adder operator for clear meaning.
- replace some message box to report in ballance elements reset operator, BME materials reset operator and rail UV operator
This commit is contained in:
yyc12345 2025-01-11 21:36:11 +08:00
parent 1d7ac76d0e
commit 4ffe29654b
27 changed files with 444 additions and 206 deletions

View File

@ -1,7 +1,7 @@
import bpy, mathutils import bpy, mathutils
import typing import typing
from . import PROP_preferences from . import PROP_preferences
from . import UTIL_functions, UTIL_bme from . import UTIL_functions, UTIL_translation, UTIL_bme
#region BME Adder #region BME Adder
@ -9,29 +9,33 @@ _g_EnumHelper_BmeStructType: UTIL_bme.EnumPropHelper = UTIL_bme.EnumPropHelper()
class BBP_PG_bme_adder_cfgs(bpy.types.PropertyGroup): class BBP_PG_bme_adder_cfgs(bpy.types.PropertyGroup):
prop_int: bpy.props.IntProperty( prop_int: bpy.props.IntProperty(
name = 'Single Int', description = 'Single Int', name = 'Integral Value', description = 'The field representing a single integral value.',
min = 0, max = 64, min = 0, max = 64,
soft_min = 0, soft_max = 32, soft_min = 0, soft_max = 32,
step = 1, step = 1,
default = 1, default = 1,
translation_context = 'BBP_PG_bme_adder_cfgs/property'
) # type: ignore ) # type: ignore
prop_float: bpy.props.FloatProperty( prop_float: bpy.props.FloatProperty(
name = 'Single Float', description = 'Single Float', name = 'Float Point Value', description = 'The field representing a single float point value.',
min = 0.0, max = 1024.0, min = 0.0, max = 1024.0,
soft_min = 0.0, soft_max = 512.0, soft_min = 0.0, soft_max = 512.0,
step = 50, # Step is in UI, in [1, 100] (WARNING: actual value is /100). So we choose 50, mean 0.5 step = 50, # Step is in UI, in [1, 100] (WARNING: actual value is /100). So we choose 50, mean 0.5
default = 5.0, default = 5.0,
translation_context = 'BBP_PG_bme_adder_cfgs/property'
) # type: ignore ) # type: ignore
prop_bool: bpy.props.BoolProperty( prop_bool: bpy.props.BoolProperty(
name = 'Single Bool', description = 'Single Bool', name = 'Boolean Value', description = 'The field representing a single boolean value.',
default = True default = True,
translation_context = 'BBP_PG_bme_adder_cfgs/property'
) # type: ignore ) # type: ignore
class BBP_OT_add_bme_struct(bpy.types.Operator): class BBP_OT_add_bme_struct(bpy.types.Operator):
"""Add BME Struct""" """Add BME structure"""
bl_idname = "bbp.add_bme_struct" bl_idname = "bbp.add_bme_struct"
bl_label = "Add BME Struct" bl_label = "Add BME Structure"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_bme_struct'
## There is a compromise due to the shitty Blender design. ## There is a compromise due to the shitty Blender design.
# #
@ -51,8 +55,9 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
## Compromise used "outdated" flag. ## Compromise used "outdated" flag.
outdated_flag: bpy.props.BoolProperty( outdated_flag: bpy.props.BoolProperty(
name = "Outdated Type", # TR: Internal property should not have name and desc otherwise they will be written in translation.
description = "Internal flag.", # name = "Outdated Type",
# description = "Internal flag.",
options = {'HIDDEN', 'SKIP_SAVE'}, options = {'HIDDEN', 'SKIP_SAVE'},
default = False default = False
) # type: ignore ) # type: ignore
@ -96,29 +101,29 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
# init data collection # init data collection
adder_cfgs_visitor: UTIL_functions.CollectionVisitor[BBP_PG_bme_adder_cfgs] op_cfgs_visitor: UTIL_functions.CollectionVisitor[BBP_PG_bme_adder_cfgs]
adder_cfgs_visitor = UTIL_functions.CollectionVisitor(self.bme_struct_cfgs) op_cfgs_visitor = UTIL_functions.CollectionVisitor(self.bme_struct_cfgs)
# clear first # clear first
adder_cfgs_visitor.clear() op_cfgs_visitor.clear()
# create enough entries specified by gotten cfgs # create enough entries specified by gotten cfgs
for _ in range(max(counter_int, counter_float, counter_bool)): for _ in range(max(counter_int, counter_float, counter_bool)):
adder_cfgs_visitor.add() op_cfgs_visitor.add()
# assign default value # assign default value
for (cfg, cfg_index) in self.bme_struct_cfg_index_cache: for (cfg, cfg_index) in self.bme_struct_cfg_index_cache:
# show prop differently by cfg type # show prop differently by cfg type
match(cfg.get_type()): match(cfg.get_type()):
case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer: case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer:
adder_cfgs_visitor[cfg_index].prop_int = cfg.get_default() op_cfgs_visitor[cfg_index].prop_int = cfg.get_default()
case UTIL_bme.PrototypeShowcaseCfgsTypes.Float: case UTIL_bme.PrototypeShowcaseCfgsTypes.Float:
adder_cfgs_visitor[cfg_index].prop_float = cfg.get_default() op_cfgs_visitor[cfg_index].prop_float = cfg.get_default()
case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean: case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean:
adder_cfgs_visitor[cfg_index].prop_bool = cfg.get_default() op_cfgs_visitor[cfg_index].prop_bool = cfg.get_default()
case UTIL_bme.PrototypeShowcaseCfgsTypes.Face: case UTIL_bme.PrototypeShowcaseCfgsTypes.Face:
# face is just 6 bool # face is just 6 bool
default_values: tuple[bool, ...] = cfg.get_default() default_values: tuple[bool, ...] = cfg.get_default()
for i in range(6): for i in range(6):
adder_cfgs_visitor[cfg_index + i].prop_bool = default_values[i] op_cfgs_visitor[cfg_index + i].prop_bool = default_values[i]
# reset outdated flag # reset outdated flag
self.outdated_flag = False self.outdated_flag = False
@ -132,15 +137,17 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
bme_struct_type: bpy.props.EnumProperty( bme_struct_type: bpy.props.EnumProperty(
name = "Type", name = "Type",
description = "BME struct type", description = "The type of BME structure.",
items = _g_EnumHelper_BmeStructType.generate_items(), items = _g_EnumHelper_BmeStructType.generate_items(),
update = bme_struct_type_updated update = bme_struct_type_updated,
translation_context = 'BBP_OT_add_bme_struct/property'
) # type: ignore ) # type: ignore
bme_struct_cfgs : bpy.props.CollectionProperty( bme_struct_cfgs : bpy.props.CollectionProperty(
name = "Cfgs", name = "Configurations",
description = "Cfg collection.", description = "The collection holding BME structure configurations.",
type = BBP_PG_bme_adder_cfgs, type = BBP_PG_bme_adder_cfgs,
translation_context = 'BBP_OT_add_bme_struct/property'
) # type: ignore ) # type: ignore
## Extra transform for good "what you see is what you gotten". ## Extra transform for good "what you see is what you gotten".
@ -151,7 +158,8 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
size = 3, size = 3,
subtype = 'TRANSLATION', subtype = 'TRANSLATION',
step = 50, # same step as the float entry of BBP_PG_bme_adder_cfgs step = 50, # same step as the float entry of BBP_PG_bme_adder_cfgs
default = (0.0, 0.0, 0.0) default = (0.0, 0.0, 0.0),
translation_context = 'BBP_OT_add_bme_struct/property'
) # type: ignore ) # type: ignore
extra_rotation: bpy.props.FloatVectorProperty( extra_rotation: bpy.props.FloatVectorProperty(
name = "Extra Rotation", name = "Extra Rotation",
@ -159,7 +167,8 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
size = 3, size = 3,
subtype = 'EULER', subtype = 'EULER',
step = 100, # We choosen 100, mean 1. Sync with property window. step = 100, # We choosen 100, mean 1. Sync with property window.
default = (0.0, 0.0, 0.0) default = (0.0, 0.0, 0.0),
translation_context = 'BBP_OT_add_bme_struct/property'
) # type: ignore ) # type: ignore
@classmethod @classmethod
@ -185,22 +194,22 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
self.__internal_update_bme_struct_type() self.__internal_update_bme_struct_type()
# create cfg visitor # create cfg visitor
adder_cfgs_visitor: UTIL_functions.CollectionVisitor[BBP_PG_bme_adder_cfgs] op_cfgs_visitor: UTIL_functions.CollectionVisitor[BBP_PG_bme_adder_cfgs]
adder_cfgs_visitor = UTIL_functions.CollectionVisitor(self.bme_struct_cfgs) op_cfgs_visitor = UTIL_functions.CollectionVisitor(self.bme_struct_cfgs)
# collect cfgs data # collect cfgs data
cfgs: dict[str, typing.Any] = {} cfgs: dict[str, typing.Any] = {}
for (cfg, cfg_index) in self.bme_struct_cfg_index_cache: for (cfg, cfg_index) in self.bme_struct_cfg_index_cache:
match(cfg.get_type()): match(cfg.get_type()):
case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer: case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer:
cfgs[cfg.get_field()] = adder_cfgs_visitor[cfg_index].prop_int cfgs[cfg.get_field()] = op_cfgs_visitor[cfg_index].prop_int
case UTIL_bme.PrototypeShowcaseCfgsTypes.Float: case UTIL_bme.PrototypeShowcaseCfgsTypes.Float:
cfgs[cfg.get_field()] = adder_cfgs_visitor[cfg_index].prop_float cfgs[cfg.get_field()] = op_cfgs_visitor[cfg_index].prop_float
case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean: case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean:
cfgs[cfg.get_field()] = adder_cfgs_visitor[cfg_index].prop_bool cfgs[cfg.get_field()] = op_cfgs_visitor[cfg_index].prop_bool
case UTIL_bme.PrototypeShowcaseCfgsTypes.Face: case UTIL_bme.PrototypeShowcaseCfgsTypes.Face:
# face is just 6 bool tuple # face is just 6 bool tuple
cfgs[cfg.get_field()] = tuple( cfgs[cfg.get_field()] = tuple(
adder_cfgs_visitor[cfg_index + i].prop_bool for i in range(6) op_cfgs_visitor[cfg_index + i].prop_bool for i in range(6)
) )
# call general creator # call general creator
@ -231,8 +240,8 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
layout.prop(self, 'bme_struct_type') layout.prop(self, 'bme_struct_type')
# create cfg visitor # create cfg visitor
adder_cfgs_visitor: UTIL_functions.CollectionVisitor[BBP_PG_bme_adder_cfgs] op_cfgs_visitor: UTIL_functions.CollectionVisitor[BBP_PG_bme_adder_cfgs]
adder_cfgs_visitor = UTIL_functions.CollectionVisitor(self.bme_struct_cfgs) op_cfgs_visitor = UTIL_functions.CollectionVisitor(self.bme_struct_cfgs)
# visit cfgs cache list to show cfg # visit cfgs cache list to show cfg
layout.label(text = "Prototype Configurations:") layout.label(text = "Prototype Configurations:")
for (cfg, cfg_index) in self.bme_struct_cfg_index_cache: for (cfg, cfg_index) in self.bme_struct_cfg_index_cache:
@ -246,29 +255,29 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
# show prop differently by cfg type # show prop differently by cfg type
match(cfg.get_type()): match(cfg.get_type()):
case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer: case UTIL_bme.PrototypeShowcaseCfgsTypes.Integer:
box_layout.prop(adder_cfgs_visitor[cfg_index], 'prop_int', text = '') box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_int', text = '')
case UTIL_bme.PrototypeShowcaseCfgsTypes.Float: case UTIL_bme.PrototypeShowcaseCfgsTypes.Float:
box_layout.prop(adder_cfgs_visitor[cfg_index], 'prop_float', text = '') box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_float', text = '')
case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean: case UTIL_bme.PrototypeShowcaseCfgsTypes.Boolean:
box_layout.prop(adder_cfgs_visitor[cfg_index], 'prop_bool', text = '') box_layout.prop(op_cfgs_visitor[cfg_index], 'prop_bool', text = '')
case UTIL_bme.PrototypeShowcaseCfgsTypes.Face: case UTIL_bme.PrototypeShowcaseCfgsTypes.Face:
# face will show a special layout (grid view) # face will show a special layout (grid view)
grids = box_layout.grid_flow( grids = box_layout.grid_flow(
row_major=True, columns=3, even_columns=True, even_rows=True, align=True) row_major=True, columns=3, even_columns=True, even_rows=True, align=True)
grids.alignment = 'CENTER' grids.alignment = 'CENTER'
grids.separator() grids.separator()
grids.prop(adder_cfgs_visitor[cfg_index + 0], 'prop_bool', text = 'Top') # top grids.prop(op_cfgs_visitor[cfg_index + 0], 'prop_bool', text = 'Top') # top
grids.prop(adder_cfgs_visitor[cfg_index + 2], 'prop_bool', text = 'Front') # front grids.prop(op_cfgs_visitor[cfg_index + 2], 'prop_bool', text = 'Front') # front
grids.prop(adder_cfgs_visitor[cfg_index + 4], 'prop_bool', text = 'Left') # left grids.prop(op_cfgs_visitor[cfg_index + 4], 'prop_bool', text = 'Left') # left
grids.label(text = '', icon = 'CUBE') # show a 3d cube as icon grids.label(text = '', icon = 'CUBE') # show a 3d cube as icon
grids.prop(adder_cfgs_visitor[cfg_index + 5], 'prop_bool', text = 'Right') # right grids.prop(op_cfgs_visitor[cfg_index + 5], 'prop_bool', text = 'Right') # right
grids.prop(adder_cfgs_visitor[cfg_index + 3], 'prop_bool', text = 'Back') # back grids.prop(op_cfgs_visitor[cfg_index + 3], 'prop_bool', text = 'Back') # back
grids.prop(adder_cfgs_visitor[cfg_index + 1], 'prop_bool', text = 'Bottom') # bottom grids.prop(op_cfgs_visitor[cfg_index + 1], 'prop_bool', text = 'Bottom') # bottom
grids.separator() grids.separator()
# show extra transform props # show extra transform props
# forcely order that each one are placed horizontally # forcely order that each one are placed horizontally
layout.label(text = "Extra Transform:") layout.label(text = "Extra Transform")
# translation # translation
layout.label(text = 'Translation') layout.label(text = 'Translation')
hbox_layout: bpy.types.UILayout = layout.row() hbox_layout: bpy.types.UILayout = layout.row()
@ -285,7 +294,8 @@ class BBP_OT_add_bme_struct(bpy.types.Operator):
cop = layout.operator( cop = layout.operator(
cls.bl_idname, cls.bl_idname,
text = _g_EnumHelper_BmeStructType.get_bme_showcase_title(ident), text = _g_EnumHelper_BmeStructType.get_bme_showcase_title(ident),
icon_value = _g_EnumHelper_BmeStructType.get_bme_showcase_icon(ident) icon_value = _g_EnumHelper_BmeStructType.get_bme_showcase_icon(ident),
text_ctxt = UTIL_translation.build_prototype_showcase_context(ident)
) )
# and assign its init type value # and assign its init type value
cop.bme_struct_type = _g_EnumHelper_BmeStructType.to_selection(ident) cop.bme_struct_type = _g_EnumHelper_BmeStructType.to_selection(ident)

View File

@ -8,10 +8,11 @@ from . import PROP_ballance_element, PROP_virtools_group, PROP_ballance_map_info
class ComponentSectorParam(): class ComponentSectorParam():
component_sector: bpy.props.IntProperty( component_sector: bpy.props.IntProperty(
name = "Sector", name = "Sector",
description = "Define which sector the object will be grouped in", description = "The sector which this component will be grouped in.",
min = 1, max = 999, min = 1, max = 999,
soft_min = 1, soft_max = 8, soft_min = 1, soft_max = 8,
default = 1, default = 1,
translation_context = 'BBP/OP_ADDS_component.ComponentSectorParam/property'
) # type: ignore ) # type: ignore
def general_get_component_sector(self) -> int: def general_get_component_sector(self) -> int:
@ -23,10 +24,11 @@ class ComponentSectorParam():
class ComponentCountParam(): class ComponentCountParam():
component_count: bpy.props.IntProperty( component_count: bpy.props.IntProperty(
name = "Count", name = "Count",
description = "The count of components you want to generate", description = "The count of components which you want to generate",
min = 1, max = 64, min = 1, max = 64,
soft_min = 1, soft_max = 32, soft_min = 1, soft_max = 32,
default = 1, default = 1,
translation_context = 'BBP/OP_ADDS_component.ComponentCountParam/property'
) # type: ignore ) # type: ignore
def general_get_component_count(self) -> int: def general_get_component_count(self) -> int:
@ -192,15 +194,17 @@ _g_EnumHelper_Component: UTIL_functions.EnumPropHelper = UTIL_functions.EnumProp
) )
class BBP_OT_add_component(bpy.types.Operator, ComponentSectorParam): class BBP_OT_add_component(bpy.types.Operator, ComponentSectorParam):
"""Add Component""" """Add ordinary Component"""
bl_idname = "bbp.add_component" bl_idname = "bbp.add_component"
bl_label = "Add Component" bl_label = "Add Component"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_add_component'
component_type: bpy.props.EnumProperty( component_type: bpy.props.EnumProperty(
name = "Type", name = "Type",
description = "This component type", description = "The type of this component.",
items = _g_EnumHelper_Component.generate_items(), items = _g_EnumHelper_Component.generate_items(),
translation_context = 'BBP_OT_add_component/property'
) # type: ignore ) # type: ignore
def invoke(self, context, event): def invoke(self, context, event):
@ -241,7 +245,8 @@ class BBP_OT_add_component(bpy.types.Operator, ComponentSectorParam):
cop = layout.operator( cop = layout.operator(
BBP_OT_add_component.bl_idname, text = item_name, BBP_OT_add_component.bl_idname, text = item_name,
icon_value = UTIL_icons_manager.get_component_icon(item_name) icon_value = UTIL_icons_manager.get_component_icon(item_name),
translate = False
) )
cop.component_type = _g_EnumHelper_Component.to_selection(item) cop.component_type = _g_EnumHelper_Component.to_selection(item)
@ -254,6 +259,7 @@ class BBP_OT_add_nong_extra_point(bpy.types.Operator, ComponentSectorParam, Comp
bl_idname = "bbp.add_nong_extra_point" bl_idname = "bbp.add_nong_extra_point"
bl_label = "Nong Extra Point" bl_label = "Nong Extra Point"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_nong_extra_point'
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -289,6 +295,7 @@ class BBP_OT_add_nong_ventilator(bpy.types.Operator, ComponentSectorParam, Compo
bl_idname = "bbp.add_nong_ventilator" bl_idname = "bbp.add_nong_ventilator"
bl_label = "Nong Ventilator" bl_label = "Nong Ventilator"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_nong_ventilator'
ventilator_count_source: bpy.props.EnumProperty( ventilator_count_source: bpy.props.EnumProperty(
name = "Ventilator Count Source", name = "Ventilator Count Source",
@ -296,6 +303,7 @@ class BBP_OT_add_nong_ventilator(bpy.types.Operator, ComponentSectorParam, Compo
('DEFINED', "Predefined", "Pre-defined ventilator count."), ('DEFINED', "Predefined", "Pre-defined ventilator count."),
('CUSTOM', "Custom", "User specified ventilator count."), ('CUSTOM', "Custom", "User specified ventilator count."),
], ],
translation_context = 'BBP_OT_add_nong_ventilator/property'
) # type: ignore ) # type: ignore
preset_vetilator_count: bpy.props.EnumProperty( preset_vetilator_count: bpy.props.EnumProperty(
@ -307,6 +315,7 @@ class BBP_OT_add_nong_ventilator(bpy.types.Operator, ComponentSectorParam, Compo
('WOOD', 'Wood', 'The ventilator count (6) can push wood ball up.'), ('WOOD', 'Wood', 'The ventilator count (6) can push wood ball up.'),
('STONE', 'Stone', 'The ventilator count (32) can push stone ball up.'), ('STONE', 'Stone', 'The ventilator count (32) can push stone ball up.'),
], ],
translation_context = 'BBP_OT_add_nong_ventilator/property'
) # type: ignore ) # type: ignore
def draw(self, context): def draw(self, context):
@ -363,6 +372,7 @@ class BBP_OT_add_tilting_block_series(bpy.types.Operator, ComponentSectorParam,
bl_idname = "bbp.add_tilting_block_series" bl_idname = "bbp.add_tilting_block_series"
bl_label = "Tilting Block Series" bl_label = "Tilting Block Series"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_tilting_block_series'
component_span: bpy.props.FloatProperty( component_span: bpy.props.FloatProperty(
name = "Span", name = "Span",
@ -370,6 +380,7 @@ class BBP_OT_add_tilting_block_series(bpy.types.Operator, ComponentSectorParam,
min = 0.0, max = 100.0, min = 0.0, max = 100.0,
soft_min = 0.0, soft_max = 12.0, soft_min = 0.0, soft_max = 12.0,
default = 6.0022, default = 6.0022,
translation_context = 'BBP_OT_add_tilting_block_series/property'
) # type: ignore ) # type: ignore
def draw(self, context): def draw(self, context):
@ -407,6 +418,7 @@ class BBP_OT_add_swing_series(bpy.types.Operator, ComponentSectorParam, Componen
bl_idname = "bbp.add_swing_series" bl_idname = "bbp.add_swing_series"
bl_label = "Swing Series" bl_label = "Swing Series"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_swing_series'
component_span: bpy.props.FloatProperty( component_span: bpy.props.FloatProperty(
name = "Span", name = "Span",
@ -414,12 +426,14 @@ class BBP_OT_add_swing_series(bpy.types.Operator, ComponentSectorParam, Componen
min = 0.0, max = 100.0, min = 0.0, max = 100.0,
soft_min = 0.0, soft_max = 30.0, soft_min = 0.0, soft_max = 30.0,
default = 15.0, default = 15.0,
translation_context = 'BBP_OT_add_swing_series/property'
) # type: ignore ) # type: ignore
staggered_swing: bpy.props.BoolProperty( staggered_swing: bpy.props.BoolProperty(
name = 'Staggered', name = 'Staggered',
description = 'Whether place Swing staggered. Staggered Swing accept any ball however Non-Staggered Swing only accept Wood and Paper ball.', description = 'Whether place Swing staggered. Staggered Swing accept any ball however Non-Staggered Swing only accept Wood and Paper ball.',
default = True default = True,
translation_context = 'BBP_OT_add_swing_series/property'
) # type: ignore ) # type: ignore
def draw(self, context): def draw(self, context):
@ -465,6 +479,7 @@ class BBP_OT_add_ventilator_series(bpy.types.Operator, ComponentSectorParam, Com
bl_idname = "bbp.add_ventilator_series" bl_idname = "bbp.add_ventilator_series"
bl_label = "Ventilator Series" bl_label = "Ventilator Series"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_ventilator_series'
component_translation: bpy.props.FloatVectorProperty( component_translation: bpy.props.FloatVectorProperty(
name = "Delta Vector", name = "Delta Vector",
@ -473,6 +488,7 @@ class BBP_OT_add_ventilator_series(bpy.types.Operator, ComponentSectorParam, Com
min = 0.0, max = 100.0, min = 0.0, max = 100.0,
soft_min = 0.0, soft_max = 50.0, soft_min = 0.0, soft_max = 50.0,
default = (0.0, 0.0, 15.0), default = (0.0, 0.0, 15.0),
translation_context = 'BBP_OT_add_ventilator_series/property'
) # type: ignore ) # type: ignore
def draw(self, context): def draw(self, context):
@ -514,6 +530,7 @@ class BBP_OT_add_sector_component_pair(bpy.types.Operator, ComponentSectorParam)
bl_idname = "bbp.add_sector_component_pair" bl_idname = "bbp.add_sector_component_pair"
bl_label = "Sector Pair" bl_label = "Sector Pair"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_add_sector_component_pair'
def __get_checkpoint(self) -> tuple[PROP_ballance_element.BallanceElementType, int]: def __get_checkpoint(self) -> tuple[PROP_ballance_element.BallanceElementType, int]:
if self.general_get_component_sector() == 1: if self.general_get_component_sector() == 1:

View File

@ -46,7 +46,8 @@ class SharedExtraTransform():
size = 3, size = 3,
subtype = 'TRANSLATION', subtype = 'TRANSLATION',
step = 50, # same step as the float entry of BBP_PG_bme_adder_cfgs step = 50, # same step as the float entry of BBP_PG_bme_adder_cfgs
default = (0.0, 0.0, 0.0) default = (0.0, 0.0, 0.0),
translation_context = 'BBP/OP_ADDS_rail.SharedExtraTransform/property'
) # type: ignore ) # type: ignore
extra_rotation: bpy.props.FloatVectorProperty( extra_rotation: bpy.props.FloatVectorProperty(
name = "Extra Rotation", name = "Extra Rotation",
@ -54,7 +55,8 @@ class SharedExtraTransform():
size = 3, size = 3,
subtype = 'EULER', subtype = 'EULER',
step = 100, # We choosen 100, mean 1. Sync with property window. step = 100, # We choosen 100, mean 1. Sync with property window.
default = (0.0, 0.0, 0.0) default = (0.0, 0.0, 0.0),
translation_context = 'BBP/OP_ADDS_rail.SharedExtraTransform/property'
) # type: ignore ) # type: ignore
def draw_extra_transform_input(self, layout: bpy.types.UILayout) -> None: def draw_extra_transform_input(self, layout: bpy.types.UILayout) -> None:
@ -91,6 +93,7 @@ class SharedRailSectionInputProperty():
('RAIL', "Rail", ""), ('RAIL', "Rail", ""),
], ],
default = 'RAIL', default = 'RAIL',
translation_context = 'BBP/OP_ADDS_rail.SharedRailSectionInputProperty/property'
) # type: ignore ) # type: ignore
def draw_rail_section_input(self, layout: bpy.types.UILayout) -> None: def draw_rail_section_input(self, layout: bpy.types.UILayout) -> None:
@ -109,13 +112,15 @@ class SharedRailCapInputProperty():
rail_start_cap: bpy.props.BoolProperty( rail_start_cap: bpy.props.BoolProperty(
name = 'Start Cap', name = 'Start Cap',
description = 'Whether this rail should have cap at start terminal.', description = 'Whether this rail should have cap at start terminal.',
default = False default = False,
translation_context = 'BBP/OP_ADDS_rail.SharedRailCapInputProperty/property'
) # type: ignore ) # type: ignore
rail_end_cap: bpy.props.BoolProperty( rail_end_cap: bpy.props.BoolProperty(
name = 'End Cap', name = 'End Cap',
description = 'Whether this rail should have cap at end terminal.', description = 'Whether this rail should have cap at end terminal.',
default = False default = False,
translation_context = 'BBP/OP_ADDS_rail.SharedRailCapInputProperty/property'
) # type: ignore ) # type: ignore
def draw_rail_cap_input(self, layout: bpy.types.UILayout) -> None: def draw_rail_cap_input(self, layout: bpy.types.UILayout) -> None:
@ -140,7 +145,8 @@ class SharedStraightRailInputProperty():
default = 5.0, default = 5.0,
min = 0, min = 0,
step = 50, # same unit as BME Struct step = 50, # same unit as BME Struct
unit = 'LENGTH' unit = 'LENGTH',
translation_context = 'BBP/OP_ADDS_rail.SharedStraightRailInputProperty/property'
) # type: ignore ) # type: ignore
def draw_straight_rail_input(self, layout: bpy.types.UILayout) -> None: def draw_straight_rail_input(self, layout: bpy.types.UILayout) -> None:
@ -159,6 +165,7 @@ class SharedScrewRailInputProperty():
description = "The segment count per iteration. More segment, more smooth but lower performance.", description = "The segment count per iteration. More segment, more smooth but lower performance.",
default = 28, default = 28,
min = 1, min = 1,
translation_context = 'BBP/OP_ADDS_rail.SharedScrewRailInputProperty/property'
) # type: ignore ) # type: ignore
rail_screw_radius: bpy.props.FloatProperty( rail_screw_radius: bpy.props.FloatProperty(
@ -166,25 +173,29 @@ class SharedScrewRailInputProperty():
description = "The screw radius.", description = "The screw radius.",
default = 5, default = 5,
min = 0, min = 0,
unit = 'LENGTH' unit = 'LENGTH',
translation_context = 'BBP/OP_ADDS_rail.SharedScrewRailInputProperty/property'
) # type: ignore ) # type: ignore
rail_screw_flip_x: bpy.props.BoolProperty( rail_screw_flip_x: bpy.props.BoolProperty(
name = 'Flip X', name = 'Flip X',
description = 'Whether flip this rail with X axis', description = 'Whether flip this rail with X axis',
default = False default = False,
translation_context = 'BBP/OP_ADDS_rail.SharedScrewRailInputProperty/property'
) # type: ignore ) # type: ignore
rail_screw_flip_y: bpy.props.BoolProperty( rail_screw_flip_y: bpy.props.BoolProperty(
name = 'Flip Y', name = 'Flip Y',
description = 'Whether flip this rail with Y axis', description = 'Whether flip this rail with Y axis',
default = False default = False,
translation_context = 'BBP/OP_ADDS_rail.SharedScrewRailInputProperty/property'
) # type: ignore ) # type: ignore
rail_screw_flip_z: bpy.props.BoolProperty( rail_screw_flip_z: bpy.props.BoolProperty(
name = 'Flip Z', name = 'Flip Z',
description = 'Whether flip this rail with Z axis', description = 'Whether flip this rail with Z axis',
default = False default = False,
translation_context = 'BBP/OP_ADDS_rail.SharedScrewRailInputProperty/property'
) # type: ignore ) # type: ignore
def draw_screw_rail_input(self, layout: bpy.types.UILayout) -> None: def draw_screw_rail_input(self, layout: bpy.types.UILayout) -> None:
@ -220,6 +231,7 @@ class BBP_OT_add_rail_section(SharedRailSectionInputProperty, bpy.types.Operator
bl_idname = "bbp.add_rail_section" bl_idname = "bbp.add_rail_section"
bl_label = "Rail Section" bl_label = "Rail Section"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_rail_section'
def execute(self, context): def execute(self, context):
UTIL_rail_creator.rail_creator_wrapper( UTIL_rail_creator.rail_creator_wrapper(
@ -240,6 +252,7 @@ class BBP_OT_add_transition_section(bpy.types.Operator):
bl_idname = "bbp.add_transition_section" bl_idname = "bbp.add_transition_section"
bl_label = "Transition Section" bl_label = "Transition Section"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_transition_section'
def execute(self, context): def execute(self, context):
UTIL_rail_creator.rail_creator_wrapper( UTIL_rail_creator.rail_creator_wrapper(
@ -257,6 +270,7 @@ class BBP_OT_add_straight_rail(SharedExtraTransform, SharedRailSectionInputPrope
bl_idname = "bbp.add_straight_rail" bl_idname = "bbp.add_straight_rail"
bl_label = "Straight Rail" bl_label = "Straight Rail"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_straight_rail'
def execute(self, context): def execute(self, context):
UTIL_rail_creator.rail_creator_wrapper( UTIL_rail_creator.rail_creator_wrapper(
@ -285,6 +299,7 @@ class BBP_OT_add_transition_rail(SharedExtraTransform, SharedRailCapInputPropert
bl_idname = "bbp.add_transition_rail" bl_idname = "bbp.add_transition_rail"
bl_label = "Transition Rail" bl_label = "Transition Rail"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_transition_rail'
def execute(self, context): def execute(self, context):
UTIL_rail_creator.rail_creator_wrapper( UTIL_rail_creator.rail_creator_wrapper(
@ -312,6 +327,7 @@ class BBP_OT_add_side_rail(SharedExtraTransform, SharedRailCapInputProperty, Sha
bl_idname = "bbp.add_side_rail" bl_idname = "bbp.add_side_rail"
bl_label = "Side Rail" bl_label = "Side Rail"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_side_rail'
side_rail_type: bpy.props.EnumProperty( side_rail_type: bpy.props.EnumProperty(
name = "Side Type", name = "Side Type",
@ -321,6 +337,7 @@ class BBP_OT_add_side_rail(SharedExtraTransform, SharedRailCapInputProperty, Sha
('STONE', "Stone Specific", "The side rail which also allow stone ball passed."), ('STONE', "Stone Specific", "The side rail which also allow stone ball passed."),
], ],
default = 'NORMAL', default = 'NORMAL',
translation_context = 'BBP_OT_add_side_rail/property'
) # type: ignore ) # type: ignore
def execute(self, context): def execute(self, context):
@ -351,6 +368,7 @@ class BBP_OT_add_arc_rail(SharedExtraTransform, SharedRailSectionInputProperty,
bl_idname = "bbp.add_arc_rail" bl_idname = "bbp.add_arc_rail"
bl_label = "Arc Rail" bl_label = "Arc Rail"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_arc_rail'
rail_screw_angle: bpy.props.FloatProperty( rail_screw_angle: bpy.props.FloatProperty(
name = "Angle", name = "Angle",
@ -358,6 +376,7 @@ class BBP_OT_add_arc_rail(SharedExtraTransform, SharedRailSectionInputProperty,
default = math.radians(90), default = math.radians(90),
min = 0, max = math.radians(360), min = 0, max = math.radians(360),
subtype = 'ANGLE', subtype = 'ANGLE',
translation_context = 'BBP_OT_add_arc_rail/property'
) # type: ignore ) # type: ignore
def execute(self, context): def execute(self, context):
@ -392,12 +411,14 @@ class BBP_OT_add_spiral_rail(SharedExtraTransform, SharedRailCapInputProperty, S
bl_idname = "bbp.add_spiral_rail" bl_idname = "bbp.add_spiral_rail"
bl_label = "Spiral Rail" bl_label = "Spiral Rail"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_spiral_rail'
rail_screw_screw: bpy.props.FloatProperty( rail_screw_screw: bpy.props.FloatProperty(
name = "Screw", name = "Screw",
description = "The increased height in each iteration. Minus height also is accepted.", description = "The increased height in each iteration. Minus height also is accepted.",
default = c_SpiralRailScrew, default = c_SpiralRailScrew,
unit = 'LENGTH' unit = 'LENGTH',
translation_context = 'BBP_OT_add_spiral_rail/property'
) # type: ignore ) # type: ignore
rail_screw_iterations: bpy.props.IntProperty( rail_screw_iterations: bpy.props.IntProperty(
@ -405,6 +426,7 @@ class BBP_OT_add_spiral_rail(SharedExtraTransform, SharedRailCapInputProperty, S
description = "Indicate how many layers of this spiral rail should be generated.", description = "Indicate how many layers of this spiral rail should be generated.",
default = 1, default = 1,
min = 1, min = 1,
translation_context = 'BBP_OT_add_spiral_rail/property'
) # type: ignore ) # type: ignore
def execute(self, context): def execute(self, context):
@ -439,6 +461,7 @@ class BBP_OT_add_side_spiral_rail(SharedExtraTransform, SharedRailSectionInputPr
bl_idname = "bbp.add_side_spiral_rail" bl_idname = "bbp.add_side_spiral_rail"
bl_label = "Side Spiral Rail" bl_label = "Side Spiral Rail"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_add_side_spiral_rail'
rail_screw_iterations: bpy.props.IntProperty( rail_screw_iterations: bpy.props.IntProperty(
name = "Iterations", name = "Iterations",
@ -447,6 +470,7 @@ class BBP_OT_add_side_spiral_rail(SharedExtraTransform, SharedRailSectionInputPr
# at least 2 ietrations can create 1 useful side spiral rail. # at least 2 ietrations can create 1 useful side spiral rail.
# becuase side spiral rail is edge shared. # becuase side spiral rail is edge shared.
min = 2, min = 2,
translation_context = 'BBP_OT_add_side_spiral_rail/property'
) # type: ignore ) # type: ignore
def execute(self, context): def execute(self, context):

View File

@ -6,19 +6,19 @@ class BBP_OT_export_bmfile(bpy.types.Operator, UTIL_file_browser.ExportBmxFile,
bl_idname = "bbp.export_bmfile" bl_idname = "bbp.export_bmfile"
bl_label = "Export BM (Ballance Map) File" bl_label = "Export BM (Ballance Map) File"
bl_options = {'PRESET'} bl_options = {'PRESET'}
bl_translation_context = 'BBP_OT_export_bmfile'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return PROP_preferences.get_raw_preferences().has_valid_blc_tex_folder() return PROP_preferences.get_raw_preferences().has_valid_blc_tex_folder()
def execute(self, context): def execute(self, context):
self.report({'ERROR'}, 'This function not supported yet.') self.report({'ERROR'}, 'This feature is not supported yet.')
# self.report({'INFO'}, "BM File Exporting Finished.") # self.report({'INFO'}, "BM File Exporting Finished.")
return {'FINISHED'} return {'FINISHED'}
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.label(text = 'Export Target')
self.draw_export_params(context, layout.box()) self.draw_export_params(context, layout.box())
def register() -> None: def register() -> None:

View File

@ -11,6 +11,7 @@ class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtool
bl_idname = "bbp.export_virtools" bl_idname = "bbp.export_virtools"
bl_label = "Export Virtools File" bl_label = "Export Virtools File"
bl_options = {'PRESET'} bl_options = {'PRESET'}
bl_translation_context = 'BBP_OT_export_virtools'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -6,19 +6,19 @@ class BBP_OT_import_bmfile(bpy.types.Operator, UTIL_file_browser.ImportBmxFile,
bl_idname = "bbp.import_bmfile" bl_idname = "bbp.import_bmfile"
bl_label = "Import BM (Ballance Map) File" bl_label = "Import BM (Ballance Map) File"
bl_options = {'PRESET', 'UNDO'} bl_options = {'PRESET', 'UNDO'}
bl_translation_context = 'BBP_OT_import_bmfile'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return PROP_preferences.get_raw_preferences().has_valid_blc_tex_folder() return PROP_preferences.get_raw_preferences().has_valid_blc_tex_folder()
def execute(self, context): def execute(self, context):
self.report({'ERROR'}, 'This function not supported yet.') self.report({'ERROR'}, 'This feature is not supported yet.')
# self.report({'INFO'}, "BM File Importing Finished.") # self.report({'INFO'}, "BM File Importing Finished.")
return {'FINISHED'} return {'FINISHED'}
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.label(text = 'Conflict Options')
self.draw_import_params(layout.box()) self.draw_import_params(layout.box())
def register() -> None: def register() -> None:

View File

@ -11,6 +11,7 @@ class BBP_OT_import_virtools(bpy.types.Operator, UTIL_file_browser.ImportVirtool
bl_idname = "bbp.import_virtools" bl_idname = "bbp.import_virtools"
bl_label = "Import Virtools File" bl_label = "Import Virtools File"
bl_options = {'PRESET', 'UNDO'} bl_options = {'PRESET', 'UNDO'}
bl_translation_context = 'BBP_OT_import_virtools'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -5,8 +5,9 @@ from . import PROP_virtools_material, PROP_preferences
class BBP_OT_fix_all_material(bpy.types.Operator): class BBP_OT_fix_all_material(bpy.types.Operator):
"""Fix All Materials by Its Referred Ballance Texture Name.""" """Fix All Materials by Its Referred Ballance Texture Name."""
bl_idname = "bbp.fix_all_material" bl_idname = "bbp.fix_all_material"
bl_label = "Fix Material" bl_label = "Fix All Materials"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_fix_all_material'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -43,24 +43,29 @@ class BBP_PG_legacy_align_history(bpy.types.PropertyGroup):
align_x: bpy.props.BoolProperty( align_x: bpy.props.BoolProperty(
name = "X Position", name = "X Position",
default = False, default = False,
translation_context = 'BBP_PG_legacy_align_history/property'
) # type: ignore ) # type: ignore
align_y: bpy.props.BoolProperty( align_y: bpy.props.BoolProperty(
name = "Y Position", name = "Y Position",
default = False, default = False,
translation_context = 'BBP_PG_legacy_align_history/property'
) # type: ignore ) # type: ignore
align_z: bpy.props.BoolProperty( align_z: bpy.props.BoolProperty(
name = "Z Position", name = "Z Position",
default = False, default = False,
translation_context = 'BBP_PG_legacy_align_history/property'
) # type: ignore ) # type: ignore
current_align_mode: bpy.props.EnumProperty( current_align_mode: bpy.props.EnumProperty(
name = "Current Object (Active Object)", name = "Current Object (Active Object)",
items = _g_EnumHelper_AlignMode.generate_items(), items = _g_EnumHelper_AlignMode.generate_items(),
default = _g_EnumHelper_AlignMode.to_selection(AlignMode.AxisCenter), default = _g_EnumHelper_AlignMode.to_selection(AlignMode.AxisCenter),
translation_context = 'BBP_PG_legacy_align_history/property'
) # type: ignore ) # type: ignore
target_align_mode: bpy.props.EnumProperty( target_align_mode: bpy.props.EnumProperty(
name = "Target Objects (Other Objects)", name = "Target Objects (Other Objects)",
items = _g_EnumHelper_AlignMode.generate_items(), items = _g_EnumHelper_AlignMode.generate_items(),
default = _g_EnumHelper_AlignMode.to_selection(AlignMode.AxisCenter), default = _g_EnumHelper_AlignMode.to_selection(AlignMode.AxisCenter),
translation_context = 'BBP_PG_legacy_align_history/property'
) # type: ignore ) # type: ignore
#endregion #endregion
@ -70,6 +75,7 @@ class BBP_OT_legacy_align(bpy.types.Operator):
bl_idname = "bbp.legacy_align" bl_idname = "bbp.legacy_align"
bl_label = "3ds Max Align" bl_label = "3ds Max Align"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_legacy_align'
# the updator for apply flag value # the updator for apply flag value
def apply_flag_updated(self, context): def apply_flag_updated(self, context):
@ -111,17 +117,20 @@ class BBP_OT_legacy_align(bpy.types.Operator):
options = {'HIDDEN', 'SKIP_SAVE'}, options = {'HIDDEN', 'SKIP_SAVE'},
default = True, # default True value to make it as a "light" button, not a grey one. default = True, # default True value to make it as a "light" button, not a grey one.
update = apply_flag_updated, update = apply_flag_updated,
translation_context = 'BBP_OT_legacy_align/property'
) # type: ignore ) # type: ignore
recursive_hinder: bpy.props.BoolProperty( recursive_hinder: bpy.props.BoolProperty(
name = "Recursive Hinder", # TR: internal used property should not have name and description, otherwise it will be translated.
description = "An internal flag to prevent the loop calling to apply_flags's updator.", # name = "Recursive Hinder",
# description = "An internal flag to prevent the loop calling to apply_flags's updator.",
options = {'HIDDEN', 'SKIP_SAVE'}, options = {'HIDDEN', 'SKIP_SAVE'},
default = False, default = False
) # type: ignore ) # type: ignore
align_history : bpy.props.CollectionProperty( align_history : bpy.props.CollectionProperty(
name = "Historys", # TR: same reason for no name and description.
description = "Align history.", # name = "Historys",
type = BBP_PG_legacy_align_history, # description = "Align history.",
type = BBP_PG_legacy_align_history
) # type: ignore ) # type: ignore
@classmethod @classmethod

View File

@ -7,6 +7,7 @@ class BBP_OT_regulate_objects_name(bpy.types.Operator):
bl_idname = "bbp.regulate_objects_name" bl_idname = "bbp.regulate_objects_name"
bl_label = "Regulate Objects Name" bl_label = "Regulate Objects Name"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_regulate_objects_name'
def invoke(self, context, event): def invoke(self, context, event):
wm = context.window_manager wm = context.window_manager
@ -24,6 +25,7 @@ class BBP_OT_auto_grouping(bpy.types.Operator):
bl_idname = "bbp.auto_grouping" bl_idname = "bbp.auto_grouping"
bl_label = "Auto Grouping" bl_label = "Auto Grouping"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_auto_grouping'
def invoke(self, context, event): def invoke(self, context, event):
wm = context.window_manager wm = context.window_manager
@ -41,6 +43,7 @@ class BBP_OT_convert_to_imengyu(bpy.types.Operator):
bl_idname = "bbp.convert_to_imengyu" bl_idname = "bbp.convert_to_imengyu"
bl_label = "Convert to Imengyu" bl_label = "Convert to Imengyu"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_convert_to_imengyu'
def invoke(self, context, event): def invoke(self, context, event):
wm = context.window_manager wm = context.window_manager

View File

@ -7,6 +7,7 @@ class BBP_OT_snoop_group_then_to_mesh(bpy.types.Operator):
bl_idname = "bbp.snoop_group_then_to_mesh" bl_idname = "bbp.snoop_group_then_to_mesh"
bl_label = "Snoop Group then to Mesh" bl_label = "Snoop Group then to Mesh"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_snoop_group_then_to_mesh'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -32,12 +32,14 @@ class BBP_OT_select_object_by_virtools_group(bpy.types.Operator, PROP_virtools_g
bl_idname = "bbp.select_object_by_virtools_group" bl_idname = "bbp.select_object_by_virtools_group"
bl_label = "Select by Virtools Group" bl_label = "Select by Virtools Group"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_select_object_by_virtools_group'
selection_mode: bpy.props.EnumProperty( selection_mode: bpy.props.EnumProperty(
name = "Mode", name = "Mode",
description = "Selection mode", description = "Selection mode",
items = _g_EnumHelper_SelectMode.generate_items(), items = _g_EnumHelper_SelectMode.generate_items(),
default = _g_EnumHelper_SelectMode.to_selection(SelectMode.Intersect) default = _g_EnumHelper_SelectMode.to_selection(SelectMode.Intersect),
translation_context = 'BBP_OT_select_object_by_virtools_group/property'
) # type: ignore ) # type: ignore
@classmethod @classmethod
@ -122,6 +124,7 @@ class BBP_OT_add_objects_virtools_group(bpy.types.Operator, PROP_virtools_group.
bl_idname = "bbp.add_objects_virtools_group" bl_idname = "bbp.add_objects_virtools_group"
bl_label = "Grouping Objects" bl_label = "Grouping Objects"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_add_objects_virtools_group'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -147,6 +150,7 @@ class BBP_OT_rm_objects_virtools_group(bpy.types.Operator, PROP_virtools_group.S
bl_idname = "bbp.rm_objects_virtools_group" bl_idname = "bbp.rm_objects_virtools_group"
bl_label = "Ungrouping Objects" bl_label = "Ungrouping Objects"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_rm_objects_virtools_group'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -172,6 +176,7 @@ class BBP_OT_clear_objects_virtools_group(bpy.types.Operator):
bl_idname = "bbp.clear_objects_virtools_group" bl_idname = "bbp.clear_objects_virtools_group"
bl_label = "Clear All Groups" bl_label = "Clear All Groups"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_clear_objects_virtools_group'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -78,6 +78,7 @@ class BBP_OT_flatten_uv(bpy.types.Operator):
bl_idname = "bbp.flatten_uv" bl_idname = "bbp.flatten_uv"
bl_label = "Flatten UV" bl_label = "Flatten UV"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}
bl_translation_context = 'BBP_OT_flatten_uv'
reference_edge: bpy.props.IntProperty( reference_edge: bpy.props.IntProperty(
name = "Reference Edge", name = "Reference Edge",
@ -85,6 +86,7 @@ class BBP_OT_flatten_uv(bpy.types.Operator):
min = 0, min = 0,
soft_min = 0, soft_max = 3, soft_min = 0, soft_max = 3,
default = 0, default = 0,
translation_context = 'BBP_OT_flatten_uv/property'
) # type: ignore ) # type: ignore
flatten_method: bpy.props.EnumProperty( flatten_method: bpy.props.EnumProperty(
@ -94,7 +96,8 @@ class BBP_OT_flatten_uv(bpy.types.Operator):
('FLOOR', "Floor", "Floor specific flatten UV."), ('FLOOR', "Floor", "Floor specific flatten UV."),
('WOOD', "Wood", "Wood specific flatten UV."), ('WOOD', "Wood", "Wood specific flatten UV."),
], ],
default = 'RAW' default = 'RAW',
translation_context = 'BBP_OT_flatten_uv/property'
) # type: ignore ) # type: ignore
scale_mode: bpy.props.EnumProperty( scale_mode: bpy.props.EnumProperty(
@ -103,7 +106,8 @@ class BBP_OT_flatten_uv(bpy.types.Operator):
('NUM', "Scale Size", "Scale UV with specific number."), ('NUM', "Scale Size", "Scale UV with specific number."),
('REF', "Ref. Point", "Scale UV with Reference Point feature."), ('REF', "Ref. Point", "Scale UV with Reference Point feature."),
], ],
default = 'NUM' default = 'NUM',
translation_context = 'BBP_OT_flatten_uv/property'
) # type: ignore ) # type: ignore
scale_number: bpy.props.FloatProperty( scale_number: bpy.props.FloatProperty(
@ -114,6 +118,7 @@ class BBP_OT_flatten_uv(bpy.types.Operator):
default = 5.0, default = 5.0,
step = 10, step = 10,
precision = 1, precision = 1,
translation_context = 'BBP_OT_flatten_uv/property'
) # type: ignore ) # type: ignore
reference_point: bpy.props.IntProperty( reference_point: bpy.props.IntProperty(
@ -122,6 +127,7 @@ class BBP_OT_flatten_uv(bpy.types.Operator):
min = 2, # 0 and 1 is invalid. we can not order the reference edge to be set on the outside of uv axis min = 2, # 0 and 1 is invalid. we can not order the reference edge to be set on the outside of uv axis
soft_min = 2, soft_max = 3, soft_min = 2, soft_max = 3,
default = 2, default = 2,
translation_context = 'BBP_OT_flatten_uv/property'
) # type: ignore ) # type: ignore
reference_uv: bpy.props.FloatProperty( reference_uv: bpy.props.FloatProperty(
@ -131,6 +137,7 @@ class BBP_OT_flatten_uv(bpy.types.Operator):
default = 0.5, default = 0.5,
step = 10, step = 10,
precision = 2, precision = 2,
translation_context = 'BBP_OT_flatten_uv/property'
) # type: ignore ) # type: ignore
@classmethod @classmethod

View File

@ -8,10 +8,11 @@ class BBP_OT_rail_uv(bpy.types.Operator):
bl_idname = "bbp.rail_uv" bl_idname = "bbp.rail_uv"
bl_label = "Rail UV" bl_label = "Rail UV"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_rail_uv'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return _check_rail_target() return _check_rail_target(context)
def invoke(self, context, event): def invoke(self, context, event):
wm: bpy.types.WindowManager = context.window_manager wm: bpy.types.WindowManager = context.window_manager
@ -26,7 +27,13 @@ class BBP_OT_rail_uv(bpy.types.Operator):
return {'CANCELLED'} return {'CANCELLED'}
# apply rail uv # apply rail uv
_create_rail_uv(_get_rail_target(), mtl) (has_invalid_objs, meshes) = _get_rail_target(context)
_create_rail_uv(meshes, mtl)
# show warning if there is invalid objects
if has_invalid_objs:
self.report({'WARNING'}, 'Some objects are invalid for this operation. See Console for more details.')
return {'FINISHED'} return {'FINISHED'}
def draw(self, context): def draw(self, context):
@ -36,8 +43,8 @@ class BBP_OT_rail_uv(bpy.types.Operator):
#region Real Worker Functions #region Real Worker Functions
def _check_rail_target() -> bool: def _check_rail_target(context: bpy.types.Context) -> bool:
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if obj.type != 'MESH': if obj.type != 'MESH':
continue continue
if obj.mode != 'OBJECT': if obj.mode != 'OBJECT':
@ -47,11 +54,11 @@ def _check_rail_target() -> bool:
return True return True
return False return False
def _get_rail_target() -> typing.Iterable[bpy.types.Mesh]: def _get_rail_target(context: bpy.types.Context) -> tuple[bool, typing.Iterable[bpy.types.Mesh]]:
# collect objects # collect objects
meshes: list[bpy.types.Mesh] = [] meshes: list[bpy.types.Mesh] = []
error_objname: list[str] = [] error_objname: list[str] = []
for obj in bpy.context.selected_objects: for obj in context.selected_objects:
if obj.type != 'MESH': if obj.type != 'MESH':
error_objname.append(obj.name) error_objname.append(obj.name)
continue continue
@ -62,28 +69,21 @@ def _get_rail_target() -> typing.Iterable[bpy.types.Mesh]:
error_objname.append(obj.name) error_objname.append(obj.name)
continue continue
meshes.append(obj.data) meshes.append(typing.cast(bpy.types.Mesh, obj.data))
# display warning window if necessary # display warning window if necessary
if len(error_objname) != 0: has_invalid_objs = len(error_objname) != 0
# show dialog if has_invalid_objs:
UTIL_functions.message_box(
("Some objects is not processed, see Console for more infos.", ),
"Object Type Warning",
UTIL_icons_manager.BlenderPresetIcons.Warning.value
)
# output to console # output to console
print('') print('')
print('=====') print('========== Rail UV Report ==========')
print('Following objects are not processed by Rail UV because they do not meet the requirements of Rail UV.') print('Following objects are not processed by Rail UV because they do not meet the requirements of Rail UV.')
for objname in error_objname: for objname in error_objname:
print(objname) print(objname)
print('=====')
print('') print('')
# return valid # return valid
return meshes return (has_invalid_objs, meshes)
def _tt_reflection_mapping_compute( def _tt_reflection_mapping_compute(
point_: UTIL_virtools_types.ConstVxVector3, point_: UTIL_virtools_types.ConstVxVector3,

View File

@ -96,12 +96,14 @@ def is_ballance_element(name: str) -> bool:
class BBP_PG_ballance_element(bpy.types.PropertyGroup): class BBP_PG_ballance_element(bpy.types.PropertyGroup):
element_id: bpy.props.IntProperty( element_id: bpy.props.IntProperty(
name = "Element Id", name = "Element Id",
default = 0 default = 0,
translation_context = 'BBP_PG_ballance_element/property'
) # type: ignore ) # type: ignore
mesh_ptr: bpy.props.PointerProperty( mesh_ptr: bpy.props.PointerProperty(
name = "Mesh", name = "Mesh",
type = bpy.types.Mesh type = bpy.types.Mesh,
translation_context = 'BBP_PG_ballance_element/property'
) # type: ignore ) # type: ignore
def get_ballance_elements(scene: bpy.types.Scene) -> UTIL_functions.CollectionVisitor[BBP_PG_ballance_element]: def get_ballance_elements(scene: bpy.types.Scene) -> UTIL_functions.CollectionVisitor[BBP_PG_ballance_element]:
@ -322,6 +324,7 @@ class BBP_OT_reset_ballance_elements(bpy.types.Operator):
bl_idname = "bbp.reset_ballance_elements" bl_idname = "bbp.reset_ballance_elements"
bl_label = "Reset Ballance Elements" bl_label = "Reset Ballance Elements"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_reset_ballance_elements'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -331,11 +334,7 @@ class BBP_OT_reset_ballance_elements(bpy.types.Operator):
with BallanceElementsHelper(context.scene) as helper: with BallanceElementsHelper(context.scene) as helper:
helper.reset_elements() helper.reset_elements()
# show a window to let user know, not silence # show a window to let user know, not silence
UTIL_functions.message_box( self.report({'INFO'}, 'Reset Ballance elements successfully.')
('Reset OK.', ),
"Reset Result",
UTIL_icons_manager.BlenderPresetIcons.Info.value
)
return {'FINISHED'} return {'FINISHED'}
class BBP_PT_ballance_elements(bpy.types.Panel): class BBP_PT_ballance_elements(bpy.types.Panel):
@ -345,6 +344,7 @@ class BBP_PT_ballance_elements(bpy.types.Panel):
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = "scene" bl_context = "scene"
bl_translation_context = 'BBP_PT_ballance_elements'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -22,7 +22,8 @@ class BBP_PG_ballance_map_info(bpy.types.PropertyGroup):
default = 1, default = 1,
max = 999, min = 1, max = 999, min = 1,
soft_max = 8, soft_min = 1, soft_max = 8, soft_min = 1,
step = 1 step = 1,
translation_context = 'BBP_PG_ballance_map_info/property'
) # type: ignore ) # type: ignore
def get_ballance_map_info(scene: bpy.types.Scene) -> BBP_PG_ballance_map_info: def get_ballance_map_info(scene: bpy.types.Scene) -> BBP_PG_ballance_map_info:
@ -51,6 +52,7 @@ class BBP_PT_ballance_map_info(bpy.types.Panel):
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = "scene" bl_context = "scene"
bl_translation_context = 'BBP_PT_ballance_map_info'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -77,12 +77,14 @@ _g_BMEMaterialPresets: dict[str, _BMEMaterialPreset] = {
class BBP_PG_bme_material(bpy.types.PropertyGroup): class BBP_PG_bme_material(bpy.types.PropertyGroup):
bme_material_name: bpy.props.StringProperty( bme_material_name: bpy.props.StringProperty(
name = "Name", name = "Name",
default = "" default = "",
translation_context = 'BBP_PG_bme_material/property'
) # type: ignore ) # type: ignore
material_ptr: bpy.props.PointerProperty( material_ptr: bpy.props.PointerProperty(
name = "Material", name = "Material",
type = bpy.types.Material type = bpy.types.Material,
translation_context = 'BBP_PG_bme_material/property'
) # type: ignore ) # type: ignore
def get_bme_materials(scene: bpy.types.Scene) -> UTIL_functions.CollectionVisitor[BBP_PG_bme_material]: def get_bme_materials(scene: bpy.types.Scene) -> UTIL_functions.CollectionVisitor[BBP_PG_bme_material]:
@ -175,6 +177,14 @@ class BMEMaterialsHelper():
self.__mMaterialMap[preset_name] = new_mtl self.__mMaterialMap[preset_name] = new_mtl
return new_mtl return new_mtl
def reset_materials(self) -> None:
if not self.is_valid():
raise UTIL_functions.BBPException('calling invalid BMEMaterialsHelper')
# load all items
for preset_name, mtl in self.__mMaterialMap.items():
_load_bme_material_preset(mtl, preset_name)
def __write_to_bme_materials(self) -> None: def __write_to_bme_materials(self) -> None:
mtls = get_bme_materials(self.__mAssocScene) mtls = get_bme_materials(self.__mAssocScene)
mtls.clear() mtls.clear()
@ -194,28 +204,6 @@ class BMEMaterialsHelper():
# add into map # add into map
self.__mMaterialMap[item.bme_material_name] = item.material_ptr self.__mMaterialMap[item.bme_material_name] = item.material_ptr
def reset_bme_materials(scene: bpy.types.Scene) -> None:
invalid_idx: list[int] = []
mtls = get_bme_materials(scene)
# re-load all elements
index: int = 0
item: BBP_PG_bme_material
for item in mtls:
# load or record invalid entry
if item.material_ptr is None:
invalid_idx.append(index)
else:
_load_bme_material_preset(item.material_ptr, item.bme_material_name)
# inc counter
index += 1
# remove invalid one with reversed order
invalid_idx.reverse()
for idx in invalid_idx:
mtls.remove(idx)
#endregion #endregion
#region BME Materials Representation #region BME Materials Representation
@ -233,19 +221,17 @@ class BBP_OT_reset_bme_materials(bpy.types.Operator):
bl_idname = "bbp.reset_bme_materials" bl_idname = "bbp.reset_bme_materials"
bl_label = "Reset BME Materials" bl_label = "Reset BME Materials"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_reset_bme_materials'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return context.scene is not None return context.scene is not None
def execute(self, context): def execute(self, context):
reset_bme_materials(context.scene) with BMEMaterialsHelper(context.scene) as helper:
helper.reset_materials()
# show a window to let user know, not silence # show a window to let user know, not silence
UTIL_functions.message_box( self.report({'INFO'}, 'Reset BME materials successfully.')
('Reset OK.', ),
"Reset Result",
UTIL_icons_manager.BlenderPresetIcons.Info.value
)
return {'FINISHED'} return {'FINISHED'}
class BBP_PT_bme_materials(bpy.types.Panel): class BBP_PT_bme_materials(bpy.types.Panel):
@ -255,6 +241,7 @@ class BBP_PT_bme_materials(bpy.types.Panel):
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = "scene" bl_context = "scene"
bl_translation_context = 'BBP_PT_bme_materials'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -22,18 +22,20 @@ class BBPPreferences(bpy.types.AddonPreferences):
ballance_texture_folder: bpy.props.StringProperty( ballance_texture_folder: bpy.props.StringProperty(
name = "Ballance Texture Folder", name = "Ballance Texture Folder",
description = "The path to folder which will be used by this plugin to get external Ballance texture.", description = "The path to folder which will be used by this plugin to get external Ballance texture.",
subtype='DIR_PATH', subtype = 'DIR_PATH',
default = RawPreferences.cBallanceTextureFolder, default = RawPreferences.cBallanceTextureFolder,
translation_context = 'BBPPreferences/property'
) # type: ignore ) # type: ignore
no_component_collection: bpy.props.StringProperty( no_component_collection: bpy.props.StringProperty(
name = "No Component Collection", name = "No Component Collection",
description = "(Import) The object which stored in this collectiion will not be saved as component. (Export) All forced no component objects will be stored in this collection", description = "When importing, it is the name of collection where objects store will not be saved as component. When exporting, all forced no component objects will be stored in this name represented collection",
default = RawPreferences.cNoComponentCollection, default = RawPreferences.cNoComponentCollection,
translation_context = 'BBPPreferences/property'
) # type: ignore ) # type: ignore
def draw(self, context): def draw(self, context):
layout = self.layout layout: bpy.types.UILayout = self.layout
row = layout.row() row = layout.row()
col = row.column() col = row.column()

View File

@ -12,7 +12,8 @@ from . import UTIL_functions, UTIL_virtools_types
class BBP_PG_bmap_encoding(bpy.types.PropertyGroup): class BBP_PG_bmap_encoding(bpy.types.PropertyGroup):
encoding: bpy.props.StringProperty( encoding: bpy.props.StringProperty(
name = "Encoding", name = "Encoding",
default = "" default = "",
translation_context = 'BBP_PG_bmap_encoding/property'
) # type: ignore ) # type: ignore
class BBP_UL_bmap_encoding(bpy.types.UIList): class BBP_UL_bmap_encoding(bpy.types.UIList):
@ -24,23 +25,25 @@ class BBP_PG_ptrprop_resolver(bpy.types.PropertyGroup):
name = "Material", name = "Material",
description = "The material used for rail", description = "The material used for rail",
type = bpy.types.Material, type = bpy.types.Material,
translation_context = 'BBP_PG_ptrprop_resolver/property'
) # type: ignore ) # type: ignore
export_collection: bpy.props.PointerProperty( export_collection: bpy.props.PointerProperty(
type = bpy.types.Collection,
name = "Collection", name = "Collection",
description = "The collection exported. Nested collections allowed." description = "The collection exported. Nested collections allowed.",
type = bpy.types.Collection,
translation_context = 'BBP_PG_ptrprop_resolver/property'
) # type: ignore ) # type: ignore
export_object: bpy.props.PointerProperty( export_object: bpy.props.PointerProperty(
type = bpy.types.Object,
name = "Object", name = "Object",
description = "The object exported" description = "The object exported",
type = bpy.types.Object,
translation_context = 'BBP_PG_ptrprop_resolver/property'
) # type: ignore ) # type: ignore
ioport_encodings: bpy.props.CollectionProperty( # TR: These encoding related items should not have explicit name and description
type = BBP_PG_bmap_encoding ioport_encodings: bpy.props.CollectionProperty(type = BBP_PG_bmap_encoding) # type: ignore
) # type: ignore
active_ioport_encodings: bpy.props.IntProperty() # type: ignore active_ioport_encodings: bpy.props.IntProperty() # type: ignore
#endregion #endregion
@ -62,6 +65,7 @@ class BBP_OT_add_ioport_encodings(bpy.types.Operator):
bl_idname = "bbp.add_ioport_encodings" bl_idname = "bbp.add_ioport_encodings"
bl_label = "Add in Encodings List" bl_label = "Add in Encodings List"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_add_ioport_encodings'
@classmethod @classmethod
def poll(cls, context: bpy.types.Context) -> bool: def poll(cls, context: bpy.types.Context) -> bool:
@ -77,6 +81,7 @@ class BBP_OT_rm_ioport_encodings(bpy.types.Operator):
bl_idname = "bbp.rm_ioport_encodings" bl_idname = "bbp.rm_ioport_encodings"
bl_label = "Remove from Encodings List" bl_label = "Remove from Encodings List"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_rm_ioport_encodings'
@classmethod @classmethod
def poll(cls, context: bpy.types.Context) -> bool: def poll(cls, context: bpy.types.Context) -> bool:
@ -100,6 +105,7 @@ class BBP_OT_up_ioport_encodings(bpy.types.Operator):
bl_idname = "bbp.up_ioport_encodings" bl_idname = "bbp.up_ioport_encodings"
bl_label = "Move Up in Encodings List" bl_label = "Move Up in Encodings List"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_up_ioport_encodings'
@classmethod @classmethod
def poll(cls, context: bpy.types.Context) -> bool: def poll(cls, context: bpy.types.Context) -> bool:
@ -119,6 +125,7 @@ class BBP_OT_down_ioport_encodings(bpy.types.Operator):
bl_idname = "bbp.down_ioport_encodings" bl_idname = "bbp.down_ioport_encodings"
bl_label = "Move Down in Encodings List" bl_label = "Move Down in Encodings List"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_down_ioport_encodings'
@classmethod @classmethod
def poll(cls, context: bpy.types.Context) -> bool: def poll(cls, context: bpy.types.Context) -> bool:
@ -138,6 +145,7 @@ class BBP_OT_clear_ioport_encodings(bpy.types.Operator):
bl_idname = "bbp.clear_ioport_encodings" bl_idname = "bbp.clear_ioport_encodings"
bl_label = "Clear Encodings List" bl_label = "Clear Encodings List"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_clear_ioport_encodings'
@classmethod @classmethod
def poll(cls, context: bpy.types.Context) -> bool: def poll(cls, context: bpy.types.Context) -> bool:

View File

@ -7,7 +7,8 @@ from . import UTIL_functions, UTIL_icons_manager
class BBP_PG_virtools_group(bpy.types.PropertyGroup): class BBP_PG_virtools_group(bpy.types.PropertyGroup):
group_name: bpy.props.StringProperty( group_name: bpy.props.StringProperty(
name = "Group Name", name = "Group Name",
default = "" default = "",
translation_context = 'BBP_PG_virtools_group/property'
) # type: ignore ) # type: ignore
def get_virtools_groups(obj: bpy.types.Object) -> UTIL_functions.CollectionVisitor[BBP_PG_virtools_group]: def get_virtools_groups(obj: bpy.types.Object) -> UTIL_functions.CollectionVisitor[BBP_PG_virtools_group]:
@ -251,18 +252,21 @@ class SharedGroupNameInputProperties():
('DEFINED', "Predefined", "Pre-defined group name."), ('DEFINED', "Predefined", "Pre-defined group name."),
('CUSTOM', "Custom", "User specified group name."), ('CUSTOM', "Custom", "User specified group name."),
), ),
translation_context = 'BME/PROP_virtools_grourp.SharedGroupNameInputProperties/property'
) # type: ignore ) # type: ignore
preset_group_name: bpy.props.EnumProperty( preset_group_name: bpy.props.EnumProperty(
name = "Group Name", name = "Group Name",
description = "Pick vanilla Ballance group name.", description = "Pick vanilla Ballance group name.",
items = _g_EnumHelper_Group.generate_items(), items = _g_EnumHelper_Group.generate_items(),
translation_context = 'BME/PROP_virtools_grourp.SharedGroupNameInputProperties/property'
) # type: ignore ) # type: ignore
custom_group_name: bpy.props.StringProperty( custom_group_name: bpy.props.StringProperty(
name = "Custom Group Name", name = "Custom Group Name",
description = "Input your custom group name.", description = "Input your custom group name.",
default = "", default = "",
translation_context = 'BME/PROP_virtools_grourp.SharedGroupNameInputProperties/property'
) # type: ignore ) # type: ignore
def draw_group_name_input(self, layout: bpy.types.UILayout) -> None: def draw_group_name_input(self, layout: bpy.types.UILayout) -> None:
@ -291,6 +295,7 @@ class BBP_OT_add_virtools_group(bpy.types.Operator, SharedGroupNameInputProperti
bl_idname = "bbp.add_virtools_groups" bl_idname = "bbp.add_virtools_groups"
bl_label = "Add to Virtools Groups" bl_label = "Add to Virtools Groups"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_add_virtools_group'
@classmethod @classmethod
def poll(cls, context: bpy.types.Context): def poll(cls, context: bpy.types.Context):
@ -315,6 +320,7 @@ class BBP_OT_rm_virtools_group(bpy.types.Operator):
bl_idname = "bbp.rm_virtools_groups" bl_idname = "bbp.rm_virtools_groups"
bl_label = "Remove from Virtools Groups" bl_label = "Remove from Virtools Groups"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_rm_virtools_group'
## This class is slightly unique. ## This class is slightly unique.
# Because we need get user selected group name first. # Because we need get user selected group name first.
@ -347,6 +353,7 @@ class BBP_OT_clear_virtools_groups(bpy.types.Operator):
bl_idname = "bbp.clear_virtools_groups" bl_idname = "bbp.clear_virtools_groups"
bl_label = "Clear Virtools Groups" bl_label = "Clear Virtools Groups"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_clear_virtools_groups'
@classmethod @classmethod
def poll(cls, context: bpy.types.Context): def poll(cls, context: bpy.types.Context):
@ -369,6 +376,7 @@ class BBP_PT_virtools_groups(bpy.types.Panel):
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = "object" bl_context = "object"
bl_translation_context = 'BBP_PT_virtools_groups'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -80,7 +80,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
name = "Type", name = "Type",
description = "The type of this light", description = "The type of this light",
items = _g_Helper_VXLIGHT_TYPE.generate_items(), items = _g_Helper_VXLIGHT_TYPE.generate_items(),
default = _g_Helper_VXLIGHT_TYPE.to_selection(RawVirtoolsLight.cDefaultType) default = _g_Helper_VXLIGHT_TYPE.to_selection(RawVirtoolsLight.cDefaultType),
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
light_color: bpy.props.FloatVectorProperty( light_color: bpy.props.FloatVectorProperty(
@ -90,7 +91,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 1.0, max = 1.0,
size = 3, size = 3,
default = RawVirtoolsLight.cDefaultColor.to_const_rgb() default = RawVirtoolsLight.cDefaultColor.to_const_rgb(),
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
constant_attenuation: bpy.props.FloatProperty( constant_attenuation: bpy.props.FloatProperty(
@ -99,7 +101,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 10.0, max = 10.0,
step = 10, step = 10,
default = RawVirtoolsLight.cDefaultConstantAttenuation default = RawVirtoolsLight.cDefaultConstantAttenuation,
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
linear_attenuation: bpy.props.FloatProperty( linear_attenuation: bpy.props.FloatProperty(
@ -108,7 +111,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 10.0, max = 10.0,
step = 10, step = 10,
default = RawVirtoolsLight.cDefaultLinearAttenuation default = RawVirtoolsLight.cDefaultLinearAttenuation,
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
quadratic_attenuation: bpy.props.FloatProperty( quadratic_attenuation: bpy.props.FloatProperty(
@ -117,7 +121,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 10.0, max = 10.0,
step = 10, step = 10,
default = RawVirtoolsLight.cDefaultQuadraticAttenuation default = RawVirtoolsLight.cDefaultQuadraticAttenuation,
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
light_range: bpy.props.FloatProperty( light_range: bpy.props.FloatProperty(
@ -126,7 +131,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 200.0, max = 200.0,
step = 100, step = 100,
default = RawVirtoolsLight.cDefaultRange default = RawVirtoolsLight.cDefaultRange,
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
hot_spot: bpy.props.FloatProperty( hot_spot: bpy.props.FloatProperty(
@ -135,7 +141,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = math.radians(180), max = math.radians(180),
subtype = 'ANGLE', subtype = 'ANGLE',
default = RawVirtoolsLight.cDefaultHotSpot default = RawVirtoolsLight.cDefaultHotSpot,
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
falloff: bpy.props.FloatProperty( falloff: bpy.props.FloatProperty(
@ -144,7 +151,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = math.radians(180), max = math.radians(180),
subtype = 'ANGLE', subtype = 'ANGLE',
default = RawVirtoolsLight.cDefaultFalloff default = RawVirtoolsLight.cDefaultFalloff,
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
falloff_shape: bpy.props.FloatProperty( falloff_shape: bpy.props.FloatProperty(
@ -153,7 +161,8 @@ class BBP_PG_virtools_light(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 10.0, max = 10.0,
step = 10, step = 10,
default = RawVirtoolsLight.cDefaultFalloffShape default = RawVirtoolsLight.cDefaultFalloffShape,
translation_context = 'BBP_PG_virtools_light/property'
) # type: ignore ) # type: ignore
# Getter Setter and Applyer # Getter Setter and Applyer
@ -239,6 +248,7 @@ class BBP_OT_apply_virtools_light(bpy.types.Operator):
bl_idname = "bbp.apply_virtools_light" bl_idname = "bbp.apply_virtools_light"
bl_label = "Apply to Blender Light" bl_label = "Apply to Blender Light"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_apply_virtools_light'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -258,6 +268,7 @@ class BBP_PT_virtools_light(bpy.types.Panel):
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = "data" # idk why blender use `data` as the light tab same as mesh. bl_context = "data" # idk why blender use `data` as the light tab same as mesh.
bl_translation_context = 'BBP_PT_virtools_light'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -132,7 +132,8 @@ class BBP_PG_virtools_material(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 1.0, max = 1.0,
size = 3, size = 3,
default = RawVirtoolsMaterial.cDefaultAmbient.to_const_rgb() default = RawVirtoolsMaterial.cDefaultAmbient.to_const_rgb(),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
diffuse: bpy.props.FloatVectorProperty( diffuse: bpy.props.FloatVectorProperty(
@ -142,7 +143,8 @@ class BBP_PG_virtools_material(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 1.0, max = 1.0,
size = 4, size = 4,
default = RawVirtoolsMaterial.cDefaultDiffuse.to_const_rgba() default = RawVirtoolsMaterial.cDefaultDiffuse.to_const_rgba(),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
specular: bpy.props.FloatVectorProperty( specular: bpy.props.FloatVectorProperty(
@ -152,7 +154,8 @@ class BBP_PG_virtools_material(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 1.0, max = 1.0,
size = 3, size = 3,
default = RawVirtoolsMaterial.cDefaultSpecular.to_const_rgb() default = RawVirtoolsMaterial.cDefaultSpecular.to_const_rgb(),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
emissive: bpy.props.FloatVectorProperty( emissive: bpy.props.FloatVectorProperty(
@ -162,7 +165,8 @@ class BBP_PG_virtools_material(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 1.0, max = 1.0,
size = 3, size = 3,
default = RawVirtoolsMaterial.cDefaultEmissive.to_const_rgb() default = RawVirtoolsMaterial.cDefaultEmissive.to_const_rgb(),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
specular_power: bpy.props.FloatProperty( specular_power: bpy.props.FloatProperty(
@ -170,13 +174,15 @@ class BBP_PG_virtools_material(bpy.types.PropertyGroup):
description = "Specular highlight power", description = "Specular highlight power",
min = 0.0, min = 0.0,
max = 100.0, max = 100.0,
default = RawVirtoolsMaterial.cDefaultSpecularPower default = RawVirtoolsMaterial.cDefaultSpecularPower,
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
texture: bpy.props.PointerProperty( texture: bpy.props.PointerProperty(
type = bpy.types.Image, type = bpy.types.Image,
name = "Texture", name = "Texture",
description = "Texture of the material" description = "Texture of the material",
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
texture_border_color: bpy.props.FloatVectorProperty( texture_border_color: bpy.props.FloatVectorProperty(
@ -186,89 +192,103 @@ class BBP_PG_virtools_material(bpy.types.PropertyGroup):
min = 0.0, min = 0.0,
max = 1.0, max = 1.0,
size = 4, size = 4,
default = RawVirtoolsMaterial.cDefaultTextureBorderColor.to_const_rgba() default = RawVirtoolsMaterial.cDefaultTextureBorderColor.to_const_rgba(),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
texture_blend_mode: bpy.props.EnumProperty( texture_blend_mode: bpy.props.EnumProperty(
name = "Texture Blend", name = "Texture Blend",
description = "Texture blend mode", description = "Texture blend mode",
items = _g_Helper_VXTEXTURE_BLENDMODE.generate_items(), items = _g_Helper_VXTEXTURE_BLENDMODE.generate_items(),
default = _g_Helper_VXTEXTURE_BLENDMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureBlendMode) default = _g_Helper_VXTEXTURE_BLENDMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureBlendMode),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
texture_min_mode: bpy.props.EnumProperty( texture_min_mode: bpy.props.EnumProperty(
name = "Filter Min", name = "Filter Min",
description = "Texture filter mode when the texture is minified", description = "Texture filter mode when the texture is minified",
items = _g_Helper_VXTEXTURE_FILTERMODE.generate_items(), items = _g_Helper_VXTEXTURE_FILTERMODE.generate_items(),
default = _g_Helper_VXTEXTURE_FILTERMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureMinMode) default = _g_Helper_VXTEXTURE_FILTERMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureMinMode),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
texture_mag_mode: bpy.props.EnumProperty( texture_mag_mode: bpy.props.EnumProperty(
name = "Filter Mag", name = "Filter Mag",
description = "Texture filter mode when the texture is magnified", description = "Texture filter mode when the texture is magnified",
items = _g_Helper_VXTEXTURE_FILTERMODE.generate_items(), items = _g_Helper_VXTEXTURE_FILTERMODE.generate_items(),
default = _g_Helper_VXTEXTURE_FILTERMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureMagMode) default = _g_Helper_VXTEXTURE_FILTERMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureMagMode),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
texture_address_mode: bpy.props.EnumProperty( texture_address_mode: bpy.props.EnumProperty(
name = "Address Mode", name = "Address Mode",
description = "The address mode controls how the texture coordinates outside the range 0..1", description = "The address mode controls how the texture coordinates outside the range 0..1",
items = _g_Helper_VXTEXTURE_ADDRESSMODE.generate_items(), items = _g_Helper_VXTEXTURE_ADDRESSMODE.generate_items(),
default = _g_Helper_VXTEXTURE_ADDRESSMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureAddressMode) default = _g_Helper_VXTEXTURE_ADDRESSMODE.to_selection(RawVirtoolsMaterial.cDefaultTextureAddressMode),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
source_blend: bpy.props.EnumProperty( source_blend: bpy.props.EnumProperty(
name = "Source Blend", name = "Source Blend",
description = "Source blend factor", description = "Source blend factor",
items = _g_Helper_VXBLEND_MODE.generate_items(), items = _g_Helper_VXBLEND_MODE.generate_items(),
default = _g_Helper_VXBLEND_MODE.to_selection(RawVirtoolsMaterial.cDefaultSourceBlend) default = _g_Helper_VXBLEND_MODE.to_selection(RawVirtoolsMaterial.cDefaultSourceBlend),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
dest_blend: bpy.props.EnumProperty( dest_blend: bpy.props.EnumProperty(
name = "Destination Blend", name = "Destination Blend",
description = "Destination blend factor", description = "Destination blend factor",
items = _g_Helper_VXBLEND_MODE.generate_items(), items = _g_Helper_VXBLEND_MODE.generate_items(),
default = _g_Helper_VXBLEND_MODE.to_selection(RawVirtoolsMaterial.cDefaultDestBlend) default = _g_Helper_VXBLEND_MODE.to_selection(RawVirtoolsMaterial.cDefaultDestBlend),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
fill_mode: bpy.props.EnumProperty( fill_mode: bpy.props.EnumProperty(
name = "Fill Mode", name = "Fill Mode",
description = "Fill mode", description = "Fill mode",
items = _g_Helper_VXFILL_MODE.generate_items(), items = _g_Helper_VXFILL_MODE.generate_items(),
default = _g_Helper_VXFILL_MODE.to_selection(RawVirtoolsMaterial.cDefaultFillMode) default = _g_Helper_VXFILL_MODE.to_selection(RawVirtoolsMaterial.cDefaultFillMode),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
shade_mode: bpy.props.EnumProperty( shade_mode: bpy.props.EnumProperty(
name = "Shade Mode", name = "Shade Mode",
description = "Shade mode", description = "Shade mode",
items = _g_Helper_VXSHADE_MODE.generate_items(), items = _g_Helper_VXSHADE_MODE.generate_items(),
default = _g_Helper_VXSHADE_MODE.to_selection(RawVirtoolsMaterial.cDefaultShadeMode) default = _g_Helper_VXSHADE_MODE.to_selection(RawVirtoolsMaterial.cDefaultShadeMode),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
enable_alpha_test: bpy.props.BoolProperty( enable_alpha_test: bpy.props.BoolProperty(
name = "Alpha Test", name = "Alpha Test",
description = "Whether the alpha test is enabled", description = "Whether the alpha test is enabled",
default = RawVirtoolsMaterial.cDefaultEnableAlphaTest default = RawVirtoolsMaterial.cDefaultEnableAlphaTest,
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
enable_alpha_blend: bpy.props.BoolProperty( enable_alpha_blend: bpy.props.BoolProperty(
name = "Blend", name = "Blend",
description = "Whether alpha blending is enabled or not.", description = "Whether alpha blending is enabled or not.",
default = RawVirtoolsMaterial.cDefaultEnableAlphaBlend default = RawVirtoolsMaterial.cDefaultEnableAlphaBlend,
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
enable_perspective_correction: bpy.props.BoolProperty( enable_perspective_correction: bpy.props.BoolProperty(
name = "Perspective Correction", name = "Perspective Correction",
description = "Whether texture perspective correction is enabled", description = "Whether texture perspective correction is enabled",
default = RawVirtoolsMaterial.cDefaultEnablePerspectiveCorrection default = RawVirtoolsMaterial.cDefaultEnablePerspectiveCorrection,
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
enable_z_write: bpy.props.BoolProperty( enable_z_write: bpy.props.BoolProperty(
name = "Z-Buffer Write", name = "Z-Buffer Write",
description = "Whether writing in ZBuffer is enabled.", description = "Whether writing in ZBuffer is enabled.",
default = RawVirtoolsMaterial.cDefaultEnableZWrite default = RawVirtoolsMaterial.cDefaultEnableZWrite,
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
enable_two_sided: bpy.props.BoolProperty( enable_two_sided: bpy.props.BoolProperty(
name = "Both Sided", name = "Both Sided",
description = "Whether the material is both sided or not", description = "Whether the material is both sided or not",
default = RawVirtoolsMaterial.cDefaultEnableTwoSided default = RawVirtoolsMaterial.cDefaultEnableTwoSided,
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
alpha_ref: bpy.props.IntProperty( alpha_ref: bpy.props.IntProperty(
@ -276,21 +296,24 @@ class BBP_PG_virtools_material(bpy.types.PropertyGroup):
description = "Alpha referential value", description = "Alpha referential value",
min = 0, min = 0,
max = 255, max = 255,
default = RawVirtoolsMaterial.cDefaultAlphaRef default = RawVirtoolsMaterial.cDefaultAlphaRef,
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
alpha_func: bpy.props.EnumProperty( alpha_func: bpy.props.EnumProperty(
name = "Alpha Test Function", name = "Alpha Test Function",
description = "Alpha comparision function", description = "Alpha comparision function",
items = _g_Helper_VXCMPFUNC.generate_items(), items = _g_Helper_VXCMPFUNC.generate_items(),
default = _g_Helper_VXCMPFUNC.to_selection(RawVirtoolsMaterial.cDefaultAlphaFunc) default = _g_Helper_VXCMPFUNC.to_selection(RawVirtoolsMaterial.cDefaultAlphaFunc),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
z_func: bpy.props.EnumProperty( z_func: bpy.props.EnumProperty(
name = "Z Compare Function", name = "Z Compare Function",
description = "Z Comparison function", description = "Z Comparison function",
items = _g_Helper_VXCMPFUNC.generate_items(), items = _g_Helper_VXCMPFUNC.generate_items(),
default = _g_Helper_VXCMPFUNC.to_selection(RawVirtoolsMaterial.cDefaultZFunc) default = _g_Helper_VXCMPFUNC.to_selection(RawVirtoolsMaterial.cDefaultZFunc),
translation_context = 'BBP_PG_virtools_material/property'
) # type: ignore ) # type: ignore
#region Getter Setter #region Getter Setter
@ -877,6 +900,7 @@ class BBP_OT_apply_virtools_material(bpy.types.Operator):
bl_idname = "bbp.apply_virtools_material" bl_idname = "bbp.apply_virtools_material"
bl_label = "Apply to Blender Material" bl_label = "Apply to Blender Material"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_apply_virtools_material'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -892,6 +916,7 @@ class BBP_OT_fix_single_material(bpy.types.Operator):
bl_idname = "bbp.fix_single_material" bl_idname = "bbp.fix_single_material"
bl_label = "Fix Material" bl_label = "Fix Material"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_fix_single_material'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -911,7 +936,7 @@ class BBP_OT_fix_single_material(bpy.types.Operator):
# if suc, apply to blender mtl and show info # if suc, apply to blender mtl and show info
if ret: if ret:
apply_to_blender_material(mtl) apply_to_blender_material(mtl)
self.report({'INFO'}, 'Fix done.') self.report({'INFO'}, 'Fix material successfully.')
else: else:
# otherwise report warning # otherwise report warning
self.report({'WARNING'}, 'This material is not suit for fixer.') self.report({'WARNING'}, 'This material is not suit for fixer.')
@ -923,6 +948,7 @@ class BBP_OT_preset_virtools_material(bpy.types.Operator):
bl_idname = "bbp.preset_virtools_material" bl_idname = "bbp.preset_virtools_material"
bl_label = "Preset Virtools Material" bl_label = "Preset Virtools Material"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_preset_virtools_material'
preset_type: bpy.props.EnumProperty( preset_type: bpy.props.EnumProperty(
name = "Preset", name = "Preset",
@ -957,6 +983,7 @@ class BBP_OT_direct_set_virtools_texture(bpy.types.Operator, UTIL_file_browser.I
bl_idname = "bbp.direct_set_virtools_texture" bl_idname = "bbp.direct_set_virtools_texture"
bl_label = "Import and Assign Texture" bl_label = "Import and Assign Texture"
bl_options = {'UNDO'} bl_options = {'UNDO'}
bl_translation_context = 'BBP_OT_direct_set_virtools_texture'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
@ -1009,6 +1036,7 @@ class BBP_PT_virtools_material(bpy.types.Panel):
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = "material" bl_context = "material"
bl_translation_context = 'BBP_PT_virtools_material'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -24,7 +24,8 @@ class BBP_PG_virtools_mesh(bpy.types.PropertyGroup):
name = "Lit Mode", name = "Lit Mode",
description = "Lighting mode of the mesh.", description = "Lighting mode of the mesh.",
items = _g_Helper_VXMESH_LITMODE.generate_items(), items = _g_Helper_VXMESH_LITMODE.generate_items(),
default = _g_Helper_VXMESH_LITMODE.to_selection(RawVirtoolsMesh.cDefaultLitMode) default = _g_Helper_VXMESH_LITMODE.to_selection(RawVirtoolsMesh.cDefaultLitMode),
translation_context = 'BBP_PG_virtools_mesh/property'
) # type: ignore ) # type: ignore
# Getter Setter # Getter Setter
@ -54,6 +55,7 @@ class BBP_PT_virtools_mesh(bpy.types.Panel):
bl_space_type = 'PROPERTIES' bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_context = "data" # idk why blender use `data` as the mesh tab. bl_context = "data" # idk why blender use `data` as the mesh tab.
bl_translation_context = 'BBP_PT_virtools_mesh'
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -29,14 +29,16 @@ class BBP_PG_virtools_texture(bpy.types.PropertyGroup):
name = "Save Options", name = "Save Options",
description = "When saving a composition textures or sprites can be kept as reference to external files or converted to a given format and saved inside the composition file.", description = "When saving a composition textures or sprites can be kept as reference to external files or converted to a given format and saved inside the composition file.",
items = _g_Helper_CK_TEXTURE_SAVEOPTIONS.generate_items(), items = _g_Helper_CK_TEXTURE_SAVEOPTIONS.generate_items(),
default = _g_Helper_CK_TEXTURE_SAVEOPTIONS.to_selection(RawVirtoolsTexture.cDefaultSaveOptions) default = _g_Helper_CK_TEXTURE_SAVEOPTIONS.to_selection(RawVirtoolsTexture.cDefaultSaveOptions),
translation_context = 'BBP_PG_virtools_texture/property'
) # type: ignore ) # type: ignore
video_format: bpy.props.EnumProperty( video_format: bpy.props.EnumProperty(
name = "Video Format", name = "Video Format",
description = "The desired surface pixel format in video memory.", description = "The desired surface pixel format in video memory.",
items = _g_Helper_VX_PIXELFORMAT.generate_items(), items = _g_Helper_VX_PIXELFORMAT.generate_items(),
default = _g_Helper_VX_PIXELFORMAT.to_selection(RawVirtoolsTexture.cDefaultVideoFormat) default = _g_Helper_VX_PIXELFORMAT.to_selection(RawVirtoolsTexture.cDefaultVideoFormat),
translation_context = 'BBP_PG_virtools_texture/property'
) # type: ignore ) # type: ignore
#region Virtools Texture Getter Setter #region Virtools Texture Getter Setter

View File

@ -159,6 +159,7 @@ class ImportParams():
items = _g_EnumHelper_ConflictStrategy.generate_items(), items = _g_EnumHelper_ConflictStrategy.generate_items(),
description = "Define how to process texture name conflict", description = "Define how to process texture name conflict",
default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Current), default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Current),
translation_context = 'BME/UTIL_ioport_shared.ImportParams/property'
) # type: ignore ) # type: ignore
material_conflict_strategy: bpy.props.EnumProperty( material_conflict_strategy: bpy.props.EnumProperty(
@ -166,6 +167,7 @@ class ImportParams():
items = _g_EnumHelper_ConflictStrategy.generate_items(), items = _g_EnumHelper_ConflictStrategy.generate_items(),
description = "Define how to process material name conflict", description = "Define how to process material name conflict",
default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename),
translation_context = 'BME/UTIL_ioport_shared.ImportParams/property'
) # type: ignore ) # type: ignore
mesh_conflict_strategy: bpy.props.EnumProperty( mesh_conflict_strategy: bpy.props.EnumProperty(
@ -173,6 +175,7 @@ class ImportParams():
items = _g_EnumHelper_ConflictStrategy.generate_items(), items = _g_EnumHelper_ConflictStrategy.generate_items(),
description = "Define how to process mesh name conflict", description = "Define how to process mesh name conflict",
default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename),
translation_context = 'BME/UTIL_ioport_shared.ImportParams/property'
) # type: ignore ) # type: ignore
light_conflict_strategy: bpy.props.EnumProperty( light_conflict_strategy: bpy.props.EnumProperty(
@ -180,6 +183,7 @@ class ImportParams():
items = _g_EnumHelper_ConflictStrategy.generate_items(), items = _g_EnumHelper_ConflictStrategy.generate_items(),
description = "Define how to process light name conflict", description = "Define how to process light name conflict",
default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename),
translation_context = 'BME/UTIL_ioport_shared.ImportParams/property'
) # type: ignore ) # type: ignore
object_conflict_strategy: bpy.props.EnumProperty( object_conflict_strategy: bpy.props.EnumProperty(
@ -187,6 +191,7 @@ class ImportParams():
items = _g_EnumHelper_ConflictStrategy.generate_items(), items = _g_EnumHelper_ConflictStrategy.generate_items(),
description = "Define how to process object name conflict", description = "Define how to process object name conflict",
default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename), default = _g_EnumHelper_ConflictStrategy.to_selection(ConflictStrategy.Rename),
translation_context = 'BME/UTIL_ioport_shared.ImportParams/property'
) # type: ignore ) # type: ignore
def draw_import_params(self, layout: bpy.types.UILayout) -> None: def draw_import_params(self, layout: bpy.types.UILayout) -> None:
@ -240,6 +245,7 @@ class ExportParams():
('COLLECTION', "Collection", "Export a collection", 'OUTLINER_COLLECTION', 0), ('COLLECTION', "Collection", "Export a collection", 'OUTLINER_COLLECTION', 0),
('OBJECT', "Object", "Export an object", 'OBJECT_DATA', 1), ('OBJECT', "Object", "Export an object", 'OBJECT_DATA', 1),
), ),
translation_context = 'BME/UTIL_ioport_shared.ExportParams/property'
) # type: ignore ) # type: ignore
def draw_export_params(self, context: bpy.types.Context, layout: bpy.types.UILayout) -> None: def draw_export_params(self, context: bpy.types.Context, layout: bpy.types.UILayout) -> None:
@ -284,13 +290,15 @@ class VirtoolsParams():
name = "Global Texture Save Options", name = "Global Texture Save Options",
description = "Decide how texture saved if texture is specified as Use Global as its Save Options.", description = "Decide how texture saved if texture is specified as Use Global as its Save Options.",
items = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.generate_items(), items = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.generate_items(),
default = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.to_selection(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS.CKTEXTURE_EXTERNAL) default = _g_EnumHelper_CK_TEXTURE_SAVEOPTIONS.to_selection(UTIL_virtools_types.CK_TEXTURE_SAVEOPTIONS.CKTEXTURE_EXTERNAL),
translation_context = 'BME/UTIL_ioport_shared.VirtoolsParams/property'
) # type: ignore ) # type: ignore
use_compress: bpy.props.BoolProperty( use_compress: bpy.props.BoolProperty(
name="Use Compress", name="Use Compress",
description = "Whether use ZLib to compress result when saving composition.", description = "Whether use ZLib to compress result when saving composition.",
default = True, default = True,
translation_context = 'BME/UTIL_ioport_shared.VirtoolsParams/property'
) # type: ignore ) # type: ignore
compress_level: bpy.props.IntProperty( compress_level: bpy.props.IntProperty(
@ -298,6 +306,7 @@ class VirtoolsParams():
description = "The ZLib compress level used by Virtools Engine when saving composition.", description = "The ZLib compress level used by Virtools Engine when saving composition.",
min = 1, max = 9, min = 1, max = 9,
default = 5, default = 5,
translation_context = 'BME/UTIL_ioport_shared.VirtoolsParams/property'
) # type: ignore ) # type: ignore
def draw_virtools_params(self, context: bpy.types.Context, layout: bpy.types.UILayout, is_importer: bool) -> None: def draw_virtools_params(self, context: bpy.types.Context, layout: bpy.types.UILayout, is_importer: bool) -> None:
@ -344,6 +353,7 @@ class BallanceParams():
name="Successive Sector", name="Successive Sector",
description = "Whether order exporter to use document specified sector count to make sure sector is successive.", description = "Whether order exporter to use document specified sector count to make sure sector is successive.",
default = True, default = True,
translation_context = 'BME/UTIL_ioport_shared.BallanceParams/property'
) # type: ignore ) # type: ignore
def draw_ballance_params(self, layout: bpy.types.UILayout, is_importer: bool) -> None: def draw_ballance_params(self, layout: bpy.types.UILayout, is_importer: bool) -> None:

View File

@ -0,0 +1,87 @@
import bpy
#region Translation Contexts
## NOTE: Translation Priniciple
# Due to the shitty design of Blender I18N tools (I can't specify context for every translation entries and its static analyse is so bad),
# I will specify all context but I can't do anything if Blender throw my translation context away.
#
# BME module has its own context naming convention which make sure all configuration fields of prototypes are properly translated.
# This module also provide a corresponding function to compute these context string from given BME prototype name and the index of configuration fields.
#
# For BBP plugin self, there is a priniciple list which you should follow when providing translation context.
# - For operator, menu, panel and etc, set their `bl_translation_context` to their names, such as `BBP_OT_some_operator`
# - For property located in operator, menu, panel and etc, set their `translation_context` to corresponding class name,
# plus `/property` suffix, such as `BBP_OT_some_operator/property`.
# - For draw function located in operator, menu, panel and etc, set their `translation_context` to corresponding class name,
# plus `/draw` suffix, such as `BBP_OT_some_operator/draw`.
# - For property loacted in shared class (usually shared by multiple operators), set their `translation_context` to `BME/<MODULE_NAME>.<CLASS_NAME>/property`.
# `<MODULE_NAME>` is the module name (file name) where this class located. `<CLASS_NAME>` is the name of this class.
# For example, `BBP/some_module.some_class/property`
#
# Due to the shitty design, I can't find a way to add translation context for descrption field.
# So these description may collide with Blender official translation and thus not put in result file.
# I have no idea about this.
#
# Due to the shitty static analyse ability of Blender I18N plugin, all context should be written in literal,
# not the reference to other fields or the return value of some function.
# However for those strings, which originally should not be extracted by Blender I18N plugin, the way to get their context string is free.
#
#
# For the string given to Python `print()` which will be output in console,
# please use `bpy.app.translations.pgettext_rpt()` to get translation message because they are report.
# For the string given to `UTIL_functions.message_box()`, please use `bpy.app.translations.pgettext_iface` because they are UI elements.
#
# It seema that `bpy.app.translations.pgettext` function family has fatal error when extracting message with context
# (it will produce a correct one and a wrong one which just simply concat the message and its context. I don't know why).
#
#
# All translation annotation are started with `TR:`
#
# The universal translation context prefix for BBP_NG plugin.
CTX_BBP: str = 'BBP'
# The universal translation context prefix for BME module in BBP_NG plugin.
CTX_BBP_BME: str = CTX_BBP + '/BME'
def build_prototype_showcase_context(identifier: str) -> str:
"""
Build the context for getting the translation for BME prototype showcase title.
@param[in] identifier The identifier of this prototype.
@return The context for getting translation.
"""
return CTX_BBP_BME + '/' + identifier
def build_prototype_showcase_cfg_context(identifier: str, cfg_index: int) -> str:
"""
Build the context for getting the translation for BME prototype showcase configuration title or description.
@param[in] identifier The identifier of this prototype.
@param[in] cfg_index The index of this configuration in this prototype showcase.
@return The context for getting translation.
"""
return CTX_BBP_BME + f'/{identifier}/[{cfg_index}]'
#endregion
# ##### BEGIN AUTOGENERATED I18N SECTION #####
# NOTE: You can safely move around this auto-generated block (with the begin/end markers!),
# and edit the translations by hand.
# Just carefully respect the format of the tuple!
# Tuple of tuples:
# ((msgctxt, msgid), (sources, gen_comments), (lang, translation, (is_fuzzy, comments)), ...)
translations_tuple = ()
translations_dict = {}
for msg in translations_tuple:
key = msg[0]
for lang, trans, (is_fuzzy, comments) in msg[2:]:
if trans and not is_fuzzy:
translations_dict.setdefault(lang, {})[key] = trans
# ##### END AUTOGENERATED I18N SECTION #####
def register() -> None:
bpy.app.translations.register(__package__, translations_dict)
def unregister() -> None:
bpy.app.translations.unregister(__package__)

View File

@ -5,6 +5,8 @@ import bpy
import typing, collections import typing, collections
# reload if needed # reload if needed
# TODO: finish reload feature if needed.
# (reload script raise too much exceptions so I usually restart blender to test my plugin.)
if "bpy" in locals(): if "bpy" in locals():
import importlib import importlib
@ -16,6 +18,7 @@ from . import UTIL_icons_manager
UTIL_icons_manager.register() UTIL_icons_manager.register()
# then load other modules # then load other modules
from . import UTIL_translation
from . import PROP_preferences, PROP_ptrprop_resolver, PROP_virtools_material, PROP_virtools_texture, PROP_virtools_mesh, PROP_virtools_light, PROP_virtools_group from . import PROP_preferences, PROP_ptrprop_resolver, PROP_virtools_material, PROP_virtools_texture, PROP_virtools_mesh, PROP_virtools_light, PROP_virtools_group
from . import PROP_ballance_element, PROP_bme_material, PROP_ballance_map_info from . import PROP_ballance_element, PROP_bme_material, PROP_ballance_map_info
from . import OP_IMPORT_bmfile, OP_EXPORT_bmfile, OP_IMPORT_virtools, OP_EXPORT_virtools from . import OP_IMPORT_bmfile, OP_EXPORT_bmfile, OP_IMPORT_virtools, OP_EXPORT_virtools
@ -29,29 +32,31 @@ from . import OP_OBJECT_legacy_align, OP_OBJECT_virtools_group, OP_OBJECT_snoop_
# ===== Menu Defines ===== # ===== Menu Defines =====
class BBP_MT_View3DMenu(bpy.types.Menu): class BBP_MT_View3DMenu(bpy.types.Menu):
"""Ballance 3D Operators""" """Ballance 3D related operators"""
bl_idname = "BBP_MT_View3DMenu" bl_idname = "BBP_MT_View3DMenu"
bl_label = "Ballance" bl_label = "Ballance"
bl_translation_context = 'BBP_MT_View3DMenu'
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.label(text = 'UV', icon = 'UV') layout.label(text='UV', icon='UV')
layout.operator(OP_UV_flatten_uv.BBP_OT_flatten_uv.bl_idname) layout.operator(OP_UV_flatten_uv.BBP_OT_flatten_uv.bl_idname)
layout.operator(OP_UV_rail_uv.BBP_OT_rail_uv.bl_idname) layout.operator(OP_UV_rail_uv.BBP_OT_rail_uv.bl_idname)
layout.separator() layout.separator()
layout.label(text = 'Align', icon = 'SNAP_ON') layout.label(text='Align', icon='SNAP_ON')
layout.operator(OP_OBJECT_legacy_align.BBP_OT_legacy_align.bl_idname) layout.operator(OP_OBJECT_legacy_align.BBP_OT_legacy_align.bl_idname)
layout.separator() layout.separator()
layout.label(text = 'Select', icon = 'SELECT_SET') layout.label(text='Select', icon='SELECT_SET')
layout.operator(OP_OBJECT_virtools_group.BBP_OT_select_object_by_virtools_group.bl_idname) layout.operator(OP_OBJECT_virtools_group.BBP_OT_select_object_by_virtools_group.bl_idname)
layout.separator() layout.separator()
layout.label(text = 'Material', icon = 'MATERIAL') layout.label(text='Material', icon='MATERIAL')
layout.operator(OP_MTL_fix_material.BBP_OT_fix_all_material.bl_idname) layout.operator(OP_MTL_fix_material.BBP_OT_fix_all_material.bl_idname)
class BBP_MT_AddBmeMenu(bpy.types.Menu): class BBP_MT_AddBmeMenu(bpy.types.Menu):
"""Add Ballance Floor""" """Add Ballance Floor"""
bl_idname = "BBP_MT_AddBmeMenu" bl_idname = "BBP_MT_AddBmeMenu"
bl_label = "Floors" bl_label = "Floors"
bl_translation_context = 'BBP_MT_AddBmeMenu'
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -61,49 +66,52 @@ class BBP_MT_AddRailMenu(bpy.types.Menu):
"""Add Ballance Rail""" """Add Ballance Rail"""
bl_idname = "BBP_MT_AddRailMenu" bl_idname = "BBP_MT_AddRailMenu"
bl_label = "Rails" bl_label = "Rails"
bl_translation_context = 'BBP_MT_AddRailMenu'
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.label(text = "Sections", icon = 'MESH_CIRCLE') layout.label(text="Sections", icon='MESH_CIRCLE')
layout.operator(OP_ADDS_rail.BBP_OT_add_rail_section.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_rail_section.bl_idname)
layout.operator(OP_ADDS_rail.BBP_OT_add_transition_section.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_transition_section.bl_idname)
layout.separator() layout.separator()
layout.label(text = "Straight Rails", icon = 'IPO_CONSTANT') layout.label(text="Straight Rails", icon='IPO_CONSTANT')
layout.operator(OP_ADDS_rail.BBP_OT_add_straight_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_straight_rail.bl_idname)
layout.operator(OP_ADDS_rail.BBP_OT_add_transition_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_transition_rail.bl_idname)
layout.operator(OP_ADDS_rail.BBP_OT_add_side_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_side_rail.bl_idname)
layout.separator() layout.separator()
layout.label(text = "Curve Rails", icon = 'MOD_SCREW') layout.label(text="Curve Rails", icon='MOD_SCREW')
layout.operator(OP_ADDS_rail.BBP_OT_add_arc_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_arc_rail.bl_idname)
layout.operator(OP_ADDS_rail.BBP_OT_add_spiral_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_spiral_rail.bl_idname)
layout.operator(OP_ADDS_rail.BBP_OT_add_side_spiral_rail.bl_idname) layout.operator(OP_ADDS_rail.BBP_OT_add_side_spiral_rail.bl_idname)
class BBP_MT_AddComponentsMenu(bpy.types.Menu): class BBP_MT_AddComponentsMenu(bpy.types.Menu):
"""Add Ballance Components""" """Add Ballance Component"""
bl_idname = "BBP_MT_AddComponentsMenu" bl_idname = "BBP_MT_AddComponentsMenu"
bl_label = "Components" bl_label = "Components"
bl_translation_context = 'BBP_MT_AddComponentsMenu'
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
layout.label(text = "Basic Components") layout.label(text="Basic Components")
OP_ADDS_component.BBP_OT_add_component.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_component.draw_blc_menu(layout)
layout.separator() layout.separator()
layout.label(text = "Nong Components") layout.label(text="Nong Components")
OP_ADDS_component.BBP_OT_add_nong_extra_point.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_nong_extra_point.draw_blc_menu(layout)
OP_ADDS_component.BBP_OT_add_nong_ventilator.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_nong_ventilator.draw_blc_menu(layout)
layout.separator() layout.separator()
layout.label(text = "Series Components") layout.label(text="Series Components")
OP_ADDS_component.BBP_OT_add_tilting_block_series.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_tilting_block_series.draw_blc_menu(layout)
OP_ADDS_component.BBP_OT_add_swing_series.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_swing_series.draw_blc_menu(layout)
OP_ADDS_component.BBP_OT_add_ventilator_series.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_ventilator_series.draw_blc_menu(layout)
layout.separator() layout.separator()
layout.label(text = "Components Pair") layout.label(text="Components Pair")
OP_ADDS_component.BBP_OT_add_sector_component_pair.draw_blc_menu(layout) OP_ADDS_component.BBP_OT_add_sector_component_pair.draw_blc_menu(layout)
# ===== Menu Drawer ===== # ===== Menu Drawer =====
@ -112,13 +120,13 @@ MenuDrawer_t = typing.Callable[[typing.Any, typing.Any], None]
def menu_drawer_import(self, context) -> None: def menu_drawer_import(self, context) -> None:
layout: bpy.types.UILayout = self.layout layout: bpy.types.UILayout = self.layout
#layout.operator(OP_IMPORT_bmfile.BBP_OT_import_bmfile.bl_idname, text = "Ballance Map (.bmx)") #layout.operator(OP_IMPORT_bmfile.BBP_OT_import_bmfile.bl_idname, text="Ballance Map (.bmx)")
layout.operator(OP_IMPORT_virtools.BBP_OT_import_virtools.bl_idname, text = "Virtools File (.nmo/.cmo/.vmo) (experimental)") layout.operator(OP_IMPORT_virtools.BBP_OT_import_virtools.bl_idname, text="Virtools File (.nmo/.cmo/.vmo) (experimental)")
def menu_drawer_export(self, context) -> None: def menu_drawer_export(self, context) -> None:
layout: bpy.types.UILayout = self.layout layout: bpy.types.UILayout = self.layout
#layout.operator(OP_EXPORT_bmfile.BBP_OT_export_bmfile.bl_idname, text = "Ballance Map (.bmx)") #layout.operator(OP_EXPORT_bmfile.BBP_OT_export_bmfile.bl_idname, text="Ballance Map (.bmx)")
layout.operator(OP_EXPORT_virtools.BBP_OT_export_virtools.bl_idname, text = "Virtools File (.nmo/.cmo/.vmo) (experimental)") layout.operator(OP_EXPORT_virtools.BBP_OT_export_virtools.bl_idname, text="Virtools File (.nmo/.cmo/.vmo) (experimental)")
def menu_drawer_view3d(self, context) -> None: def menu_drawer_view3d(self, context) -> None:
layout: bpy.types.UILayout = self.layout layout: bpy.types.UILayout = self.layout
@ -127,7 +135,7 @@ def menu_drawer_view3d(self, context) -> None:
def menu_drawer_add(self, context) -> None: def menu_drawer_add(self, context) -> None:
layout: bpy.types.UILayout = self.layout layout: bpy.types.UILayout = self.layout
layout.separator() layout.separator()
layout.label(text = "Ballance") layout.label(text="Ballance")
layout.menu(BBP_MT_AddBmeMenu.bl_idname, icon='MESH_CUBE') layout.menu(BBP_MT_AddBmeMenu.bl_idname, icon='MESH_CUBE')
layout.menu(BBP_MT_AddRailMenu.bl_idname, icon='MESH_CIRCLE') layout.menu(BBP_MT_AddRailMenu.bl_idname, icon='MESH_CIRCLE')
layout.menu(BBP_MT_AddComponentsMenu.bl_idname, icon='MESH_ICOSPHERE') layout.menu(BBP_MT_AddComponentsMenu.bl_idname, icon='MESH_ICOSPHERE')
@ -143,16 +151,16 @@ def menu_drawer_grouping(self, context) -> None:
col = layout.column() col = layout.column()
col.operator_context = 'INVOKE_DEFAULT' col.operator_context = 'INVOKE_DEFAULT'
col.label(text = "Virtools Group") col.label(text="Virtools Group")
col.operator(OP_OBJECT_virtools_group.BBP_OT_add_objects_virtools_group.bl_idname, icon = 'ADD', text = "Group into...") col.operator(OP_OBJECT_virtools_group.BBP_OT_add_objects_virtools_group.bl_idname, icon='ADD', text="Group into...")
col.operator(OP_OBJECT_virtools_group.BBP_OT_rm_objects_virtools_group.bl_idname, icon = 'REMOVE', text = "Ungroup from...") col.operator(OP_OBJECT_virtools_group.BBP_OT_rm_objects_virtools_group.bl_idname, icon='REMOVE', text="Ungroup from...")
col.operator(OP_OBJECT_virtools_group.BBP_OT_clear_objects_virtools_group.bl_idname, icon = 'TRASH', text = "Clear All Groups") col.operator(OP_OBJECT_virtools_group.BBP_OT_clear_objects_virtools_group.bl_idname, icon='TRASH', text="Clear All Groups")
def menu_drawer_snoop_then_conv(self, context) -> None: def menu_drawer_snoop_then_conv(self, context) -> None:
layout: bpy.types.UILayout = self.layout layout: bpy.types.UILayout = self.layout
layout.separator() layout.separator()
layout.label(text = "Ballance") layout.label(text="Ballance")
layout.operator(OP_OBJECT_snoop_group_then_to_mesh.BBP_OT_snoop_group_then_to_mesh.bl_idname, icon = 'OUTLINER_OB_MESH') layout.operator(OP_OBJECT_snoop_group_then_to_mesh.BBP_OT_snoop_group_then_to_mesh.bl_idname, icon='OUTLINER_OB_MESH')
def menu_drawer_naming_convention(self, context) -> None: def menu_drawer_naming_convention(self, context) -> None:
layout: bpy.types.UILayout = self.layout layout: bpy.types.UILayout = self.layout
@ -162,10 +170,10 @@ def menu_drawer_naming_convention(self, context) -> None:
col = layout.column() col = layout.column()
col.operator_context = 'INVOKE_DEFAULT' col.operator_context = 'INVOKE_DEFAULT'
col.label(text = "Ballance") col.label(text="Ballance")
col.operator(OP_OBJECT_naming_convention.BBP_OT_regulate_objects_name.bl_idname, icon = 'GREASEPENCIL') col.operator(OP_OBJECT_naming_convention.BBP_OT_regulate_objects_name.bl_idname, icon='GREASEPENCIL')
col.operator(OP_OBJECT_naming_convention.BBP_OT_auto_grouping.bl_idname, icon = 'GROUP') col.operator(OP_OBJECT_naming_convention.BBP_OT_auto_grouping.bl_idname, icon='GROUP')
col.operator(OP_OBJECT_naming_convention.BBP_OT_convert_to_imengyu.bl_idname, icon = 'ARROW_LEFTRIGHT') col.operator(OP_OBJECT_naming_convention.BBP_OT_convert_to_imengyu.bl_idname, icon='ARROW_LEFTRIGHT')
#endregion #endregion
@ -204,7 +212,9 @@ g_BldMenus: tuple[MenuEntry, ...] = (
def register() -> None: def register() -> None:
# register module # register module
UTIL_translation.register()
PROP_preferences.register() PROP_preferences.register()
PROP_ptrprop_resolver.register() PROP_ptrprop_resolver.register()
PROP_virtools_material.register() PROP_virtools_material.register()
@ -285,7 +295,9 @@ def unregister() -> None:
PROP_virtools_material.unregister() PROP_virtools_material.unregister()
PROP_ptrprop_resolver.unregister() PROP_ptrprop_resolver.unregister()
PROP_preferences.unregister() PROP_preferences.unregister()
UTIL_translation.unregister()
if __name__ == "__main__": if __name__ == "__main__":
register() register()