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:
Diffstat (limited to 'source/blender/editors/space_node/node_edit.c')
-rw-r--r--source/blender/editors/space_node/node_edit.c153
1 files changed, 153 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;
+}