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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-08-05 13:14:55 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-08-10 18:53:00 +0300
commit4375e7ff0b74f96447e27f78a0d9245353d36865 (patch)
tree24ea32717810f89f8c8ba54f2aa28aa81122a8cd
parent86c363a02706b1a5d3cb18d17b4b37bd78461ded (diff)
WM: internal changes to support dragging multiple IDs.
To be used by the outliner.
-rw-r--r--source/blender/editors/space_node/space_node.c4
-rw-r--r--source/blender/editors/space_text/space_text.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c8
-rw-r--r--source/blender/windowmanager/WM_api.h8
-rw-r--r--source/blender/windowmanager/WM_types.h9
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c95
6 files changed, 92 insertions, 34 deletions
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: