//////////////////////////////////////////////////////////////////////// // Name: nodeops.cc // // Description: // // This file contains all BDE code responsible for controlling node // operations. The code has been taken from the BDE 1.0 buttondown.cc, // buttonup.cc and buttonmoved.cc files. // // Routines :node_create();node_delete();node_move();node_resize(); // // History: // // 05/01/93 nlinsky created. // 08/23/93 hlee modified. // // // $Log: nodeops.cc,v $ // // Revision 1.5 1995/12/16 phsia // The node_create() only needs 2 arguments: event and button_op. No // need to pass state to addno() because no more six states for nodeshapes. // // Revision 1.4 1995/05/13 02:31:59 hcpatel // Implemented corrected state model for node delete operation. // // Revision 1.3 1995/05/11 21:31:23 bbarry // renamed state SRectaingle to SRectangle to make easier to find // // Revision 1.2 1995/04/04 04:41:38 cgopal // File bde20 and others were fixed so that multiple definitions // of variables were eliminated. All enumarated types were capitializes and give // n a prefix. // // Arguments to XtAddcallback was casted to the right type. Handler.cc // was also fixed to use right variables. // // Revision 1.16 1994/08/23 01:54:36 lechner // Eliminated obsolete calls to dirdo and to save("wchen") // // Revision 1.15 1994/05/07 23:43:12 dgrant // In routines node_move() and node_resize() changed calls from // infomessage to displayMessage. // // Revision 1.14 1994/05/07 22:00:27 dgrant // In routine addattr, made required changes so that HA's would // work in GENV8. // // Revision 1.13 1994/04/23 19:04:25 mtorpey // Cursons now change at the appropriate times. // // Revision 1.12 1994/04/22 21:30:48 mtorpey // Fixed the last remaining bug in node_resize().. :) // // Revision 1.11 1994/04/22 19:37:42 mtorpey // Fixed on more minor bug in node_resize(). Before if you resized a node, // it left it highlighted, even though at this point you were in the // unhighlited state. Now it unhighlites the node // // Revision 1.10 1994/04/22 00:48:04 mtorpey // Fixed delete node and resize node to work according to the new state // machines, ie. they work right. // // Revision 1.9 1994/04/21 21:18:28 mtorpey // Reduce the function node_create() from 134 lines to 46 lines. // // Revision 1.8 1994/04/15 19:30:48 mtorpey // Replaced all occurances of RosterView with 94sbdeview and all occurances // of RosterReadView with 94sbdedefaultsView. These reflect the new changes // made to the bdetest.viewdefs file. // // Revision 1.7 1994/04/09 18:14:28 dgrant // CHGEN ver 6 to ver8 updates. DGrant and TSeeley // // Revision 1.6 1994/04/01 01:49:58 namin // version 8 changes (to make it work for version 6) // // Revision 1.5 1994/03/31 19:21:14 namin // version 8 changes // // Revision 1.4 1994/03/12 16:44:39 lking // Added the include file "prototype.h" which contains all the function // declarations. Removed all external function declarations from this file. // // Revision 1.3 1994/03/11 21:16:59 lking // Reformatted the header comment to make it more readable. Move rcsid // below the header comment. Removed all debugging printfs from the file. // // Revision 1.2 1994/03/09 18:27:48 jrichard // Added a rcs log replacement statement to all .cc files as part of the // header comment. THis places all checkin comments directly into the // header comment. // //////////////////////////////////////////////////////////////////////// #ifndef lint static char rcsid[] = "$Id: nodeops.cc,v 1.4 1995/05/13 02:31:59 hcpatel Exp $"; #endif /********************** System include files *******************************/ #include #include #include #include #include #include #include /********************** Program include files ******************************/ #include "tags.h" #include "bde.h" #include "graph.h" #include "state.h" #include "prototype.h" /********************** Macro defines **************************************/ #ifdef GENV6 extern "C" { void pr_add (char *,char *); /*hlee, should be declared in .h */ char find_view_idx(char *); /*hlee;added this to get rid of warning <x, event->y, &sx, &sy); /* At this point, we are in the Node Create state */ switch (button_op) { ANCHORTAG(node_create_BDE) case BUTTON_DOWN_EVENT: topobject->addnode(sx, sy); break; /* end of BUTTON_DOWN_EVENT case */ ANCHORTAG(node_create_BUE) case BUTTON_UP_EVENT: break; ANCHORTAG(node_create_BME) case BUTTON_MOVED_EVENT: break; default: /* illegal value for button_op variable */ //add PostErrorMsg() to handle error message - phsia 12/8/95 PostErrorMsg(SCnode); break; } } /*************************************************************************** * Name: * void node_delete(XButtonEvent*, int, node_attributes *, int) * Added by: * ??? * Modified by: * hcpatel & mmaliset - bdesrc 95sbde * A generic selction routine is used for selecting a Node which searches * the whole object list till it finds a Node. This routine implements the * improved state model suggested by Prof.Lechner. * Description: * This performs the node deletion operation. It does this based on the * button event and other variables passed in to it. (Note that attribute * is not actually used for the delete operation. We don't need to know * whether the node was a circle or rectangle to delete it.) * All code within this function was lifted from the button*.cc files. * button_op is one of: BUTTON_UP, BUTTON_DOWN, BUTTON_MOVED * Uses: * DCtoWC(), Ggroup class method select_HN(widget, int, int), * changeCanvasCursor(), changeAttribState(), docut() * Side effects: * NONE ***************************************************************************/ ANCHORTAG(node_delete) void node_delete (XButtonEvent *event, int state, /* Canvas State (eventually just NodeCreate)*/ node_attributes *attribute, /* circle, square, etc. */ int button_op /* BUTTON_UP, BUTTON_DOWN, BUTTON_MOVED */ ) { float sx, sy; static graphobject *selected_node = NULL; DCtoWC(event->x, event->y, &sx, &sy); switch (state) { /* Note that once the canvas state has been changed to be more meaningful, the following state case should eventually be replaced by a line of the form "case NodeDelete:" */ ANCHORTAG(node_delete_SD1) case SDnode1: switch (button_op) { ANCHORTAG(node_delete_SD1_BDE) case BUTTON_DOWN_EVENT: topobject->select_HN(canvas, (int)sx, (int)sy); selected_node = currentselection; if (currentselection != NULL) { selected.changeAttribState(SDnode2); changeCanvasCursor(pirate); } break; ANCHORTAG(node_delete_SD1_BUE) case BUTTON_UP_EVENT: break; ANCHORTAG(node_delete_SD1_BME) case BUTTON_MOVED_EVENT: break; default: //add PostErrorMsg() to handle error message - phsia 12/8/95 PostErrorMsg(SDnode1); break; } break; ANCHORTAG(node_delete_SD2) case SDnode2: switch (button_op) { ANCHORTAG(node_delete_SD2_BDE) case BUTTON_DOWN_EVENT: topobject->select_HN(canvas, (int)sx, (int)sy); if(currentselection != NULL && selected_node == currentselection) { docut((Widget) 0,0,0); selected.changeAttribState(SDnode1); changeCanvasCursor(arrow); } else selected_node = currentselection; break; ANCHORTAG(node_delete_SD2_BUE) case BUTTON_UP_EVENT: break; ANCHORTAG(node_delete_SD2_BME) case BUTTON_MOVED_EVENT: break; default: /* illegal value for button_op variable */ //add PostErrorMsg() to handle error message - phsia 12/8/95 PostErrorMsg(SDnode2); break; } break; default: /* illegal value for state variable */ fprintf(stderr, "Out of State in function node_delete.\n"); fprintf(stderr, "switch on state\n"); fprintf(stderr, "Report this to Professor Lechner.\n"); break; } } // end void node_delete() /*************************************************************************** * Description: * node_move performs the node movement operation. It does * this based on the button event and other variables passed * in to it. All code within this function was lifted from * the button*.cc files. Note that we don't actually use * the attribute information (at least for now). * * Error handling: * NONE. * Side effects: * NONE. ***************************************************************************/ ANCHORTAG(node_move) void node_move (XButtonEvent *event, int state, /* Canvas State (eventually just NodeCreate)*/ node_attributes *attribute, /* circle, square, etc. */ int button_op) /* BUTTON_UP, BUTTON_DOWN,BUTTON_MOVED */ { float sx, sy; #ifdef GENV6 char *id; #else hcg_key id; #endif /* Xlate into world coordinates */ DCtoWC(event->x, event->y, &sx, &sy); switch (state) { /* Note that once the canvas state has been changed to be more meaningful, the following state case should eventually be replaced by one line of the form "case NodeMove:" */ ANCHORTAG(node_move_SM) case SMove: /* At this point, we are in the Node Move state */ switch (button_op) { ANCHORTAG(node_move_SM_BDE) case BUTTON_DOWN_EVENT: unselect(); /* Unselect any current sel. */ /* Now get the pointed at */ topobject->select_HN(canvas, (int)sx, (int)sy); if (currentselection != 0) { #ifdef GENV6 id = currentselection->getid(); #else id = (hcg_key)currentselection->getid(); #endif pr_find(HN,HNid,id); if (HNcurr != NULL) { selectedx = sx; selectedy = sy; savedx = currentselection->getcenterx(); savedy = currentselection->getcentery(); displayMessage("Drag node to new location\n"); } else { unselect(); currentselection = 0; displayMessage( "Link cannot be moved by draging it\n"); } } break; ANCHORTAG(node_move_SM_BUE) case BUTTON_UP_EVENT: if(currentselection != 0) { #ifdef GENV6 topobject->dorecalc(currentselection->getid()); #else topobject->dorecalc((hcg_key)currentselection->getid()); #endif unselect(); ReDraw(); } break; ANCHORTAG(node_move_SM_BME) case BUTTON_MOVED_EVENT: if(currentselection != 0) { /* This is the case for moving symbols */ currentselection -> highlight(0); /* Incremental move of bounding box */ currentselection->setcenterx(savedx + sx - selectedx); /* Limit movement */ if (currentselection -> getcenterx() < 0) currentselection -> setcenterx(0); if (currentselection->getcentery() < 0) currentselection -> setcentery(0); currentselection->setcentery(savedy + sy - selectedy); currentselection -> highlight(1); } break; default: /* illegal value for button_op variable */ //add PostErrorMsg() to handle error message - phsia 12/8/95 PostErrorMsg(SMove); break; } break; default: /* illegal value for state variable */ fprintf(stderr, "Out of State in function node_move.\n"); fprintf(stderr, "switch on state\n"); fprintf(stderr, "Report this to Professor Lechner.\n"); break; } } //**************************** Begin ************************************ /*************************************************************************** * Description: * node_resize performs the node resize operation. It does * this based on the button event and other variables passed * in to it. All code within this function was lifted from * the button*.cc files. Note that we don't actually use * the attribute information (at least for now). * * Error handling: * NONE. * Side effects: * NONE. ***************************************************************************/ // This procedure is added by bde3 // Aug,22,93 by Wenchin Chen // ANCHORTAG(node_resize) void node_resize ( XButtonEvent *event, int state, /* Canvas State (eventually just NodeCreate)*/ node_attributes *attribute, /* circle, square, etc. */ int button_op) /* BUTTON_UP, BUTTON_DOWN,BUTTON_MOVED */ { /* Stub function, not written yet */ float sx, sy; #ifdef GENV6 char *id; #else hcg_key id; #endif char curr_shape[20]; float center_x, center_y, radius; float temp_x, temp_y, temp_radius; float diff_x, diff_y; double squares; extern int first_time; static graphobject *selected_node = NULL; static int Resize = 0; DCtoWC(event->x, event->y, &sx, &sy); switch (state) { /* Note that once the canvas state has been changed to be more meaningful, the following state case should eventually be replaced by a line of the form "case NodeResize:" */ ANCHORTAG(node_resize_SR) case SResize: switch (button_op) { ANCHORTAG(node_resize_SR_BDE) case BUTTON_DOWN_EVENT: unselect(); unselect(); selection(canvas, (int)sx, (int)sy); selected_node = currentselection; selected.changeAttribState(SResize_node); changeCanvasCursor(movehand); Resize = 0; break; ANCHORTAG(node_resize_SR_BUE) case BUTTON_UP_EVENT: break; ANCHORTAG(node_resize_SR_BME) case BUTTON_MOVED_EVENT: break; default: //add PostErrorMsg() to handle error message - phsia 12/8/95 PostErrorMsg(SResize); break; } break; ANCHORTAG(node_resize_SRn) case SResize_node: /* At this point, we are in the NodeResize state */ switch (button_op) { ANCHORTAG(node_resize_SRn_BDE) case BUTTON_DOWN_EVENT: unselect(); selection(canvas, (int)sx, (int)sy); if (selected_node != currentselection) { selected_node = currentselection; break; } Resize = 1; if(currentselection != 0){ #ifdef GENV6 id = currentselection->getid(); #else id = (hcg_key)currentselection->getid(); #endif pr_find(HN,HNid,id); if(HNcurr != NULL){ first_time = TRUE; selectedx = sx; selectedy = sy; savedx = currentselection->getcenterx(); savedy = currentselection->getcentery(); displayMessage("Drag the mouse button to resize\n"); center_x = currentselection->getcenterx(); center_y = currentselection->getcentery(); radius = currentselection->getradius(); } else{ unselect(); currentselection = 0; displayMessage("Node cannot be resized\n"); } } break; ANCHORTAG(node_resize_SRn_BME) case BUTTON_MOVED_EVENT: if (Resize == 1) LINKTAG(doresize)((int)event->x, (int)event->y); break; ANCHORTAG(node_resize_SRn_BUE) case BUTTON_UP_EVENT: if (selected_node == NULL) { selected.changeAttribState(SResize_node); changeCanvasCursor(arrow); break; } else if (Resize == 0) break; selected.changeAttribState(SResize); changeCanvasCursor(arrow); if(currentselection != 0){ #ifdef GENV6 id = currentselection->getid(); #else id = (hcg_key)currentselection->getid(); #endif pr_find(HN,HNid,id); if(HNcurr == NULL){ return; } } else { return; } center_x = currentselection->getcenterx(); center_y = currentselection->getcentery(); temp_x = event->x; temp_y = event->y; diff_x = temp_x - center_x; diff_y = temp_y - center_y; strcpy(curr_shape, currentselection->getshape()); if((int)curr_shape[0] == 'C' || (int)curr_shape[0] == 'c'){ squares = (double)(diff_x * diff_x + diff_y * diff_y); temp_radius = (float)sqrt(squares) * 2.0; currentselection->setradius(temp_radius,temp_radius); }else{ if(diff_x < 0) diff_x = -diff_x ; if(diff_y < 0) diff_y = -diff_y ; currentselection->setradius(diff_x*2.0, diff_y*2.0); } #ifdef GENV6 topobject->dorecalc(currentselection->getid()); #else topobject->dorecalc((hcg_key)currentselection->getid()); #endif ReDraw(); first_time = TRUE; unselect(); break; default: /* illegal value for button_op variable */ fprintf(stderr, "Out of State in function node_resize.\n"); fprintf(stderr, "switch on state\n"); fprintf(stderr, "Report this to Professor Lechner.\n"); break; } } } /* Routine: doresize() called by case BUTTON_MOVED_EVENT */ ANCHORTAG(doresize) void doresize(int x, int y) { float curr_x,curr_y,center_x,center_y; float temp_x,temp_y,diff_x,diff_y; static float last_radius,last_width,last_height; double squares; #ifdef GENV6 char *id; #else hcg_key id; #endif char curr_shape[20]; extern int first_time; if(currentselection != 0){ #ifdef GENV6 id = currentselection->getid(); #else id = (hcg_key)currentselection->getid(); #endif pr_find(HN,HNid,id); if(HNcurr == NULL){ return; } curr_x = (float)x; curr_y = (float)y; temp_x = currentselection->getcenterx(); temp_y = currentselection->getcentery(); strcpy( curr_shape, currentselection->getshape()); if(curr_shape[0] == 'C' || curr_shape[0] == 'c'){ center_x = currentselection->getcenterx(); center_y = currentselection->getcentery(); if(first_time){ last_radius = currentselection->getradius(); drawimage(center_x,center_y,last_radius*2.0, last_radius*2.0); first_time = FALSE; } else{ drawimage(center_x,center_y,last_radius*2.0, last_radius*2.0); } diff_x = curr_x - temp_x; diff_y = curr_y - temp_y; squares = (double)(diff_x * diff_x + diff_y * diff_y); last_radius = (float)sqrt(squares); drawimage(center_x,center_y,last_radius*2.0, last_radius*2.0); if(diff_x < 0)diff_x = -diff_x; if(diff_y < 0)diff_y = -diff_y; } else{ center_x = currentselection->getcenterx(); center_y = currentselection->getcentery(); if(first_time){ last_width = currentselection->getwidth(); last_height = currentselection->getheight(); switch(curr_shape[0]){ case 'E': case 'e': drawimage(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'R': case 'r': drawrectangular(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'F': case 'f': drawfile(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'O': case 'o': drawoutput(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'I': case 'i': drawinput(center_x,center_y,last_width*2.0, last_height*2.0); break; default: break; } first_time = FALSE; } else{ switch(curr_shape[0]){ case 'E': case 'e': drawimage(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'R': case 'r': drawrectangular(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'F': case 'f': drawfile(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'O': case 'o': drawoutput(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'I': case 'i': drawinput(center_x,center_y,last_width*2.0, last_height*2.0); break; default: break; } } diff_x = curr_x - temp_x; diff_y = curr_y - temp_y; last_width = diff_x; last_height = diff_y; if(last_width < 0)last_width = -last_width; if(last_height < 0)last_height = -last_height; switch(curr_shape[0]){ case 'E': case 'e': drawimage(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'R': case 'r': drawrectangular(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'F': case 'f': drawfile(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'O': case 'o': drawoutput(center_x,center_y,last_width*2.0, last_height*2.0); break; case 'I': case 'i': drawinput(center_x,center_y,last_width*2.0, last_height*2.0); break; default: break; } if(diff_x < 0)diff_x = -diff_x; if(diff_y < 0)diff_y = -diff_y; } } } //****************************** end ***********************************// //this procedure is to add the attribute of a node //created by : su93bde2 - hlee 93/08/21 ANCHORTAG(node::addattr) void node::addattr(float x, float y) { extern char globalfontname[51]; extern void trim(char *); extern void load_font(char *,GC); extern GC copyGC; float beginx, beginy,heighttmp,newbeginx=0, newbeginy=0; int width,height; char *tempid; #ifdef GENV6 char temp_pkey[9]; char temp_buff[256]; /* constant size */ char *id; #else hcg_key temp_pkey; struct HA *HA_elt; hcg_key id; #endif float origin = 0; void ReDraw(); #ifdef GENV6 id = currentselection->getid(); #else id = (hcg_key)currentselection->getid(); #endif pr_find(HN,HNid,id); // The node's default in the network database. tempid = "DA010009"; #ifdef GENV6 pr_gen_pkey("94sbdeview", HA, temp_pkey); #else HA_elt = pr_create(HA); #endif beginx = currentselection->getcenterx()-x; beginy = currentselection->getcentery()-y; trim(globalfontname); load_font(globalfontname,copyGC); getDimensions(new_string,globalfontname,&width,&height); heighttmp = height; child_loop(HN,HA,HAid,HNid) { newbeginx = HAcurr->txtoffsetx ; newbeginy = HAcurr->txtoffsety ; origin = HAcurr->HAorigin; } if ( newbeginy != 0 ) { beginy = newbeginy - height ; beginx = newbeginx; } #ifdef GENV6 sprintf (temp_buff, " %s %s %s %8.4f %8.4f %8.4f %d %d %s %s", temp_pkey, cHN->HNid, tempid, beginx, beginy,origin,width,height,new_string,globalfontname); pr_add("94sbdeview",temp_buff); #else pr_set_int( HA_elt, HAid, temp_pkey ) ; pr_set_int( HA_elt, HNid, cHN->HNid ) ; pr_set_str( HA_elt, DAid, tempid ) ; pr_set_flt( HA_elt, txtoffsetx, beginx ) ; pr_set_flt( HA_elt, txtoffsety, beginy ) ; pr_set_flt( HA_elt, HAorigin, origin ) ; pr_set_int( HA_elt, txtwidth, width ) ; pr_set_int( HA_elt, txtheight, height ) ; //switch txtfont field with hlabel field. - phsia 11/5/95 pr_set_str( HA_elt, txtfont, globalfontname ) ; pr_set_str( HA_elt, hlabel, new_string ) ; pr_add( "94sbdeview", HA, HA_elt ) ; #endif ReDraw(); } //this procedure is to change the attribute of a node //created by : su93bde2 - hlee 93/08/21 ANCHORTAG(node::chgattr) void node::chgattr(float x, float y) { extern char globalfontname[51]; extern GC copyGC; float beginx, beginy,heighttmp,newbeginx=0, newbeginy=0; int width,height; char *tempid; #ifdef GENV6 char temp_pkey[9]; char temp_buff[256]; /* constant size */ #else hcg_key temp_pkey; struct HN *HN_elt; struct HA *HA_elt; #endif float origin = 0; void ReDraw(); #ifdef GENV6 pr_find(HN,HNid,id); #else pr_find(HN,HNid,pr_get_key(HN_elt,HNid)); #endif // The node's default in the network database. tempid = "DA010009"; #ifdef GENV6 pr_gen_pkey("94sbdeview", HA, temp_pkey); #else HA_elt = pr_create( HA ) ; #endif beginx = currentselection->getcenterx()-x; beginy = currentselection->getcentery()-y; trim(globalfontname); load_font(globalfontname,copyGC); getDimensions(new_string,globalfontname,&width,&height); heighttmp = height; child_loop(HN,HA,HAid,HNid) { newbeginx = HAcurr->txtoffsetx ; newbeginy = HAcurr->txtoffsety ; origin = HAcurr->HAorigin; } if ( newbeginy != 0 ) { beginy = newbeginy - height ; beginx = newbeginx; } #ifdef GENV6 sprintf (temp_buff, " %s %s %s %8.4f %8.4f %8.4f %d %d %s %s", temp_pkey, cHN->HNid, tempid, beginx, beginy,origin,width,height,new_string,globalfontname); pr_add("94sbdeview",temp_buff); #else pr_set_int( HA_elt, HAid, temp_pkey ) ; pr_set_int( HA_elt, HNid, cHN->HNid ) ; pr_set_str( HA_elt, DAid, tempid ) ; pr_set_flt( HA_elt, txtoffsetx, beginx ) ; pr_set_flt( HA_elt, txtoffsety, beginy ) ; pr_set_flt( HA_elt, HAorigin, origin ) ; pr_set_int( HA_elt, txtwidth, width ) ; pr_set_int( HA_elt, txtheight, height ) ; //switch txtfont field with hlabel field. - phsia 11/5/95 pr_set_str( HA_elt, txtfont, globalfontname ) ; pr_set_str( HA_elt, hlabel, new_string ) ; pr_add( "94sbdeview", HA, HA_elt ) ; #endif ReDraw(); }