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:
authorLukas Toenne <lukas.toenne@googlemail.com>2012-08-02 13:52:37 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2012-08-02 13:52:37 +0400
commit9d2173518cd7da7d18bb032c8537c8952abc2b78 (patch)
tree5fd02e1b8013ed6a37915cacfabb960dd9f66877 /source/blender/editors/space_node
parent0a782a4550904cdec15efbf5bf81c8be144896ee (diff)
Clipboard feature for nodes. With the Copy operator a copy of all selected nodes and links between them is stored in an offscreen list (not in the library). The Paste operator then in turn copies these into the active node tree in the editor.
Currently does not support copying of animation data. This would require copying of individual fcurves etc. between data block, which is not implemented yet. Also it is currently possible to circumvent some constraints of the nodes, in particular for node groups (e.g. no groups inside groups, render layer not inside groups).
Diffstat (limited to 'source/blender/editors/space_node')
-rw-r--r--source/blender/editors/space_node/node_edit.c153
-rw-r--r--source/blender/editors/space_node/node_intern.h4
-rw-r--r--source/blender/editors/space_node/node_ops.c6
3 files changed, 163 insertions, 0 deletions
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 4b554185933..fa8fa13a645 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2215,3 +2215,156 @@ void NODE_OT_node_copy_color(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+
+/* ****************** Copy to clipboard ******************* */
+
+static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeTree *ntree = snode->edittree;
+ bNode *node, *newnode;
+ bNodeLink *link, *newlink;
+
+ ED_preview_kill_jobs(C);
+
+ /* clear current clipboard */
+ nodeClipboardClear();
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->flag & SELECT) {
+ newnode = nodeCopyNode(NULL, node);
+ nodeClipboardAddNode(newnode);
+ }
+ }
+
+ /* copy links between selected nodes
+ * NB: this depends on correct node->new_node and sock->new_sock pointers from above copy!
+ */
+ for (link = ntree->links.first; link; link = link->next) {
+ /* This creates new links between copied nodes. */
+ if (link->tonode && (link->tonode->flag & NODE_SELECT) &&
+ link->fromnode && (link->fromnode->flag & NODE_SELECT))
+ {
+ newlink = MEM_callocN(sizeof(bNodeLink), "bNodeLink");
+ newlink->flag = link->flag;
+ newlink->tonode = link->tonode->new_node;
+ newlink->tosock = link->tosock->new_sock;
+ newlink->fromnode = link->fromnode->new_node;
+ newlink->fromsock = link->fromsock->new_sock;
+
+ nodeClipboardAddLink(newlink);
+ }
+ }
+
+ /* reparent copied nodes */
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if ((node->flag & SELECT) && node->parent) {
+ if (node->parent->flag & SELECT)
+ node->parent = node->parent->new_node;
+ else
+ node->parent = NULL;
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_clipboard_copy(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Copy to clipboard";
+ ot->description = "Copies selected nodes to the clipboard";
+ ot->idname = "NODE_OT_clipboard_copy";
+
+ /* api callbacks */
+ ot->exec = node_clipboard_copy_exec;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ****************** Paste from clipboard ******************* */
+
+static int node_clipboard_paste_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeTree *ntree = snode->edittree;
+ bNode *node;
+ bNodeLink *link;
+ int num_nodes;
+ float centerx, centery;
+
+ ED_preview_kill_jobs(C);
+
+ /* deselect old nodes */
+ node_deselect_all(snode);
+
+ /* calculate "barycenter" for placing on mouse cursor */
+ num_nodes = 0;
+ centerx = centery = 0.0f;
+ for (node = nodeClipboardGetNodes()->first; node; node = node->next) {
+ ++num_nodes;
+ centerx += node->locx + 0.5f * node->width;
+ centery += node->locy - 0.5f * node->height;
+ }
+ centerx /= num_nodes;
+ centery /= num_nodes;
+
+ /* copy nodes from clipboard */
+ for (node = nodeClipboardGetNodes()->first; node; node = node->next) {
+ bNode *newnode = nodeCopyNode(ntree, node);
+
+ /* pasted nodes are selected */
+ node_select(newnode);
+
+ /* place nodes around the mouse cursor */
+ newnode->locx += snode->mx - centerx;
+ newnode->locy += snode->my - centery;
+ }
+
+ for (link = nodeClipboardGetLinks()->first; link; link = link->next) {
+ nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock,
+ link->tonode->new_node, link->tosock->new_sock);
+ }
+
+ /* reparent copied nodes */
+ for (node = nodeClipboardGetNodes()->first; node; node = node->next) {
+ if (node->new_node->parent)
+ node->new_node->parent = node->new_node->parent->new_node;
+ }
+
+ ntreeUpdateTree(snode->edittree);
+
+ snode_notify(C, snode);
+ snode_dag_update(C, snode);
+
+ return OPERATOR_FINISHED;
+}
+
+static int node_clipboard_paste_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->mval[0], event->mval[1], &snode->mx, &snode->my);
+
+ return node_clipboard_paste_exec(C, op);
+}
+
+void NODE_OT_clipboard_paste(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Paste from clipboard";
+ ot->description = "Pastes nodes from the clipboard to the active node tree";
+ ot->idname = "NODE_OT_clipboard_paste";
+
+ /* api callbacks */
+ ot->exec = node_clipboard_paste_exec;
+ ot->invoke = node_clipboard_paste_invoke;
+ ot->poll = ED_operator_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 5c6a91195a6..7077229fae1 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -200,6 +200,10 @@ void NODE_OT_output_file_add_socket(struct wmOperatorType *ot);
void NODE_OT_output_file_remove_active_socket(struct wmOperatorType *ot);
void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot);
+/* Note: clipboard_cut is a simple macro of copy + delete */
+void NODE_OT_clipboard_copy(struct wmOperatorType *ot);
+void NODE_OT_clipboard_paste(struct wmOperatorType *ot);
+
extern const char *node_context_dir[];
// XXXXXX
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 0ce72848c56..2efeebbfc75 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -113,6 +113,9 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_join);
WM_operatortype_append(NODE_OT_attach);
WM_operatortype_append(NODE_OT_detach);
+
+ WM_operatortype_append(NODE_OT_clipboard_copy);
+ WM_operatortype_append(NODE_OT_clipboard_paste);
}
void ED_operatormacros_node(void)
@@ -281,5 +284,8 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_read_fullsamplelayers", RKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "NODE_OT_render_changed", ZKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_clipboard_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+
transform_keymap_for_space(keyconf, keymap, SPACE_NODE);
}