[Bf-blender-cvs] [4375e7ff0b7] blender2.8: WM: internal changes to support dragging multiple IDs.

Brecht Van Lommel noreply at git.blender.org
Fri Aug 10 17:57:39 CEST 2018


Commit: 4375e7ff0b74f96447e27f78a0d9245353d36865
Author: Brecht Van Lommel
Date:   Sun Aug 5 12:14:55 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB4375e7ff0b74f96447e27f78a0d9245353d36865

WM: internal changes to support dragging multiple IDs.

To be used by the outliner.

===================================================================

M	source/blender/editors/space_node/space_node.c
M	source/blender/editors/space_text/space_text.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/WM_types.h
M	source/blender/windowmanager/intern/wm_dragdrop.c

===================================================================

diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 2b2e659d151..51ba3a62d1b 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -692,14 +692,14 @@ static bool node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent
 
 static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
-	ID *id = drag->poin;
+	ID *id = WM_drag_ID(drag, 0);
 
 	RNA_string_set(drop->ptr, "name", id->name + 2);
 }
 
 static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
-	ID *id = drag->poin;
+	ID *id = WM_drag_ID(drag, 0);
 
 	if (id) {
 		RNA_string_set(drop->ptr, "name", id->name + 2);
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 469e1b84c29..f3c55aa3474 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -499,7 +499,7 @@ static bool text_drop_paste_poll(bContext *UNUSED(C), wmDrag *drag, const wmEven
 static void text_drop_paste(wmDrag *drag, wmDropBox *drop)
 {
 	char *text;
-	ID *id = drag->poin;
+	ID *id = WM_drag_ID(drag, 0);
 
 	/* copy drag path to properties */
 	text = RNA_path_full_ID_py(id);
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 68ea59859da..98c5c4e604d 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -632,14 +632,14 @@ static bool view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *
 
 static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
-	ID *id = drag->poin;
+	ID *id = WM_drag_ID(drag, ID_OB);
 
 	RNA_string_set(drop->ptr, "name", id->name + 2);
 }
 
 static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
-	ID *id = drag->poin;
+	ID *id = WM_drag_ID(drag, ID_GR);
 
 	drop->opcontext = WM_OP_EXEC_DEFAULT;
 	RNA_string_set(drop->ptr, "name", id->name + 2);
@@ -647,14 +647,14 @@ static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
 
 static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
-	ID *id = drag->poin;
+	ID *id = WM_drag_ID(drag, 0);
 
 	RNA_string_set(drop->ptr, "name", id->name + 2);
 }
 
 static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop)
 {
-	ID *id = drag->poin;
+	ID *id = WM_drag_ID(drag, 0);
 
 	if (id) {
 		RNA_string_set(drop->ptr, "name", id->name + 2);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index d175b11fe5c..b15ce2d11ad 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -484,15 +484,17 @@ void				WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx
 void                WM_drag_free(struct wmDrag *drag);
 void                WM_drag_free_list(struct ListBase *lb);
 
-struct ID          *WM_drag_ID(const struct wmDrag *drag, short idcode);
-struct ID          *WM_drag_ID_from_event(const struct wmEvent *event, short idcode);
-
 struct wmDropBox	*WM_dropbox_add(
         ListBase *lb, const char *idname,
         bool (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event, const char **),
         void (*copy)(struct wmDrag *, struct wmDropBox *));
 ListBase	*WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
 
+			/* ID drag and drop */
+void                WM_drag_add_ID(struct wmDrag *drag, struct ID *id, struct ID *from_parent);
+struct ID          *WM_drag_ID(const struct wmDrag *drag, short idcode);
+struct ID          *WM_drag_ID_from_event(const struct wmEvent *event, short idcode);
+
 			/* Set OpenGL viewport and scissor */
 void		wmViewport(const struct rcti *rect);
 void		wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 809588b1a36..4882741680a 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -111,6 +111,7 @@ struct wmEvent;
 struct wmWindowManager;
 struct wmMsgBus;
 struct wmOperator;
+struct ID;
 struct ImBuf;
 
 #include "RNA_types.h"
@@ -660,6 +661,12 @@ typedef enum wmDragFlags {
 
 /* note: structs need not exported? */
 
+typedef struct wmDragID {
+	struct wmDragID  *next, *prev;
+	struct ID *id;
+	struct ID *from_parent;
+} wmDragID;
+
 typedef struct wmDrag {
 	struct wmDrag *next, *prev;
 
@@ -674,6 +681,8 @@ typedef struct wmDrag {
 
 	char opname[200]; /* if set, draws operator name*/
 	unsigned int flags;
+
+	ListBase ids; /* List of wmDragIDs, all are guaranteed to have the same ID type. */
 } wmDrag;
 
 /* dropboxes are like keymaps, part of the screen/area/region definition */
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 6b9a7fb5430..0c77ad89292 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -45,6 +45,7 @@
 #include "BIF_glutil.h"
 
 #include "BKE_context.h"
+#include "BKE_idcode.h"
 
 #include "GPU_shader.h"
 
@@ -155,10 +156,17 @@ wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin,
 	drag->flags = flags;
 	drag->icon = icon;
 	drag->type = type;
-	if (type == WM_DRAG_PATH)
+	if (type == WM_DRAG_PATH) {
 		BLI_strncpy(drag->path, poin, FILE_MAX);
-	else
+	}
+	else if (type == WM_DRAG_ID) {
+		if (poin) {
+			WM_drag_add_ID(drag, poin, NULL);
+		}
+	}
+	else {
 		drag->poin = poin;
+	}
 	drag->value = value;
 
 	return drag;
@@ -178,6 +186,7 @@ void WM_drag_free(wmDrag *drag)
 		MEM_freeN(drag->poin);
 	}
 
+	BLI_freelistN(&drag->ids);
 	MEM_freeN(drag);
 }
 
@@ -190,26 +199,6 @@ void WM_drag_free_list(struct ListBase *lb)
 }
 
 
-ID *WM_drag_ID(const wmDrag *drag, short idcode)
-{
-	if (drag->type != WM_DRAG_ID) {
-		return NULL;
-	}
-
-	ID *id = drag->poin;
-	return (idcode == 0 || GS(id->name) == idcode) ? id : NULL;
-}
-
-ID *WM_drag_ID_from_event(const wmEvent *event, short idcode)
-{
-	if (event->custom != EVT_DATA_DRAGDROP) {
-		return NULL;
-	}
-
-	ListBase *lb = event->customdata;
-	return WM_drag_ID(lb->first, idcode);
-}
-
 static const char *dropbox_active(bContext *C, ListBase *handlers, wmDrag *drag, const wmEvent *event)
 {
 	wmEventHandler *handler = handlers->first;
@@ -290,6 +279,57 @@ void wm_drags_check_ops(bContext *C, const wmEvent *event)
 	}
 }
 
+/* ************** IDs ***************** */
+
+void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent)
+{
+	/* Don't drag the same ID twice. */
+	for (wmDragID *drag_id = drag->ids.first; drag_id; drag_id = drag_id->next) {
+		if (drag_id->id == id) {
+			if (drag_id->from_parent == NULL) {
+				drag_id->from_parent = from_parent;
+			}
+			return;
+		}
+		else if (GS(drag_id->id->name) != GS(id->name)) {
+			BLI_assert(!"All dragged IDs must have the same type");
+			return;
+		}
+	}
+
+	/* Add to list. */
+	wmDragID *drag_id = MEM_callocN(sizeof(wmDragID), __func__);
+	drag_id->id = id;
+	drag_id->from_parent = from_parent;
+	BLI_addtail(&drag->ids, drag_id);
+}
+
+ID *WM_drag_ID(const wmDrag *drag, short idcode)
+{
+	if (drag->type != WM_DRAG_ID) {
+		return NULL;
+	}
+
+	wmDragID *drag_id = drag->ids.first;
+	if (!drag_id) {
+		return NULL;
+	}
+
+	ID *id = drag_id->id;
+	return (idcode == 0 || GS(id->name) == idcode) ? id : NULL;
+
+}
+
+ID *WM_drag_ID_from_event(const wmEvent *event, short idcode)
+{
+	if (event->custom != EVT_DATA_DRAGDROP) {
+		return NULL;
+	}
+
+	ListBase *lb = event->customdata;
+	return WM_drag_ID(lb->first, idcode);
+}
+
 /* ************** draw ***************** */
 
 static void wm_drop_operator_draw(const char *name, int x, int y)
@@ -306,8 +346,15 @@ static const char *wm_drag_name(wmDrag *drag)
 	switch (drag->type) {
 		case WM_DRAG_ID:
 		{
-			ID *id = drag->poin;
-			return id->name + 2;
+			ID *id = WM_drag_ID(drag, 0);
+			bool single = (BLI_listbase_count_at_most(&drag->ids, 2) == 1);
+
+			if (single) {
+				return id->name + 2;
+			}
+			else {
+				return BKE_idcode_to_name_plural(GS(id->name));
+			}
 		}
 		case WM_DRAG_PATH:
 		case WM_DRAG_NAME:



More information about the Bf-blender-cvs mailing list