|
|
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: T
Length: 36728 (0x8f78)
Types: TextFile
Names: »TitleBar.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/TitleBar.c«
/*
* $Source: /u1/Xr/src/Xrlib/Editor/RCS/TitleBar.c,v $
* $Header: TitleBar.c,v 1.1 86/12/17 09:06:08 swick Exp $
*/
#ifndef lint
static char *rcsid_TitleBar_c = "$Header: TitleBar.c,v 1.1 86/12/17 09:06:08 swick Exp $";
#endif lint
#include <Xr/xr-copyright.h>
/* $Header: TitleBar.c,v 1.1 86/12/17 09:06:08 swick Exp $ */
/* Copyright 1986, Hewlett-Packard Company */
/* Copyright 1986, Massachussetts Institute of Technology */
static char rcsid[] = "$Header: TitleBar.c,v 1.1 86/12/17 09:06:08 swick Exp $";
/*************************************<+>*************************************
*****************************************************************************
**
** File: TitleBar.c
**
** Project: X-ray Toolbox
**
** Description:
** Source code for the X-ray TitleBar field editor.
**
**
** ------------------------ MODIFICATION RECORD ------------------------
*
* $Log: TitleBar.c,v $
* Revision 1.1 86/12/17 09:06:08 swick
* Initial revision
*
* Revision 7.0 86/11/13 08:29:23 08:29:23 fred ()
* Final QA Release
*
* Revision 6.0 86/11/10 15:37:54 15:37:54 fred ()
* QA #2 release
*
* Revision 5.3 86/11/07 14:24:59 14:24:59 fred ()
* Added new copyright message.
*
* Revision 5.2 86/11/04 09:04:28 09:04:28 fred ()
* Fixed a bug dealing with the generation of a fake select up event.
* The detail bits were being masked off.
*
* Revision 5.1 86/10/30 13:32:26 13:32:26 fred ()
* Changed input processing routine to not swallow select up events.
*
* Revision 5.0 86/10/28 08:38:41 08:38:41 fred ()
* QA #1.1 release
*
* Revision 4.2 86/10/23 09:11:37 09:11:37 fred ()
* Removed unused variables.
*
* Revision 4.1 86/10/22 08:23:26 08:23:26 fred ()
* Filled in procedure headers.
*
* Revision 4.0 86/10/20 12:15:30 12:15:30 fred ()
* QA #1 release
*
* Revision 3.4 86/10/16 09:21:43 09:21:43 fred ()
* Performance enhanced: added use of register variables.
*
* Revision 3.3 86/10/13 10:10:59 10:10:59 fred ()
* Added use of the default tile, if needed.
*
* Revision 3.2 86/10/09 07:56:58 07:56:58 fred ()
* Added default color check to create routine.
*
* Revision 3.1 86/10/07 16:08:43 16:08:43 fred ()
* Added check for invalid rectangle height.
*
* Revision 3.0 86/10/02 16:03:21 16:03:21 fred ()
* Alpha release set to 3.0
*
* Revision 2.2 86/09/22 13:12:31 13:12:31 fred ()
* Added calls to XrEditorGroup().
*
* Revision 2.1 86/09/19 07:13:56 07:13:56 fred ()
* Added a check for XrVISIBLE before doing any drawing.
*
* Revision 2.0 86/09/16 08:13:31 08:13:31 fred ()
* Updated input processing routine to use new SELECT strategy.
*
* Revision 1.3 86/09/16 05:51:49 05:51:49 fred ()
* Modified to swallow a select up event.
*
* Revision 1.2 86/09/10 11:49:55 11:49:55 fred ()
* Fixed bug in createTitleBar(), where if the XMakePixmap()
* request failed, it automatically freed the title string
* memory, even if no memory was allocated.
*
* Revision 1.1 86/09/03 13:59:00 13:59:00 fred ()
* Initial revision
*
*
*****************************************************************************
*************************************<+>*************************************/
#include <X/Xlib.h>
#include <Xr/defs.h>
#include <Xr/types.h>
#include <Xr/in_types.h>
extern INT32 createTitleBar();
extern INT32 drawTitleBar();
extern INT32 processTitleBar();
extern INT32 tbFreeMemory();
/*
* This array contains the x offsets used to draw the vertical lines
* in the titlebar header.
*/
static INT16 xOffsets[] = {1, 3, 5, 8, 12, 17, -1, -3, -5, -8, -12, -17};
\f
/*************************************<->*************************************
*
* xrEditor *
* XrTitleBar (titleBar, message, data)
*
* xrEditor * titleBar;
* INT32 message;
* INT8 * data;
*
* Description:
* -----------
* This is the main entry point and message handler for the titlebar
* field editor. It takes all message request, and passes them onto
* the appropriate handler; invalid messages will fail and return an
* error.
*
*
* Inputs:
* ------
* titleBar = For all messages but MSG_NEW and MSG_SIZE, this contains
* the instance pointer for the instance being acted upon.
*
* 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]
* XrCopyRect() [calc.c]
* XrOffsetRect() [calc.c]
* _XrMakeInvisible() [editorUtil.c]
* XrEditorGroup() [group.c]
* createTitleBar()
* drawTitleBar()
* sizeTitleBar()
*
*************************************<->***********************************/
xrEditor *
XrTitleBar (titleBar, message, data)
register xrEditor *titleBar;
INT32 message;
INT8 * data;
{
/* Determine the action being requested */
switch (message)
{
case MSG_NEW:
{
/*
* Create a new titlebar instance.
* The only parameter of interest is the 'data' parameter,
* which is a pointer to a filled instance of the
* xrTitleBarInfo structure.
*/
return ((xrEditor *) _MsgNew (titleBar, data,
sizeof(xrTitleBarData),
createTitleBar, drawTitleBar,
tbFreeMemory, XrTitleBar, NULL));
}
case MSG_FREE:
{
/*
* Destroy the specified titlebar instance.
* The 'titleBar' parameter specifies the instance to
* be destroyed; the 'data' parameter is unused.
*/
return ((xrEditor *) _MsgFree (titleBar, tbFreeMemory));
}
case MSG_GETSTATE:
{
/*
* Return the settings of the state flags for the specified
* titlebar instance. The 'titleBar' 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 (titleBar, data));
}
case MSG_SETSTATE:
{
/*
* Change the state flag settings for the specified titlebar
* instance. The 'titleBar' 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 (titleBar, data,
drawTitleBar, NULL));
}
case MSG_MINSIZE:
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 'xrTitleBarInfo' structure; upon completion, the
* 'editorRect' field of the 'info' structure will be filled.
*/
xrTitleBarInfo *tbInfoPtr = (xrTitleBarInfo *)data;
if (tbInfoPtr == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrEditor *) NULL);
}
else if (sizeTitleBar (tbInfoPtr, &tbInfoPtr->editorRect, message)
== FALSE)
{
/* Size request failed; xrErrno set by sizeTitleBar() */
return ((xrEditor *)NULL);
}
return ((xrEditor *) TRUE);
}
case MSG_REDRAW:
{
/*
* Redraw a titlebar instance.
* The 'titleBar' parameter specifies the instance to be redrawn,
* while the 'data' parameter is interpreted as an INT32 value,
* specifying the type of redraw to perform.
*/
return ((xrEditor *) _MsgRedraw (titleBar, data, drawTitleBar, NULL));
}
case MSG_MOVE:
{
/*
* Relocate a titlebar instance to a new location.
* The 'titleBar' parameter specifies the isntance to be moved,
* while the 'data' parameter must point to a POINT structure,
* containing the new editor rectangle origin.
*/
register xrTitleBarData * tbDataPtr;
RECTANGLE workRect;
POINT * ptPtr = (POINT *) data;
register INT16 xDelta;
register INT16 yDelta;
if (titleBar == NULL)
{
xrErrno = XrINVALIDID;
return ((xrEditor *) NULL);
}
else if (data == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrEditor *) NULL);
}
/* Determine how much to relocate the instance by */
tbDataPtr = (xrTitleBarData *)titleBar->editorData;
XrCopyRect (&titleBar->editorRect, &workRect);
xDelta = ptPtr->x - titleBar->editorRect.x;
yDelta = ptPtr->y - titleBar->editorRect.y;
/* Relocate each component */
XrOffsetRect (&titleBar->editorRect, xDelta, yDelta);
if (tbDataPtr->titleName)
{
XrOffsetRect (&tbDataPtr->titleRect, xDelta, yDelta);
tbDataPtr->titleLoc.x += xDelta;
tbDataPtr->titleLoc.y += yDelta;
}
if (tbDataPtr->gadgetIcon1)
{
XrOffsetRect (&tbDataPtr->gadgetRect1, xDelta, yDelta);
tbDataPtr->iconLoc1.x += xDelta;
tbDataPtr->iconLoc1.y += yDelta;
}
if (tbDataPtr->gadgetIcon2)
{
XrOffsetRect (&tbDataPtr->gadgetRect2, xDelta, yDelta);
tbDataPtr->iconLoc2.x += xDelta;
tbDataPtr->iconLoc2.y += yDelta;
}
if (titleBar->editorState & XrVISIBLE)
{
/* Remove the instance from the window */
_XrMakeInvisible (titleBar->editorWindowId, &workRect, TRUE);
/* Redisplay the instance */
drawTitleBar (titleBar, NULL);
}
/* Force the editor group rectangle to be recalculated */
XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, titleBar);
return (titleBar);
}
case MSG_RESIZE:
{
/*
* Resize an existing titlebar instance.
* The 'titleBar' parameter specifies the instance to be
* resized, while the 'data' parameter must point to a
* RECTANGLE structure, containing the new editor rectangle.
*/
register xrTitleBarData * tbDataPtr;
xrTitleBarInfo tbInfo;
RECTANGLE workRect;
if (titleBar == NULL)
{
xrErrno = XrINVALIDID;
return ((xrEditor *) NULL);
}
else if (data == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrEditor *) NULL);
}
/* Create a pseudo Info structure */
tbDataPtr = (xrTitleBarData *) titleBar->editorData;
XrCopyRect (&titleBar->editorRect, &workRect);
XrCopyRect ((RECTANGLE *) data, &tbInfo.editorRect);
tbInfo.editorFont = tbDataPtr->titleFont.fontInfo;
tbInfo.editorWindowId = titleBar->editorWindowId;
tbInfo.titleName = tbDataPtr->titleName;
tbInfo.gadgetIcon1 = tbDataPtr->gadgetIcon1;
tbInfo.gadgetIcon2 = tbDataPtr->gadgetIcon2;
if (createTitleBar (tbDataPtr, &tbInfo, MSG_RESIZE)==FALSE)
/* xrErrno is set by createTitleBar() */
return ((xrEditor *) NULL);
/* Save the new rectangle definition */
XrCopyRect (&tbInfo.editorRect, &titleBar->editorRect);
/* Remove the instance from the window, if visible */
if (titleBar->editorState & XrVISIBLE)
{
_XrMakeInvisible (titleBar->editorWindowId, &workRect, TRUE);
/* Redisplay the instance */
drawTitleBar (titleBar, NULL);
}
/* Force the editor group rectangle to be recalculated */
XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, titleBar);
return (titleBar);
}
case MSG_EDIT:
{
/*
* Process the incoming event, and generate a return event,
* to indicate to the application program how the editor
* instance was modified. The 'data' parameter must point
* to the event which is to be processed.
*/
return ((xrEditor *) _MsgEdit (titleBar, data,
processTitleBar, XrTITLEBAR));
}
default:
/* All other commands are invalid */
xrErrno = XrINVALIDMSG;
return ((xrEditor *)NULL);
} /* end of switch */
} /* end of XrTitleBar() */
\f
/*************************************<->*************************************
*
* INT32
* tbFreeMemory (tbDataPtr)
*
* xrTitleBarData * tbDataPtr;
*
* Description:
* -----------
* This routine is called both when an existing instance is freed,
* and when a MSG_NEW request fails after createTitleBar() has
* been called. It will free up all resources which createTitleBar()
* allocated for the instance.
*
*
* Inputs:
* ------
* tbDataPtr = Points to the instance's internal 'data' structure.
*
* Outputs:
* -------
*
* Procedures Called
* -----------------
* XFreePixmap() [libX.a]
*
*************************************<->***********************************/
static
INT32
tbFreeMemory (tbDataPtr)
xrTitleBarData * tbDataPtr;
{
if (tbDataPtr->titleTileId != xrDefaultTile)
XFreePixmap (tbDataPtr->titleTileId);
if (tbDataPtr->titleName)
(*xrFree) (tbDataPtr->titleName);
}
\f
/*************************************<->*************************************
*
* INT32
* sizeTitleBar (tbInfoPtr, rectPtr, sizeType)
*
* xrTitleBarInto * tbInfoPtr;
* RECTANGLE * rectPtr;
* INT32 sizeType
*
* Description:
* -----------
* This routine calculates the size of the rectangle needed to contain
* the hypothetical titlebar instance described by the 'tbInfoPtr'
* structure. If 'sizeType' is set to MSG_SIZE, then the rectangle
* will be the minimal rectangle needed to contain the gadget boxes and
* the complete title string.
* If 'sizeType' is set to MSG_MINSIZE, then the rectangle will be
* the minimal rectangle needed to contain the gadget boxes and only
* the first letter within the title string.
*
*
* Inputs:
* ------
* tbInfoPtr = Points to a partially filled out instance of the
* xrTitleBarInfo structure, which contains the description
* of the hypothetical instance being sized.
*
* rectPtr = Points to a RECTANGLE structure, into which the rectangle
* definition will be placed.
*
* sizeType = Can be set to MSG_SIZE or MSG_MINSIZE, as described above.
*
* Outputs:
* -------
* Upon successful completion, TRUE is returned, and the editor
* rectangle is returned.
*
* Upon failure, FALSE is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
* _XrTextInfo() [textUtil.c]
*
*************************************<->***********************************/
static
INT32
sizeTitleBar (tbInfoPtr, rectPtr, sizeType)
register xrTitleBarInfo * tbInfoPtr;
register RECTANGLE * rectPtr;
INT32 sizeType;
{
INT8 * titleName = tbInfoPtr->titleName;
INT8 * gadget1 = tbInfoPtr->gadgetIcon1;
INT8 * gadget2 = tbInfoPtr->gadgetIcon2;
INT16 width;
FontInfo * fontPtr;
xrTextInfo fontData;
INT16 tbSize;
/* Verify the titleType parameter; empty titlebars are not allowed */
if ((!titleName || !strlen(titleName)) && (!gadget1 || !strlen(gadget1)) &&
(!gadget2 || !strlen(gadget2)))
{
xrErrno = XrINVALIDPARM;
return (FALSE);
}
/* Get a pointer to the font description */
fontPtr= (tbInfoPtr->editorFont) ? tbInfoPtr->editorFont : xrBaseFontInfo;
_XrTextInfo (fontPtr, &fontData);
/* Set the rectangle coordinates */
rectPtr->x = 0;
rectPtr->y = 0;
/*
* height = 1 pixel of border + leading/2 of padding +
* 2 more pixels of padding (for gadget boxes) +
* the font height + leading/2 of padding +
* 2 more pixels of padding (for gadget boxes) +
* 1 pixel of border.
*/
rectPtr->height = 1 + fontData.leading + fontData.ascent +
fontData.descent + 2 + 1 + 2;
/* Don't allow the title bar height to be less than 11 */
if (rectPtr->height < XrTB_MIN_HEIGHT)
rectPtr->height = XrTB_MIN_HEIGHT;
/* Calculate the width of the titlebar */
/* Take into account the 2 pixels of border */
width = 2;
if (titleName)
{
if (sizeType == MSG_SIZE)
tbSize = XrStringWidth (fontPtr, titleName, XrNULLTERMINATED, 0, 0);
else
tbSize = XrStringWidth (fontPtr, titleName, 1, 0, 0);
/*
* width += 5 pixels of padding on each end +
* 23 pixels of title border on each side +
* width of the title string.
*/
width += 5 + 23 + tbSize + 23 + 5;
}
if (gadget1 || gadget2)
{
if ((sizeType == MSG_MINSIZE) && !titleName)
width += 5 + 4 + 5 + (2*(fontData.ascent + fontData.descent)) + 4 + 5;
else
width += 5 + 4 + (2*(fontData.ascent + fontData.descent)) + 4 + 5;
}
rectPtr->width = width;
return (TRUE);
}
\f
/*************************************<->*************************************
*
* INT32
* createTitleBar (tbDataPtr, tbInfoPtr, message)
*
* xrTitleBarData * tbDataPtr;
* xrTitleBarInfo * tbInfoPtr;
* INT32 message;
*
* Description:
* -----------
* if (message == MSG_NEW)
* This routine is responsible for creating a new titlebar instance.
* The description of the new instance is contained within the structure
* pointed to by the 'tbInfoPtr' parameter. Besides allocating the
* resources needed for the new instance, this procedure will also fill
* in the structure pointed to by the 'tbDataPtr' parameter with the
* state information for the new instance.
*
* if (message == MSG_RESIZE)
* This routine will take the information contained within the
* 'tbInfoPtr' structure, and will recalculate the location of each
* component within an existing titlebar instance, to match the new
* data. This will do no resource allocation.
*
*
* Inputs:
* ------
* tbDataPtr = Points to the 'data' structure for the instance being
* created or resized.
*
* tbInfoPtr = 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 'tbDataPtr'
* structure is filled out.
*
* Upon failure, FALSE is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
* XQueryWindow() [libX.a]
* XMakePixmap() [libX.a]
* XrCopyRect() [calc.c]
* _XrTextInfo() [textUtil.c]
* XrStringWidth() [utilities.c]
* XrResource() [resource.c]
* sizeTitleBar()
*
*************************************<->***********************************/
static
INT32
createTitleBar (tbDataPtr, tbInfoPtr, message)
register xrTitleBarData * tbDataPtr;
register xrTitleBarInfo * tbInfoPtr;
INT32 message;
{
RECTANGLE * editorRect = &tbInfoPtr->editorRect;
register xrTextInfo * fontPtr = &tbDataPtr->titleFont;
INT8 * titleName = tbInfoPtr->titleName;
INT8 * gadget1 = tbInfoPtr->gadgetIcon1;
INT8 * gadget2 = tbInfoPtr->gadgetIcon2;
WindowInfo winfo;
RECTANGLE workRect, tempRect;
INT16 regionWidth;
INT16 stringWidth;
INT32 i;
xrResourceInfo bitmapInfo;
/* Verify the titleType parameter; empty titlebars are not allowed */
if ((!titleName || !strlen(titleName)) && (!gadget1 || !strlen(gadget1)) &&
(!gadget2 || !strlen(gadget2)))
{
xrErrno = XrINVALIDPARM;
return (FALSE);
}
/*
* If the application has set the editorRect to (0,0,0,0), then
* calculate the editorRect, such that the titlebar will run the
* full extend of the top of the window; otherwise, make sure the
* editorRect specified is large enough to hold the instance.
*/
if ((editorRect->x == 0) && (editorRect->y == 0) &&
(editorRect->height == 0) && (editorRect->width == 0))
{
/* Calculate the rectangle for the application */
sizeTitleBar (tbInfoPtr, editorRect, MSG_SIZE);
if (XQueryWindow (tbInfoPtr->editorWindowId, &winfo) == 0)
{
xrErrno = XrXCALLFAILED;
return (FALSE);
}
editorRect->width = winfo.width;
}
else
{
/* Make sure the editorRect is large enough to hold the instance */
sizeTitleBar (tbInfoPtr, &workRect, MSG_MINSIZE);
XrCopyRect (editorRect, &tempRect);
if ((tempRect.height != workRect.height) ||
(tempRect.width < workRect.width))
{
xrErrno = XrINVALIDRECT;
return (FALSE);
}
}
/*
* Now that we know all of the parameters are valid, we can start
* filling in the structure pointed to by 'tbDataPtr'.
*/
if (message == MSG_NEW)
{
/* Copy some of the information from the 'tbInfoPtr' structure */
if (tbInfoPtr->editorFont)
_XrTextInfo (tbInfoPtr->editorFont, fontPtr);
else
_XrTextInfo (xrBaseFontInfo, fontPtr);
tbDataPtr->tbFGColor = (tbInfoPtr->editorFGColor == -1) ?
xrForegroundColor : tbInfoPtr->editorFGColor;
tbDataPtr->tbBGColor = (tbInfoPtr->editorBGColor == -1) ?
xrBackgroundColor : tbInfoPtr->editorBGColor;
tbDataPtr->gadgetIcon1 = tbInfoPtr->gadgetIcon1;
tbDataPtr->gadgetIcon2 = tbInfoPtr->gadgetIcon2;
}
/*
* Determine the size of gadget box 1 rectangle
*
* x origin = left of editorRect + 1 pixel ER border + 5 pixels padding.
* y origin = top of editorRect + 1 pixel ER border + leading/2 padding.
* width = font height + 2 pixels padding + 2 pixels of border.
* height = font height + 2 pixels padding + 2 pixels of border.
*/
tempRect.x = editorRect->x + 1 + 5;
tempRect.y = editorRect->y + 1 + (fontPtr->leading >> 1);
tempRect.width = fontPtr->ascent + fontPtr->descent + 2 + 2;
tempRect.height =fontPtr->ascent + fontPtr->descent + 2 + 2;
XrCopyRect (&tempRect, &tbDataPtr->gadgetRect1);
/*
* Determine the size of gadget box 2 rectangle
*
* x origin = right of editorRect - 1 pixel ER border - 5 pixels padding -
* width of gadget box - 2 pixels of border - 2 pixels of
* padding + 1 adjustment pixel.
* y origin = top of editorRect + 1 pixel border + leading/2 padding.
* width = font height + 2 pixels padding + 2 pixels of border.
* height = font height + 2 pixels padding + 2 pixels of border.
*/
tempRect.x = (editorRect->x + editorRect->width - 1) - 1 - 5
- (fontPtr->ascent + fontPtr->descent) - 2 - 2 + 1;
tempRect.y = editorRect->y + 1 + (fontPtr->leading >> 1);
tempRect.width = fontPtr->ascent + fontPtr->descent + 2 + 2;
tempRect.height = fontPtr->ascent + fontPtr->descent + 2 + 2;
XrCopyRect (&tempRect, &tbDataPtr->gadgetRect2);
/*
* Before determining the titleRect, determine how much space is
* available for the title string, and then determine how much of
* the title string will fit.
*/
if (titleName)
{
if (gadget1 || gadget2)
/*
* width = width between the two gadget boxes
* - 5 pixels padding between gadgets and title borders
* - 23 pixels of title border on each end.
*/
regionWidth = tbDataPtr->gadgetRect2.x - 1 -
(tbDataPtr->gadgetRect1.x + tbDataPtr->gadgetRect1.width - 1)
- 10 - 46;
else
/*
* width = width of editorRect - 2 pixels of border
* - 5 pixels padding on each end
* - 23 pixels of title border on each end.
*/
regionWidth = tbInfoPtr->editorRect.width - 10 - 46 - 2;
/* Allocate some space for the title string */
if (message == MSG_NEW)
{
if ((tbDataPtr->titleName =(char *)(*xrMalloc)(strlen(titleName) + 1))
== NULL)
{
xrErrno = XrOUTOFMEM;
return (FALSE);
}
/* Copy over the title string to the new buffer */
strcpy (tbDataPtr->titleName, titleName);
}
/* Determine how much of the string we can use */
titleName = tbDataPtr->titleName;
stringWidth = XrStringWidth (fontPtr->fontInfo, titleName,
XrNULLTERMINATED, 0, 0);
for (i = strlen(titleName); i > 0; i--)
{
stringWidth = XrStringWidth (fontPtr->fontInfo, titleName,
i, 0, 0);
if (stringWidth <= regionWidth)
break;
}
tbDataPtr->titleLen = i;
/* Now, we can determine the size of the title string rectangle */
tempRect.x = editorRect->x + (editorRect->width >> 1) -
(stringWidth>>1) - 23;
tempRect.y = editorRect->y;
tempRect.width = 23 + stringWidth + 23;
tempRect.height = editorRect->height;
XrCopyRect (&tempRect, &tbDataPtr->titleRect);
/* Determine the pen position for the title string */
tbDataPtr->titleLoc.x = tempRect.x + 23;
tbDataPtr->titleLoc.y = editorRect->y + (fontPtr->leading >> 1) + 3;
/* + fontPtr->ascent ; */
}
else
tbDataPtr->titleName = NULL;
/* Lastly, determine the pen position for the icons in the gadget boxes */
if (gadget1)
{
stringWidth = XrStringWidth (fontPtr->fontInfo, tbDataPtr->gadgetIcon1,
1, 0, 0);
tbDataPtr->iconLoc1.x = tbDataPtr->gadgetRect1.x - (stringWidth >> 1) +
(tbDataPtr->gadgetRect1.width >> 1);
tbDataPtr->iconLoc1.y = tbDataPtr->gadgetRect1.y + 2;
/* fontPtr->ascent ; */
}
if (gadget2)
{
stringWidth = XrStringWidth (fontPtr->fontInfo, tbDataPtr->gadgetIcon2,
1, 0, 0);
tbDataPtr->iconLoc2.x = tbDataPtr->gadgetRect2.x - (stringWidth >> 1) +
(tbDataPtr->gadgetRect2.width >> 1);
tbDataPtr->iconLoc2.y = tbDataPtr->gadgetRect2.y + 2;
/* fontPtr->ascent ; */
}
/* Create the 50% tile used as the background for the titlebar */
if (message == MSG_NEW)
{
if ((tbInfoPtr->editorFGColor == -1) &&
(tbInfoPtr->editorBGColor == -1))
{
/* Use the default 50% tile */
tbDataPtr->titleTileId = xrDefaultTile;
}
else
{
bitmapInfo.resourceType = XrTYPE_BITMAPID;
bitmapInfo.resourceId = XrPERCENT50;
if ((XrResource (MSG_FIND, &bitmapInfo) == FALSE) ||
((tbDataPtr->titleTileId =
XMakePixmap (((xrBitmapId *)bitmapInfo.resourceObject)->bitmapId,
tbDataPtr->tbFGColor,
tbDataPtr->tbBGColor)) == 0))
{
if (tbDataPtr->titleName)
(*xrFree) (tbDataPtr->titleName);
xrErrno = XrXCALLFAILED;
return (FALSE);
}
}
}
return (TRUE);
}
\f
/*************************************<->*************************************
*
* INT32
* drawTitleBar (titleBar, drawOption)
*
* xrEditor * titleBar;
* INT32 drawOption;
*
* Description:
* -----------
* This routine will display a titlebar instance.
*
*
* Inputs:
* ------
* titleBar = Points to the editor instance structure.
*
* drawOption = Not used; this parameter is present so that _MsgNew()
* can call this procedure.
*
* Outputs:
* -------
*
* Procedures Called
* -----------------
* _XrMakeInvisible() [editorUtil.c]
* _XrInitEditorGCs() [gcUtil.c]
* _XrCopyGC() [gcUtil.c]
* _XrChangeGC() [gcUtil.c]
* _XrBorderFillRectangle() [rectUtil.c]
* _XrFillRectangle() [rectUtil.c]
* _XrLine() [rectUtil.c]
* _XrImageText8() [textUtil.c]
*
*************************************<->***********************************/
static
INT32
drawTitleBar (titleBar, drawOption)
register xrEditor * titleBar;
INT32 drawOption;
{
register xrTitleBarData * tbDataPtr;
INT8 sensitive;
register INT32 i;
INT16 x1, y1, x2, y2;
register Window windowId = titleBar->editorWindowId;
INT32 changeList[21];
INT32 changeMask;
/*
* If the instance is not visible, then fill its area with the
* background tile for the window, thus making the instance invisible.
*/
tbDataPtr = (xrTitleBarData *) titleBar->editorData;
if (!(titleBar->editorState & XrVISIBLE))
{
_XrMakeInvisible (windowId, &titleBar->editorRect, TRUE);
return;
}
/* Initialize the graphic contexts we will be using */
_XrInitEditorGCs (tbDataPtr->tbFGColor, tbDataPtr->tbBGColor,
tbDataPtr->titleFont.fontInfo->id);
/*
* Initialize another graphics context, which we will use
* to tile fill the background area within a sensitive titlebar.
*/
changeList[XrFILLSTYLEVAL] = Tiled;
changeList[XrTILEVAL] = tbDataPtr->titleTileId;
changeMask = (XrFILLSTYLE | XrTILE);
_XrCopyGC (xrDefaultGC, xrEditorGC3);
_XrChangeGC (xrEditorGC3, changeMask, changeList);
sensitive = (titleBar->editorState & XrSENSITIVE) ? TRUE : FALSE;
/* Draw the titleBar instance */
if (! sensitive)
{
/*
* The titlebar instance is insensitive, therefore
* draw a bordered rectangle, filled with the background color
* and then display the title string.
*/
_XrBorderFillRectangle (windowId, xrEditorGC1, xrEditorGC2,
&titleBar->editorRect);
/* Display just the title string */
if (tbDataPtr->titleName)
{
_XrImageText8 (windowId, xrEditorGC1, tbDataPtr->titleLen,
tbDataPtr->titleLoc.x, tbDataPtr->titleLoc.y,
tbDataPtr->titleName);
}
}
else
{
/* Draw a bordered rectangle, with 50% tile fill */
_XrBorderFillRectangle (windowId, xrEditorGC1, xrEditorGC3,
&titleBar->editorRect);
if (tbDataPtr->titleName)
{
/* Draw the title borders */
_XrFillRectangle (windowId, xrEditorGC1, &tbDataPtr->titleRect);
/* Draw the highlight lines */
y1 = tbDataPtr->titleRect.y + 1;
y2 = tbDataPtr->titleRect.y + tbDataPtr->titleRect.height - 2;
for (i = 0; i < 12; i++)
{
if (i < 6)
x1 = tbDataPtr->titleRect.x + xOffsets[i];
else
x1 = (tbDataPtr->titleRect.x +
tbDataPtr->titleRect.width - 1) + xOffsets[i];
x2 = x1;
_XrLine (windowId, xrEditorGC2, x1, y1, x2, y2);
}
/* Display the title string */
_XrImageText8 (windowId, xrEditorGC2, tbDataPtr->titleLen,
tbDataPtr->titleLoc.x, tbDataPtr->titleLoc.y,
tbDataPtr->titleName);
}
/* Display gadget box 1 */
if (tbDataPtr->gadgetIcon1)
{
/* Draw a bordered gadget box */
_XrBorderFillRectangle (windowId, xrEditorGC1, xrEditorGC2,
&tbDataPtr->gadgetRect1);
/* Display the icon character */
_XrImageText8 (windowId, xrEditorGC1, 1, tbDataPtr->iconLoc1.x,
tbDataPtr->iconLoc1.y, tbDataPtr->gadgetIcon1);
}
/* Display gadget box 2 */
if (tbDataPtr->gadgetIcon2)
{
/* Draw a bordered gadget box */
_XrBorderFillRectangle (windowId, xrEditorGC1, xrEditorGC2,
&tbDataPtr->gadgetRect2);
/* Display the icon character */
_XrImageText8 (windowId, xrEditorGC1, 1, tbDataPtr->iconLoc2.x,
tbDataPtr->iconLoc2.y, tbDataPtr->gadgetIcon2);
}
}
}
\f
/*************************************<->*************************************
*
* INT32
* processTitleBar (titleBar, input, returnEvent)
*
* xrEditor * titleBar;
* XButtonEvent * input;
* xrEvent * returnEvent;
*
* Description:
* -----------
* This is the event processing routine for the titlebar editor.
* It takes an event, and determines which of the titlebar components
* the select occurred within. In return, a return event is generated
* which will tell the application which components was selected.
*
*
* Inputs:
* ------
* titleBar = Instance pointer for the titlebar instance in which the
* event occurred.
*
* input = Points to the event to be processed.
*
* returnEvent = 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.
*
* Outputs:
* -------
* Although a value is not directly returned, an input event will be
* generated, telling the application which part of the instance
* was selected.
*
* Procedures Called
* -----------------
* XrSetPt() [calc.c]
* XrPtInRect() [calc.c]
*
*************************************<->***********************************/
static
INT32
processTitleBar (titleBar, input, returnEvent)
xrEditor * titleBar;
XButtonEvent * input;
xrEvent * returnEvent;
{
register xrTitleBarData * tbDataPtr;
POINT spritePt;
xrWindowEvent windowEvent;
XButtonEvent selectUp;
tbDataPtr = (xrTitleBarData *) titleBar->editorData;
XrSetPt (&spritePt, input->x, input->y);
returnEvent->value1 = NULL;
/*
* Determine which region was selected
*/
/* Check for a select in gadget box 1 region */
if ((tbDataPtr->gadgetIcon1) &&
XrPtInRect (&spritePt, &(tbDataPtr->gadgetRect1)))
{
returnEvent->value1 = XrGADGET_BOX1;
}
/* Check for a select in gadget box 2 region */
else if ((tbDataPtr->gadgetIcon2) &&
XrPtInRect (&spritePt, &(tbDataPtr->gadgetRect2)))
{
returnEvent->value1 = XrGADGET_BOX2;
}
/* Check for a select in the title string region */
else if ((tbDataPtr->titleName) &&
XrPtInRect (&spritePt, &(tbDataPtr->titleRect)))
{
returnEvent->value1 = XrTITLE_REGION;
}
/* Push a fake select up event */
XrGetWindowEvent (XrSELECTUP, &windowEvent);
selectUp.type = windowEvent.inputType;
selectUp.detail = windowEvent.inputCode;
XrInput (NULL, MSG_PUSHEVENT, &selectUp);
}