/* Enforce margins for children if margins are non-zero */ void _XmGMEnforceMargin(XmManagerWidget manager, #if NeedWidePrototypes int margin_width, int margin_height, int setvalue #else Dimension margin_width, Dimension margin_height, Boolean setvalue #endif /* NeedWidePrototypes */ ) { int i ; register Widget child ; register Boolean do_move ; Position newx, newy ; for(i = 0 ; i < manager->composite.num_children ; i++) { do_move = False ; child = (Widget) manager->composite.children[i] ; if(XtIsManaged (child)) { if ((margin_width != 0) && (XtX(child) < (int) margin_width )) { do_move = True ; newx = margin_width ; } else newx = XtX(child) ; if ((margin_height != 0) && (XtY(child) < (int) margin_height )) { do_move = True ; newy = margin_height ; } else newy = XtY(child) ; if(do_move) { if (setvalue) { Arg args[2] ; XtSetArg(args[0], XmNx, newx); XtSetArg(args[1], XmNy, newy); XtSetValues(child, args, 2); } else XmeConfigureObject(child, newx, newy, child->core.width, child->core.height, child->core.border_width); } } } }
static void DoLayout(Widget wid) { XmGrabShellWidget gs = (XmGrabShellWidget)wid; if (XtIsManaged(gs->composite.children[0])) { Widget childwid = gs->composite.children[0]; Position offset = (gs->grab_shell.shadow_thickness + childwid->core.border_width); int cw = ((int) gs->core.width) - 2 * offset; int ch = ((int) gs->core.height) - 2 * offset; Dimension childW = MAX(1, cw); Dimension childH = MAX(1, ch); XmeConfigureObject (childwid, offset, offset, childW, childH, childwid->core.border_width); } }
/************************************************************************ * * ConfigureChildren * Configure the title and work area if they aren't instigaror * of the request (Yes policy). Compute the shadow location. * ************************************************************************/ static void ConfigureChildren( XmFrameWidget fw, Widget instigator, XtWidgetGeometry * inst_geometry) { Widget child; XmFrameConstraint fc; Position childX = 0; Position childY; Dimension childWidth; Dimension childHeight; Dimension childBW; Dimension shadowThickness = fw->manager.shadow_thickness; Dimension titleExtent = shadowThickness; Dimension shadowHeight = fw->core.height; Position shadowY = 0; XtWidgetGeometry title_reply; Dimension spacing; if (fw->frame.title_area && XtIsManaged(fw->frame.title_area)) { child = fw->frame.title_area; fc = GetFrameConstraint(child); spacing = shadowThickness + fc->child_h_spacing; /* asking the preferred geometry without constraint */ XtQueryGeometry (child, NULL, &title_reply); childWidth = (title_reply.request_mode & CWWidth) ? title_reply.width : child->core.width; childHeight = (title_reply.request_mode & CWHeight) ? title_reply.height : child->core.height; childBW = child->core.border_width; if (child == instigator) { childWidth = (inst_geometry->request_mode & CWWidth) ? inst_geometry->width : childWidth; childHeight = (inst_geometry->request_mode & CWHeight) ? inst_geometry->height : childHeight; childBW = (inst_geometry->request_mode & CWBorderWidth) ? inst_geometry->border_width : childBW; } if (childWidth + 2 * (spacing + childBW) > fw->core.width) { if (fw->core.width > 2 * (spacing + childBW)) childWidth = fw->core.width - 2 * (spacing + childBW); else childWidth = 1; } switch (fc->child_h_alignment) { case(XmALIGNMENT_BEGINNING): if (LayoutIsRtoLM(fw)) childX = fw->core.width - spacing - childWidth - 2 * childBW; else childX = spacing; break; case(XmALIGNMENT_CENTER): childX = fw->core.width/2 - childWidth/2 - childBW; break; case(XmALIGNMENT_END): default: if (LayoutIsRtoLM(fw)) childX = spacing; else childX = fw->core.width - spacing - childWidth - 2 * childBW; break; } CalcTitleExtent (fw, childHeight, childBW, &titleExtent, &childY, &shadowHeight, &shadowY); if (child != instigator) { XmeConfigureObject (child, childX, childY, childWidth, childHeight, childBW); } else { /* Do not resize the instigator, just return GeometryYes */ inst_geometry->request_mode = CWX | CWY | CWWidth | CWHeight | CWBorderWidth; child->core.x = childX; child->core.y = childY; child->core.width = childWidth; child->core.height = childHeight; child->core.border_width = childBW; } } if (fw->frame.work_area && XtIsManaged(fw->frame.work_area)) { child = fw -> frame.work_area; if (child != instigator) childBW = child->core.border_width; else childBW = (inst_geometry->request_mode & CWBorderWidth) ? inst_geometry->border_width : child->core.border_width; CalcWorkAreaSize (fw, &childWidth, &childHeight, childBW, fw->core.width, fw->core.height); childX = shadowThickness + fw->frame.margin_width; childY = titleExtent + fw->frame.margin_height; if (child != instigator) { XmeConfigureObject (child, childX, childY, childWidth, childHeight, childBW); } else { /* Do not resize the instigator, just return GeometryYes */ inst_geometry->request_mode = CWX | CWY | CWWidth | CWHeight | CWBorderWidth; child->core.x = childX; child->core.y = childY; child->core.width = childWidth; child->core.height = childHeight; child->core.border_width = childBW; } } fw->frame.old_shadow_x = 0; fw->frame.old_shadow_y = shadowY; fw->frame.old_width = fw->core.width; fw->frame.old_height = shadowHeight; fw->frame.old_shadow_thickness = shadowThickness; }
int main (int argc, char **argv) { Widget workRegion, simpleWidget, simpleGadget; register int n; Arg args[MAX_ARGS]; Position x, y; Dimension width, height, border_width; CommonTestInit(argc, argv); n = 0; XtSetArg(args[n], XmNwidth, 200); n++; XtSetArg(args[n], XmNheight, 200); n++; XtSetValues(Shell1, args, n); XtRealizeWidget(Shell1); /* set up a manager */ n = 0; XtSetArg(args[n],XmNnoResize, True); n++; XtSetArg(args[n],XmNresizePolicy, XmRESIZE_NONE); n++; XtSetArg(args[n],XmNwidth, 200); n++; XtSetArg(args[n],XmNheight, 200); n++; workRegion = XmCreateBulletinBoard(Shell1,"WorkRegion", args, n); XtManageChild(workRegion); /* Instantiate a PushButton widget. */ n = 0; XtSetArg(args[n],XmNrecomputeSize, False); n++; XtSetArg(args[n],XmNshadowThickness, 5); n++; XtSetArg(args[n],XmNmarginWidth, 5); n++; XtSetArg(args[n],XmNx, 5); n++; XtSetArg(args[n],XmNy, 5); n++; XtSetArg(args[n],XmNborderWidth, 5); n++; XtSetArg(args[n],XmNwidth, 90); n++; XtSetArg(args[n],XmNheight, 50); n++; simpleWidget = XmCreatePushButton(workRegion,"Widget", args, n); XtManageChild(simpleWidget); CommonPause(); /* move the child widget */ XmeConfigureObject(simpleWidget, 30, 30, 90, 50, 5); XtVaGetValues(simpleWidget, XmNx, &x, XmNy, &y, NULL); if (x != 30 || y !=30) printf("ERROR: incorrect position values\n"); CommonPause(); /* change the child widget's border */ XmeConfigureObject(simpleWidget, 30, 30, 90, 50, 25); XtVaGetValues(simpleWidget, XmNborderWidth, &border_width, NULL); if (border_width != 25) printf("ERROR: incorrect border value\n"); CommonPause(); /* change the size of the widget */ XmeConfigureObject(simpleWidget, 30, 30, 150, 100, 5); XtVaGetValues(simpleWidget, XmNheight, &height, XmNwidth, &width, NULL); if (width != 150 || height != 100) printf("ERROR: incorrect size values\n"); CommonPause(); /* Instantiate a PushButton gadget. */ XtDestroyWidget(simpleWidget); n = 0; XtSetArg(args[n],XmNrecomputeSize, False); n++; XtSetArg(args[n],XmNshadowThickness, 5); n++; XtSetArg(args[n],XmNmarginWidth, 5); n++; XtSetArg(args[n],XmNx, 5); n++; XtSetArg(args[n],XmNy, 5); n++; XtSetArg(args[n],XmNborderWidth, 5); n++; XtSetArg(args[n],XmNwidth, 90); n++; XtSetArg(args[n],XmNheight, 50); n++; simpleGadget = XmCreatePushButtonGadget(workRegion,"Gadget", args, n); XtManageChild(simpleGadget); CommonPause(); /* move the child gadget */ XmeConfigureObject(simpleGadget, 80, 30, 90, 50, 5); XtVaGetValues(simpleGadget, XmNx, &x, XmNy, &y, NULL); if (x != 80 || y !=30) printf("ERROR: incorrect position values\n"); CommonPause(); /* change the child gadget's border */ XmeConfigureObject(simpleGadget, 30, 30, 90, 50, 25); XtVaGetValues(simpleGadget, XmNborderWidth, &border_width, NULL); if (border_width != 25) printf("ERROR: incorrect border value: %d\n",border_width); CommonPause(); /* change the size of the gadget */ XmeConfigureObject(simpleGadget, 30, 30, 150, 100, 5); XtVaGetValues(simpleGadget, XmNheight, &height, XmNwidth, &width, NULL); if (width != 150 || height != 100) printf("ERROR: incorrect size values\n"); CommonPause(); CommonPause(); /* quit */ XtAppMainLoop(app_context); XtDestroyWidget(Shell1); }
/************************************************************************ * * * GeometryManager * * * ************************************************************************/ static XtGeometryResult GeometryManager( Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply ) { CompositeWidgetClass superclass = (CompositeWidgetClass) xmMainWindowClassRec.core_class.superclass ; XmMainWindowWidget mw = (XmMainWindowWidget ) w->core.parent; XtGeometryResult res; Dimension newWidth,newHeight, OldHeight; Dimension bw; XtWidgetGeometry parent_request ; XtWidgetGeometry desired, preferred; XtWidgetProc resize; CheckKids(mw); /**************** * * If it's not a mainwindow kid, let the scrolled window deal with it. * If it's from the workwindow, and the width changed, resize the menubar * and ask for a new height so my layout routine doesn't clip the workwindow. * ****************/ if (w != mw->mwindow.MenuBar && w != mw->mwindow.Message && w != mw->mwindow.CommandWindow && w != (Widget )mw->mwindow.Sep1 && w != (Widget) mw->mwindow.Sep2 && w != (Widget) mw->mwindow.Sep3) { /* this is the only case of geometry manager enveloping that I know of in Motif */ XtGeometryHandler geo_mgr; _XmProcessLock(); geo_mgr = superclass->composite_class.geometry_manager; _XmProcessUnlock(); res = (*geo_mgr)(w, request, reply); if (res == XtGeometryYes) { Widget mb = mw->mwindow.MenuBar; if ((w == mw->swindow.WorkWindow) && (request->request_mode & CWWidth) && mb && XtIsManaged(mb)) { desired.x = mb->core.x; desired.y = mb->core.y; desired.border_width = mb->core.border_width; desired.width = mw->core.width - (2 * mw->mwindow.margin_width); desired.height = mb->core.height; desired.request_mode = (CWWidth); XtQueryGeometry(mw->mwindow.MenuBar, &desired, &preferred); if (preferred.height != mb->core.height) { parent_request.request_mode = CWWidth | CWHeight; if (request->request_mode & XtCWQueryOnly) parent_request.request_mode |= XtCWQueryOnly; parent_request.width = mw->core.width ; parent_request.height = newHeight = mw->core.height - (mb->core.height - (2 * mb->core.border_width)) + preferred.height + (2 *preferred.border_width); if (XtMakeGeometryRequest((Widget) mw, &parent_request, NULL) == XtGeometryYes) { if (!(request->request_mode & XtCWQueryOnly)) XmeConfigureObject(mw->mwindow.MenuBar, mb->core.x, mb->core.y, preferred.width, preferred.height, preferred.border_width); else return XtGeometryYes ; } } } _XmProcessLock(); resize = XtCoreProc(mw, resize); _XmProcessUnlock(); (*resize)((Widget)mw) ; } return(res); } /** Disallow any X or Y changes for MainW children **/ if ((request -> request_mode & CWX || request -> request_mode & CWY)) return(XtGeometryNo); if(request->request_mode & CWBorderWidth) bw = request->border_width; else bw = w->core.border_width; if (request->request_mode & CWWidth) newWidth = request->width + 2 * (bw + mw->mwindow.margin_width); else newWidth = mw->core.width ; /* grow only in width */ if (newWidth <= mw->core.width) newWidth = mw->core.width; /**************** * * Margins are already included in the old width & height * ****************/ if(request->request_mode & CWHeight) newHeight = mw->core.height - (w->core.height - (2 * w->core.border_width)) + request->height + 2 * bw; else newHeight = mw->core.height; OldHeight = mw->core.height; parent_request.request_mode = CWWidth | CWHeight; if (request->request_mode & XtCWQueryOnly) parent_request.request_mode |= XtCWQueryOnly; parent_request.width = newWidth ; parent_request.height = newHeight; res = XtMakeGeometryRequest((Widget) mw, &parent_request, NULL) ; if (res == XtGeometryYes) { if (!(request->request_mode & XtCWQueryOnly)) { if(request->request_mode & CWWidth) w->core.width = request->width; if(request->request_mode & CWHeight) w->core.height = request->height; mw->swindow.YOffset = mw->swindow.YOffset + (newHeight - OldHeight); _XmProcessLock(); resize = XtCoreProc(mw, resize); _XmProcessUnlock(); (*resize) ((Widget)mw) ; } } return(res); }
/************************************************************************ * * * Layout - Layout the main window. * * * * * ************************************************************************/ static void Layout( XmMainWindowWidget mw ) { Position mbx,mby, cwx,cwy, swy, mwx, mwy, sepy, sep2y = 0; Dimension mbwidth, mbheight, cwwidth= 0, cwheight; Dimension MyXpad, MyYpad, mwwidth, mwheight; Dimension bw = 0, sep2h, sep3h; XtWidgetGeometry desired, preferred; int tmp ; /* used for checking negative Dimension value */ CheckKids(mw); /**************** * * Query the kids - and we have definite preferences as to their sizes. * The Menubar gets top billing - we tell it it how wide it is going to be , * and let it have whatever height it wants. The command box gets to stay * it's current height, but has to go to the new width. The scrolled window * gets the leftovers. * ****************/ MyXpad = mw->mwindow.margin_width; MyYpad = mw->mwindow.margin_height; mw->swindow.XOffset = MyXpad; mw->swindow.YOffset = MyYpad; mw->swindow.HeightPad = mw->mwindow.margin_height; mw->swindow.WidthPad = mw->mwindow.margin_width; cwx = MyXpad; cwy = swy = MyYpad; mw->mwindow.ManagingSep = True; if (ExistManaged(mw->mwindow.MenuBar)) { bw = mw->mwindow.MenuBar->core.border_width; mbx = MyXpad; mby = MyYpad; tmp = mw->core.width - (2 * (MyXpad + bw)); if (tmp <= 0) mbwidth = 10; else mbwidth = tmp ; mbheight = mw->mwindow.MenuBar->core.height; desired.x = mbx; desired.y = mby; desired.border_width = bw; desired.width = mbwidth; desired.height = mbheight; desired.request_mode = (CWWidth); if (XtQueryGeometry(mw->mwindow.MenuBar, &desired, &preferred) != XtGeometryYes) { bw = preferred.border_width; mbheight = preferred.height; } XmeConfigureObject(mw->mwindow.MenuBar, mbx, mby, mbwidth, mbheight,bw); if (mw->mwindow.ShowSep) { XtManageChild((Widget) mw->mwindow.Sep1); XmeConfigureObject( (Widget) mw->mwindow.Sep1, 0, mby + mbheight + (2 * bw), mw->core.width, mw->mwindow.Sep1->rectangle.height, 0); cwy = swy = mw->mwindow.Sep1->rectangle.y + mw->mwindow.Sep1->rectangle.height ; } else { XtUnmanageChild((Widget) mw->mwindow.Sep1); cwy = swy = mby + mbheight + (2 * bw); } } else { XtUnmanageChild((Widget) mw->mwindow.Sep1); } if (ExistManaged(mw->mwindow.CommandWindow)) { bw = mw->mwindow.CommandWindow->core.border_width; tmp = mw->core.width - (2 * (MyXpad + bw)); if (tmp <= 0) cwwidth = 10; else cwwidth = tmp ; cwheight = mw->mwindow.CommandWindow->core.height; desired.x = cwx; desired.y = cwy; desired.border_width = bw; desired.width = cwwidth; desired.height = cwheight; desired.request_mode = (CWWidth); if (XtQueryGeometry(mw->mwindow.CommandWindow, &desired, &preferred) != XtGeometryYes) { bw = preferred.border_width; cwheight = preferred.height; } if ((cwheight + cwy + (2 * bw)) > (mw->core.height - MyYpad)) { tmp = mw->core.height - (2 * bw) - MyYpad - cwy; if (tmp <= 0) cwheight = 10 ; else cwheight = tmp; } if (mw->mwindow.ShowSep) sep2h = mw->mwindow.Sep2->rectangle.height; else sep2h = 0; sep2y = (cwy + cwheight) + 2 * bw; swy = sep2y + sep2h ; if (mw->mwindow.CommandLoc == XmCOMMAND_BELOW_WORKSPACE) { mby = swy; sep2y = cwy + (mw->core.height - swy - MyYpad); swy = cwy; mw->swindow.HeightPad = sep2h + cwheight + mw->mwindow.margin_height; if (mw->mwindow.ShowSep) cwy = sep2y + mw->mwindow.Sep2->rectangle.height; else cwy = sep2y; } } else { XtUnmanageChild((Widget) mw->mwindow.Sep2); sep2h = 0; cwheight = 0; } if (ExistManaged(mw->mwindow.Message)) { bw = mw->mwindow.Message->core.border_width; mwx = MyXpad; tmp = mw->core.width - (2 * (MyXpad + bw)); if (tmp <= 0) mwwidth = 10 ; else mwwidth = tmp ; mwheight = mw->mwindow.Message->core.height; desired.x = mwx; desired.y = swy; desired.border_width = bw; desired.width = mwwidth; desired.height = mwheight; desired.request_mode = (CWWidth); if (XtQueryGeometry(mw->mwindow.Message, &desired, &preferred) != XtGeometryYes) { bw = preferred.border_width; mwheight = preferred.height; } if (mw->mwindow.ShowSep) sep3h = mw->mwindow.Sep3->rectangle.height; else sep3h = 0; sepy = mw->core.height - mwheight - (2 * bw) - mw->mwindow.margin_height - sep3h; mwy = sepy + sep3h; if (mw->mwindow.CommandLoc == XmCOMMAND_BELOW_WORKSPACE) { mw->swindow.HeightPad = sep2h + cwheight + sep3h + mwheight + mw->mwindow.margin_height; sep2y -= (sep3h + mwheight); cwy -= (sep3h + mwheight); } else mw->swindow.HeightPad = sep3h + mwheight + mw->mwindow.margin_height; XmeConfigureObject(mw->mwindow.Message, mwx, mwy, mwwidth, mwheight, bw); if (mw->mwindow.ShowSep) { XtManageChild((Widget) mw->mwindow.Sep3); XmeConfigureObject( (Widget) mw->mwindow.Sep3, 0, sepy, mw->core.width, mw->mwindow.Sep3->rectangle.height, 0); } else XtUnmanageChild((Widget) mw->mwindow.Sep3); } else { XtUnmanageChild((Widget) mw->mwindow.Sep3); } if (ExistManaged(mw->mwindow.CommandWindow)) { XmeConfigureObject( mw->mwindow.CommandWindow, cwx, cwy, cwwidth, cwheight, bw); if (mw->mwindow.ShowSep) { XtManageChild((Widget) mw->mwindow.Sep2); XmeConfigureObject((Widget) mw->mwindow.Sep2, 0, sep2y, mw->core.width, mw->mwindow.Sep2->rectangle.height, 0); } else XtUnmanageChild((Widget) mw->mwindow.Sep2); } mw->swindow.YOffset = swy; mw->mwindow.ManagingSep = False; }