📄 gobject.c
字号:
event.n = h; SendEvent(&event); /* Should we draw a frame around the object */ if (o->flagFrame) { WSetColor(win,o->fgColor); WSetClipRect(win, x, y, w, h); WSetLineStyle(win,o->lineStyle); WSetPenSize(win,o->penSize); if (!IsWin(o)) WDrawRect((GOBJECT) win,o->x,o->y,o->w,o->h,YES,NormalRect); else WDrawRect((GOBJECT) win,0,0,o->w,o->h,YES,NormalRect); } /* Restore the clip rect */ WSetClipRect(clipWin,clipX,clipY,clipW,clipH); /* Restore the font */ if (font != o->font) WSetFont(win,font); /* Flush the graphics */ WFlush();}/* * Function to draw the object 'o' and only in the * rectangle specified by x,y,w,h. * * if 'flagJustTheObject' == NO then all the eventual objects intersecting the rect x,y,w,h * will be redrawn. Otherwise just this object is drawn. * */ void DrawGObject(GOBJECT o, int x,int y,int w,int h, char flagJustTheObject){ WINDOW win; GCLASS class; GOBJECT o1; int x1, y1, w1, h1; /* If object is hidden then return */ if (o->flagHide) return; /* We must compute the part which is visible */ if (GetVisibleRect(o,&x,&y,&w,&h) == NO) return; /* Get the window the object is in */ win = GetWin(o); /* Then just call the DrawGObject_ function */ if (!flagJustTheObject) { o1 = o; while (!IsWin(o1) && o1->bgColor == invisibleColor) o1 = (GOBJECT) o1->father; win = GetWin(o1); for (;o1 != NULL; o1 = o1->front) { class = o1->classCur; o1->classCur = o1->gclass; x1 = x; y1 = y; w1 = w; h1 = h; if (GetVisibleRect(o1,&x1,&y1,&w1,&h1) == NO) continue; DrawGObject_(win,o1,x1,y1,w1,h1); o1->classCur = class; if (IsWin(o1)) break; } } else DrawGObject_(win,o,x,y,w,h);}/* Same as above but draw the whole object */void DrawWholeGObject(GOBJECT o, char flagJustTheObject){ DrawGObject(o,0,0,INT_MAX/2,INT_MAX/2,flagJustTheObject);}/* * Function to draw a list of objects 'gobjects' only in the * rectangle specified by x0,y0,w0,h0. * * All the eventual objects intersecting the rect x,y,w,h * will be redrawn. * * All the gobjects must belong to the same window. */void DrawGObjectList(GOBJECT *gobjects,int x0, int y0, int w0 , int h0){ WINDOW win; int x[1]; int y[1]; int w[1]; int h[1]; int x1,y1,w1,h1; int nRect,nGObj; int i; /* If no object then just return */ if (*gobjects == NULL) return; /* If just one object then call DrawGObject */ if (gobjects[1] == NULL) { DrawGObject(*gobjects,x0,y0,w0,h0,toplevelCur->flagInDrawMessage); return; } /* If flagInDrawMessage then we cannot daw (for now) several objects */ if (toplevelCur->flagInDrawMessage) Errorf("DrawGObjectList() : Sorry, cannot draw several gobjects while executing a drawing message"); /* If window is hidden then return */ win = GetWin(*gobjects); if (win->flagHide) return; /* Check that all gobjects belong to the same window */ for (nGObj = 0;gobjects[nGObj];nGObj++) { if (GetWin(gobjects[nGObj]) != win) Errorf("DrawGObjectList() : The gobjects must belong to the same window"); } /* * We are going to loop on the gobjects in order to get a list of rectangles using absolute coordinates */ /* Get the first rect */ nRect = 0; nGObj = 0; for (;gobjects[nGObj] != NULL;nGObj++) { x[0] = x0; y[0] = y0; w[0] = w0; h[0] = h0; if (GetVisibleRect(gobjects[nGObj],&x[0],&y[0],&w[0],&h[0])) { nRect++; break; } } /* If no rect then return */ if (nRect == 0) return; nGObj++; /* Loop on all the other rects */ for (;gobjects[nGObj];nGObj++) { x1 = x0; y1 = y0; w1 = w0; h1 = h0; if (!GetVisibleRect(gobjects[nGObj],&x1,&y1,&w1,&h1)) continue; UnionRect1(x1,y1,w1,h1,&x[0],&y[0],&w[0],&h[0]); } /* Then Draw !!! */ for(i=0;i<nRect;i++) { DrawGObject_(win,(GOBJECT) win,x[i],y[i],w[i],h[i]); }}/* Same as above but draw the whole of each object in the object list 'gobjects' */void DrawWholeGObjectList(GOBJECT *gobjects){ DrawGObjectList(gobjects,0,0,INT_MAX/2,INT_MAX/2);}/*************************************************** * * * Hide/show functions * * ***************************************************//* Function to show a gobject */void ShowGObject(GOBJECT o){ WINDOW w; /* If it was not hidden then return */ if (o->flagHide == NO) return; /* Special treatment for windows (creating a frame) */ if (IsWin(o)) { w = (WINDOW) o; if (w->frame != (FRAME) NULL) Errorf("ShowGObject() : Weird error"); w->frame = WNewFrame(w->title,w->x,w->y,w->w,w->h); w->flag = 0; } o->flagHide = NO; /* Let's draw it ! */ DrawWholeGObject(o,NO);}/* Function to hide a gobject */void HideGObject(GOBJECT o){ WINDOW win; GCLASS class; int x,y,w,h; /* If it was hidden then return */ if (o->flagHide == YES) return; /* Special treatments for windows (deleting the frame) */ if (IsWin(o)) { win = (WINDOW) o; if (win->frame == (FRAME) NULL) Errorf("HideGObject() : Weird error"); WDeleteFrame(win->frame); win->frame = (FRAME) NULL; win->flagHide = YES; } /* And for non window objects */ else { /* We must compute the part which is visible */ x = 0; y = 0; w = INT_MAX/2; h = INT_MAX/2; if (GetVisibleRect(o,&x,&y,&w,&h) == NO) { o->flagHide = YES; return; } o->flagHide = YES; win = GetWin(o); class = win->classCur; win->classCur = win->gclass; DrawGObject_(win,(GOBJECT) win,x,y,w,h); win->classCur = class; }}/*************************************************** * * * Back/Front functions * * ***************************************************//* Function to make a gobject move to the front */void FrontGObject(GOBJECT o, char flagDraw){ GLIST list; GOBJECT o1; if (IsWin(o)) { WFrontWindow((WINDOW) o); return; } /* Get the glist */ list = (GLIST) o->father; /* If object is in the back, just remove it */ if (list->back == o) { if (o->front == NULL) return; o1 = list->back = o->front; } /* Otherwise look for it and remove it */ else { for (o1 = list->back;o1->front != o;o1 = o1->front); o1->front = o->front; } /* Then add it to the end */ while (o1->front != NULL) o1 = o1->front; o1->front = o; o->front = NULL; /* then redraw the object */ if (flagDraw) DrawWholeGObject(o,NO);}/* Function to make a gobject move to the back */void BackGObject(GOBJECT o,char flagDraw){ GLIST list; GOBJECT o1; /* this function does not work for windows yet */ if (IsWin(o)) return; /* Get the glist */ list = (GLIST) o->father; /* If object is in the back then just return */ if (list->back == o) return; /* Look for the object */ for (o1 = list->back;o1->front != o;o1 = o1->front); /* Then put it in the back */ o1->front = o->front; o->front = list->back; list->back = o; /* then redraw the object */ if (flagDraw) DrawWholeGObject(o,NO);}/*************************************************** * * * Move and/or resize an object * * ***************************************************/void MoveResizeDrawGObject(GOBJECT o,LWFLOAT x, LWFLOAT y, LWFLOAT w, LWFLOAT h){ char *list[4],*list1[4]; char str1[20],str2[20],str3[20],str4[20]; char flagDraw; if (!(o->gclass->flags & GClassMoveResize)) return; list[0] = NULL; if (o->x != x || o->y != y) { list[0] = "-pos"; sprintf(str1,"%g",x); list[1] = str1; sprintf(str2,"%g",y); list[2] = str2; list[3] = NULL; } list1[0] = NULL; if (o->w != w || o->h != h) { list1[0] = "-size"; sprintf(str3,"%g",w); list1[1] = str3; sprintf(str4,"%g",h); list1[2] = str4; list1[3] = NULL; } if (IsWin(o)) { if (list[0] != NULL) SetGObject(o,list,NO); if (list1[0] != NULL) SetGObject(o,list1,NO); return; } if (o->flagHide) flagDraw = NO; else flagDraw = YES; if (flagDraw) HideGObject(o); if (list[0] != NULL) SetGObject(o,list,NO); if (list1[0] != NULL) SetGObject(o,list1,NO); if (flagDraw) ShowGObject(o); } /****************************************************** * * Function to test whether a point (global coordinates) is within a gobject. * It returns a negative number if it is not * Otherwise it returns a positive LWFLOAT that indicates the "distance" to * the object. If this distance is 0 it means that the point is in the object. * The object the distance corresponds to is returned in *o1 * (*o1 is just o in case of simple gobjects but could be a different object * in case 'o' is a glist). * ***************************************************/ LWFLOAT IsInGObject(GOBJECT o, GOBJECT *o1, int x, int y){ GCLASS class,class1; LWFLOAT rx,ry; LISTV lv; /* Get the class */ class = o->classCur; /* Init of the returned value */ *o1 = NULL; /* If the object is hidden then return */ if (o->flagHide) return(-1); /* * Is the point in the object bounding box ? * If not then we just return -1 */ if (!IsWin(o) && (o->x > x || o->x+o->w < x || o->y > y || o->y+o->h < y)) return(-1); if (IsWin(o) && (0 > x || o->w < x || 0 > y || o->h < y)) return(-1); /* A priori the object the point is in is the object 'o' itself */ *o1 = o; /* We must call the IsIn C function or script if there is any in the class hierarchy */ class1 = class; while (class1 != NULL) { /* Should we call a script command ? */ if (class1->isInSCommand) { Global2Local(o,x,y,&rx,&ry); lv = TNewListv(); AppendFloat2Listv(lv,rx); AppendFloat2Listv(lv,ry); DoScriptListv(o,class1->isInSCommand,NULL,lv,YES); return(GetResultFloat()); } /* Should we call a C function ? (????? pourquoi pas en local??) */ if (class1->isIn != NULL) return((*(class1->isIn))(o,o1,x,y)); /* Loop on the class */ class1 = class1->fatherClass; } /* If no specific command were found, it means we are in the object 'o' */ return(0);}/*************************************************** * * * Functions that deal with gupdates * * ***************************************************//* * The following variables are used in order to remember which objects should be updated on the screen. * Whenever a 'setgd' is called or 'update start' is explicitely called, all the gobjects * whose fields are changed will be put in the 'gupdateList' table (of size 'sizeGUpdateList') to be redrawn later * (i.e., at the end of the setgd or when 'update do' is explicitely called). * * Actually whenever the 'setg' command is applied to a certain field <field> in a script and whenever it returns -1, it means * that the change of the field <field> did not actually affect the display of the object, * Thus the object should not be redrawn (it is not put in the 'gupdateList' table. * * If it returns 0 it means that the object does not know about the field <field> * * If it returns 1, it means pdate should be perform * * The same convention is used for C Set functions. * * Since 'setgd' calls can be imbricated, there is a stack of gupdates. * 'nGUpdates' is the number of imbricated gupdates and 'indexGUpdate' are the indexes where * each of these gupdates start in the 'gupdateList' table. */ static GOBJECT gupdateList[MaxSizeGObjectList];static int sizeGUpdateList = 0;static int indexGUpdate[MaxSizeGObjectList];static int nGUpdates = 0;/* Start a new gupdate */static void StartGUpdate(void){ if (nGUpdates == MaxSizeGObjectList) Errorf("StartGUpdate() : Too many imbricated gupdates"); indexGUpdate[nGUpdates] = sizeGUpdateList; gupdateList[sizeGUpdateList] = NULL; nGUpdates++;} /* Remove object 'o' from the 'updateList' if it is in it */static void RemoveGUpdate(GOBJECT o){ int i; for (i=0;i<sizeGUpdateList;i++) { if (gupdateList[i] == o) { gupdateList[i] = NULL; } }}/* Add a new object to the update list */static void AddGUpdate(GOBJECT o){ GOBJECT o1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -