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:
-rw-r--r--source/blender/blenkernel/BKE_context.h3
-rw-r--r--source/blender/blenkernel/intern/context.c12
-rw-r--r--source/blender/editors/interface/interface_ops.c78
-rw-r--r--source/blender/makesrna/RNA_access.h3
-rw-r--r--source/blender/makesrna/intern/rna_access.c30
5 files changed, 104 insertions, 22 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 105f8e82343..88a27b67963 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -198,6 +198,9 @@ enum {
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
+PointerRNA CTX_data_pointer_get_type_silent(const bContext *C,
+ const char *member,
+ StructRNA *type);
ListBase CTX_data_collection_get(const bContext *C, const char *member);
ListBase CTX_data_dir_get_ex(const bContext *C,
const bool use_store,
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 2e4f756ce68..e3d95bb660f 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -466,6 +466,18 @@ PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, Stru
return PointerRNA_NULL;
}
+PointerRNA CTX_data_pointer_get_type_silent(const bContext *C, const char *member, StructRNA *type)
+{
+ PointerRNA ptr = CTX_data_pointer_get(C, member);
+
+ if (ptr.data && RNA_struct_is_a(ptr.type, type)) {
+ return ptr;
+ }
+ else {
+ return PointerRNA_NULL;
+ }
+}
+
ListBase CTX_data_collection_get(const bContext *C, const char *member)
{
bContextDataResult result;
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");
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 5bf6fb40c6a..7fe88ec94b7 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -40,6 +40,7 @@ struct Main;
struct ReportList;
struct Scene;
struct bContext;
+struct IDProperty;
/* Types */
extern BlenderRNA BLENDER_RNA;
@@ -1156,6 +1157,8 @@ struct PropertyElemRNA {
};
bool RNA_path_resolve_elements(PointerRNA *ptr, const char *path, struct ListBase *r_elements);
+char *RNA_path_from_struct_to_idproperty(PointerRNA *ptr, struct IDProperty *needle);
+
struct ID *RNA_find_real_ID_and_path(struct Main *bmain, struct ID *id, const char **r_path);
char *RNA_path_from_ID_to_struct(PointerRNA *ptr);
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 78cd99837c3..d8889455ac7 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -5738,11 +5738,28 @@ static char *rna_idp_path(PointerRNA *ptr,
return path;
}
+/**
+ * Find the path from the structure referenced by the pointer to the IDProperty object.
+ *
+ * \param ptr Reference to the object owning the custom property storage.
+ * \param needle Custom property object to find.
+ * \return Relative path or NULL.
+ */
+char *RNA_path_from_struct_to_idproperty(PointerRNA *ptr, IDProperty *needle)
+{
+ IDProperty *haystack = RNA_struct_idprops(ptr, false);
+
+ if (haystack) { /* can fail when called on bones */
+ return rna_idp_path(ptr, haystack, needle, NULL);
+ }
+ else {
+ return NULL;
+ }
+}
+
static char *rna_path_from_ID_to_idpgroup(PointerRNA *ptr)
{
PointerRNA id_ptr;
- IDProperty *haystack;
- IDProperty *needle;
BLI_assert(ptr->owner_id != NULL);
@@ -5753,14 +5770,7 @@ static char *rna_path_from_ID_to_idpgroup(PointerRNA *ptr)
*/
RNA_id_pointer_create(ptr->owner_id, &id_ptr);
- haystack = RNA_struct_idprops(&id_ptr, false);
- if (haystack) { /* can fail when called on bones */
- needle = ptr->data;
- return rna_idp_path(&id_ptr, haystack, needle, NULL);
- }
- else {
- return NULL;
- }
+ return RNA_path_from_struct_to_idproperty(&id_ptr, ptr->data);
}
/**