📄 buttonbox.c
字号:
PlaceChildren( Widget bbw, Dimension wd, Dimension ht){ int i; int rows = 1, cols = 1; int xoff, yoff; int r, c; int num; Dimension usedWd, usedHt; Dimension *rowSizes, *colSizes; int count = ManagedChildCount(bbw); Boolean found = False; if ( debuglev > 2 ) printf("ButtonBox(%s):PlaceChildren with size %d by %d\n", XtName(bbw), wd, ht); if ( BB_orient(bbw) == XmHORIZONTAL ) {/* * Increase the number of rows until we have a fit */ for (rows=1; !found && rows <= count; ) { cols = count / rows; if ( count % rows > 0 ) cols++; found = TrySize(bbw, rows, cols, &wd, &ht); if ( !found ) rows++; } if ( !found ) { rows = 1; cols = count; } } /* End if horizontal */ else { /* vertical *//* * Increase the number of columns until we have a fit */ for (cols=1; !found && cols <= count; ) { rows = count / cols; if ( count % cols > 0 ) rows++; found = TrySize(bbw, rows, cols, &wd, &ht); if ( !found ) cols++; } if ( !found ) { rows = count; cols = 1; } } /* End if height is fixed *//* * Calculate the size of each row and column */ rowSizes = (Dimension*)XtMalloc(rows*sizeof(Dimension)); colSizes = (Dimension*)XtMalloc(cols*sizeof(Dimension)); GetCellSizes(bbw, rows, cols, rowSizes, colSizes);/* * Calculate the space used by the buttons */ usedWd = BB_colSpacing(bbw) * (cols-1); usedHt = BB_rowSpacing(bbw) * (rows-1); for (c=0; c<cols; c++) usedWd += colSizes[c]; for (r=0; r<rows; r++) usedHt += rowSizes[r];/* * Calculate the left and top offset required to get the desired alignment */ if ( BB_colAlignment(bbw) == XmALIGNMENT_BEGINNING ) xoff = BB_marginWd(bbw); else if ( BB_colAlignment(bbw) == XmALIGNMENT_END ) xoff = wd - usedWd - BB_marginWd(bbw); else /* Centered */ xoff = (int)(wd - usedWd) / (int)2; if ( BB_rowAlignment(bbw) == XmALIGNMENT_BEGINNING ) yoff = BB_marginHt(bbw); else if ( BB_rowAlignment(bbw) == XmALIGNMENT_END ) yoff = ht - usedHt - BB_marginHt(bbw); else /* Centered */ yoff = (int)(ht - usedHt) / (int)2;/* * Loop through widgets */ count = BB_numChildren(bbw); num = 0; for (i=0; i<count; i++) { int row, col; int r, c; Dimension *rowSize, *colSize; Position x, y; Widget w; w = BB_children(bbw)[i]; if ( !XtIsManaged(w) ) continue;/* * Calculate row and column number */ if ( BB_orient(bbw) == XmHORIZONTAL ) { col = num % cols; row = num / cols; } else { row = num % rows; col = num / rows; }/* * Calculate x position of child */ x = xoff; for (c=0; c<col; c++) { x += colSizes[c]; x += BB_colSpacing(bbw); }/* * Calculate y position of child */ y = yoff; for (r=0; r<row; r++) { y += rowSizes[r]; y += BB_rowSpacing(bbw); }/* * Set child geometry */ XmDropSiteStartUpdate(w); XtConfigureWidget(w, x, y, colSizes[col], rowSizes[row], XtBorderWidth(w)); XmDropSiteEndUpdate(w); num++; } /* End for each child */ BB_lastWd(bbw) = wd; BB_lastHt(bbw) = ht;/* * Return allocated memory */ XtFree((char*)rowSizes); XtFree((char*)colSizes);} /* End PlaceChildren *//*----------------------------------------------------------------------- * Function to initialize child constraint settings */static voidConstraintInitialize( Widget wreq, Widget wnew, ArgList argv, Cardinal *argc){ BB_wasManaged(wnew) = False; BB_prefWd(wnew) = 10; BB_prefHt(wnew) = 10; BB_acceptGeo(wnew) = False;}/*----------------------------------------------------------------------- * Function to modify child constraint settings */static BooleanConstraintSetValues( Widget wold, Widget wreq, Widget wnew, ArgList argv, Cardinal *argc){ int oldIndex = BB_posIndex(wold); int newIndex = BB_posIndex(wnew); if ( oldIndex != newIndex ) { int inc, i; Widget tmp; Widget bbw = XtParent(wnew); if ( newIndex == XmLAST_POSITION || newIndex < 1 || newIndex >= BB_numChildren(bbw) ) { newIndex = BB_numChildren(bbw); } oldIndex--; newIndex--;/* * Move the widget from its old position to its new one. Shift all other * widgets accordingly */ tmp = BB_children(bbw)[oldIndex]; inc = (newIndex < oldIndex) ? -1 : 1; for (i = oldIndex; i != newIndex; i += inc) { Widget cnew = BB_children(bbw)[i+inc]; BB_children(bbw)[i] = cnew; BB_posIndex(cnew) = i+1; } BB_children(bbw)[newIndex] = tmp; BB_posIndex(wnew) = newIndex+1; if ( XtIsManaged(wnew) ) {/* * Save geometry in case it changes */ XtWidgetGeometry geo; geo.x = XtX(wnew); geo.y = XtY(wnew); geo.width = XtWidth(wnew); geo.height = XtHeight(wnew);/* * Update the display */ if ( BB_exposed(bbw) ) Refresh(bbw);/* * Request a redisplay if the geometry has changed */ if ( geo.x != XtX(wnew) || geo.y != XtY(wnew) || geo.width != XtWidth(wnew) || geo.height != XtHeight(wnew) ) { BB_acceptGeo(wnew) = True; return True; } } /* End if child is managed */ } /* End if position index has changed */ return False; /* Don't need redisplay */} /* End ConstraintSetValues *//*--------------------------------------------------------------- * Handle child geometry requests */static XtGeometryResultGeometryManager( Widget w, XtWidgetGeometry *req, XtWidgetGeometry *reply){ Widget bbw = XtParent(w);/* * Accept the size change */ if ( (req->request_mode & CWX) && (req->x >= 0) ) w->core.x = req->x; if ( (req->request_mode & CWY) && (req->y >= 0) ) w->core.y = req->y; if ( (req->request_mode & CWWidth) && (req->width > 0) ) w->core.width = req->width; if ( (req->request_mode & CWHeight) && (req->height > 0) ) w->core.height = req->height;/* * First treat the special case resulting from a change in positionIndex */ if ( BB_acceptGeo(w) ) { /* set in ConstraintSetValues */ BB_acceptGeo(w) = False; return XtGeometryYes; }/* * Calculate the positions and sizes again */ if ( BB_exposed(bbw) ) Refresh(bbw); return XtGeometryYes;} /* End GeometryManager *//*--------------------------------------------------------------- * Someone wants to know how big we want to be. */static XtGeometryResultQueryGeometry( Widget bbw, XtWidgetGeometry *ask, XtWidgetGeometry *answer){ Dimension wd, ht; Boolean acceptWd, acceptHt; GetPreferredSize(bbw, &wd, &ht); answer->width = wd; answer->height = ht; answer->request_mode = 0; if ( BB_resizeWidth(bbw) ) answer->request_mode |= CWWidth; if ( BB_resizeHeight(bbw) ) answer->request_mode |= CWHeight; if ( ask->request_mode & CWWidth ) acceptWd = (ask->width == answer->width); else acceptWd = True; if ( ask->request_mode & CWHeight ) acceptHt = (ask->height == answer->height); else acceptHt = True; if ( acceptWd && acceptHt ) return XtGeometryYes; if ( (!acceptWd && !acceptHt) || (answer->width == XtWidth(bbw) && answer->height == XtWidth(bbw)) ) return XtGeometryNo; return XtGeometryAlmost;} /* End QueryGeometry *//*--------------------------------------------------------------- * Process the first exposure */static voidHandleExpose( Widget bbw, XEvent *ev, Region reg){ if ( !BB_exposed(bbw) ) { Refresh(bbw); BB_exposed(bbw) = True; }}/*--------------------------------------------------------------- * Do resize in a timer proc so that we can adjust our non-fixed axis */static voidFinishResize( XtPointer data, XtIntervalId *id){ ButtonBoxCallbackStruct cb; Widget bbw = (Widget)data; BB_resizeTimer(bbw) = 0; Refresh(bbw); cb.reason = XmCR_RESIZE; cb.event = NULL; cb.window = XtWindow(bbw); XtCallCallbackList(bbw, BB_resizeCallback(bbw), &cb); return;}/*--------------------------------------------------------------- * Our size has changed */static voidResize( Widget bbw){ if ( debuglev > 2 ) printf("ButtonBox(%s):Resize\n", XtName(bbw));/* * Handle the resize in a timer proc so we can adjust our non-constrained * axis. */ if ( (XtWidth(bbw) != BB_lastWd(bbw) || XtHeight(bbw) != BB_lastHt(bbw)) && !BB_resizeTimer(bbw) ) BB_resizeTimer(bbw) = XtAppAddTimeOut(XtWidgetToApplicationContext(bbw), 0, FinishResize, (XtPointer)bbw);} /* End Resize *//*--------------------------------------------------------------- * Check for changes. Ask for expose event if necessary. */static BooleanSetValues( Widget wold, /* Values before call */ Widget wreq, /* Values user requested */ Widget wnew, /* Values after base class processing */ ArgList argv, Cardinal *argc){ Boolean redraw; if ( XtWidth (wreq) == 0 ) XtWidth(wnew) = XtWidth(wold); if ( XtHeight(wreq) == 0 ) XtHeight(wnew) = XtHeight(wold);/* * If the size has changed, call the Resize function. Any other changes * will get picked up at this time. */ if ( XtWidth(wnew) != XtWidth(wold) || XtWidth(wnew) != XtWidth(wold) ) { Resize(wnew); return False; }/* * If there is any other type of change, ask for a redisplay. */ redraw = (BB_marginWd(wnew) != BB_marginWd(wold) || BB_marginHt(wnew) != BB_marginWd(wold) || BB_resizeWidth(wnew) != BB_resizeWidth(wold) || BB_resizeHeight(wnew) != BB_resizeHeight(wold) || BB_rowAlignment(wnew) != BB_rowAlignment(wold) || BB_colAlignment(wnew) != BB_colAlignment(wold) || BB_orient(wnew) != BB_orient(wold) || BB_uniformRows(wnew) != BB_uniformRows(wold) || BB_uniformCols(wnew) != BB_uniformCols(wold) || BB_rowSpacing(wnew) != BB_rowSpacing(wold) || BB_colSpacing(wnew) != BB_colSpacing(wold)); if ( redraw ) BB_exposed(wnew) = False; /* So HandleExpose will process this one */ return redraw;} /* End SetValues *//*--------------------------------------------------------------- * Convenience function to create a ButtonBox widget */WidgetCreateButtonBox( Widget par, String name, ArgList argv, Cardinal argc){ return XtCreateWidget(name, buttonBoxWidgetClass, par, argv, argc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -