⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gobject.c

📁 LastWave
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (IsView(o1)) {      if (((VIEW) o1)->flagReverse & YFlagReverse) signH -=signH;      if (((VIEW) o1)->flagReverse & XFlagReverse) signW -=signW;    }  }    /* Convert the rectangle from regular to generalized */  Rect2GRect(&mx,&my,&mw,&mh,rectType,signW,signH);  /* We convert each extremity of the rectangle */  Global2Local(o,mx,my,x,y);  Global2Local(o,mx+mw,my+mh,w,h);  *w -= *x;  *h -= *y;  if (*w < 0) {    *x += *w;    *w = -*w;  }  if (*h < 0) {    *y += *h;    *h = -*h;  }}/*  * Update the local rect of an object from its global rect  */void UpdateLocalRectGObject(GOBJECT o){  Global2LocalRect((GOBJECT) (o->father),o->x,o->y,o->w,o->h,&(o->rx),&(o->ry),&(o->rw),&(o->rh),o->rectType);}/* Update the global rect of an object from its local rect */void UpdateGlobalRectGObject(GOBJECT o){  Local2GlobalRect((GOBJECT) (o->father),o->rx,o->ry,o->rw,o->rh,o->rectType,&(o->x),&(o->y),&(o->w),&(o->h));}/********************************************************************************** * * Some other misc functions * **********************************************************************************//* Get the name of an object (returns a temporary string) */char *GetNameGObject(GOBJECT o){  GOBJECT array[200];  char *name;  int s,i,n;    n = 0;  s = 0;  while (o != NULL) {    array[n++] = o;         s += strlen(o->name);    o = (GOBJECT) o->father;  }    name = CharAlloc(s+n);  TempStr(name);    name[0] = '\0';  for(i=n-1;i>=0;i--) {    strcat(name,array[i]->name);    if (i != 0) strcat(name,".");  }    return(name);}/* * Compute the positions (absolute and relative) of an object using its grid position */static void ComputeGridRect(GOBJECT obj){  GRID grid;  int x,y,w,h,xGrid,yGrid;  int dx,dy;  char *l[4];  char str1[20],str2[20];      /* Basic checking */    if (!IsSubClass(obj->father->gclass,theGridClass)) Errorf("ComputeGridRect() : Weird error 1");  grid = (GRID) obj->father;  /* More checking */      if (!(obj->flagGrid)) Errorf("ComputeGridRect() : Weird error 2");    /* Get the absolute position of the grid */  if (IsWin((GOBJECT) grid)) {    xGrid = 0;    yGrid = 0;  }  else {    xGrid = grid->x;    yGrid = grid->y;  }      /* Compute the number of pixels for a grid unit */  dx = (int) ((grid->w-grid->leftMargin-grid->rightMargin+grid->dx)/((LWFLOAT) grid->gridM)-grid->dx+.5);  dy = (int) ((grid->h-grid->topMargin-grid->bottomMargin+grid->dy)/((LWFLOAT) grid->gridN)-grid->dy+.5);  if (dx <=0) dx = 1;  if (dy <=0) dy = 1;    /* Compute the absolute position of the object */  x = xGrid + grid->leftMargin + (obj->i-1)*(dx+grid->dx);  y = yGrid + grid->topMargin  + (obj->j-1)*(dy+grid->dy);    /* Compute the size of the object */  w = obj->m*(dx+grid->dx)-grid->dx;  h = obj->n*(dy+grid->dy)-grid->dy;    /* If it is the last object of a row or column, we must correct the size so that it fits the grid */  if (obj->i+obj->m-1 == grid->gridM) w = xGrid+grid->w-grid->rightMargin-x;  if (obj->j+obj->n-1 == grid->gridN) h = yGrid+grid->h-grid->bottomMargin-y;  if (w <= 0) w =  obj->m*dx +1;  if (h <= 0) h =  obj->n*dy +1;    /* Then we set the position MERDE */  sprintf(str1,"%d",x);        sprintf(str2,"%d",y);        l[0] = "-apos";  l[1] = str1;  l[2] = str2;  l[3] = NULL;  SetGObject(obj,l,NO);  /* Then we set the size MERDE */  sprintf(str1,"%d",w);        sprintf(str2,"%d",h);        l[0] = "-asize";  l[1] = str1;  l[2] = str2;  l[3] = NULL;  SetGObject(obj,l,NO);}/*  * Send (varcontent) message to a gobject (from a hash table ONLY !)  * Actually, this routine should never be called ! */static void * SendMessage2AGObject(void *content,int message,void **arg){  Errorf("SendMessage2AGObject() : Weired error");  return(NULL);}/*************************************************** * * * (Des)Allocation of gobjects functions * * ***************************************************/ /* * Function for creating a gobject named 'name' of a given 'class' and adding it to the glist 'father'. * 'argv' is a list of optional initialization fields that will be set after creating the gobject. * 'flagDraw' indicates whether the newly created object must be drawn or not  */GOBJECT NewGObject(GCLASS class, GLIST father, char *name, char **argv,char flagDraw){  GOBJECT o;  GCLASS c[MaxClassHierarchyDepth];  char flagWindow;  int n;      /* Is the class a window class ? */  flagWindow = IsSubClass(class,theWindowClass);        /* Cannot specify a father for a window */  if (flagWindow && father != NULL) Errorf("NewGObject() : Cannot specify a father for a window");  /* Must specify a father for non window */  if (!flagWindow && father == NULL) Errorf("NewGObject() : Must specify a father for a gobject which is not a window");    /* Print a warning if the object already exists */  if (father != NULL && (o = (GOBJECT) GetElemHashTable(father->theGObjects,name)) != NULL) {    if (DeleteGObject(o) == NO) {      Warningf("Cannot add object '%s' in glist '%s' since object with the same name already exists and is protected",name,father->name);      return(NULL);    }    else       Warningf("Adding object '%s' (which already exists) in glist '%s' -> delete former version",name,father->name);  }    /* Alloc the object */ #ifdef DEBUGALLOCDebugType = "GObject";#endif  o = (GOBJECT) Malloc(class->nbBytes);  InitValue(o,NULL);  o->nRef = 0;  /* Copying the name */  o->name = CopyStr(name);    /* Setting the class */    o->gclass = class;    /* Adding the object to the 'father' */  o->father = NULL;  o->front = NULL;  o->sendMessage = SendMessage2AGObject;  if (father != NULL) AddGObject2GList(o,father);         /* Get the class hierarchy in the c array */  n = 0;  c[n] = class;  while (c[n]->fatherClass != NULL) {    c[n+1] = c[n]->fatherClass;    n++;  }  /* Perform the initializations : from the top class initialization to the initialization of the 'class' */  for (;n>=0;n--) {    o->classCur = c[n];    if (c[n]->init) (*(c[n]->init))(o);    if (c[n]->msgeSCommand != NULL) DoScriptListv(o,c[n]->msgeSCommand,"init",NULL,-1);  }            /* Optional initializations of fields */    o->classCur = o->gclass;  SetGObject(o,argv,NO);    /* Draw the gobject if asked */  o->classCur = o->gclass;  if (flagDraw) DrawWholeGObject(o,YES);        /* Then return */  return(o);}/* * Basic Function to delete the gobject 'o' (not to be called directly) * * No hiding is performed before * * It returns YES if deletion was made and NO if not  * (NOTA : for now the o->nRef is never greater than 1 thus deletion is always performed when * this function is called) */static void RemoveGUpdate(GOBJECT o);static char DeleteGObject_(GOBJECT o){  struct event event;  GCLASS class;  GLIST list;  WINDOW w,w1;  int r;  AHASHELEM e;  GOBJECT obj;  /* If there still exists a reference then return otherwise we have to destroy the gobject */  if (o->nRef > 1) {    o->nRef--;    return(NO);  }      /* Force the classCur of the object to be its class */  o->classCur = o->gclass;    /* We first send all the delete events */  class = o->gclass;  while (class != NULL) {    o->classCur = class;    event.object = o;    event.type = Del;    SendEvent(&event);    /* Then loop on the class */    class = class->fatherClass;  }  o->classCur = o->gclass;  /* If it is a GLIST then we MUST delete all the gobjects in it first (because they might adress the GList) */  if (IsGList(o)) {    list = (GLIST) o;    /* We loop on the gobjects */    for (r = 0; r<list->theGObjects->nRows;r++) {      for (e = list->theGObjects->rows[r]; e != NULL;) {            obj = (GOBJECT) e;        e = e->next;        obj->flagHide = YES;        DeleteGObject_(obj);      }    }    list->theGObjects->nElems = 0;  }  /* We perform deletion methods from the class of the object to the topclass */  class = o->gclass;  while (class != NULL) {    /* Then call the specific script delete method if any */    if (class->msgeSCommand != NULL) DoScriptListv(o,class->msgeSCommand,"delete",NULL,NO);          /* Then call the specific delete function if any */    if (class->deleteContent) (*(class->deleteContent))(o);              /* Then loop on the class */    class = class->fatherClass;  }  o->classCur = o->gclass;    /* We must remove the gobject from the update list if it is in it */  RemoveGUpdate(o);    /* Remove the object from its father GList */  if (o->father != NULL) {    RemoveGObject2GList(o,o->father);    o->father = NULL;  }    /* If it is a window then we remove it from the window hash table */  if (IsWin(o)) {    GetRemoveElemHashTable(theWindowsHT,o->name);    w = (WINDOW) o;    if (theWindows == w) theWindows = (WINDOW) w->front;    else {      w1 = theWindows;      while(w1->front != o) w1 = (WINDOW) w1->front;      w1->front = w->front;      w->front = NULL;    }  }    /* Then free the non specific content of the object */  Free(o->name);    /* Then the object */ #ifdef DEBUGALLOCDebugType = "GObject";#endif  Free(o);       return(YES);}/* * Function to delete the gobject 'o' after hiding it * * Before trying to delete it, it notifies its glist that it will be * deleted. If the notify method sends back YES, then deletion is allowed * otherwise it is not allowed and the object is not deleted. */char DeleteGObject(GOBJECT o){  GCLASS class;  LISTV lv;  /* This line is useless for now since the 'nRef' field is never greater than 1 */  if (o->nRef > 1) return(DeleteGObject_(o));  /* If the object is not a window we must notify the glist it belongs to */  if (!IsWin(o)) {    /* The notification method is sent to the father and is inherited thus we must loop on the top classes */      class = o->father->gclass;    while (class != NULL) {      /* Then call the specific script deleteNotify method if any */      if (class->msgeSCommand != NULL) {        lv = TNewListv();        AppendStr2Listv(lv,o->name);                DoScriptListv((GOBJECT) o->father,class->msgeSCommand,"deleteNotify",lv,YES);                if (toplevelCur->flagReturn) {          /* if it returned 0 then we forbid deletion ?????? */          if (GetResultType() == numType && GetResultFloat() == 0);                  /* Otherwise let's do the deletion */          break;        }      }            /* Then call the specific deleteNotify function if any */      if (class->deleteNotify) {        if ((*(class->deleteNotify))((GOBJECT) o->father) == 0) return(NO);        break;      }          /* Then loop on the class */      class = class->fatherClass;    }  }    HideGObject(o);  return(DeleteGObject_(o));}/*************************************************** * * * Drawing functions * * ***************************************************//* * Basic function to draw the object 'o' in the window 'win'  * (that is the window 'o' is displayed in) and only in the * rectangle specified by x,y,w,h. * Just the object 'o' is drawn. No other objects are redrawn (event those in front of 'o'). */static void DrawGObject_(WINDOW win, GOBJECT o, int x,int y,int w,int h){  LWFLOAT lx,ly,lw,lh;   struct event event;  GCLASS class,class1;  WINDOW clipWin;  int clipX,clipY,clipW,clipH;  FONT font;              /* If window or object is hidden then return */    if (win->flagHide) return;  if (o->flagHide) return;    /* Get the current class of the object */  class = o->classCur;    /* If rect empty then return */  if (w <= 0 || h <= 0) return;      /* Get the current clip rect and set it to the new one */  WGetClipRect(&clipWin,&clipX,&clipY,&clipW,&clipH);  WSetClipRect(win, x, y, w, h);  /* Clear the corresponding rect */  WClearRect((GOBJECT) win,o->bgColor,x,y,w,h,YES,NormalRect);    /* Set some graphic attributes */  WSetColor(win,o->fgColor);  font = WGetFont(win);  WSetFont(win,o->font);  WSetLineStyle(win,o->lineStyle);  WSetPenMode(win,o->penMode);  WSetPenSize(win,o->penSize);  /* Remember the last window we drawn into */  toplevelCur->lastWindow = win;    /* Local coordinates of the rectangle */  Global2LocalRect(o,x,y,w,h,&lx,&ly,&lw,&lh,NormalRect);     /* We must find the first drawing method in the class hierarchy */  class1 = class;  while (class1 != NULL) {    /* DrawMessage */    if (DrawMessage(o,win,class1,x,y,w,h)) break;    class1 = class1->fatherClass;  }    /* Send a draw event */  event.object = o;  event.object->classCur = class;  event.type = Draw;  event.x = lx;  event.y = ly;  event.w = lw;  event.h = lh;  event.i = x;  event.j = y;  event.m = w;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -