feat: hide some operators in edit mode and add some notify for grouping oper.

- now grouping, ungrouping clear groups operators will show a report at the bottom of blender to indicate their work have done.
- disable fix material, 3ds max align, select by virtools group operators in edit mode to prevent any possible undefined behavior.
This commit is contained in:
yyc12345 2024-04-22 21:03:57 +08:00
parent c58af8ce48
commit 84e7e8380f
4 changed files with 38 additions and 15 deletions

View File

@ -1,4 +1,5 @@
import bpy import bpy
from . import UTIL_functions
from . import PROP_virtools_material, PROP_preferences 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):
@ -9,7 +10,9 @@ class BBP_OT_fix_all_material(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
return PROP_preferences.get_raw_preferences().has_valid_blc_tex_folder() # only enable this when plugin have a valid ballance texture folder
# and we are in object mode
return PROP_preferences.get_raw_preferences().has_valid_blc_tex_folder() and UTIL_functions.is_in_object_mode()
def invoke(self, context, event): def invoke(self, context, event):
wm = context.window_manager wm = context.window_manager

View File

@ -43,25 +43,25 @@ 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,
) ) # type: ignore
align_y: bpy.props.BoolProperty( align_y: bpy.props.BoolProperty(
name = "Y Position", name = "Y Position",
default = False, default = False,
) ) # type: ignore
align_z: bpy.props.BoolProperty( align_z: bpy.props.BoolProperty(
name = "Z Position", name = "Z Position",
default = False, default = False,
) ) # 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),
) ) # 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),
) ) # type: ignore
#endregion #endregion
@ -109,21 +109,21 @@ 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,
) ) # type: ignore
recursive_hinder: bpy.props.BoolProperty( recursive_hinder: bpy.props.BoolProperty(
name = "Recursive Hinder", name = "Recursive Hinder",
description = "An internal flag to prevent the loop calling to apply_flags's updator.", 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
align_history : bpy.props.CollectionProperty( align_history : bpy.props.CollectionProperty(
name = "Historys", name = "Historys",
description = "Align history.", description = "Align history.",
type = BBP_PG_legacy_align_history, type = BBP_PG_legacy_align_history,
) ) # type: ignore
@classmethod @classmethod
def poll(self, context): def poll(cls, context):
return _check_align_requirement() return _check_align_requirement()
def invoke(self, context, event): def invoke(self, context, event):
@ -180,10 +180,13 @@ class BBP_OT_legacy_align(bpy.types.Operator):
#region Core Functions #region Core Functions
def _check_align_requirement() -> bool: def _check_align_requirement() -> bool:
# if we are not in object mode, do not do legacy align
if not UTIL_functions.is_in_object_mode():
return False
# check current obj # check current obj
if bpy.context.active_object is None: if bpy.context.active_object is None:
return False return False
# check target obj with filter of current obj # check target obj with filter of current obj
length = len(bpy.context.selected_objects) length = len(bpy.context.selected_objects)
if bpy.context.active_object in bpy.context.selected_objects: if bpy.context.active_object in bpy.context.selected_objects:

View File

@ -38,7 +38,11 @@ class BBP_OT_select_object_by_virtools_group(bpy.types.Operator, PROP_virtools_g
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)
) ) # type: ignore
@classmethod
def poll(cls, context):
return UTIL_functions.is_in_object_mode()
def invoke(self, context, event): def invoke(self, context, event):
wm = context.window_manager wm = context.window_manager
@ -119,7 +123,7 @@ class BBP_OT_add_objects_virtools_group(bpy.types.Operator, PROP_virtools_group.
bl_options = {'UNDO'} bl_options = {'UNDO'}
@classmethod @classmethod
def poll(self, context): def poll(cls, context):
return len(bpy.context.selected_objects) != 0 return len(bpy.context.selected_objects) != 0
def invoke(self, context, event): def invoke(self, context, event):
@ -131,6 +135,7 @@ class BBP_OT_add_objects_virtools_group(bpy.types.Operator, PROP_virtools_group.
for obj in bpy.context.selected_objects: for obj in bpy.context.selected_objects:
with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp: with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp:
gp.add_group(group_name) gp.add_group(group_name)
self.report({'INFO'}, "Grouping objects successfully.")
return {'FINISHED'} return {'FINISHED'}
def draw(self, context): def draw(self, context):
@ -143,7 +148,7 @@ class BBP_OT_rm_objects_virtools_group(bpy.types.Operator, PROP_virtools_group.S
bl_options = {'UNDO'} bl_options = {'UNDO'}
@classmethod @classmethod
def poll(self, context): def poll(cls, context):
return len(bpy.context.selected_objects) != 0 return len(bpy.context.selected_objects) != 0
def invoke(self, context, event): def invoke(self, context, event):
@ -155,6 +160,7 @@ class BBP_OT_rm_objects_virtools_group(bpy.types.Operator, PROP_virtools_group.S
for obj in bpy.context.selected_objects: for obj in bpy.context.selected_objects:
with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp: with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp:
gp.remove_group(group_name) gp.remove_group(group_name)
self.report({'INFO'}, "Ungrouping objects successfully.")
return {'FINISHED'} return {'FINISHED'}
def draw(self, context): def draw(self, context):
@ -167,7 +173,7 @@ class BBP_OT_clear_objects_virtools_group(bpy.types.Operator):
bl_options = {'UNDO'} bl_options = {'UNDO'}
@classmethod @classmethod
def poll(self, context): def poll(cls, context):
return len(bpy.context.selected_objects) != 0 return len(bpy.context.selected_objects) != 0
def invoke(self, context, event): def invoke(self, context, event):
@ -179,6 +185,7 @@ class BBP_OT_clear_objects_virtools_group(bpy.types.Operator):
for obj in bpy.context.selected_objects: for obj in bpy.context.selected_objects:
with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp: with PROP_virtools_group.VirtoolsGroupsHelper(obj) as gp:
gp.clear_groups() gp.clear_groups()
self.report({'INFO'}, "Clear objects groups successfully.")
return {'FINISHED'} return {'FINISHED'}
#endregion #endregion

View File

@ -80,6 +80,16 @@ def select_certain_objects(objs: tuple[bpy.types.Object, ...]) -> None:
# select first object as active object # select first object as active object
bpy.context.view_layer.objects.active = objs[0] bpy.context.view_layer.objects.active = objs[0]
def is_in_object_mode() -> bool:
# get active object from context
obj = bpy.context.active_object
# if there is no active object, we think it is in object mode
if obj is None: return True
# simply check active object mode
return obj.mode == 'OBJECT'
class EnumPropHelper(): class EnumPropHelper():
""" """
These class contain all functions related to EnumProperty, including generating `items`, These class contain all functions related to EnumProperty, including generating `items`,