|
|
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 - metrics - 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;
}
}
}