From 7aa907c996cd9a22a1b1d14159ef7ef9822f0a54 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 12 May 2010 04:25:33 +0000 Subject: [PATCH] Another one for drag and drop: Allow dropping image files from outside blender, or image datablocks from inside blender to the compositing node editor, to add an image node. Also small tweak: Only set 'path' properties on drops, if the drag->path isn't empty. --- source/blender/editors/space_node/node_edit.c | 82 +++++++++++++++++++ .../blender/editors/space_node/node_intern.h | 2 + source/blender/editors/space_node/node_ops.c | 2 + .../blender/editors/space_node/space_node.c | 49 +++++++++++ .../editors/space_view3d/space_view3d.c | 2 +- 5 files changed, 136 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 99ac88f83a7..42c9f4ce1a2 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2030,4 +2030,86 @@ void NODE_OT_show_cyclic_dependencies(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* ****************** Add File Node Operator ******************* */ + +static int node_add_file_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SpaceNode *snode= CTX_wm_space_node(C); + bNode *node; + Image *ima= NULL; + int ntype=0; + + /* check input variables */ + if (RNA_property_is_set(op->ptr, "path")) + { + char path[FILE_MAX]; + RNA_string_get(op->ptr, "path", path); + ima= BKE_add_image_file(path, scene ? scene->r.cfra : 1); + } + else if(RNA_property_is_set(op->ptr, "name")) + { + char name[32]; + RNA_string_get(op->ptr, "name", name); + ima= (Image *)find_id("IM", name); + } + + if(!ima) { + BKE_report(op->reports, RPT_ERROR, "Not an Image."); + return OPERATOR_CANCELLED; + } + + + node_deselectall(snode); + + if (snode->nodetree->type==NTREE_COMPOSIT) + ntype = CMP_NODE_IMAGE; + + node = node_add_node(snode, scene, ntype, snode->mx, snode->my); + + if (!node) { + BKE_report(op->reports, RPT_ERROR, "Could not add an image node."); + return OPERATOR_CANCELLED; + } + + node->id = (ID *)ima; + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +static int node_add_file_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + SpaceNode *snode= CTX_wm_space_node(C); + + /* convert mouse coordinates to v2d space */ + UI_view2d_region_to_view(&ar->v2d, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin, + &snode->mx, &snode->my); + + if (RNA_property_is_set(op->ptr, "path") || RNA_property_is_set(op->ptr, "name")) + return node_add_file_exec(C, op); + else + return WM_operator_filesel(C, op, event); +} + +void NODE_OT_add_file(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add File Node"; + ot->description= "Add a file node to the current node editor"; + ot->idname= "NODE_OT_add_file"; + + /* callbacks */ + ot->exec= node_add_file_exec; + ot->invoke= node_add_file_invoke; + ot->poll= ED_operator_node_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE, FILE_SPECIAL, FILE_OPENFILE); + RNA_def_string(ot->srna, "name", "Image", 24, "Name", "Datablock name to assign."); +} diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 20c062acab1..53a088d6f6a 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -108,6 +108,8 @@ void NODE_OT_read_renderlayers(struct wmOperatorType *ot); void NODE_OT_backimage_move(struct wmOperatorType *ot); void NODE_OT_backimage_zoom(struct wmOperatorType *ot); +void NODE_OT_add_file(struct wmOperatorType *ot); + // XXXXXX // XXX from BSE_node.h diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 5fb950792e9..cc5ce84a5c1 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -77,6 +77,8 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_backimage_move); WM_operatortype_append(NODE_OT_backimage_zoom); + + WM_operatortype_append(NODE_OT_add_file); } void ED_operatormacros_node(void) diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 3bafcc25f6e..d22d1b4aa2d 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -53,6 +53,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "UI_resources.h" #include "UI_view2d.h" #include "RNA_access.h" @@ -263,6 +264,7 @@ static void node_buttons_area_draw(const bContext *C, ARegion *ar) static void node_main_area_init(wmWindowManager *wm, ARegion *ar) { wmKeyMap *keymap; + ListBase *lb; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); @@ -272,6 +274,11 @@ static void node_main_area_init(wmWindowManager *wm, ARegion *ar) keymap= WM_keymap_find(wm->defaultconf, "Node Editor", SPACE_NODE, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + + /* add drop boxes */ + lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW); + + WM_event_add_dropbox_handler(&ar->handlers, lb); } static void node_main_area_draw(const bContext *C, ARegion *ar) @@ -281,6 +288,47 @@ static void node_main_area_draw(const bContext *C, ARegion *ar) drawnodespace(C, ar, v2d); } + +/* ************* dropboxes ************* */ + +static int node_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) +{ + if(drag->type==WM_DRAG_ID) { + ID *id= (ID *)drag->poin; + if( GS(id->name)==ID_IM ) + return 1; + } + else if(drag->type==WM_DRAG_PATH){ + if(ELEM(drag->icon, 0, ICON_FILE_IMAGE)) /* rule might not work? */ + return 1; + } + return 0; +} + +static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id= (ID *)drag->poin; + + if(id) { + RNA_string_set(drop->ptr, "name", id->name+2); + } + if (drag->path[0]) { + RNA_string_set(drop->ptr, "path", drag->path); + } +} + +/* this region dropbox definition */ +static void node_dropboxes(void) +{ + ListBase *lb= WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW); + + WM_dropbox_add(lb, "NODE_OT_add_file", node_drop_poll, node_id_path_drop_copy); + +} + +/* ************* end drop *********** */ + + /* add handlers, stuff you only do once or on area/region changes */ static void node_header_area_init(wmWindowManager *wm, ARegion *ar) { @@ -366,6 +414,7 @@ void ED_spacetype_node(void) st->listener= node_area_listener; st->refresh= node_area_refresh; st->context= node_context; + st->dropboxes = node_dropboxes; /* regions: main window */ art= MEM_callocN(sizeof(ARegionType), "spacetype node region"); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 472631c3616..e78618f4627 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -453,7 +453,7 @@ static void view3d_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) if(id) RNA_string_set(drop->ptr, "name", id->name+2); - if(drag->path) + if(drag->path[0]) RNA_string_set(drop->ptr, "path", drag->path); }