Collection Manager: Add object selection to CM popup. Task: T69577

Exposes selecting objects by collection to the CM popup, and adds
additional state information regarding selection.
Refines Set Object Collection UI to be less likely to hit by accident.
This commit is contained in:
Ryan Inch 2021-03-16 22:31:44 -04:00
parent 88db9c67be
commit 6dfba91574
4 changed files with 139 additions and 9 deletions

View File

@ -22,7 +22,7 @@ bl_info = {
"name": "Collection Manager",
"description": "Manage collections and their objects",
"author": "Ryan Inch",
"version": (2, 20, 0),
"version": (2, 21, 0),
"blender": (2, 80, 0),
"location": "View3D - Object Mode (Shortcut - M)",
"warning": '', # used for warning icon and text in addons panel

View File

@ -77,6 +77,7 @@ addon_disable_objects_hotkey_keymaps = []
classes = (
internals.CMListCollection,
internals.CMSendReport,
internals.CMUISeparatorButton,
operators.SetActiveCollection,
operators.ExpandAllOperator,
operators.ExpandSublevelOperator,

View File

@ -794,3 +794,30 @@ def send_report(message):
bpy.ops.view3d.cm_send_report(ctx, 'INVOKE_DEFAULT', message=message)
bpy.app.timers.register(report)
class CMUISeparatorButton(Operator):
bl_label = "UI Separator Button"
bl_idname = "view3d.cm_ui_separator_button"
def execute(self, context):
return {'CANCELED'}
def add_vertical_separator_line(row):
# add buffer before to account for scaling
separator = row.row()
separator.scale_x = 0.1
separator.label()
# add separator line
separator = row.row()
separator.scale_x = 0.2
separator.enabled = False
separator.operator("view3d.cm_ui_separator_button",
text="",
icon='BLANK1',
)
# add buffer after to account for scaling
separator = row.row()
separator.scale_x = 0.1
separator.label()

View File

@ -44,6 +44,7 @@ from .internals import (
get_move_selection,
get_move_active,
update_qcd_header,
add_vertical_separator_line,
)
preview_collections = {}
@ -75,6 +76,7 @@ class CollectionManager(Operator):
cm = context.scene.collection_manager
prefs = context.preferences.addons[__package__].preferences
view_layer = context.view_layer
collection = context.view_layer.layer_collection.collection
if view_layer.name != cls.last_view_layer:
if prefs.enable_qcd:
@ -163,16 +165,52 @@ class CollectionManager(Operator):
master_collection_row.separator()
# name
name_row = master_collection_row.row()
name_row.prop(self, "master_collection", text='')
name_row.enabled = False
name_row = master_collection_row.row(align=True)
name_field = name_row.row(align=True)
name_field.prop(self, "master_collection", text='')
name_field.enabled = False
# set selection
setsel = name_row.row(align=True)
icon = 'DOT'
if any((laycol["ptr"].exclude,
collection.hide_select,
collection.hide_viewport,
laycol["ptr"].hide_viewport,
not collection.objects,)):
# objects cannot be selected
setsel.active = False
else:
for obj in collection.objects:
if obj.select_get() == False:
# some objects remain unselected
icon = 'LAYER_USED'
break
if icon != 'LAYER_USED':
# all objects are selected
icon = 'LAYER_ACTIVE'
prop = setsel.operator("view3d.select_collection_objects",
text="",
icon=icon,
depress=bool(icon == 'LAYER_ACTIVE')
)
prop.is_master_collection = True
prop.collection_name = 'Master Collection'
master_collection_row.separator()
# global rtos
global_rto_row = master_collection_row.row()
global_rto_row.alignment = 'RIGHT'
# used as a separator (actual separator not wide enough)
global_rto_row.label()
# set collection
row_setcol = global_rto_row.row()
row_setcol.alignment = 'LEFT'
row_setcol.operator_context = 'INVOKE_DEFAULT'
@ -184,7 +222,10 @@ class CollectionManager(Operator):
collection = context.view_layer.layer_collection.collection
icon = 'MESH_CUBE'
icon = 'GRID'
if collection.objects:
icon = 'MESH_CUBE'
if selected_objects:
if active_object and active_object.name in collection.objects:
@ -194,13 +235,33 @@ class CollectionManager(Operator):
icon = 'STICKY_UVS_LOC'
else:
row_setcol.enabled = False
row_setcol.active = False
# add vertical separator line
separator = row_setcol.row()
separator.scale_x = 0.2
separator.enabled = False
separator.operator("view3d.cm_ui_separator_button",
text="",
icon='BLANK1',
)
# add operator
prop = row_setcol.operator("view3d.set_collection", text="",
icon=icon, emboss=False)
prop.is_master_collection = True
prop.collection_name = 'Master Collection'
# add vertical separator line
separator = row_setcol.row()
separator.scale_x = 0.2
separator.enabled = False
separator.operator("view3d.cm_ui_separator_button",
text="",
icon='BLANK1',
)
copy_icon = 'COPYDOWN'
swap_icon = 'ARROW_LEFTRIGHT'
copy_swap_icon = 'SELECT_INTERSECT'
@ -534,7 +595,8 @@ class CM_UL_items(UIList):
QCD.scale_x = 0.4
QCD.prop(item, "qcd_slot_idx", text="")
c_name = row.row()
# collection name
c_name = row.row(align=True)
#if rename[0] and index == cm.cm_list_index:
#c_name.activate_init = True
@ -542,16 +604,54 @@ class CM_UL_items(UIList):
c_name.prop(item, "name", text="", expand=True)
# set selection
setsel = c_name.row(align=True)
icon = 'DOT'
if any((laycol["ptr"].exclude,
collection.hide_select,
collection.hide_viewport,
laycol["ptr"].hide_viewport,
not collection.objects,)):
# objects cannot be selected
setsel.active = False
else:
for obj in collection.objects:
if obj.select_get() == False:
# some objects remain unselected
icon = 'LAYER_USED'
break
if icon != 'LAYER_USED':
# all objects are selected
icon = 'LAYER_ACTIVE'
prop = setsel.operator("view3d.select_collection_objects",
text="",
icon=icon,
depress=bool(icon == 'LAYER_ACTIVE')
)
prop.is_master_collection = False
prop.collection_name = item.name
# used as a separator (actual separator not wide enough)
row.label()
row = s2 if cm.align_local_ops else s1
add_vertical_separator_line(row)
# add set_collection op
set_obj_col = row.row()
set_obj_col.operator_context = 'INVOKE_DEFAULT'
icon = 'MESH_CUBE'
icon = 'GRID'
if collection.objects:
icon = 'MESH_CUBE'
if selected_objects:
if active_object and active_object.name in collection.objects:
@ -569,6 +669,8 @@ class CM_UL_items(UIList):
prop.is_master_collection = False
prop.collection_name = item.name
add_vertical_separator_line(row)
if cm.show_exclude:
exclude_history_base = internals.rto_history["exclude"].get(view_layer.name, {})