Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Inch <mythologylover75@gmail.com>2020-04-06 00:08:02 +0300
committerRyan Inch <mythologylover75@gmail.com>2020-04-06 00:08:02 +0300
commit5c9aaca64d7c54aaa09684d64542c59b896c5f11 (patch)
treef0ff51cec5b70e5a91d0a6318d086025944f32d7
parentba19a9a74770a39fb23d96a99a0abe30d154a8f2 (diff)
Collection Manager: Update Move Operator. Task: T69577
Updates the Collection Manager's Move Operator with improvements developed for QCD.
-rw-r--r--object_collection_manager/__init__.py23
-rw-r--r--object_collection_manager/internals.py27
-rw-r--r--object_collection_manager/operators.py74
-rw-r--r--object_collection_manager/qcd_init.py20
-rw-r--r--object_collection_manager/qcd_operators.py32
-rw-r--r--object_collection_manager/ui.py18
6 files changed, 128 insertions, 66 deletions
diff --git a/object_collection_manager/__init__.py b/object_collection_manager/__init__.py
index 2aa38c5b..1f3fdef1 100644
--- a/object_collection_manager/__init__.py
+++ b/object_collection_manager/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
"name": "Collection Manager",
"description": "Manage collections and their objects",
"author": "Ryan Inch",
- "version": (2,4,12),
+ "version": (2,5,0),
"blender": (2, 80, 0),
"location": "View3D - Object Mode (Shortcut - M)",
"warning": '', # used for warning icon and text in addons panel
@@ -52,6 +52,7 @@ else:
from . import preferences
import bpy
+from bpy.app.handlers import persistent
from bpy.types import PropertyGroup
from bpy.props import (
CollectionProperty,
@@ -108,7 +109,19 @@ classes = (
CollectionManagerProperties,
)
+@persistent
+def depsgraph_update_post_handler(dummy):
+ if internals.move_triggered:
+ internals.move_triggered = False
+ return
+ internals.move_selection.clear()
+ internals.move_active = None
+
+@persistent
+def undo_redo_post_handler(dummy):
+ internals.move_selection.clear()
+ internals.move_active = None
def register():
for cls in classes:
@@ -122,6 +135,10 @@ def register():
kmi = km.keymap_items.new('view3d.collection_manager', 'M', 'PRESS')
addon_keymaps.append((km, kmi))
+ bpy.app.handlers.depsgraph_update_post.append(depsgraph_update_post_handler)
+ bpy.app.handlers.undo_post.append(undo_redo_post_handler)
+ bpy.app.handlers.redo_post.append(undo_redo_post_handler)
+
if bpy.context.preferences.addons[__package__].preferences.enable_qcd:
qcd_init.register_qcd()
@@ -132,6 +149,10 @@ def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
+ bpy.app.handlers.depsgraph_update_post.remove(depsgraph_update_post_handler)
+ bpy.app.handlers.undo_post.remove(undo_redo_post_handler)
+ bpy.app.handlers.redo_post.remove(undo_redo_post_handler)
+
del bpy.types.Scene.collection_manager
# remove keymaps when add-on is deactivated
diff --git a/object_collection_manager/internals.py b/object_collection_manager/internals.py
index 292d8cfd..594756c9 100644
--- a/object_collection_manager/internals.py
+++ b/object_collection_manager/internals.py
@@ -32,6 +32,10 @@ from bpy.props import (
IntProperty,
)
+move_triggered = False
+move_selection = []
+move_active = None
+
layer_collections = {}
collection_tree = []
collection_state = {}
@@ -186,6 +190,7 @@ def update_col_name(self, context):
self.last_name = self.name
+
def update_qcd_slot(self, context):
global qcd_slots
@@ -357,6 +362,7 @@ def get_modifiers(event):
return set(modifiers)
+
def generate_state():
global layer_collections
@@ -380,6 +386,27 @@ def generate_state():
return state
+def get_move_selection():
+ global move_selection
+
+ if not move_selection:
+ move_selection = [obj.name for obj in bpy.context.selected_objects]
+
+ return [bpy.data.objects[name] for name in move_selection]
+
+
+def get_move_active():
+ global move_active
+ global move_selection
+
+ if not move_active:
+ move_active = getattr(bpy.context.view_layer.objects.active, "name", None)
+
+ if move_active not in [obj.name for obj in get_move_selection()]:
+ move_active = None
+
+ return bpy.data.objects[move_active] if move_active else None
+
class CMSendReport(Operator):
bl_label = "Send Report"
diff --git a/object_collection_manager/operators.py b/object_collection_manager/operators.py
index 30cf17a9..1094e578 100644
--- a/object_collection_manager/operators.py
+++ b/object_collection_manager/operators.py
@@ -32,12 +32,16 @@ from bpy.props import (
IntProperty
)
+from . import internals
+
from .internals import (
expanded,
layer_collections,
qcd_slots,
update_property_group,
get_modifiers,
+ get_move_selection,
+ get_move_active,
send_report,
)
@@ -187,30 +191,74 @@ class CMSetCollectionOperator(Operator):
collection_name: StringProperty()
def invoke(self, context, event):
- collection = layer_collections[self.collection_name]["ptr"].collection
+ laycol = layer_collections[self.collection_name]
+ target_collection = laycol["ptr"].collection
+
+ selected_objects = get_move_selection()
+ active_object = get_move_active()
+
+ internals.move_triggered = True
+
+ if not selected_objects:
+ return {'CANCELLED'}
if event.shift:
- # add object to collection
+ # add objects to collection
+
+ # make sure there is an active object
+ if not active_object:
+ active_object = selected_objects[0]
# check if in collection
- if context.active_object.name not in collection.objects:
+ if not active_object.name in target_collection.objects:
# add to collection
- bpy.ops.object.link_to_collection(collection_index=self.collection_index)
+ for obj in selected_objects:
+ if obj.name not in target_collection.objects:
+ target_collection.objects.link(obj)
else:
- # check and disallow removing from all collections
- for obj in context.selected_objects:
- if len(obj.users_collection) == 1:
- send_report("Error removing 1 or more objects from this collection.\nObjects would be left without a collection")
+ errors = False
+
+ # remove from collections
+ for obj in selected_objects:
+ if obj.name in target_collection.objects:
+
+ # disallow removing if only one
+ if len(obj.users_collection) == 1:
+ errors = True
+ continue
+
+ # remove from collection
+ target_collection.objects.unlink(obj)
- return {'FINISHED'}
+ if errors:
+ send_report("Error removing 1 or more objects from this collection.\nObjects would be left without a collection")
- # remove from collection
- bpy.ops.collection.objects_remove(collection=collection.name)
else:
- # move object to collection
- bpy.ops.object.move_to_collection(collection_index=self.collection_index)
+ # move objects to collection
+ for obj in selected_objects:
+ if obj.name not in target_collection.objects:
+ target_collection.objects.link(obj)
+
+ # remove from all other collections
+ for collection in obj.users_collection:
+ if collection.name != target_collection.name:
+ collection.objects.unlink(obj)
+
+ # update the active object if needed
+ if not context.active_object:
+ try:
+ context.view_layer.objects.active = active_object
+
+ except RuntimeError: # object not in visible collection
+ pass
+
+ # update qcd header UI
+ cm = bpy.context.scene.collection_manager
+ cm.update_header.clear()
+ new_update_header = cm.update_header.add()
+ new_update_header.name = "updated"
return {'FINISHED'}
diff --git a/object_collection_manager/qcd_init.py b/object_collection_manager/qcd_init.py
index 87cbcd16..0bef6e44 100644
--- a/object_collection_manager/qcd_init.py
+++ b/object_collection_manager/qcd_init.py
@@ -21,20 +21,6 @@ qcd_classes = (
)
@persistent
-def depsgraph_update_post_handler(dummy):
- if qcd_operators.move_triggered:
- qcd_operators.move_triggered = False
- return
-
- qcd_operators.move_selection.clear()
- qcd_operators.move_active = None
-
-@persistent
-def undo_redo_post_handler(dummy):
- qcd_operators.move_selection.clear()
- qcd_operators.move_active = None
-
-@persistent
def save_internal_data(dummy):
cm = bpy.context.scene.collection_manager
@@ -66,9 +52,6 @@ def register_qcd():
kmi = km.keymap_items.new('view3d.qcd_move_widget', 'V', 'PRESS')
addon_qcd_keymaps.append((km, kmi))
- bpy.app.handlers.depsgraph_update_post.append(depsgraph_update_post_handler)
- bpy.app.handlers.undo_post.append(undo_redo_post_handler)
- bpy.app.handlers.redo_post.append(undo_redo_post_handler)
bpy.app.handlers.save_pre.append(save_internal_data)
bpy.app.handlers.load_post.append(load_internal_data)
@@ -122,9 +105,6 @@ def unregister_qcd():
for cls in qcd_classes:
bpy.utils.unregister_class(cls)
- bpy.app.handlers.depsgraph_update_post.remove(depsgraph_update_post_handler)
- bpy.app.handlers.undo_post.remove(undo_redo_post_handler)
- bpy.app.handlers.redo_post.remove(undo_redo_post_handler)
bpy.app.handlers.save_pre.remove(save_internal_data)
bpy.app.handlers.load_post.remove(load_internal_data)
diff --git a/object_collection_manager/qcd_operators.py b/object_collection_manager/qcd_operators.py
index 98d3b455..a7a6079e 100644
--- a/object_collection_manager/qcd_operators.py
+++ b/object_collection_manager/qcd_operators.py
@@ -30,39 +30,19 @@ from bpy.props import (
IntProperty
)
+from . import internals
+
from .internals import (
layer_collections,
qcd_slots,
update_property_group,
get_modifiers,
+ get_move_selection,
+ get_move_active
)
from .operators import rto_history
-move_triggered = False
-move_selection = []
-move_active = None
-
-def get_move_selection():
- global move_selection
-
- if not move_selection:
- move_selection = [obj.name for obj in bpy.context.selected_objects]
-
- return [bpy.data.objects[name] for name in move_selection]
-
-def get_move_active():
- global move_active
- global move_selection
-
- if not move_active:
- move_active = getattr(bpy.context.view_layer.objects.active, "name", None)
-
- if move_active not in [obj.name for obj in get_move_selection()]:
- move_active = None
-
- return bpy.data.objects[move_active] if move_active else None
-
class MoveToQCDSlot(Operator):
'''Move object(s) to QCD slot'''
@@ -76,11 +56,11 @@ class MoveToQCDSlot(Operator):
def execute(self, context):
global qcd_slots
global layer_collections
- global move_triggered
selected_objects = get_move_selection()
active_object = get_move_active()
- move_triggered = True
+ internals.move_triggered = True
+
qcd_laycol = None
slot_name = qcd_slots.get_name(self.slot)
diff --git a/object_collection_manager/ui.py b/object_collection_manager/ui.py
index a90a619f..2209f18f 100644
--- a/object_collection_manager/ui.py
+++ b/object_collection_manager/ui.py
@@ -36,6 +36,8 @@ from .internals import (
update_collection_tree,
update_property_group,
generate_state,
+ get_move_selection,
+ get_move_active
)
from .operators import (
@@ -46,8 +48,6 @@ from .operators import (
phantom_history,
)
-from . import qcd_operators
-
preview_collections = {}
last_icon_theme_text = None
@@ -353,6 +353,8 @@ class CM_UL_items(UIList):
view_layer = context.view_layer
laycol = layer_collections[item.name]
collection = laycol["ptr"].collection
+ selected_objects = get_move_selection()
+ active_object = get_move_active()
split = layout.split(factor=0.96)
row = split.row(align=True)
@@ -409,9 +411,13 @@ class CM_UL_items(UIList):
icon = 'MESH_CUBE'
- if len(context.selected_objects) > 0 and context.active_object:
- if context.active_object.name in collection.objects:
+ if selected_objects:
+ if active_object and active_object.name in collection.objects:
icon = 'SNAP_VOLUME'
+
+ elif not set(selected_objects).isdisjoint(collection.objects):
+ icon = 'STICKY_UVS_LOC'
+
else:
row_setcol.enabled = False
@@ -588,8 +594,8 @@ def view3d_header_qcd_slots(self, context):
if qcd_slot_name:
qcd_laycol = layer_collections[qcd_slot_name]["ptr"]
collection_objects = qcd_laycol.collection.objects
- selected_objects = qcd_operators.get_move_selection()
- active_object = qcd_operators.get_move_active()
+ selected_objects = get_move_selection()
+ active_object = get_move_active()
icon_value = 0