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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2019-11-16 20:50:59 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-12-04 12:23:41 +0300
commitb3f388dca9e547c12db277b8422c620ca3b64eaa (patch)
treeffbf14c7371ef7dd96ac49cb0c6e1810c1708f6f /source/blender/editors/interface
parentfda791ab1241534e377bee84b3a214e1343094af (diff)
UI: support Copy To Selected and Alt-Click for PropertyGroup members.
Rigify uses a property group to contain options of its rigs, so currently it is impossible to use Alt-Click or Copy To Selected to change a setting for multiple rigs at the same time. The main problem here is that there is no efficient way to find which bone the property group belongs to. To maintain performance, implement this by checking the active bone if it is known. Copy Data Path and related features still don't work, as data path calculation can't use context. Differential Revision: https://developer.blender.org/D6264
Diffstat (limited to 'source/blender/editors/interface')
-rw-r--r--source/blender/editors/interface/interface_ops.c78
1 files changed, 66 insertions, 12 deletions
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 8af82864b03..2a9ebdfaea9 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -707,6 +707,25 @@ static void UI_OT_override_remove_button(wmOperatorType *ot)
/** \name Copy To Selected Operator
* \{ */
+#define NOT_NULL(assignment) ((assignment) != NULL)
+#define NOT_RNA_NULL(assignment) ((assignment).data != NULL)
+
+static void ui_context_selected_bones_via_pose(bContext *C, ListBase *r_lb)
+{
+ ListBase lb;
+ lb = CTX_data_collection_get(C, "selected_pose_bones");
+
+ if (!BLI_listbase_is_empty(&lb)) {
+ CollectionPointerLink *link;
+ for (link = lb.first; link; link = link->next) {
+ bPoseChannel *pchan = link->ptr.data;
+ RNA_pointer_create(link->ptr.owner_id, &RNA_Bone, pchan->bone, &link->ptr);
+ }
+ }
+
+ *r_lb = lb;
+}
+
bool UI_context_copy_to_selected_list(bContext *C,
PointerRNA *ptr,
PropertyRNA *prop,
@@ -717,6 +736,52 @@ bool UI_context_copy_to_selected_list(bContext *C,
*r_use_path_from_id = false;
*r_path = NULL;
+ /* PropertyGroup objects don't have a reference to the struct that actually owns
+ * them, so it is normally necessary to do a brute force search to find it. This
+ * handles the search for non-ID owners by using the 'active' reference as a hint
+ * to preserve efficiency. Only properties defined through RNA are handled, as
+ * custom properties cannot be assumed to be valid for all instances.
+ *
+ * Properties owned by the ID are handled by the 'if (ptr->owner_id)' case below.
+ */
+ if (!RNA_property_is_idprop(prop) && RNA_struct_is_a(ptr->type, &RNA_PropertyGroup)) {
+ PointerRNA owner_ptr;
+ char *idpath = NULL;
+
+ /* First, check the active PoseBone and PoseBone->Bone. */
+ if (NOT_RNA_NULL(
+ owner_ptr = CTX_data_pointer_get_type(C, "active_pose_bone", &RNA_PoseBone))) {
+ if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(&owner_ptr, ptr->data))) {
+ *r_lb = CTX_data_collection_get(C, "selected_pose_bones");
+ }
+ else {
+ bPoseChannel *pchan = owner_ptr.data;
+ RNA_pointer_create(owner_ptr.owner_id, &RNA_Bone, pchan->bone, &owner_ptr);
+
+ if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(&owner_ptr, ptr->data))) {
+ ui_context_selected_bones_via_pose(C, r_lb);
+ }
+ }
+ }
+
+ if (idpath == NULL) {
+ /* Check the active EditBone if in edit mode. */
+ if (NOT_RNA_NULL(
+ owner_ptr = CTX_data_pointer_get_type_silent(C, "active_bone", &RNA_EditBone)) &&
+ NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(&owner_ptr, ptr->data))) {
+ *r_lb = CTX_data_collection_get(C, "selected_editable_bones");
+ }
+
+ /* Add other simple cases here (Node, NodeSocket, Sequence, ViewLayer etc). */
+ }
+
+ if (idpath) {
+ *r_path = BLI_sprintfN("%s.%s", idpath, RNA_property_identifier(prop));
+ MEM_freeN(idpath);
+ return true;
+ }
+ }
+
if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) {
*r_lb = CTX_data_collection_get(C, "selected_editable_bones");
}
@@ -724,18 +789,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
*r_lb = CTX_data_collection_get(C, "selected_pose_bones");
}
else if (RNA_struct_is_a(ptr->type, &RNA_Bone)) {
- ListBase lb;
- lb = CTX_data_collection_get(C, "selected_pose_bones");
-
- if (!BLI_listbase_is_empty(&lb)) {
- CollectionPointerLink *link;
- for (link = lb.first; link; link = link->next) {
- bPoseChannel *pchan = link->ptr.data;
- RNA_pointer_create(link->ptr.owner_id, &RNA_Bone, pchan->bone, &link->ptr);
- }
- }
-
- *r_lb = lb;
+ ui_context_selected_bones_via_pose(C, r_lb);
}
else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
*r_lb = CTX_data_collection_get(C, "selected_editable_sequences");