diff options
Diffstat (limited to 'source/blender/editors/space_node/node_edit.c')
-rw-r--r-- | source/blender/editors/space_node/node_edit.c | 286 |
1 files changed, 85 insertions, 201 deletions
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index e5a216d42b0..87a56274035 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -690,108 +690,6 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) } } -static int compare_nodes(bNode *a, bNode *b) -{ - bNode *parent; - /* These tell if either the node or any of the parent nodes is selected. - * A selected parent means an unselected node is also in foreground! - */ - int a_select=(a->flag & NODE_SELECT), b_select=(b->flag & NODE_SELECT); - int a_active=(a->flag & NODE_ACTIVE), b_active=(b->flag & NODE_ACTIVE); - - /* if one is an ancestor of the other */ - /* XXX there might be a better sorting algorithm for stable topological sort, this is O(n^2) worst case */ - for (parent = a->parent; parent; parent=parent->parent) { - /* if b is an ancestor, it is always behind a */ - if (parent==b) - return 1; - /* any selected ancestor moves the node forward */ - if (parent->flag & NODE_ACTIVE) - a_active = 1; - if (parent->flag & NODE_SELECT) - a_select = 1; - } - for (parent = b->parent; parent; parent=parent->parent) { - /* if a is an ancestor, it is always behind b */ - if (parent==a) - return 0; - /* any selected ancestor moves the node forward */ - if (parent->flag & NODE_ACTIVE) - b_active = 1; - if (parent->flag & NODE_SELECT) - b_select = 1; - } - - /* if one of the nodes is in the background and the other not */ - if ((a->flag & NODE_BACKGROUND) && !(b->flag & NODE_BACKGROUND)) - return 0; - else if (!(a->flag & NODE_BACKGROUND) && (b->flag & NODE_BACKGROUND)) - return 1; - - /* if one has a higher selection state (active > selected > nothing) */ - if (!b_active && a_active) - return 1; - else if (!b_select && (a_active || a_select)) - return 1; - - return 0; -} -/* Sorts nodes by selection: unselected nodes first, then selected, - * then the active node at the very end. Relative order is kept intact! - */ -void node_sort(bNodeTree *ntree) -{ - /* merge sort is the algorithm of choice here */ - bNode *first_a, *first_b, *node_a, *node_b, *tmp; - int totnodes= BLI_countlist(&ntree->nodes); - int k, a, b; - - k = 1; - while (k < totnodes) { - first_a = first_b = ntree->nodes.first; - - do { - /* setup first_b pointer */ - for (b=0; b < k && first_b; ++b) { - first_b = first_b->next; - } - /* all batches merged? */ - if (first_b==NULL) - break; - - /* merge batches */ - node_a = first_a; - node_b = first_b; - a = b = 0; - while (a < k && b < k && node_b) { - if (compare_nodes(node_a, node_b)==0) { - node_a = node_a->next; - ++a; - } - else { - tmp = node_b; - node_b = node_b->next; - ++b; - BLI_remlink(&ntree->nodes, tmp); - BLI_insertlinkbefore(&ntree->nodes, node_a, tmp); - } - } - - /* setup first pointers for next batch */ - first_b = node_b; - for (; b < k; ++b) { - /* all nodes sorted? */ - if (first_b==NULL) - break; - first_b = first_b->next; - } - first_a = first_b; - } while (first_b); - - k = k << 1; - } -} - static int inside_rctf(rctf *bounds, rctf *rect) { return (bounds->xmin <= rect->xmin && bounds->xmax >= rect->xmax @@ -940,7 +838,7 @@ static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op)) ED_preview_kill_jobs(C); if (snode->nodetree==snode->edittree) { - bNode *gnode= nodeGetActive(snode->nodetree); + bNode *gnode = nodeGetActive(snode->edittree); snode_make_group_editable(snode, gnode); } else @@ -955,8 +853,11 @@ static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e { SpaceNode *snode = CTX_wm_space_node(C); bNode *gnode; - - gnode= nodeGetActive(snode->edittree); + + gnode = nodeGetActive(snode->edittree); + if (!gnode) + return OPERATOR_CANCELLED; + /* XXX callback? */ if(gnode && gnode->id && GS(gnode->id->name)==ID_NT && gnode->id->lib) { uiPupMenuOkee(C, op->type->idname, "Make group local?"); @@ -1696,90 +1597,8 @@ void NODE_OT_resize(wmOperatorType *ot) ot->flag= OPTYPE_BLOCKING; } -/* ********************** select ******************** */ - - -/* no undo here! */ -void node_deselectall(SpaceNode *snode) -{ - bNode *node; - - for(node= snode->edittree->nodes.first; node; node= node->next) - node->flag &= ~SELECT; -} -/* return 1 if we need redraw otherwise zero. */ -int node_select_same_type(SpaceNode *snode) -{ - bNode *nac, *p; - int redraw; - - /* search for the active node. */ - for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { - if (nac->flag & SELECT) - break; - } - - /* no active node, return. */ - if (!nac) - return(0); - - redraw= 0; - for (p= snode->edittree->nodes.first; p; p= p->next) { - if (p->type != nac->type && p->flag & SELECT) { - /* if it's selected but different type, unselect */ - redraw= 1; - p->flag &= ~SELECT; - } - else if (p->type == nac->type && (!(p->flag & SELECT))) { - /* if it's the same type and is not selected, select! */ - redraw= 1; - p->flag |= SELECT; - } - } - return(redraw); -} - -/* return 1 if we need redraw, otherwise zero. - * dir can be 0 == next or 0 != prev. - */ -int node_select_same_type_np(SpaceNode *snode, int dir) -{ - bNode *nac, *p; - - /* search the active one. */ - for (nac= snode->edittree->nodes.first; nac; nac= nac->next) { - if (nac->flag & SELECT) - break; - } - - /* no active node, return. */ - if (!nac) - return(0); - - if (dir == 0) - p= nac->next; - else - p= nac->prev; - - while (p) { - /* Now search the next with the same type. */ - if (p->type == nac->type) - break; - - if (dir == 0) - p= p->next; - else - p= p->prev; - } - - if (p) { - node_deselectall(snode); - p->flag |= SELECT; - return(1); - } - return(0); -} +/* ********************** hidden sockets ******************** */ int node_has_hidden_sockets(bNode *node) { @@ -1794,6 +1613,31 @@ int node_has_hidden_sockets(bNode *node) return 0; } +/* note: call node_tree_verify_groups(snode->nodetree) after this + */ +void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) +{ + bNodeSocket *sock; + + if(set==0) { + for(sock= node->inputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_HIDDEN; + for(sock= node->outputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_HIDDEN; + } + else { + /* hide unused sockets */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link==NULL) + sock->flag |= SOCK_HIDDEN; + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(nodeCountSocketLinks(snode->edittree, sock)==0) + sock->flag |= SOCK_HIDDEN; + } + } +} + static void node_link_viewer(SpaceNode *snode, bNode *tonode) { bNode *node; @@ -2232,7 +2076,7 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate { bNode *node= NULL, *gnode; - node_deselectall(snode); + node_deselect_all(snode); node = nodeAddNode(snode->edittree, ntemp); @@ -3130,15 +2974,21 @@ void NODE_OT_group_make(wmOperatorType *ot) static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) { - int tot_eq= 0, tot_neq= 0; bNode *node; + int tot_eq= 0, tot_neq= 0; + /* Toggles the flag on all selected nodes. + * If the flag is set on all nodes it is unset. + * If the flag is not set on all nodes, it is set. + */ for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - + if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0) continue; - + if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0) + continue; + if(node->flag & toggle_flag) tot_eq++; else @@ -3147,10 +2997,12 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) } for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { - + if(toggle_flag== NODE_PREVIEW && (node->typeinfo->flag & NODE_PREVIEW)==0) continue; - + if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0) + continue; + if( (tot_eq && tot_neq) || tot_eq==0) node->flag |= toggle_flag; else @@ -3159,7 +3011,7 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) } } -static int node_hide_exec(bContext *C, wmOperator *UNUSED(op)) +static int node_hide_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode= CTX_wm_space_node(C); @@ -3182,14 +3034,14 @@ void NODE_OT_hide_toggle(wmOperatorType *ot) ot->idname= "NODE_OT_hide_toggle"; /* callbacks */ - ot->exec= node_hide_exec; + ot->exec= node_hide_toggle_exec; ot->poll= ED_operator_node_active; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int node_preview_exec(bContext *C, wmOperator *UNUSED(op)) +static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode= CTX_wm_space_node(C); @@ -3214,7 +3066,37 @@ void NODE_OT_preview_toggle(wmOperatorType *ot) ot->idname= "NODE_OT_preview_toggle"; /* callbacks */ - ot->exec= node_preview_exec; + ot->exec= node_preview_toggle_exec; + ot->poll= ED_operator_node_active; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int node_options_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceNode *snode= CTX_wm_space_node(C); + + /* sanity checking (poll callback checks this already) */ + if((snode == NULL) || (snode->edittree == NULL)) + return OPERATOR_CANCELLED; + + node_flag_toggle_exec(snode, NODE_OPTIONS); + + snode_notify(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_options_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Toggle Node Options"; + ot->description= "Toggle option buttons display for selected nodes"; + ot->idname= "NODE_OT_options_toggle"; + + /* callbacks */ + ot->exec= node_options_toggle_exec; ot->poll= ED_operator_node_active; /* flags */ @@ -3225,7 +3107,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode= CTX_wm_space_node(C); bNode *node; - int hidden= 0; + int hidden; /* sanity checking (poll callback checks this already) */ if((snode == NULL) || (snode->edittree == NULL)) @@ -3233,6 +3115,8 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) ED_preview_kill_jobs(C); + /* Toggle for all selected nodes */ + hidden = 0; for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { if(node_has_hidden_sockets(node)) { @@ -3241,7 +3125,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op)) } } } - + for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { node_set_hidden_sockets(snode, node, !hidden); @@ -3570,7 +3454,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) } } - node_deselectall(snode); + node_deselect_all(snode); if (snode->nodetree->type==NTREE_COMPOSIT) ntemp.type = CMP_NODE_IMAGE; |