Orange; update commit on WIP project for Noodle editing. :)

- Grabbing works (Gkey) or tweak (LMB) or use RMB click-drag for grab
- Shift+d works
- Akey: select all
- Drawing links works too now!
This commit is contained in:
2005-12-18 23:08:22 +00:00
parent 87d9ca4b99
commit be0b59ea6d
9 changed files with 505 additions and 53 deletions

View File

@@ -51,6 +51,7 @@
#include "BKE_material.h"
#include "BKE_utildefines.h"
#include "BIF_editview.h"
#include "BIF_gl.h"
#include "BIF_interface.h"
#include "BIF_language.h"
@@ -62,19 +63,26 @@
#include "BSE_drawipo.h"
#include "BSE_headerbuttons.h"
#include "BSE_node.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BDR_editobject.h"
#include "blendef.h"
#include "interface.h" /* urm... for rasterpos_safe, roundbox */
#include "PIL_time.h"
#include "mydevice.h"
/* ***************************** */
/* **************** NODE draw callbacks ************* */
#define NODE_DY 20
#define NODE_SOCK 5
#define SOCK_IN 1
#define SOCK_OUT 2
static void nodeshadow(rctf *rct, int select)
{
@@ -165,7 +173,7 @@ static int node_basis_draw(SpaceNode *snode, bNode *node)
BIF_DrawString(snode->curfont, node->name, trans);
for(sock= node->inputs.first; sock; sock= sock->next) {
socket_circle_draw(sock->locx, sock->locy, 5.0f);
socket_circle_draw(sock->locx, sock->locy, NODE_SOCK);
BIF_ThemeColor(TH_TEXT);
ui_rasterpos_safe(sock->locx+8.0f, sock->locy-5.0f, snode->aspect);
@@ -173,7 +181,7 @@ static int node_basis_draw(SpaceNode *snode, bNode *node)
}
for(sock= node->outputs.first; sock; sock= sock->next) {
socket_circle_draw(sock->locx, sock->locy, 5.0f);
socket_circle_draw(sock->locx, sock->locy, NODE_SOCK);
BIF_ThemeColor(TH_TEXT);
slen= snode->aspect*BIF_GetStringWidth(snode->curfont, sock->name, trans);
@@ -184,29 +192,7 @@ static int node_basis_draw(SpaceNode *snode, bNode *node)
return 0;
}
static void node_deselectall(SpaceNode *snode, int swap)
{
bNode *node;
if(swap) {
for(node= snode->nodetree->nodes.first; node; node= node->next)
if(node->flag & SELECT)
break;
if(node==NULL) {
for(node= snode->nodetree->nodes.first; node; node= node->next)
node->flag |= SELECT;
allqueue(REDRAWNODE, 0);
return;
}
/* else pass on to deselect */
}
for(node= snode->nodetree->nodes.first; node; node= node->next)
node->flag &= ~SELECT;
allqueue(REDRAWNODE, 0);
}
/* ************************** Node generic ************** */
/* based on settings in tree and node,
- it fills it with appropriate callbacks
@@ -250,6 +236,172 @@ void node_update(bNodeTree *ntree, bNode *node)
node->tot.ymax= node->locy + dy;
}
/* ********************* transform ****************** */
/* releases on event, only intern (for extern see below) */
static void transform_nodes(SpaceNode *snode, char *undostr)
{
bNode *node;
float mxstart, mystart, mx, my, *oldlocs, *ol;
int cont=1, tot=0, cancel=0, firsttime=1;
short mval[2], mvalo[2];
char str[64];
/* count total */
for(node= snode->nodetree->nodes.first; node; node= node->next)
if(node->flag & SELECT) tot++;
if(tot==0) return;
/* store oldlocs */
ol= oldlocs= MEM_mallocN(sizeof(float)*2*tot, "oldlocs transform");
for(node= snode->nodetree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
ol[0]= node->locx; ol[1]= node->locy;
ol+= 2;
}
}
getmouseco_areawin(mvalo);
areamouseco_to_ipoco(G.v2d, mvalo, &mxstart, &mystart);
while(cont) {
getmouseco_areawin(mval);
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) {
firsttime= 0;
areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
mvalo[0]= mval[0];
mvalo[1]= mval[1];
for(ol= oldlocs, node= snode->nodetree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
node->locx= ol[0] + mx-mxstart;
node->locy= ol[1] + my-mystart;
node_update(snode->nodetree, node);
ol+= 2;
}
}
sprintf(str, "X: %.1f Y: %.1f", mx-mxstart, my-mystart);
headerprint(str);
force_draw(0);
}
else
PIL_sleep_ms(10);
while (qtest()) {
short val;
unsigned short event= extern_qread(&val);
switch (event) {
case LEFTMOUSE:
case SPACEKEY:
case RETKEY:
cont=0;
break;
case ESCKEY:
case RIGHTMOUSE:
if(val) {
cancel=1;
cont=0;
}
break;
default:
if(val) arrows_move_cursor(event);
break;
}
}
}
if(cancel) {
for(ol= oldlocs, node= snode->nodetree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
node->locx= ol[0];
node->locy= ol[1];
ol+= 2;
node_update(snode->nodetree, node);
}
}
}
else
BIF_undo_push(undostr);
allqueue(REDRAWNODE, 1);
MEM_freeN(oldlocs);
}
/* external call, also for callback */
void node_transform_ext(int mode, int unused)
{
transform_nodes(curarea->spacedata.first, "Translate node");
}
/* ********************** select ******************** */
/* no undo here! */
void node_deselectall(SpaceNode *snode, int swap)
{
bNode *node;
if(swap) {
for(node= snode->nodetree->nodes.first; node; node= node->next)
if(node->flag & SELECT)
break;
if(node==NULL) {
for(node= snode->nodetree->nodes.first; node; node= node->next)
node->flag |= SELECT;
allqueue(REDRAWNODE, 0);
return;
}
/* else pass on to deselect */
}
for(node= snode->nodetree->nodes.first; node; node= node->next)
node->flag &= ~SELECT;
allqueue(REDRAWNODE, 0);
}
static void node_mouse_select(SpaceNode *snode)
{
bNode *node;
float mx, my;
short mval[2];
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
if((G.qual & LR_SHIFTKEY)==0)
node_deselectall(snode, 0);
for(node= snode->nodetree->nodes.first; node; node= node->next) {
if(BLI_in_rctf(&node->tot, mx, my)) {
if(G.qual & LR_SHIFTKEY) {
if(node->flag & SELECT)
node->flag &= ~SELECT;
else
node->flag |= SELECT;
}
else
node->flag |= SELECT;
break;
}
}
/* not so nice (no event), but function below delays redraw otherwise */
force_draw(0);
std_rmouse_transform(node_transform_ext); /* does undo push for select */
}
/* ****************** Add *********************** */
/* editor context */
static void node_add_menu(SpaceNode *snode)
{
@@ -283,30 +435,178 @@ static void node_add_menu(SpaceNode *snode)
node_update(snode->nodetree, node);
/* fake links */
// if(snode->nodetree->nodes.first!=snode->nodetree->nodes.last) {
// bNode *first= snode->nodetree->nodes.first;
//
// nodeAddLink(snode->nodetree, first, first->outputs.first, node, node->inputs.first);
// }
allqueue(REDRAWNODE, 0);
}
BIF_undo_push("Add Node");
}
static void node_select(SpaceNode *snode)
void node_adduplicate(SpaceNode *snode)
{
bNode *node, *nnode;
/* backwards, we add to list end */
for(node= snode->nodetree->nodes.last; node; node= node->prev) {
if(node->flag & SELECT) {
nnode= nodeCopyNode(snode->nodetree, node);
node->flag &= ~SELECT;
nnode->flag |= SELECT;
}
}
transform_nodes(snode, "Duplicate");
}
/* checks mouse position, and returns found node/socket */
/* type is SOCK_IN and/or SOCK_OUT */
static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int type)
{
bNode *node;
float mx, my;
bNodeSocket *sock;
rctf rect;
short mval[2];
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &mx, &my);
areamouseco_to_ipoco(G.v2d, mval, &rect.xmin, &rect.ymin);
if((G.qual & LR_SHIFTKEY)==0)
node_deselectall(snode, 0);
rect.xmin -= NODE_SOCK+3;
rect.ymin -= NODE_SOCK+3;
rect.xmax = rect.xmin + 2*NODE_SOCK+6;
rect.ymax = rect.ymin + 2*NODE_SOCK+6;
/* check if we click in a socket */
for(node= snode->nodetree->nodes.first; node; node= node->next) {
if(BLI_in_rctf(&node->tot, mx, my)) {
node->flag |= SELECT;
if(type & SOCK_IN) {
for(sock= node->inputs.first; sock; sock= sock->next) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
*nodep= node;
*sockp= sock;
return 1;
}
}
}
if(type & SOCK_OUT) {
for(sock= node->outputs.first; sock; sock= sock->next) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
*nodep= node;
*sockp= sock;
return 1;
}
}
}
}
allqueue(REDRAWNODE, 0);
return 0;
}
/* loop that adds a link node, called by function below though */
static int node_draw_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int type)
{
bNode *tnode;
bNodeSocket *tsock;
bNodeLink *link= NULL;
short mval[2], mvalo[2];
/* we make a temporal link */
if(type==SOCK_OUT)
link= nodeAddLink(snode->nodetree, node, sock, NULL, NULL);
else
link= nodeAddLink(snode->nodetree, NULL, NULL, node, sock);
getmouseco_areawin(mvalo);
while (get_mbut() & L_MOUSE) {
getmouseco_areawin(mval);
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
mvalo[0]= mval[0];
mvalo[1]= mval[1];
if(type==SOCK_OUT) {
if(find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) {
if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) {
if(tnode!=node) {
link->tonode= tnode;
link->tosock= tsock;
}
}
}
else {
link->tonode= NULL;
link->tosock= NULL;
}
}
else {
if(find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) {
if(nodeFindLink(snode->nodetree, sock, tsock)==NULL) {
if(tnode!=node) {
link->fromnode= tnode;
link->fromsock= tsock;
}
}
}
else {
link->fromnode= NULL;
link->fromsock= NULL;
}
}
force_draw(0);
}
else BIF_wait_for_statechange();
}
if(link->tonode==NULL || link->fromnode==NULL) {
BLI_remlink(&snode->nodetree->links, link);
MEM_freeN(link);
}
allqueue(REDRAWNODE, 0);
return 1;
}
static int node_draw_link(SpaceNode *snode)
{
bNode *node;
bNodeSocket *sock;
/* we're going to draw an output */
if(find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
return node_draw_link_drag(snode, node, sock, SOCK_OUT);
}
if(find_indicated_socket(snode, &node, &sock, SOCK_IN)) {
bNodeLink *link;
/* find if we break a link */
for(link= snode->nodetree->links.first; link; link= link->next) {
if(link->tosock==sock)
break;
}
if(link) {
node= link->fromnode;
sock= link->fromsock;
BLI_remlink(&snode->nodetree->links, link);
MEM_freeN(link);
return node_draw_link_drag(snode, node, sock, SOCK_OUT);
}
else {
/* link from input to output */
return node_draw_link_drag(snode, node, sock, SOCK_IN);
}
}
return 0;
}
/* ******************** main event loop ****************** */
void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
@@ -323,11 +623,12 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
switch(event) {
case LEFTMOUSE:
node_select(snode);
if(node_draw_link(snode)==0)
node_mouse_select(snode);
break;
case RIGHTMOUSE:
node_select(snode);
node_mouse_select(snode);
break;
case MIDDLEMOUSE:
@@ -356,14 +657,19 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case AKEY:
if(G.qual==LR_SHIFTKEY)
node_add_menu(snode);
else if(G.qual==0)
else if(G.qual==0) {
node_deselectall(snode, 1);
BIF_undo_push("Deselect all nodes");
}
break;
case DKEY:
if(G.qual==LR_SHIFTKEY)
node_adduplicate(snode);
break;
case CKEY:
break;
case GKEY:
transform_nodes(snode, "Translate Node");
break;
case DELKEY:
case XKEY: