📄 gobject.c
字号:
/* Some basic tests */ if (nGUpdates == 0) return; if (sizeGUpdateList == MaxSizeGObjectList-1) Errorf("AddGUpdate() : Too many objects to update"); if (indexGUpdate[nGUpdates-1] != sizeGUpdateList) { o1 = gupdateList[sizeGUpdateList-1]; /* Check that it does not exist already */ if (o1 == o) return; /* Check that it is not included in the former one */ if (!IsWin(o)) { if (o1 != NULL && IsWin(o1)) { if (GetWin(o) == (WINDOW) o1) return; } else if (o1 != NULL && o1->x < o->x && o1->y < o->y && o1->x+o1->w >= o->x+o->w && o1->y+o1->h >= o->y+o->h) return; } } /* Otherwise just add the gobject */ gupdateList[sizeGUpdateList++] = o; gupdateList[sizeGUpdateList] = NULL;}/* Perform the last gupdate (Call 'DrawWholeGObjectList') */static void DoGUpdate(void){ GOBJECT *list; int first,last,i,j; if (nGUpdates == 0) Errorf("DoGUpdate() : No gupdates to do"); /* We copy the list of gobjects to update */ first = indexGUpdate[nGUpdates-1]; last = sizeGUpdateList; list = (GOBJECT *) Malloc(sizeof(GOBJECT)*(last-first+1)); TempPtr(list); for (j=0,i=first;i<last;i++) { if (gupdateList[i] == NULL) continue; list[j] = gupdateList[i]; j++; } list[j] = NULL; /* We update the gupdate counter */ sizeGUpdateList = first; nGUpdates--; gupdateList[sizeGUpdateList] = NULL; /* Then we draw the list of gobjects */ DrawWholeGObjectList(list);} /* Init the gupdates mechanism */void InitGUpdates(void){ sizeGUpdateList = 0; nGUpdates = 0;}/* The gupdate command */void C_GUpdate(char **argv){ char *msge; GOBJECT *list; if (levelCur == levelFirst) Errorf("This command must be used in a script"); argv = ParseArgv(argv,tWORD,&msge,-1); if (!strcmp(msge,"start")) { NoMoreArgs(argv); StartGUpdate(); return; } if (!strcmp(msge,"do")) { NoMoreArgs(argv); DoGUpdate(); return; } if (!strcmp(msge,"add")) { argv = ParseArgv(argv,tGOBJECTLIST,&list,0); while(*list) { AddGUpdate(*list); list++; } return; } Errorf("Unknown action'%s'",msge);}/*************************************************** * * * Functions that deal with setting and getting fields of a gobject * * ***************************************************//* A function defined below (used for parsing a gobject list) */static char _ParseGObjectList_(char *arg, GLIST glist, GOBJECT *def, GOBJECT **objlist);/* * Basic function to perform a set/get field message specified by 'argv on a gobject 'o' considered * as an object of class 'class' * * It returns 0 if the field name was not found 1 if it exists and if the corresponding gobject must be updated * and -1 if it exists and the corresponding gobject must not be updated. */ static int Set1GObjectClass(GCLASS class, GOBJECT o, char **argv){ char flagSet; int n; LISTV lv; VALUE val; /* Is it a 'set' or a 'get' */ if (argv[1] != NULL) flagSet = YES; else flagSet = NO; /* Should we perform a script ? */ if (class->setSCommand && !(*argv != NULL && (!strcmp(*argv,"-rectx") || !strcmp(*argv,"-recty") || !strcmp(*argv,"-rect") || !strcmp(*argv,"-arect") || !IsGList(o) && (!strcmp(*argv,"-pos") || !strcmp(*argv,"-apos") || !strcmp(*argv,"-size") || !strcmp(*argv,"-asize"))))) { lv = TNewListv(); AppendStr2Listv(lv,*argv+1); argv++; while (*argv) { ParseVal(*argv,&val); AppendValue2Listv(lv,val); argv++; } DoScriptListv(o,class->setSCommand,NULL,lv,YES); if (!toplevelCur->flagReturn) return(NO); if (!flagSet) return(YES); if (GetResultType() == numType) { if (GetResultFloat() == 1) return(YES); if (GetResultFloat() == -1) return(-1); Errorf("Set1GObjectClass() : Bad value returned '%g' by the 'set' method of gobject '%s'",GetResultFloat(),GetNameGObject(o)); } Errorf("Set1GObjectClass() : Bad value type '%s' returned by the 'set' method of gobject '%s'",GetResultType(),GetNameGObject(o)); } /* Should we perform a C-function */ if (class->set) { if (argv == NULL || *argv == NULL) n = (*(class->set))(o,NULL,NULL); else n = (*(class->set))(o,*argv+1,argv+1); if (n == NO) return(NO); if (!flagSet) return(YES); else return(n); } return(NO);}/* * General function to perform a list of set/get field messages specified by 'argv' on the object 'o' * * if flagGUpdate == YES then it means that a gupdate is on * * This function returns NO if the last field name (in argv) was not found and YES otherwise */char SetGObject(GOBJECT o, char **argv,char flagGUpdate){ char **argv1; char *str; GCLASS class; char answer; GOBJECT objCur,objList[2],*objlist,*list,o1; int n; char flagStop; /* If no message then just return */ if (argv == NULL) return(YES); /* init */ answer = NO; objList[0] = o; objList[1] = NULL; objlist = objList; /* We loop on the list to separate each set/get message */ flagStop = NO; while (!flagStop && *argv != NULL) { /* The first word should be of type '-field' */ if (**argv != '-') Errorf("SetGObject() : Bad set/get field '%s' (should start with a '-')",*argv); /* Let's loop to get the end of the first message */ argv1 = argv; argv++; while (*argv != NULL) { if (**argv != '-' || (*argv)[1] == '-' || isdigit((*argv)[1]) || ((*argv)[1] == '.' && isdigit((*argv)[2]))) { if (**argv == '-' && (*argv)[1] == '-') (*argv)++; argv++; continue; } break; } /* We got the first message (it is pointed to by 'argv1' and the remaining is pointed by 'argv') */ str = *argv; *argv = NULL; /* If there is a '-.' message then we must have a glist and send all the following messages to the corresponding objects */ if ((*argv1)[1] == '.' && !isdigit((*argv1)[2])) { if (!IsGList(o)) Errorf("SetGObject() : '%s' message cannot be used with object '%s' which is a not a GList",*argv1,GetNameGObject(o)); if (argv1[1] != NULL) Errorf("SetGObject() : '%s' message must be followed by other '-' messages",*argv1); if (_ParseGObjectList_(*argv1+1,(GLIST) o, NULL,&objlist) == NO) Errorf1(""); if (*objlist == NULL) Errorf("SetGObject() : '%s' message failed since I cannot find '%s' object",*argv1,*argv1+3); *argv = str; continue; } /* Send the set/get message we found to each object of the list and to its class hierarchy (from bottom to top) till we get an answer */ for (list = objlist;*list;list++) { objCur = *list; class = objCur->classCur; InitResult(); while (class != NULL) { n = Set1GObjectClass(class,objCur,argv1); if (!strcmp(*argv1,"-add")) { flagStop = YES; *argv = str; if (IsGList(objCur)) { o1 = (GOBJECT) GetElemHashTable(((GLIST) objCur)->theGObjects,argv1[1]); if (o1!=NULL) { SetGObject(o1,argv,flagGUpdate); } } } if (n != NO) { /* Should we add this object to the update list ? */ if (n == YES && flagGUpdate && objCur->flagHide == NO && *argv1 != NULL && argv1[1] != NULL && (*argv1)[1] != '?') AddGUpdate(objCur); answer = YES; break; } answer = NO; class = class->fatherClass; } } for (list = objlist;*list;list++) { if (*list != o) (*list)->classCur = (*list)->gclass; } *argv = str; } return(answer); } /* * Basic subroutine for the setg and setgd commands */static char _C_SetGObject(GOBJECT *objlist, char **argv, char flagDraw,char flagUpdate){ char answer = NO; GOBJECT *list; /* Start the GUpdate counter if it is a 'setgd' call */ if (flagDraw && flagUpdate) StartGUpdate(); /* Then we loop on the object list */ list = objlist; while (*list) { answer = SetGObject(*list,argv,flagUpdate); list++; } /* Then we end the update if necessary */ if (flagDraw && flagUpdate) DoGUpdate(); return(answer);}/* * The setg command */void C_Setg(char **argv){ GOBJECT *objlist; char answer,flagUpdate; /* If the first argument is '-' then no update will be performed */ flagUpdate = YES; if (*argv != NULL && !strcmp(*argv,"-")) { flagUpdate = NO; argv++; } argv = ParseArgv(argv,tGOBJECTLIST,&objlist,-1); /* Set/Get the fields */ answer = _C_SetGObject(objlist,argv,NO,flagUpdate); while (*objlist) {(*objlist)->classCur = (*objlist)->gclass;objlist++;}}/* * The setgu command */void C_SetgU(char **argv){ GOBJECT *objlist; argv = ParseArgv(argv,tGOBJECTLIST,&objlist,-1); /* Set/Get the fields */ _C_SetGObject(objlist,argv,YES,YES); while (*objlist) {(*objlist)->classCur = (*objlist)->gclass;objlist++;}}/*************************************************** * * * Functions that deal with sending messages to gobjects * * ***************************************************//* * The msge command (for sending messages) */void C_Msge(char **argv){ LISTV lv; char *msge,*str,**argv1; GOBJECT o,o1; GCLASS class; int x,y,w,h,cx,cy,cw,ch; LWFLOAT fx,fy,rx,ry,rw,rh; WINDOW cwin; GOBJECT *objlist,*objlist1; char flagLocal; /* Basic checkings */ if (*argv == NULL || *(argv+1) == NULL) ErrorUsage(); /* Special treatment for the 'exist' message */ if (!strcmp(*(argv+1),"exist")) { class = NULL; if (*(argv+2) != NULL) { if (*(argv+3) != NULL) ErrorUsage(); str = *(argv+2); class = (GCLASS) GetElemHashTable(theGClasses,str); if (class == NULL) Errorf("Class '%s' does not exist",str); } argv = ParseArgv(argv,tGOBJECTLIST_,NULL,&objlist,-1); if (objlist == NULL) SetResultInt(0); else { if (class != NULL) { objlist1 = objlist; while(*objlist1) { if (!IsSubClass((*objlist1)->gclass,class)) break; objlist1++; } SetResultInt((int) (*objlist1 == NULL)); while(*objlist) { (*objlist)->classCur = (*objlist)->gclass; objlist++; } } else SetResultInt(1); } return; } /* Get the message and the objectlist */ argv = ParseArgv(argv,tGOBJECTLIST,&objlist,tWORD,&msge,-1); argv1 = argv-1; /* Special treatment for the 'name' message */ if (!strcmp(msge,"name")) { NoMoreArgs(argv); objlist1 = objlist; while(*objlist1) { AppendListResultStr(GetNameGObject(*objlist1)); objlist1++; } while(*objlist) { (*objlist)->classCur = (*objlist)->gclass; objlist++; } return; } /* Special treatment for the 'draw' message */ if (!strcmp(msge,"draw")) { /* Case there is no rect specified */ if (*argv == NULL || *(argv+1) == NULL) { if (*argv != NULL) { /* Case we do not use the current clip */ if (strcmp("-clip",*argv)) ErrorUsage(); DrawWholeGObjectList(objlist); } else { /* Case we should use the current clip */ WGetClipRect(&cwin,&cx,&cy,&cw,&ch); if (cwin != GetWin(objlist[0])) DrawWholeGObjectList(objlist); else DrawGObjectList(objlist,cx,cy,cw,ch); } while(*objlist) { (*objlist)->classCur = (*objlist)->gclass; objlist++; } return; } /* Case a rect (local/global coordinate) is specified */ if (!strcmp(*argv,"-l")) { flagLocal = YES; if (objlist[1] != NULL) Errorf("Cannot use local coordinates if more than 1 gobject"); } else if (!strcmp(*argv,"-g")) flagLocal = NO; else ErrorUsage(); argv++; if (flagLocal) { argv = ParseArgv(argv,tFLOAT,&rx,tFLOAT,&ry,tFLOAT,&rw,tFLOAT,&rh,-1); Local2GlobalRect(*objlist,rx,ry,rw,rh,LargeRect,&x,&y,&w,&h); } else { argv = ParseArgv(argv,tINT,&x,tINT,&y,tINT,&w,tINT,&h,-1); } /* Case we do not use the clip */ if (*argv != NULL) { if (*(argv+1) != NULL) ErrorUsage(); if (strcmp("-clip",*argv)) ErrorUsage(); DrawGObjectList(objlist,x,y,w,h); } else { /* case we should use the clip */ WGetClipRect(&cwin,&cx,&cy,&cw,&ch); if (cwin != GetWin(objlist[0])) { DrawGObjectList(objlist,x,y,w,h); } else { IntersectRect(cx,cy,cw,ch,&x,&y,&w,&h); DrawGObjectList(objlist,x,y,w,h); } } /* Reset the current class */ while(*objlist) { (*objlist)->classCur = (*objlist)->gclass; objlist++; } return; } /* The 'init' message is forbidden */ if (!strcmp(msge,"init")) return; /* * Then we loop on all the objects of the list */ while(*objlist) { o = *objlist; objlist++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -