y2@DINORAH.WUSTL.EDU (Yeong-Yeong Liu) (08/03/88)
I have a widget tree that looks like this: Widget toplevel, frame, mainwidget, text, auxtext; /* each indentation is a generation lower */ "text" and "auxtext" are siblings and their contents (subwidgets) may change from time to time. They hold most of the activities of my application. Here is what I want to do: 1. In main(), create and realize an initial display using Restart() function. Multiple choices go to callbacks. (I had no problem) 2. execute appropriate callback depending on user's choice (the callback was indeed properly invoked). In one of the callbacks, I did: i) retrieve main_width,main_height,main_x and main_y by XtGetValues(mainwidget,...); ii) XtDestroy(mainwidget); /* wipe out mainwidget and its children */ iii) recreate mainwidget with old x,y,width,height. iv) create text, auxtext, their children and their children's callbacks v) XtRealizeWidget(mainwidget); (steps ii thru v are in function InitialPage()) 3. back in main(), return to XtMainLoop() and wait for something to happen appropriate to the widgets created in step 2 iv I ran into following problems: * after step 2 iii), the dump statement tells me the mainwidget recreated has height of 1 and y position of 780, which is approximately the opposite of the two parameters I put in. This is minor but seems strange. * in step 2 iv) I must set widget geometry (x,y,width,height) in args or I'll get "integer out of range" in X_CreateWidget from Server. Is this required ? Why would I be able to create widget in step 1 (before any of the widgets is realized) without setting geometry ? * after completion of step 2 v), program apparently goes to XtMainLoop(), but it didn't display any of the widgets created in step 2 (didn't map mainwidget). * If I replace Restart in main program with InitialPage, less the final XtRealizeWidget(mainwidget), then all widgets created by InitialPage are visible. It looks like it depends on if the parent has been realized or not. Is this really so?? Or have I missed something? Has anyone else created widgets after the parent has been realized? Here is my main program: ------------------------ . . Widget frame,mainwidget,text,auxtext; int main_width,main_height,main_x,main_y; . main() { . . XtGetApplicationResources(toplevel,(caddr_t)NULL,resources, XtNumber(resources),NULL,0); . . frame = XtCreateWidget("rtp", vPanedWidgetClass, toplevel, args, n); CreateMainWidget(); /* create (managed) mainwidget (dimension set according to DisplayWidth etc. for DefaultScreen) */ Restart(); /* setup (initial) multiple choice in "text", message in "auxtext" (all subwidgets are managed) */ XtManageChild(frame); XtRealizeWidget(toplevel); XtMainLoop(); } Here is the subroutine (which does step 2 ii to 2 v) called by callbacks ------------------------------------------------------------------------ void InitialPage() { Widget funcky,panel; Arg args[6]; int i,n,width,height,wdth,hght,horiz=0; /* destroy mainwidget and its children, then recreate mainwidget again */ XtDestroyWidget(mainwidget); CreateMainWidget(); /* create a shell for text */ n = 0; XtSetArg(args[n],XtNwidth,main_width); n ++; XtSetArg(args[n],XtNheight,main_height/3); n ++; XtSetArg(args[n],XtNborderWidth,0); n ++; XtSetArg(args[n],XtNx,0); n ++; XtSetArg(args[n],XtNy,0); n ++; text = XtCreateManagedWidget("text",formWidgetClass, mainwidget,args,n); /* create another shell for text help */ XtSetArg(args[n-1],XtNy,main_height/3); XtSetArg(args[n],XtNfromVert,text); n ++; auxtext = XtCreateManagedWidget("auxtext",formWidgetClass, mainwidget,args,n); /* create a shell for multiple choice */ XtSetArg(args[n-1],XtNfromVert,auxtext); XtSetArg(args[n-2],XtNy,main_height * 2 / 3); funcky = XtCreateWidget("mainwidget",formWidgetClass, mainwidget,args,n); /* create multiple choices inside funcky */ panel = MenuPage(funcky,"funcky",funcalls,funcdata,horiz,frame, txplanActionsTableCount,txplanActionsTable, nfuncky,txplanTranslations, &wdth,&hght); /* reposition function keys to the bottom of the mainwidget */ XtMoveWidget(funcky,0,main_height - hght); /* manage and realize all children */ XtManageChild(funcky); XtRealizeWidget(mainwidget); } Any help will be highly appreciated. Thanks. Y Liu {uunet...}!wucs1!dinorah!y2 or wucs1.wustl.edu!dinorah!y2 or y2@dinorah.wustl.edu or 314-362-2950
swick@ATHENA.MIT.EDU (Ralph R. Swick) (08/03/88)
The answer to your subject question is yes, but the scenario you describe is a lot more complicated. Remember that geometry negotiation behaves very differently before and after a widget (branch) is realized. When a widget hierarchy is created and managed before any of its ancestors have been realized, then geometries are effectively calculated from the inside out. This allows each parent's layout routine to be called exactly once and have full information on the desires of it's children. Once the hierarchy has been realized, however, the parent must react to each individual change in it's managed set of children and must negotiate any changes in it's own geometry with it's parent. Thus, geometries of realized hierarchies are effectively calculated from the outside in. One technique that will work well when you want to create and destroy branches of a realized tree is to leave the uppermost node of the branch unmanaged until the remainder of the branch has been created (and managed). You can then set the uppermost node to be managed, which will also cause the entire branch to be realized. You may also want some way to inform the parent of the new branch not to perform a re-layout operation between the time you destroy the old branch and manage the new one. Some composite widgets will support this (deferring a re-layout) and some won't. The better one probably will.