|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ C T ┃
Length: 35073 (0x8901) Types: TextFile Names: »CheckBox.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z« └─⟦2109abc41⟧ └─ ⟦this⟧ »./X.V10R4/Toolkit/Xr/src/Xrlib/Editor/CheckBox.c«
/* * $Source: /u1/Xr/src/Xrlib/Editor/RCS/CheckBox.c,v $ * $Header: CheckBox.c,v 1.1 86/12/17 08:59:21 swick Exp $ */ #ifndef lint static char *rcsid_CheckBox_c = "$Header: CheckBox.c,v 1.1 86/12/17 08:59:21 swick Exp $"; #endif lint #include <Xr/xr-copyright.h> /* $Header: CheckBox.c,v 1.1 86/12/17 08:59:21 swick Exp $ */ /* Copyright 1986, Hewlett-Packard Company */ /* Copyright 1986, Massachussetts Institute of Technology */ static char rcsid[] = "$Header: CheckBox.c,v 1.1 86/12/17 08:59:21 swick Exp $"; /*************************************<+>************************************* ***************************************************************************** ** ** File: CheckBox.c ** ** Project: X-ray Toolbox ** ** Description: ** Source code for the X-ray CheckBox field editor. ** ** ** ------------------------ MODIFICATION RECORD ------------------------ * * $Log: CheckBox.c,v $ * Revision 1.1 86/12/17 08:59:21 swick * Initial revision * * Revision 7.0 86/11/13 08:20:10 08:20:10 fred () * Final QA Release * * Revision 6.0 86/11/10 15:23:09 15:23:09 fred () * QA #2 release * * Revision 5.2 86/11/07 14:18:00 14:18:00 fred () * Added new copyright message. * * Revision 5.1 86/10/30 13:22:00 13:22:00 fred () * Added a check for numCols = 0. * * Revision 5.0 86/10/28 08:25:08 08:25:08 fred () * QA #1.1 release * * Revision 4.1 86/10/22 10:05:21 10:05:21 fred () * Filled in the procedure headers. * * Revision 4.0 86/10/20 12:04:42 12:04:42 fred () * QA #1 release * * Revision 3.4 86/10/16 09:13:00 09:13:00 fred () * Performance enhanced: added use of register variables. * * Revision 3.3 86/10/13 10:04:47 10:04:47 fred () * Added use of the default tile, if needed. * * Revision 3.2 86/10/09 07:43:27 07:43:27 fred () * Added default color check to create routine. * * Revision 3.1 86/10/07 16:03:43 16:03:43 fred () * Added check for invalid rectangle size * * Revision 3.0 86/10/02 15:57:24 15:57:24 fred () * Alpha release set to 3.0 * * Revision 2.3 86/10/01 06:53:33 06:53:33 fred () * Changed default label padding from font's maxWidth to avgWidth. * * Revision 2.2 86/09/22 13:09:43 13:09:43 fred () * Added calls to XrEditorGroup(). * * Revision 2.1 86/09/19 07:08:12 07:08:12 fred () * Added a check for XrVISIBLE before doing any drawing. * * Revision 2.0 86/09/16 08:01:58 08:01:58 fred () * Updated the input processing routine to match new select strategy. * * Revision 1.4 86/09/16 05:44:15 05:44:15 fred () * Modified to swallow a select up event. * * Revision 1.3 86/09/10 07:24:50 07:24:50 fred () * Changed numRows to numCols in all data structures. * * Revision 1.2 86/09/09 13:06:40 13:06:40 fred () * Changed some variables from INT32 to INT16 * * Revision 1.1 86/09/03 13:55:43 13:55:43 fred () * Initial revision * * ***************************************************************************** *************************************<+>*************************************/ #include <X/Xlib.h> #include <Xr/defs.h> #include <Xr/types.h> #include <Xr/in_types.h> extern INT32 createCBoxes(); extern INT32 drawCBoxes(); extern INT32 processCBoxes(); extern INT32 cbFreeMemory(); extern INT32 calcComponents(); \f /*************************************<->************************************* * * xrEditor * * XrCheckBox (checkBox, message, data) * * xrEditor * checkBoxr; * INT32 message; * INT8 * data; * * Description: * ----------- * This is the main entry point an dmessage handler for the checkbox * field editor. It takes all message requests, and passes them * onto the appropriate handler; invalid messages will fail and * return an error. * * * Inputs: * ------ * checkBox = For all messages but MSG_NEW and MSG_SIZE, this contains * the instance pointer. * * message = This indicates which action the editor should perform. * * data = This is the message specific data. It's usage depends upon * the 'message' parameter, and may be a scalar or a pointer. * * Outputs: * ------- * Upon successful completion of a command, the instance pointer * is returned; additional information may be returned by * means of the 'data' parameter. * * Upon failure, NULL is returned, and xrErrno is set. * * Procedures Called * ----------------- * _MsgNew() [MsgCommon.c] * _MsgFree() [MsgCommon.c] * _MsgGetState() [MsgCommon.c] * _MsgSetState() [MsgCommon.c] * _MsgRedraw() [MsgCommon.c] * _MsgEdit() [MsgCommon.c] * _MsgSize() [MsgItem.c] * _MsgGetItemStates() [MsgItem.c] * _MsgSetItemStates() [MsgItem.c] * _MsgGetItemCount() [MsgItem.c] * _MsgGetItemRects() [MsgItem.c] * _MsgMove() [MsgItem.c] * XrCopyRect() [calc.c] * _XrMakeInvisible() [editorUtil.c] * XrEditorGroup() [group.c] * createCBoxes() * drawCBoxes() * *************************************<->***********************************/ xrEditor * XrCheckBox (checkBox, message, data) register xrEditor * checkBox; INT32 message; INT8 * data; { /* Determine the action being requested */ switch (message) { case MSG_NEW: { /* * Create a new instance of the checkbox editor. * The only parameter of interest is the 'data' parameter, * which is a pointer to a filled instance of the * 'xrCheckBoxInfo' structure. */ return ((xrEditor *)_MsgNew (checkBox, data, sizeof(xrCheckBoxData), createCBoxes, drawCBoxes, cbFreeMemory, XrCheckBox, XrALLBUTTONS)); } case MSG_FREE: { /* * Destroy the specified checkbox instance. * The 'checkBox' parameter specifies the instance to * be destroyed; the 'data' parameter is unused. */ return ((xrEditor *) _MsgFree (checkBox, cbFreeMemory)); } case MSG_GETSTATE: { /* * Return the settings of the state flags for the * specified checkbox instance. The 'checkBox' * parameter specifies the instance to be queried, * while the 'data' parameter must point to an INT8 * value, into which the state flags will be placed. */ return ((xrEditor *) _MsgGetState (checkBox, data)); } case MSG_SETSTATE: { /* * Change the state flag settings for the specified * instance. The 'checkBox' parameter specifies the * instance to be modified, and the 'data' parameter is * interpreted as an INT8 value, containing the new state * flag settings. */ return ((xrEditor *) _MsgSetState (checkBox, data, drawCBoxes, XrALLBUTTONS)); } case MSG_GETITEMSTATES: { /* * Return the state flags for the individual checkboxes. The * 'checkBox' parameter specifies the instance to be queried, * while the 'data' parameter must point to an array of INT8 * values, into which the state flags will be returned. */ return ((xrEditor *)_MsgGetItemStates(checkBox, data)); } case MSG_SETITEMSTATES: { /* * Set the individual checkbox states; redraw only those * whose state has then changed. The 'checkBox' parameter * specifies the instance to be modified, while the 'data' * parameter points to an array of INT8 values, containing * the new state flags. */ return ((xrEditor *) _MsgSetItemStates (checkBox, data, drawCBoxes)); } case MSG_GETITEMCOUNT: { /* * Return the number of checkboxes in the specified instance. * The 'checkBox' parameter specifies the instance to be * queried, while the 'data' parameter must point to an INT32 * value, into which the item count will be placed. */ return ((xrEditor *) _MsgGetItemCount (checkBox, data)); } case MSG_GETITEMRECTS: { /* * Fill the array passed in by the application, with the * rectangle information describing each checkbox in * the specified instance. The 'checkbox' parameter * indicates the instance to be queried, while the 'data' * parameter must point to an array of RECTANGLE structures, * into which the individual button rectangles will be placed. */ return ((xrEditor *) _MsgGetItemRects (checkBox, data)); } case MSG_SIZE: { /* * Return the size of the rectangle needed to enclose * an instance of this editor, using the specifications * passed in by the application program. The 'data' * parameter must point to a partially filled out * instance of the 'xrCheckBoxInfo' structure; upon completion, * the 'editorRect' field of the 'info' structure will * be filled. */ return ((xrEditor *) _MsgSize (data, calcComponents)); } case MSG_MOVE: { /* * Relocate an instance of checkboxes to a new location. * The 'checkBox' parameter specifies the instance to be * moved, while the 'data' parameter must point to a POINT * structure, containing the new editor rectangle origin. */ return ((xrEditor *) _MsgMove (checkBox, data, drawCBoxes)); } case MSG_RESIZE: { /* * Resize an existing instance of checkboxes. * The 'checkBox' parameter indicates the instance to be * resized, while the 'data' parameter must point to a * RECTANGLE structure, containing the new editor rectangle * definition. */ RECTANGLE workRect; xrCheckBoxInfo cbInfo; register xrCheckBoxData * cbDataPtr; register xrCheckBoxInfo * cbInfoPtr; if (checkBox == NULL) { xrErrno = XrINVALIDID; return ((xrEditor *) NULL); } else if (data == NULL) { xrErrno = XrINVALIDPTR; return ((xrEditor *) NULL); } /* Create a pseudo Info structure */ cbDataPtr = (xrCheckBoxData *) checkBox->editorData; XrCopyRect (&checkBox->editorRect, &workRect); cbInfoPtr = &cbInfo; XrCopyRect ((RECTANGLE *) data, &cbInfoPtr->editorRect); cbInfoPtr->editorFont = cbDataPtr->cbFont.fontInfo; cbInfoPtr->numFields = cbDataPtr->cbNumFields; cbInfoPtr->numCols = cbDataPtr->cbNumCols; cbInfoPtr->labels = cbDataPtr->cbLabels; if (createCBoxes (cbDataPtr, cbInfoPtr, MSG_RESIZE) == FALSE) return ((xrEditor *) NULL); XrCopyRect (&cbInfoPtr->editorRect, &checkBox->editorRect); if (checkBox->editorState & XrVISIBLE) { /* Remove the instance from the window */ _XrMakeInvisible (checkBox->editorWindowId, &workRect, TRUE); /* Redisplay the instance */ drawCBoxes (checkBox, XrALLBUTTONS); } /* Force the editor group rectangle to be recalculated */ XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, checkBox); return (checkBox); } case MSG_REDRAW: { /* * Redraw a checkbox instance. * The 'checkBox' parameter specifies the instance to redraw, * while the 'data' parameter is interpreted as an INT32 value, * specifying the type of redraw to perform. */ return ((xrEditor *) _MsgRedraw (checkBox, data, drawCBoxes, XrALLBUTTONS)); } case MSG_EDIT: { /* * Process the incoming keystroke, and generate a return * keystroke, to indicate to the application program * how the editor instance was modified. the 'data' * parameter must point to the event to be processed. */ return ((xrEditor *) _MsgEdit (checkBox, data, processCBoxes, XrCHECKBOX)); } default: /* All other commands are invalid */ xrErrno = XrINVALIDMSG; return ((xrEditor *)NULL); } /* end of switch */ } /* end of XrCheckBox() */ \f /*************************************<->************************************* * * INT32 * cbFreeMemory (cbDataPtr) * * xrCheckBoxData * cbDataPtr; * * Description: * ----------- * This routine is called both when an existing instance is freed, * and when a MSG_NEW request fails after createCBoxes() has been * called. It will free up all resources which createCBoxes() * allocated for the instance. * * * Inputs: * ------ * cbDataPtr = Points to the instance's internal 'data' structure. * * Outputs: * ------- * * Procedures Called * ----------------- * XFreePixmap() [libX.a] * *************************************<->***********************************/ static INT32 cbFreeMemory (cbDataPtr) xrCheckBoxData * cbDataPtr; { if (cbDataPtr->cbTileId != xrDefaultTile) XFreePixmap (cbDataPtr->cbTileId); (*xrFree) (cbDataPtr->cbFields); } \f /*************************************<->************************************* * * INT32 * calcComponents (cbInfoPtr, fields, cmd) * * xrCheckBoxInfo * cbInfoPtr; * XrItemData * fields; * INT32 cmd; * * Description: * ----------- * If the 'cmd' parameter is set to MSG_SIZE, then this routine will * calculate the size of the editor rectangle needed to contain the * instance described by the structure pointed to by 'cbInfoPtr'; the * editor rectangle information is returned in the 'editorRect' field * within the structure pointed to by the 'cbInfoPtr' parameter. * If the 'cmd' parameter is set to any other value, then this routine * will calculate the location and size of each checkbox rectangle * and corresponding checkbox label; this information is then stored * in the structure pointed to by the 'fields' parameter. * * * Inputs: * ------ * cbInfoPtr = Points to an instance of the checkbox 'info' structure, * which describes the instance being sized or created. * * fields = This must point to an array of structures, which will be * used to store temporary information, if 'cmd' is set to * MSG_SIZE, or will be used to store the component information, * if 'cmd' is set to MSG_NEW. * * cmd = This indicates whether just the size of the editor rectangle * needs to be calculated (MSG_SIZE), or whether the size and * location of each component must be calculated (MSG_NEW). * * Outputs: * ------- * Upon successful completion, TRUE is returned, along with some * additional information in either the 'cbInfoPtr' structure, * or the 'fields' structure. * * Upon failure, FALSE is returned, and xrErrno is set. * * Procedures Called * ----------------- * _XrTextInfo() [textUtil.c] * XrStringWidth() [utilities.c] * XrCopyRect() [calc.c] * XrSetRect() [calc.c] * XrSetPt() [calc.c] * *************************************<->***********************************/ static INT32 calcComponents (cbInfoPtr, fields, cmd) register xrCheckBoxInfo * cbInfoPtr; register xrItemData * fields; INT32 cmd; { INT16 numFields = cbInfoPtr->numFields; INT16 numCols = cbInfoPtr->numCols; INT16 numRows; RECTANGLE * rectPtr = &(cbInfoPtr->editorRect); FontInfo * fontPtr; xrTextInfo fontData; register INT16 i, col; INT16 hPadding, vPadding; INT16 xPos, yPos; INT16 itemWidth, maxItemWidth; INT16 heightMin, widthMin; INT16 lineHt; /* Check for invalid dimensions */ if ((numFields < numCols) || (numFields <= 0) || (numCols <= 0)) { xrErrno = XrINVALIDPARM; return (FALSE); } /* Initialize variables we'll need for our calculations */ numRows = (numFields + numCols - 1) / numCols; fontPtr = cbInfoPtr->editorFont ? cbInfoPtr->editorFont : xrBaseFontInfo; _XrTextInfo (fontPtr, &fontData); lineHt = fontData.ascent + fontData.descent; rectPtr = &(cbInfoPtr->editorRect); /* * Determine the preliminary size of the instance. This is done by * using the following formulae: * * height = number of Rows * height of a line * width = Sum of longest item in each column * * An item in a column is composed of a checkbox, some padding, * and an optional label. */ heightMin = numRows * lineHt; for (widthMin = 0, col = 0; col < numCols; col++) { /* Keep track of longest item in each column */ maxItemWidth = 0; /* Calculate the width of each item in the column */ for (i = col; i < numFields; i += numCols) { /* Take into account the size of the checkbox */ itemWidth = lineHt; /* Include the label and padding, if a label is defined */ if ((cbInfoPtr->labels) && (cbInfoPtr->labels[i])) itemWidth += fontData.avgWidth + XrStringWidth (fontData.fontInfo, cbInfoPtr->labels[i], XrNULLTERMINATED, 0, 0); /* See if this is the longest item encountered in the column */ if (itemWidth > maxItemWidth) maxItemWidth = itemWidth; } /* Keep a running total of all the column width */ widthMin += maxItemWidth; } /* * If this is being done in response to a MSG_SIZE request, then * take the height and width values calculated above, and add some * default padding values between each row and column; then return * the rectangle definition. The following padding values are used: * * hPadding = 2 * font leading vPadding = font leading */ if (cmd == MSG_SIZE) { /* Add the default padding */ XrCopyRect (&xrZeroRect, rectPtr); rectPtr->height = heightMin + (numRows - 1) * fontData.leading; rectPtr->width = widthMin + (numCols - 1) * (fontData.leading << 1); return (TRUE); } /* If the rectangle passed in by the application is larger than the * preliminary rectangle calculated above, then use this extra space * as padding between the row and column items. */ hPadding = (rectPtr->width - widthMin)/((numCols == 1) ? 1 : (numCols - 1)); vPadding = (rectPtr->height - heightMin)/((numRows == 1) ? 1:(numRows - 1)); /* Now, we can calculate the rectangle definition for each checkbox */ for (xPos = rectPtr->x, col = 0; col < numCols; col++) { maxItemWidth = 0; yPos = rectPtr->y; for (i = col; i < numFields; i += numCols) { /* Keep track of the longest item in a column */ itemWidth = lineHt; if ((cbInfoPtr->labels) && (cbInfoPtr->labels[i])) itemWidth += fontData.avgWidth + XrStringWidth (fontData.fontInfo, cbInfoPtr->labels[i], XrNULLTERMINATED, 0, 0); if (itemWidth > maxItemWidth) maxItemWidth = itemWidth; /* Set the rectangle describing the complete checkbox */ XrSetRect (&((fields+i)->subRectangle), xPos, yPos, itemWidth, lineHt); /* Set the rectangle describing just the checkbox; no label */ XrSetRect (&((fields+i)->rectangle), xPos, yPos, lineHt, lineHt); /* Set the point describing where the label is displayed */ XrSetPt (&((fields+i)->labelPt), xPos + lineHt + fontData.avgWidth, yPos); /* Increment for the next checkbox in the column */ yPos += lineHt + vPadding; } /* Increment for the start of the next column */ xPos += maxItemWidth + hPadding; } return (TRUE); } \f /*************************************<->************************************* * * INT32 * createCBoxes (cbDataPtr, cbInfoPtr, message) * * xrCheckBoxData * cbDataPtr; * xrCheckBoxInfo * cbInfoPtr; * INT32 message; * * Description: * ----------- * if (message == MSG_NEW) * This routine is responsible for creating a new checkbox instance. * The description of the new instance is contained within the structure * pointed to by the 'cbInfoPtr' parameter. Besides allocating the * resources needed for the new instance, this routine will also fill * in the structure pointed to by the 'cbDataPtr' parameter with the * state information for the new instance. * * if (message == MSG_RESIZE) * This routine will take the information contained within the 'cbInfoPtr' * structure, and will recalculate the location of each component within * an existing instance of checkboxes, to match the new data. This * will do no resource allocation. * * * Inputs: * ------ * cbDataPtr = Points to the 'data' structure for the instance being * created or resized. * * cbInfoPtr = Points to the 'info' structure, which describes how * the instance is to be laid out. * * message = This can be set to MSG_NEW or MSG_RESIZE. * * Outputs: * ------- * Upon successful completion, TRUE is returned, and the 'cbDataPtr' * structure is filled out. * * Upon failure, FALSE is returned, and xrErrno is set. * * Procedures Called * ----------------- * XrResource() [resource.c] * XMakePixmap() [libX.a] * XrCopyRect() [calc.c] * XFreePixmap() [libX.a] * _XrTextInfo() [textUtil.c] * calcComponents() * *************************************<->***********************************/ static INT32 createCBoxes (cbDataPtr, cbInfoPtr, message) register xrCheckBoxData * cbDataPtr; register xrCheckBoxInfo * cbInfoPtr; int message; { FontInfo * fontPtr; register xrItemData * aButton; register INT16 i; xrResourceInfo bitmapInfo; RECTANGLE minRect; RECTANGLE editorRect; xrItemData * tempItems; /* Allocate some space to hold the rectangle calculations */ if ((tempItems = (xrItemData *) (*xrMalloc) (sizeof (xrItemData) * cbInfoPtr->numFields)) == NULL) { /* Unable to allocate the memory we need */ xrErrno = XrOUTOFMEM; return (FALSE); } if (message == MSG_NEW) { /* Validate incoming parameters */ if (cbInfoPtr->values == NULL) { (*xrFree)(tempItems); xrErrno = XrINVALIDPTR; return (FALSE); } /* Allocate space to hold the individual checkbox information */ if ((cbDataPtr->cbFields = (xrItemData *) (*xrMalloc) (sizeof (xrItemData) * cbInfoPtr->numFields)) == NULL) { /* Unable to allocate the memory we need */ (*xrFree)(tempItems); xrErrno = XrOUTOFMEM; return (FALSE); } cbDataPtr->cbFGColor = (cbInfoPtr->editorFGColor == -1) ? xrForegroundColor : cbInfoPtr->editorFGColor; cbDataPtr->cbBGColor = (cbInfoPtr->editorBGColor == -1) ? xrBackgroundColor : cbInfoPtr->editorBGColor; /* Create the 50% tile we will need when drawing insensitive box */ if ((cbInfoPtr->editorFGColor == -1) && (cbInfoPtr->editorBGColor == -1)) { /* Use the default 50% tile */ cbDataPtr->cbTileId = xrDefaultTile; } else { bitmapInfo.resourceType = XrTYPE_BITMAPID; bitmapInfo.resourceId = XrPERCENT50; if ((XrResource (MSG_FIND, &bitmapInfo)== FALSE) || ((cbDataPtr->cbTileId = XMakePixmap (((xrBitmapId *)bitmapInfo.resourceObject)->bitmapId, cbDataPtr->cbFGColor, cbDataPtr->cbBGColor)) == 0)) { /* Unable to create the tile */ (*xrFree)(tempItems); (*xrFree) (cbDataPtr->cbFields); xrErrno = XrXCALLFAILED; return (FALSE); } } } /* Check the rectangle size */ XrCopyRect (&cbInfoPtr->editorRect, &editorRect); if (calcComponents (cbInfoPtr, tempItems, MSG_SIZE) == FALSE) { /* The application must have supplied invalid information */ /* xrErrno is set by calcComponents */ XrCopyRect (&editorRect, &cbInfoPtr->editorRect); (*xrFree)(tempItems); if (message == MSG_NEW) { if (cbDataPtr->cbTileId != xrDefaultTile) XFreePixmap (cbDataPtr->cbTileId); (*xrFree) (cbDataPtr->cbFields); } return (FALSE); } (*xrFree)(tempItems); XrCopyRect (&cbInfoPtr->editorRect, &minRect); XrCopyRect (&editorRect, &cbInfoPtr->editorRect); if ((editorRect.height < minRect.height) || (editorRect.width < minRect.width)) { /* The application has supplied an invalid rectangle */ xrErrno = XrINVALIDRECT; if (message == MSG_NEW) { if (cbDataPtr->cbTileId != xrDefaultTile) XFreePixmap (cbDataPtr->cbTileId); (*xrFree) (cbDataPtr->cbFields); } return (FALSE); } /* Generate the location and size information associated with each button */ calcComponents (cbInfoPtr, cbDataPtr->cbFields, MSG_NEW); if (message == MSG_NEW) { /* Fill in the rest of the fields in the checkbox structures */ cbDataPtr->cbNumFields = cbInfoPtr->numFields; cbDataPtr->cbNumCols = cbInfoPtr->numCols; fontPtr = cbInfoPtr->editorFont ? cbInfoPtr->editorFont : xrBaseFontInfo; _XrTextInfo (fontPtr, &cbDataPtr->cbFont); cbDataPtr->cbLabels = cbInfoPtr->labels; cbDataPtr->cbValues = cbInfoPtr->values; cbDataPtr->cbStates = cbInfoPtr->stateFlags; aButton = cbDataPtr->cbFields; for (i = 0; i < cbDataPtr->cbNumFields; i++, aButton++) { /* Copy over each checkbox label */ if (cbInfoPtr->labels) aButton->label = cbInfoPtr->labels[i]; else aButton->label = NULL; /* Copy the initial value, and the state flags */ aButton->value = &(cbInfoPtr->values[i]); if (cbInfoPtr->stateFlags) aButton->state = cbInfoPtr->stateFlags[i]; else aButton->state = (XrVISIBLE | XrSENSITIVE); } } return (TRUE); } \f /*************************************<->************************************* * * INT32 * drawCBoxes (checkBox, buttonNum) * * xrEditor * checkBox; * INT32 buttonNum; * * Description: * ----------- * This routine will display either a single checkbox, or all of * the checkboxes, depending upon the vlaue specified in the * 'buttonNum' parameter. * * * Inputs: * ------ * checkBox = Points to the editor instance structure. * * buttonNum = This can be set to the index of the checkbox to be * drawn, or to the define XrALLBUTTONS, if all the * checkboxex should be redrawn. * * Outputs: * ------- * * Procedures Called * ----------------- * _XrMakeInvisible() [editorUtil.c] * _XrInitEditorGCs() [gcUtil.c] * _XrCopyGC() [gcUtil.c] * _XrChangeGC() [gcUtil.c] * XrCopyRect() [calc.c] * _XrFillRectangle() [rectUtil.c] * _XrBorderFillRectangle() [rectUtil.c] * _XrImageText8() [textUtil.c] * *************************************<->***********************************/ static INT32 drawCBoxes (checkBox, buttonNum) xrEditor * checkBox; INT32 buttonNum; { register xrCheckBoxData * cbDataPtr; Window windowId; INT32 sensitive; register INT16 firstButton, lastButton; register xrItemData * aButton; RECTANGLE workRect; register RECTANGLE * workRectPtr; INT32 changeList[21]; INT8 makeGCFlag; /* Initialize variables */ cbDataPtr = (xrCheckBoxData *) checkBox->editorData; windowId = checkBox->editorWindowId; workRectPtr = &workRect; makeGCFlag = TRUE; /* * If the instance is not visible, then fill its area with the * background tile for the window, thus making the instance invisible. */ if (!(checkBox->editorState & XrVISIBLE)) { _XrMakeInvisible (windowId, &checkBox->editorRect, TRUE); return; } /* Initialize the standard graphic contexts we will be using */ _XrInitEditorGCs (cbDataPtr->cbFGColor, cbDataPtr->cbBGColor, cbDataPtr->cbFont.fontInfo->id); /* Initialize the graphics context used to draw insensitive checkboxes */ _XrCopyGC (xrDefaultGC, xrEditorGC3); changeList[XrTILEVAL] = cbDataPtr->cbTileId; changeList[XrFILLSTYLEVAL] = Tiled; _XrChangeGC (xrEditorGC3, (XrTILE | XrFILLSTYLE), changeList); sensitive = (checkBox->editorState & XrSENSITIVE) ? TRUE : FALSE; /* Determine the range of checkboxes to be drawn */ if (buttonNum == XrALLBUTTONS) { firstButton = 0; lastButton = cbDataPtr->cbNumFields - 1; } else firstButton = lastButton = buttonNum; while (firstButton <= lastButton) { aButton = (cbDataPtr->cbFields) + firstButton; XrCopyRect (&(aButton->rectangle), workRectPtr); /* Determine how to draw the button, depending upon it's state */ if (aButton->state & XrVISIBLE) { if (sensitive && (aButton->state & XrSENSITIVE)) { /* Determine if the button is active or inactive */ if ( *(aButton->value)) { /* * The state of the checkbox is 'ACTIVE', so draw * it as a filled square, using the foreground color. */ _XrFillRectangle (windowId, xrEditorGC1, workRectPtr); } else { /* * The state of the checkbox is 'INACTIVE', so draw * draw the square with the border in the foreground * color, and the interior in the background color. */ _XrBorderFillRectangle (windowId, xrEditorGC1, xrEditorGC2, workRectPtr); } } else { /* * The checkbox is insensitive, so we will draw it as a * filled square, using the 50% tile. */ _XrBorderFillRectangle (windowId, xrEditorGC1, xrEditorGC3, workRectPtr); } /* If the checkbox has a label, then we will draw that now. */ if ((aButton->label) && (strlen(aButton->label) > 0)) _XrImageText8 (windowId, xrEditorGC1, strlen(aButton->label), aButton->labelPt.x, aButton->labelPt.y, aButton->label); } else { /* * The checkbox is not visible, so fill the area it would occupy * with the window's background color. */ _XrMakeInvisible (windowId, &(aButton->subRectangle), makeGCFlag); makeGCFlag = FALSE; } /* Go on and process the next checkBox */ firstButton++; } } \f /*************************************<->************************************* * * INT32 * processCBoxes (checkBox, input, returnEvent) * * xrEditor * checkBox; * XButtonEvent * input; * xrEvent * returnEvent; * * Description: * ----------- * This is the event processing routine for the checkbox editor. * It takes an event, and determines which, if any, of the checkboxes * the event occurred within. If a checkbox was selected, then it * will be redrawn as active, and its index will be returned to the * application, along with the index of the previously active checkbox. * * * Inputs: * ------ * checkBox = Instance pointer for the instance in which the event * occurred. * * input = This points to the event to be processed. * * returnEvent = This points to a partially filled out X-ray event * structure. It can be used by this routine when it * needs to generate a return event for the application. * All fields, except for the 'value' fields, are already * filled out. * * Outputs: * ------- * Although a value is not directly returned, an input event will be * generated, telling the application which checkbox was selected. * * Procedures Called * ----------------- * XrSetPt() [calc.c] * drawCBoxes * *************************************<->***********************************/ static INT32 processCBoxes (checkBox, input, returnEvent) xrEditor * checkBox; XButtonEvent * input; xrEvent * returnEvent; { register xrCheckBoxData * cbDataPtr; POINT spritePt; register INT16 i; register xrItemData * aButton; cbDataPtr = (xrCheckBoxData *) checkBox->editorData; XrSetPt (&spritePt, input->x, input->y); returnEvent->value1 = NULL; /* Check each checkbox to see if one was selected */ for (i = 0; i < cbDataPtr->cbNumFields; i++) { aButton = (cbDataPtr->cbFields) + i; if (XrPtInRect (&spritePt, &(aButton->rectangle)) && ((aButton->state & (XrVISIBLE | XrSENSITIVE)) == (XrVISIBLE | XrSENSITIVE))) { /* A checkbox was selected; modify its value and redraw it */ *(aButton->value) = *(aButton->value) ? FALSE : TRUE; drawCBoxes (checkBox, i); /* Save the index of the checkbox which changed, and return */ returnEvent->value2 = i; returnEvent->value1 = XrSELECT; } } }