// Please see the README file or the LEGAL NOTES-section in the manual before modifying, compiling or using 'xmrm' // Idea: Manfred Kopp // Programming: Gerhard Waldhör, Andreas Artmann #include #include "morphvec.h" #include "init.h" #include "const.h" #include "io.h" #include "xmrm.h" //#include "areas.h" #include //static int oneliner = 1; extern FD_MORPH *fd_MORPH; extern FD_VEC_MENU *fd_VEC_MENU; extern Display *disp; extern int max_x,max_y; extern ControlClass control; extern VisualInfoClass vis; extern WindowClass *s_win, *d_win; extern MyImageClass *MyImage; extern GC gc; extern FL_OBJECT *obj_vs,*obj_vd,*obj_s,*obj_d; /* Class PictureClass: */ extern PictureClass *s_pic, *d_pic; /* Constructor: */ PictureClass::PictureClass() { pic = NULL; pic_x=0; pic_y=0; } /* Destructor: */ PictureClass::~PictureClass() { free (pic); } /* Method: InitMem */ int PictureClass::InitMem() { // Allocating or reallocating memory for pictures: if (pic == NULL) { if ( (pic = (unsigned long *)malloc(pic_x*pic_y*sizeof(unsigned long))) == NULL ) { fl_show_alert("WARNING:","Not enough memory available !","" ,1); return -1; } } else { if ( (pic = (unsigned long *)fl_realloc(pic, pic_x*pic_y*sizeof(unsigned long))) == NULL ) { fl_show_alert("WARNING:","Not enough memory available !","" ,1); return -1; } } return 0; } /* Method: SetPicSize */ void PictureClass::SetPicSize(int x, int y) { pic_x = x; pic_y = y; } /* Method: GetPicSize */ void PictureClass::GetPicSize(int *x, int *y) { *x = pic_x; *y = pic_y; } /* Method: GetPicPointer */ unsigned long *PictureClass::GetPicPointer() { return pic; } /* Method: SetPicPointer */ void PictureClass::SetPicPointer(unsigned long *pic_ptr) { pic = pic_ptr; } /* MyImageClass: */ /* Constructor: */ MyImageClass::MyImageClass() { pic_scal = NULL; image = NULL; } /* Destructor: */ MyImageClass::~MyImageClass() { if (image != NULL) { // free(pic_scal); XDestroyImage(image); } // image=NULL; } /* Method InitImage: */ int MyImageClass::InitImage(int x,int y) { if (pic_scal==NULL) { if ( (pic_scal = (char *)malloc(x*y*(vis.p_fetch/8))) == NULL ) { fl_show_alert("WARNING:","Not enough memory available !","" ,1); return -1; } } else { if ( (pic_scal = (char *)realloc(pic_scal,x*y*(vis.p_fetch/8))) == NULL ) { fl_show_alert("WARNING:","Not enough memory available !","" ,1); return -1; } } if (x==0) image=NULL; else /* Create image: */ if ( (image = XCreateImage(disp,vis.xvis_info->visual,vis.depth,ZPixmap,0,pic_scal, x,y,32,x*(vis.p_fetch/8))) == NULL) { fl_show_alert("ERROR:","Cannot create image !","",1); return -2; } image_x=x; image_y=y; // printf ("Mem adress: %d\n",(void *)pic_scal); return 0; } /* Method GetImage: */ XImage *MyImageClass::GetImage() { return image; } /* Method ShowImage: */ void MyImageClass::ShowImage(FL_OBJECT *obj,Window win) { XPutImage(disp,win,gc,image,0,0,obj->x,obj->y,obj->w,obj->h); } /* Method MapPicture: */ void MyImageClass::MapPicture(FL_OBJECT *obj, PictureClass *pic_class) { unsigned long i,j,col,adr, rmask,gmask,bmask; unsigned long *raster; double x,y,dx,dy; int px,py, rshift,gshift,bshift; rmask = (256-(1<<(8-vis.red_len))); gmask = (256-(1<<(8-vis.green_len))) << 8; bmask = (256-(1<<(8-vis.blue_len))) << 16; rshift = 24 - (vis.red_beg + vis.red_len); gshift = 24 - (vis.green_beg + vis.green_len); bshift = 24 - (vis.blue_beg + vis.blue_len); // printf ("%x %x %x %d %d %d \n",rmask,gmask,bmask,rshift,gshift,bshift); pic_class->GetPicSize(&px,&py); raster = pic_class->GetPicPointer(); dx = (double) px / obj->w; dy = (double) py / obj->h; y=0; for (j=0; jh; j++) { x=0; for (i=0; iw; i++) { adr = (unsigned long)y * px + (unsigned long)x; col = raster[adr]; XPutPixel(image,i,j, ((col & bmask) >> bshift) | (((col & gmask) << 8) >> gshift) | (((col & rmask) << 16) >> rshift) ); // ...this confusing left-right-shifting is necessary to be compatible to different DirectColor modes ! x+=dx; } y+=dy; } } /* Method MapArea */ void MyImageClass::MapArea(FL_OBJECT *obj, PictureClass *pic_class, unsigned char *raster) { unsigned long i,j,col,adr, rmask,gmask,bmask; double x,y,dx,dy; int px,py, rshift,gshift,bshift; rmask = (256-(1<<(8-vis.red_len))); gmask = (256-(1<<(8-vis.green_len))) << 8; bmask = (256-(1<<(8-vis.blue_len))) << 16; rshift = 24 - (vis.red_beg + vis.red_len); gshift = 24 - (vis.green_beg + vis.green_len); bshift = 24 - (vis.blue_beg + vis.blue_len); // printf ("%x %x %x %d %d %d \n",rmask,gmask,bmask,rshift,gshift,bshift); pic_class->GetPicSize(&px,&py); dx = (double) px / obj->w; dy = (double) py / obj->h; y=0; for (j=0; jh; j++) { x=0; for (i=0; iw; i++) { adr = (unsigned long)y * px + (unsigned long)x; col = (unsigned long) raster[adr]; col = col | (col << 8) | (col << 16); XPutPixel(image,i,j, ((col & bmask) >> bshift) | (((col & gmask) << 8) >> gshift) | (((col & rmask) << 16) >> rshift) ); // ...this confusing left-right-shifting is necessary to be compatible to different DirectColor modes ! x+=dx; } y+=dy; } } /* Method RemapPicture: */ unsigned long *MyImageClass::RemapPicture(FL_OBJECT *obj) { unsigned long i,j,adr,col,rmask,gmask,bmask; unsigned long *raster; int px,py, rshift,gshift,bshift; rmask = vis.xvis_info->red_mask; gmask = vis.xvis_info->green_mask; bmask = vis.xvis_info->blue_mask; rshift = 24 - (vis.red_beg + vis.red_len); gshift = 24 - (vis.green_beg + vis.green_len); bshift = 24 - (vis.blue_beg + vis.blue_len); // Get Memory for remapped image: if ( (raster=(unsigned long *)malloc(image_x*image_y*sizeof(unsigned long))) == NULL ) { fl_show_alert("WARNING:","Not enough memory available !","" ,1); return raster; } adr=0; for (j=0; j> 16) | (((col & gmask)<> 8) | ((col & bmask)<w; sc_y = (double)max_y / obj->h; nr_vec++; if (nr_vec>=MAX_VEC) { nr_vec--; fl_show_alert("INFORMATION:","Vector limit reached !","",1); return -1; } xa[nr_vec]=sc_x*(nxa-obj->x); ya[nr_vec]=sc_y*(nya-obj->y); xe[nr_vec]=sc_x*(nxe-obj->x); ye[nr_vec]=sc_y*(nye-obj->y); connect[nr_vec]=con; return 0; } /* Method DelVec: */ void MorphVecClass::DelVec(int item) { if (item > nr_vec) { printf("Warning: Wrong vector number, MorphVekClass::DelVek()\n"); return; } for (int i=item; iw; sc_y = (double) max_y / obj->h; if (item > nr_vec) { printf("Warning: Wrong vector number, MorphVekClass::RepVek()\n"); return; } xa[item]=sc_x*(rxa-obj->x); ya[item]=sc_y*(rya-obj->y); xe[item]=sc_x*(rxe-obj->x); ye[item]=sc_y*(rye-obj->y); } /* Method NormVec: */ void MorphVecClass::NormVec() { for (int i=1; i<=nr_vec; i++) { xa[i]=xa[i]/max_x; xe[i]=xe[i]/max_x; ya[i]=ya[i]/max_y; ye[i]=ye[i]/max_y; } } /* Method DeNormVec: */ void MorphVecClass::DeNormVec() { for (int i=1; i<=nr_vec; i++) { xa[i]=xa[i]*max_x; xe[i]=xe[i]*max_x; ya[i]=ya[i]*max_y; ye[i]=ye[i]*max_y; } } /* Method SearchVec: */ int MorphVecClass::SearchVec(FL_OBJECT *obj,int sx,int sy,int *flag_found) { int i,found; double sc_x,sc_y, mx,my, rad, norm, qnorm, PQx,PQy, PXx, PXy, u,v, xx,yy; sc_x = (double)max_x / obj->w; sc_y = (double)max_y / obj->h; mx = sc_x*(sx-obj->x); my = sc_y*(sy-obj->y); if (nr_vec == 0) return 0; rad = Q_SEARCH_RAD; i=0; found=0; do { i++; PQx = xe[i]-xa[i]; PQy = ye[i]-ya[i]; PXx = mx-xa[i]; PXy = my-ya[i]; qnorm = ( PQx*PQx + PQy*PQy ); u = ( PXx*PQx + PXy*PQy )/qnorm; if (u<0.0) { xx=PXx*PXx; yy=PXy*PXy; v=xx+yy; } else if (u>1.0) { xx=mx-xe[i]; xx*=xx; yy=my-ye[i]; yy*=yy; v=xx+yy; } else { v = PXx*(-PQy) + PXy*PQx; v=(v*v)/qnorm; } if (v < rad) { if (u<0.5) *flag_found=1; else *flag_found=2; found=i; rad=v; } } while (iw / max_x; sc_y = (double) obj->h / max_y; if (item > nr_vec) { printf("Warning: Wrong vector number ! (MorphVecClass::DrawVectorScal())\n"); return; } DrawVector(int((sc_x*xa[item])+obj->x),int((sc_y*ya[item])+obj->y), int((sc_x*xe[item])+obj->x),int((sc_y*ye[item])+obj->y),mode,col); fl_linestyle(LineSolid); fl_linewidth(1); fl_drawmode(GXcopy); } /* Method MapVectors: */ void MorphVecClass::MapVectors(FL_OBJECT *obj,int exept1,int exept2) { int i; for (i=1; i<=nr_vec; i++) if (i != exept1 && i!= exept2) DrawVectorScal(obj,i,GXcopy,FL_WHITE); } /* Method GetMaxVec: */ int MorphVecClass::GetMaxVec() { return nr_vec; } /* Method SetMaxVec: */ void MorphVecClass::SetMaxVec(int items) { nr_vec = items; } /* Method GetVec: */ void MorphVecClass::GetVec(FL_OBJECT *obj,int *gxa, int *gya, int *gxe, int *gye, int i) { double sc_x,sc_y; sc_x = (double) obj->w / max_x; sc_y = (double) obj->h / max_y; *gxa = (int)((sc_x*xa[i])+obj->x); *gya = (int)((sc_y*ya[i])+obj->y); *gxe = (int)((sc_x*xe[i])+obj->x); *gye = (int)((sc_y*ye[i])+obj->y); } /* Method GetVecArray: */ void MorphVecClass::GetVecArray(double **gxa, double **gya, double **gxe, double **gye) { *gxa=&xa[1]; *gya=&ya[1]; *gxe=&xe[1]; *gye=&ye[1]; } int MorphVecClass::GetCon(int item) { return connect[item]; } void MorphVecClass::GetConArray(int **con) { *con=&connect[1]; } /* obj_s - objecthandler: Redraws source image */ int obj_s_handler(FL_OBJECT *obj, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { if (event == FL_DRAW) { s_win->SetWin(); if (s_pic->GetPicPointer() != NULL) { if (s_pic->GetPicPointer() == NULL) fl_rectf(obj->x,obj->y,obj->w,obj->h,FL_COL1); if (MyImage->InitImage(obj->w,obj->h) != 0) return -1; MyImage->MapPicture(obj,s_pic); MyImage->ShowImage(obj,s_win->GetWin()); } } return 0; } /* obj_d - objecthandler: Redraws destination image */ int obj_d_handler(FL_OBJECT *obj, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { if (event == FL_DRAW) { d_win->SetWin(); if (d_pic->GetPicPointer() != NULL) { if (d_pic->GetPicPointer() == NULL) fl_rectf(obj->x,obj->y,obj->w,obj->h,FL_COL1); if (MyImage->InitImage(obj->w,obj->h) != 0) return -1; MyImage->MapPicture(obj,d_pic); MyImage->ShowImage(obj,d_win->GetWin()); } } return 0; } /* set_vec - objecthandler: Controls vector setting & editing */ int set_vec_handler(FL_OBJECT *obj, int event, FL_Coord mx, FL_Coord my,int key, void *xev, Window win, int src_dst) { static int old_src_dst=1, flag_clear_vector,i=0,vec_i=0,connect=0,w=0, what_point, what_connect=0; static FL_Coord x,y,xa,ya,xo,yo,xa2,ya2,xo2,yo2; int allow_setting; MorphVecClass *vec; FL_COLOR color; if ((control.flag_set_vector == VEC_SET) && (src_dst != old_src_dst)) return -1; old_src_dst = src_dst; // Choose src/dst vectors to edit if (src_dst) vec=s_vec; else vec=d_vec; // Check mouse events: switch (event) { case FL_DRAW: // Control drawing events: if (control.edit_mode==EDIT_NEW || control.edit_mode==EDIT_LINE) // drawing routines for a NEW vector: { switch(control.flag_set_vector) { case VEC_DRAWSTART: vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // Draw first xor-vector control.flag_set_vector = VEC_SET; control.edit_change_perm=0; // edit-mode-settings break; case VEC_DRAWEND: // mouse button has been released, vector is defined now, vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // clear xor-vector vec->DrawVectorScal(obj, vec->GetMaxVec(),GXcopy,FL_WHITE); // and draw the vector new & fine control.flag_set_vector = VEC_NOSET; // edit-mode-settings control.edit_change_perm=1; allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // check what cursor to be set control.SetCursor(allow_setting,win); // maybe the next corresponding vec in src-win has to be shown: if (!src_dst) { control.co_vector=CO_SHOW; fl_redraw_object(obj_vs); control.co_vector=CO_OK; } break; case VEC_CLEAR: vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // Clear xor-vector fl_set_cursor(win,XC_arrow); // change cursor from X to arrow control.flag_set_vector = VEC_NOSET; control.edit_change_perm=1; // edit-mode-settings break; case VEC_SET: vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // Clear old xor-vector vec->DrawVector(xa,ya,x,y,GXxor,FL_WHITE); // and draw new xor-vector break; case VEC_NOSET: if (src_dst) { if (control.co_vector == CO_SHOW) { if (s_vec->GetMaxVec() > d_vec->GetMaxVec()) vec->DrawVectorScal(obj,d_vec->GetMaxVec()+1,GXcopy,FL_GREEN); // Draw new corresp. source vec if (d_vec->GetMaxVec()>0) vec->DrawVectorScal(obj,d_vec->GetMaxVec(),GXcopy,FL_WHITE); // Clear old corresp. source vec } else if (control.co_vector == CO_HIDE) { if (s_vec->GetMaxVec() > d_vec->GetMaxVec()) vec->DrawVectorScal(obj,d_vec->GetMaxVec()+1,GXcopy,FL_WHITE); // Hide new corresponding source vec } } break; default: ; } } else // EDIT_REPLACE: { if (control.edit_mode == EDIT_REPLACE) color=FL_YELLOW; else color=FL_RED; // drawing routines for an EDITED vector: switch (control.flag_set_vector) { case VEC_SEARCH: // mouse near a vec -> draw vec YELLOW or RED vec->MapVectors(obj,0,0); if (vec_i <= vec->GetMaxVec()) { vec->DrawVectorScal(obj,vec_i,GXcopy,color); if (control.edit_mode == EDIT_REPLACE) { // end of vector: test if connected if (what_connect==1) vec->DrawVectorScal(obj,vec_i-1, GXcopy,color); if (what_connect==2) vec->DrawVectorScal(obj,vec_i+1, GXcopy,color); } } break; case VEC_NOSEARCH: // mouse away from vec -> draw vec WHITE //if (vec_i <= vec->GetMaxVec()) vec->DrawVectorScal(obj,vec_i,GXcopy,FL_WHITE); color=FL_WHITE; if (vec_i <= vec->GetMaxVec()) { vec->DrawVectorScal(obj,vec_i,GXcopy,color); if (control.edit_mode == EDIT_REPLACE) { // end of vector: test if connected if (what_connect==1) vec->DrawVectorScal(obj,vec_i-1, GXcopy,color); if (what_connect==2) vec->DrawVectorScal(obj,vec_i+1, GXcopy,color); } } control.flag_set_vector = VEC_NOSET; break; case VEC_DRAWSTART: if (what_connect==0) vec->MapVectors(obj,vec_i,0); if (what_connect==1) vec->MapVectors(obj,vec_i,vec_i-1); if (what_connect==2) vec->MapVectors(obj,vec_i,vec_i+1); vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // Draw first xor-vector // connected ?: if (what_connect!=0) vec->DrawVector(xa2,ya2,xo2,yo2,GXxor,FL_WHITE); control.flag_set_vector = VEC_SET; fl_set_cursor_color(XC_arrow,color,FL_BLACK); break; case VEC_DRAWEND: // mouse button has been released, vector is defined now, vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // clear xor-vector vec->DrawVectorScal(obj, vec_i,GXcopy,FL_WHITE); // and draw the vector new & fine if (what_connect != 0) { vec->DrawVector(xa2,ya2,xo2,yo2,GXxor,FL_WHITE); if (what_connect==1) vec->DrawVectorScal(obj,vec_i-1,GXcopy,FL_WHITE); else vec->DrawVectorScal(obj,vec_i+1,GXcopy,FL_WHITE); what_connect=0; } control.flag_set_vector = VEC_NOSET; control.edit_change_perm=1; allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // check what cursor to be set control.SetCursor(allow_setting,win); // fl_set_cursor_color(XC_arrow,FL_GREEN,FL_BLACK); vec_i=0; break; case VEC_SET: if (what_point == 1) // What side of vec can be moved ? { vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // Clear old xor-vector vec->DrawVector(x,y,xo,yo,GXxor,FL_WHITE); // and draw new xor-vector if (what_connect!=0) { vec->DrawVector(xa2,ya2,xo2,yo2,GXxor,FL_WHITE); // Clear old xor-vector vec->DrawVector(xa2,ya2,x,y,GXxor,FL_WHITE); // and draw new xor-vector } } else { vec->DrawVector(xa,ya,xo,yo,GXxor,FL_WHITE); // Clear old xor-vector vec->DrawVector(xa,ya,x,y,GXxor,FL_WHITE); // and draw new xor-vector if (what_connect!=0) { vec->DrawVector(xa2,ya2,xo2,yo2,GXxor,FL_WHITE); // Clear old xor-vector vec->DrawVector(x,y,xo2,yo2,GXxor,FL_WHITE); // and draw new xor-vector } } break; case VEC_CLEAR: if (vec_i <= d_vec->GetMaxVec()) { if (src_dst) d_vec->DelVec(vec_i); else s_vec->DelVec(vec_i); } vec->DelVec(vec_i); control.flag_set_vector = VEC_NOSET; vec_i=0; control.edit_change_perm=1; fl_set_cursor_color(XC_arrow,FL_GREEN,FL_BLACK); if (control.edit_mode == EDIT_REPLACE) { fl_set_cursor(win, XC_hand2); } else { fl_set_cursor(win, XC_pirate); } fl_redraw_object(obj_s); fl_redraw_object(obj_d); control.SetDraw(DRAW_SRCVECTORS); fl_redraw_object(obj_vs); control.SetDraw(DRAW_DSTVECTORS); fl_redraw_object(obj_vd); break; default: ; } } fl_linestyle(LineSolid); fl_linewidth(1); fl_drawmode(GXcopy); break; // Mouse enters the object-window: case FL_ENTER: allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // Check if edit vectors OK: // fl_set_cursor_color(XC_arrow,FL_GREEN,FL_BLACK); control.SetCursor(allow_setting,win); XFlush(fl_get_display()); // When entering the dest-win, show the corresponding vector from the src-win: if (!src_dst) { control.co_vector=CO_SHOW; fl_redraw_object(obj_vs); control.co_vector=CO_OK; } break; case FL_LEAVE: // Set default cursor: fl_reset_cursor(win); // fl_set_cursor_color(XC_arrow,FL_BLACK,FL_WHITE); // When leaving the dest-win, hide the corresponding vector from the src-win: if (!src_dst) { control.co_vector=CO_HIDE; fl_redraw_object(obj_vs); control.co_vector=CO_OK; } break; case FL_PUSH: // right mouse-button pressed: if ( (key==3) && (control.edit_change_perm == 0) && (control.edit_mode == EDIT_LINE) ) { control.flag_set_vector = VEC_CLEAR; fl_redraw_object(obj); } if ( (key==3) && (control.edit_change_perm == 1) ) { if (control.edit_mode==EDIT_REPLACE || control.edit_mode==EDIT_DELETE) { control.flag_set_vector = VEC_NOSEARCH; fl_redraw_object(obj_vs); control.flag_set_vector = VEC_NOSEARCH; fl_redraw_object(obj_vd); } // change edit mode: control.edit_mode=(control.edit_mode+1)%4; // draw new wintitle and change buttons in vector-menu: switch ( control.edit_mode ) { case EDIT_NEW: fl_wintitle(fd_MORPH->MORPH->window,"SET VECTOR"); fl_set_button(fd_VEC_MENU->BT_SetVec,1); fl_set_button(fd_VEC_MENU->BT_EditVec,0); fl_set_button(fd_VEC_MENU->BT_DeleteVec,0); fl_set_button(fd_VEC_MENU->BT_SetLines,0); break; case EDIT_REPLACE: fl_wintitle(fd_MORPH->MORPH->window,"EDIT VECTOR"); fl_set_button(fd_VEC_MENU->BT_SetVec,0); fl_set_button(fd_VEC_MENU->BT_EditVec,1); fl_set_button(fd_VEC_MENU->BT_DeleteVec,0); fl_set_button(fd_VEC_MENU->BT_SetLines,0); break; case EDIT_DELETE: fl_wintitle(fd_MORPH->MORPH->window,"DELETE VECTOR"); fl_set_button(fd_VEC_MENU->BT_SetVec,0); fl_set_button(fd_VEC_MENU->BT_EditVec,0); fl_set_button(fd_VEC_MENU->BT_DeleteVec,1); fl_set_button(fd_VEC_MENU->BT_SetLines,0); break; case EDIT_LINE: fl_wintitle(fd_MORPH->MORPH->window,"SET LINE"); fl_set_button(fd_VEC_MENU->BT_SetVec,0); fl_set_button(fd_VEC_MENU->BT_EditVec,0); fl_set_button(fd_VEC_MENU->BT_DeleteVec,0); fl_set_button(fd_VEC_MENU->BT_SetLines,1); break; default: fl_wintitle(fd_MORPH->MORPH->window,"ERROR: NO MODE !!!"); } allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // Check if edit vectors OK: control.SetCursor(allow_setting,win); vec_i=0; control.flag_set_vector = VEC_NOSET; if ( !src_dst && (control.edit_mode==EDIT_NEW || control.edit_mode==EDIT_LINE) ) { control.co_vector=CO_SHOW; fl_redraw_object(obj_vs); control.co_vector=CO_OK; } fl_redraw_object(obj); break; } // left mouse-button pressed: if (key==1) { if (control.edit_mode==EDIT_NEW) // || control.edit_mode==EDIT_LINE) // WOIDL+- { switch (control.flag_set_vector) { case VEC_NOSET: allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // Check if edit vectors OK: if (allow_setting) { xa=mx; ya=my; xo=mx; yo=my; control.flag_set_vector=VEC_DRAWSTART; connect=0; fl_redraw_object(obj); } break; } } else // EDIT_REPLACE: if (control.edit_mode==EDIT_REPLACE) { switch(control.flag_set_vector) { case VEC_SEARCH: vec->GetVec(obj,&xa,&ya,&xo,&yo,vec_i); if (what_connect==1) vec->GetVec(obj,&xa2,&ya2,&xo2,&yo2,vec_i-1); if (what_connect==2) vec->GetVec(obj,&xa2,&ya2,&xo2,&yo2,vec_i+1); if (what_point == 1) { xa=mx; ya=my; xo2=mx; yo2=my; } else { xo=mx; yo=my; xa2=mx; ya2=my; } control.flag_set_vector=VEC_DRAWSTART; control.edit_change_perm=0; if (src_dst) fl_redraw_object(obj_s); else fl_redraw_object(obj_d); fl_redraw_object(obj); break; } } else if (control.edit_mode==EDIT_DELETE) { switch(control.flag_set_vector) { case VEC_SEARCH: control.flag_set_vector=VEC_CLEAR; control.edit_change_perm=0; fl_redraw_object(obj); break; } } // all vectors deleted: if (s_vec->GetMaxVec() == 0) control.vec_changed=0; else control.vec_changed=1; } break; case FL_RELEASE: if (key == 1) { switch (control.flag_set_vector) { case VEC_SET: if (flag_clear_vector) { control.flag_set_vector=VEC_CLEAR; if (what_connect != 0) { if (what_connect==1) vec->RepVec(obj,xa2,ya2,xo2,yo2,vec_i-1); else vec->RepVec(obj,xa2,ya2,xo2,yo2,vec_i+1); } fl_redraw_object(obj); // all vectors deleted: if (s_vec->GetMaxVec() == 0) control.vec_changed=0; else control.vec_changed=1; } else { if (control.edit_mode==EDIT_NEW) vec->NewVec(obj,xa,ya,x,y,0); else if (control.edit_mode==EDIT_LINE) vec->NewVec(obj,xa,ya,x,y,connect); else if (control.edit_mode==EDIT_REPLACE) { vec->RepVec(obj,xa,ya,xo,yo,vec_i); if (what_connect != 0) { if (what_connect==1) vec->RepVec(obj,xa2,ya2,xo2,yo2,vec_i-1); else vec->RepVec(obj,xa2,ya2,xo2,yo2,vec_i+1); } } control.flag_set_vector=VEC_DRAWEND; fl_redraw_object(obj); if (control.edit_mode==EDIT_LINE) { allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // Check if edit vectors OK: if (allow_setting) { xa=mx; ya=my; xo=mx; yo=my; control.flag_set_vector=VEC_DRAWSTART; connect=1; fl_redraw_object(obj); } } } break; // WOIDL+ case VEC_NOSET: if (control.edit_mode==EDIT_LINE) { allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // Check if edit vectors OK: if (allow_setting) { xa=mx; ya=my; xo=mx; yo=my; control.flag_set_vector=VEC_DRAWSTART; connect=0; fl_redraw_object(obj); } } // WOIDL- break; } } break; case FL_MOUSE: if (control.edit_mode==EDIT_NEW || control.edit_mode==EDIT_LINE) //*** { switch(control.flag_set_vector) { case VEC_SET: double distx,disty; distx=(double)(mx-xa); distx*=distx; disty=(double)(my-ya); disty*=disty; if ( sqrt(distx+disty) <= (double)CIRC_RAD ) { flag_clear_vector = 1; fl_set_cursor(win, XC_X_cursor); } else { flag_clear_vector = 0; fl_set_cursor(win, XC_arrow); } // Get mouse coordinates: x=mx; y=my; // Check borders: if (x < obj->x) x=obj->x; if (x >= obj->x+obj->w) x=obj->x+obj->w-1; if (y < obj->y) y=obj->y; if (y >= obj->y+obj->h) y=obj->y+obj->h-1; // Draw vector: fl_redraw_object(obj); // Store old coordinates: xo=x; yo=y; break; } } else if (control.edit_mode != EDIT_LINE) { switch(control.flag_set_vector) { case VEC_SET: double distx,disty; if (what_point == 2) { distx=(double)(mx-xa); distx*=distx; disty=(double)(my-ya); disty*=disty; } else { distx=(double)(mx-xo); distx*=distx; disty=(double)(my-yo); disty*=disty; } if ( sqrt(distx+disty) <= (double)CIRC_RAD ) { flag_clear_vector = 1; fl_set_cursor(win, XC_X_cursor); } else { flag_clear_vector = 0; fl_set_cursor(win, XC_arrow); } x=mx; y=my; // Check borders: if (x < obj->x) x=obj->x; if (x >= obj->x+obj->w) x=obj->x+obj->w-1; if (y < obj->y) y=obj->y; if (y >= obj->y+obj->h) y=obj->y+obj->h-1; // Draw vector: fl_redraw_object(obj); // Store old coordinates: if (what_point == 1) { xa=x; ya=y; if (what_connect !=0) xo2=x; yo2=y; } else { xo=x; yo=y; if (what_connect !=0) xa2=x; ya2=y; } break; } } break; case FL_MOTION: if (control.edit_mode==EDIT_LINE) { switch(control.flag_set_vector) { case VEC_SET: double distx,disty; distx=(double)(mx-xa); distx*=distx; disty=(double)(my-ya); disty*=disty; if ( sqrt(distx+disty) <= (double)CIRC_RAD ) { flag_clear_vector = 1; fl_set_cursor(win, XC_X_cursor); } else { flag_clear_vector = 0; fl_set_cursor(win, XC_arrow); } // Get mouse coordinates: x=mx; y=my; // Check borders: if (x < obj->x) x=obj->x; if (x >= obj->x+obj->w) x=obj->x+obj->w-1; if (y < obj->y) y=obj->y; if (y >= obj->y+obj->h) y=obj->y+obj->h-1; // Draw vector: fl_redraw_object(obj); // Store old coordinates: xo=x; yo=y; break; } } else if (control.edit_mode==EDIT_NEW) //||(control.edit_mode==EDIT_LINE) { switch(control.flag_set_vector) { case VEC_NOSET: allow_setting = src_dst || (s_vec->GetMaxVec()>d_vec->GetMaxVec()); // Check if edit vectors OK: if ( (!src_dst) && (allow_setting) && (control.co_vector==CO_SHOW) ) { fl_redraw_object(obj_vs); } break; } } else // EDIT_REPLACE: { if (i=vec->SearchVec(obj,mx,my,&w)) { if ( (i != vec_i) || (i==vec_i && w!=what_point)) { vec_i=i; what_point=w; what_connect=0; if (what_point==1) { if (vec->GetCon(vec_i)) what_connect=1; } else { if (vec_i+1 <= vec->GetMaxVec()) if (vec->GetCon(vec_i+1)) what_connect=2; } control.flag_set_vector = VEC_SEARCH; fl_redraw_object(obj_vs); fl_redraw_object(obj_vd); } } else { if (control.flag_set_vector == VEC_SEARCH) { control.flag_set_vector = VEC_NOSEARCH; fl_redraw_object(obj_vs); control.flag_set_vector = VEC_NOSEARCH; fl_redraw_object(obj_vd); vec_i=0; } } } break; default: ; } return 0; } /* obj_vs - objecthandler: Redraws source vectors */ int obj_vs_handler(FL_OBJECT *obj, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { static int x_old,y_old,w_old,h_old,win_changed; int x,y,w,h; // If size of object changes, redraw object fl_get_win_geometry(s_win->GetWin(),&x,&y,&w,&h); if ( (x_old != x) || (y_old != y) || (w_old != w) || (h_old != h) || (win_changed) || (control.GetDraw() == DRAW_SRCVECTORS) ) { s_vec->MapVectors(obj_vs,0,0); x_old=x; y_old=y; w_old=w; h_old=h; win_changed=0; control.SetDraw(DRAW_NOTHING); } if (event == FL_OTHER) win_changed=1; // Call handler for editing vectors: set_vec_handler(obj,event,mx,my,key,xev,s_win->GetWin(),1); return 0; } /* obj_vd - objecthandler: Redraws destination vectors */ int obj_vd_handler(FL_OBJECT *obj, int event, FL_Coord mx, FL_Coord my, int key, void *xev) { static int x_old,y_old,w_old,h_old,win_changed; int x,y,w,h; // If size of object changes, redraw object fl_get_win_geometry(d_win->GetWin(),&x,&y,&w,&h); if ( (x_old != x) || (y_old != y) || (w_old != w) || (h_old != h) || (win_changed) || (control.GetDraw() == DRAW_DSTVECTORS) ) { d_vec->MapVectors(obj,0,0); x_old=x; y_old=y; w_old=w; h_old=h; win_changed=0; control.SetDraw(DRAW_NOTHING); } if (event == FL_OTHER) win_changed=1; // Call handler for editing vectors: set_vec_handler(obj,event,mx,my,key,xev,d_win->GetWin(),0); return 0; }