/***************************************************************************
*
Description: nodeops.cc:482-808 -
041012.2355 nodeops041012r1.cc in COOL-BDE\04sbde
* 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 ... BUTTON_MOVED action
calls doresize;
* Revised
- RJL 041007-13 - refactoring for state model clarity
* TBD: Restore xor GC in doresize to erase as
well as redraw during motion
* Error
handling:
* NONE.
* Side
effects:
* NONE.
***************************************************************************/
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 */
{
float
sx, sy;
static
hcg_key id; // static added - RJL041012
char
curr_shape[20];
float
center_x, center_y, radius;
float
temp_x, temp_y, temp_radius;
float
diff_x, diff_y;
double
squares;
static
int first_time = 0; //RJL041012
static
graphobject *selected_node = NULL;
//static int NResize = 0; //
Resize ---> NResize ---> Reconfirmed- RJL041010
static
int Reconfirmed = 0; // new flag to
discrim SResize_Node action at button_up
// TBD: split state SNode_Resize, replacing
Reconfirmed
DCtoWC(event->x, event->y, &sx, &sy);
switch
(state)
{
case SResize:
Reconfirmed = 0;
first_time = 0;
switch (button_op) {
case BUTTON_DOWN_EVENT:
unselect(); //graphobject::unselect(){selected=0;highlight(0)}
selection(canvas,
(int)sx, (int)sy);
break; // wait for button Up
case BUTTON_MOVED_EVENT: //
wait for button_up and reconfirm
break;
case BUTTON_UP_EVENT: //moved action from case
BUTTON_DOWN-041010
// added getid() and
hasType(id,HN) - RJL041010
if (currentselection ==
0) {
break;
}
else { //
(currentselection != 0)
id = (hcg_key)currentselection->getid();
if (!hasType(id,
HN)) { // a type HN was selected
unselect();
currentselection = 0;
displayMessage(
"Invalid selection; select Node to Resize\n");
}
else {
selected_node =
currentselection; // save obj*
HNcurr = (struct
HN*)currentselection->getcurr();
selected.changeAttribState(SResize_node);
changeCanvasCursor(movehand); // from arrow;
}
break;
} // end case BUTTON_UP
default:
PostErrorMsg(SResize);
break;
} // end switch(button_op)
break; // end case SResize;
case SResize_node:
switch (button_op) {
case BUTTON_DOWN_EVENT:
//assert(selected_node != 0
&& hasType(id.HN));
unselect(); //graphobject::unselect(){selected=0;highlight(0)}
selection(canvas, (int)sx,
(int)sy); // could be NULL
if(currentselection ==
0){ // invalid graphobject* - no
selection;
selected_node = 0;
changeCanvasCursor(arrow);
unselect();
displayMessage("No
object selected; try again\n");
selected.changeAttribState(SResize); //to wait for BUTTON_UP
break; // reenter SResize for BUTTON_UP action
}
else { // (currentselection != 0)
id = (hcg_key)
currentselection->getid();
fprintf(stderr,
"SResize_node: id = 0x%lx\n", id);
if (!hasType(id,
HN)){ //new selection, wrong type
changeCanvasCursor(arrow);
unselect();
currentselection = 0;
selected_node =
0; // RJL041021
displayMessage("Wrong type selected; try again\n");
selected.changeAttribState(SResize);
break; // reenter SResize for BUTTON_UP action
}
else if
(currentselection != selected_node) {
// new type HN
currentselection
selected_node =
currentselection; // save new obj*
HNcurr =
(struct HN*)currentselection->getcurr();
displayMessage("New node; reselect to confirm it");
fprintf(stderr,
"SResize_node: curr*sel* != selected_node\n");
//Same state;
ignore BUTTON_MOVED, wait for BUTTON_UP;
break;
}
else { // first selection
is reconfirmed
assert(currentselection==selected_node);
DP;fprintf(stderr,
"SResize_node:selection confirmed: id=0x%lx\n", id);
assert(hasType(id,HN)); // failed 9041011; OK 041013
dprintdd("SNode_resize: Reconfirmed:
id=%lx ==? HNid=%lx\n",
id,
HNcurr->HNid);
assert(id==HNcurr->HNid); //failed 041012:2030,2035
changeCanvasCursor(movehand); //during BUTTON_MOVED
selectedx = sx;
selectedy = sy;
displayMessage("Drag the mouse button to resize\n");
savedx = center_x =
currentselection->getcenterx();
savedy = center_y =
currentselection->getcentery();
radius =
currentselection->getradius();
first_time =
TRUE; //Another Flag Var!
Reconfirmed =
1; // do BUTTON_MOVED action
break;
}
} // end else non-null
selection
break; // end case
BUTTON_DOWN
case BUTTON_MOVED_EVENT: // new or old HN selection
DP;dprintdd("id = %lx,
HNid = %lx\n", id, HNcurr->HNid);
assert(hasType(id,HN)); //
failed 041011,12: invalid id
if (Reconfirmed) { // old HN reselected
assert(first_time ==
TRUE); //remove flag if superfluous
DP;doresize((int)event->x, (int)event->y, id);
// doresize clears
first_time
}
break; // end BUTTON_MOVED
case BUTTON_UP_EVENT:
if (!Reconfirmed) { // same
next state?
changeCanvasCursor(arrow);
// first_time == FALSE;
// skip MOVED:doresize
break;
}
else { // assert(Reconfirmed);cursor:
movehand;finish node_resize:
center_x =
currentselection->getcenterx();
center_y =
currentselection->getcentery();
temp_x
= event->x;//DC
temp_y = event->y;
diff_x = temp_x -
center_x; //DC
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);
}
topobject->dorecalc((hcg_key)currentselection->getid());
position_text(); //
gets its own local id via getid
// OK to repeat
node_resize for THIS node in state SNode_resize
break;
} // end if..else
break; // end case BUTTON_UP
default: /* illegal value for
button_op variable */
PostErrorMsg(SResize_node);
break;
} // end switch(button_op)
break; // RJL041021
//
end case SResize_node
default:
fprintf(stderr, "Out of State in function node_resize.\n");
fprintf(stderr, "switch arg
state=0x%x\n", state);
fprintf(stderr, "Report this to Professor Lechner.\n");
break;
} //
end switch(state)
} // end
node_resize()
/********************************************************/
/* doresize() client: node_resize: state
SResize_node: */
/* doresize is done on each BUTTON_MOVED
event */
/* Args are float event->x, event->y (=
centerx,y */
/* after first BUTTON_MOVED increment) */
/* TBD: switch(shape) cases should be
class-specific */
/* override methods. */
/********************************************************/
void doresize(int x, int y, hcg_key id)
{
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;
char
curr_shape[20];
extern
int first_time; // in node_resize
/* Checks
No longer needed - done BEFORE BUTTON_MOVED action call RJL041011 */
EP;assert(currentselection!=0 && id == HNcurr->HNid
&& \
HNcurr==(struct HN*)currentselection->getcurr() );
curr_x
= (float)x; // new x
curr_y
= (float)y;
temp_x
= currentselection->getcenterx();// old x
temp_y
= currentselection->getcentery();
strcpy(
curr_shape, currentselection->getshape()); //invariant
center_x = currentselection->getcenterx();
center_y = currentselection->getcentery();
if(curr_shape[0] == 'C' || curr_shape[0] == 'c'){
if(first_time){
first_time = FALSE;
last_radius = currentselection->getradius();
drawimage(center_x,center_y,last_radius*2.0,
last_radius*2.0); //
erase original circle?
}
else { // redraw at new location and size:
diff_x = fabs(curr_x - temp_x);
diff_y = fabs(curr_y - temp_y);
squares = (double)(diff_x*diff_x +
diff_y*diff_y);
last_radius = (float)sqrt(squares); // delta-center length
drawimage(center_x,center_y,last_radius*2.0,
last_radius*2.0); // draw new
circle?
}
} //
end circular shape move
else
{ // shape not circular
center_x = currentselection->getcenterx(); // old position
center_y = currentselection->getcentery();
if(first_time){
first_time = FALSE;
last_width = currentselection->getwidth(); // old dimensions
last_height = currentselection->getheight();
switch(curr_shape[0]){ // assert non-circular; erase old shape
// this switch is a crutch to avoid polymorphic shape subclass:draw()
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;
} // end switch( shape)
} // end if(first_time); first_time = FALSE now
else{ // not first_time - erase
prior shape:
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;
}
} // end not first_time
// now redraw same non-circular shape in new size:
last_width = diff_x = fabs(curr_x - temp_x);
last_height = diff_y = fabs(curr_y - temp_y);
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;
} // end switch(shape)
} // end
non-circular shapes
} // end do_resize:480:828