840 lines
23 KiB
C
840 lines
23 KiB
C
/*
|
||
* tixDItem.c --
|
||
*
|
||
* This file implements the "Display Items" in the Tix library.
|
||
*
|
||
* Since many Tix widgets use the same type of display items, for
|
||
* example, text items, image items, or text-image items (used in
|
||
* HList, TList and Table), it makes sense to provide a set of
|
||
* common routines to support these display items. Code re-use is
|
||
* the major issue: we don't want to re-define almost the same
|
||
* configSpecs again and again in different widgets. Therefore,
|
||
* all display items provide common methods to configure,
|
||
* display, calculate geometry, etc.
|
||
*
|
||
*
|
||
* Copyright (c) 1993-1999 Ioi Kim Lam.
|
||
* Copyright (c) 2000-2001 Tix Project Group.
|
||
*
|
||
* See the file "license.terms" for information on usage and redistribution
|
||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||
*
|
||
* $Id: tixDItem.c,v 1.3 2004/03/28 02:44:56 hobbs Exp $
|
||
*/
|
||
|
||
#include <tixPort.h>
|
||
#include <tixInt.h>
|
||
|
||
|
||
static int DItemParseProc _ANSI_ARGS_((ClientData clientData,
|
||
Tcl_Interp *interp, Tk_Window tkwin, CONST84 char *value,
|
||
char *widRec, int offset));
|
||
|
||
static char *DItemPrintProc _ANSI_ARGS_((
|
||
ClientData clientData, Tk_Window tkwin, char *widRec,
|
||
int offset, Tcl_FreeProc **freeProcPtr));
|
||
|
||
/*----------------------------------------------------------------------
|
||
*
|
||
*
|
||
* PUBLIC INTERFACE
|
||
*
|
||
*
|
||
* The following functions are called by widget implementors
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
/* Tix_AddDItemType, Tix_GetDItemType --
|
||
*
|
||
*
|
||
* Maintain a list of item types, each identifies by a unique string
|
||
* name;
|
||
*/
|
||
|
||
static Tix_DItemInfo * diTypes = NULL;
|
||
|
||
void Tix_AddDItemType(diTypePtr)
|
||
Tix_DItemInfo * diTypePtr;
|
||
{
|
||
diTypePtr->next = diTypes;
|
||
diTypes = diTypePtr;
|
||
}
|
||
|
||
Tix_DItemInfo * Tix_GetDItemType(interp, type)
|
||
Tcl_Interp * interp;
|
||
CONST84 char * type;
|
||
{
|
||
Tix_DItemInfo * diTypePtr;
|
||
|
||
for (diTypePtr = diTypes; diTypePtr; diTypePtr = diTypePtr->next) {
|
||
if (strcmp(type, diTypePtr->name)==0) {
|
||
return diTypePtr;
|
||
}
|
||
}
|
||
|
||
if (interp) {
|
||
Tcl_AppendResult(interp, "unknown display type \"", type, "\"", NULL);
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------
|
||
* Tix_DItemCreate --
|
||
*
|
||
* Create a display item according to the "type" string.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
Tix_DItem * Tix_DItemCreate(ddPtr, type)
|
||
Tix_DispData * ddPtr;
|
||
CONST84 char * type;
|
||
{
|
||
Tix_DItemInfo * diTypePtr;
|
||
|
||
if ((diTypePtr = Tix_GetDItemType(ddPtr->interp, type)) == NULL) {
|
||
return NULL;
|
||
}
|
||
|
||
return diTypePtr->createProc(ddPtr, diTypePtr);
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* Tix_DItemConfigure --
|
||
*
|
||
* Configures a display item.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
int Tix_DItemConfigure(iPtr, argc, argv, flags)
|
||
Tix_DItem * iPtr;
|
||
int argc;
|
||
CONST84 char ** argv;
|
||
int flags;
|
||
{
|
||
return iPtr->base.diTypePtr->configureProc(iPtr, argc, argv, flags);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* Tix_DItemDisplay --
|
||
*
|
||
* Display a DItem. {x, y, width, height} specifies a region
|
||
* for to display this item in. {xOffset, yOffset} gives the
|
||
* offset of the top-left corner of the item relative to
|
||
* the top-left corder of the region.
|
||
*
|
||
* Background and foreground of the item are displayed according
|
||
* to the flags parameter.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
Tix_DItemDisplay(drawable, iPtr, x, y, width, height, xOffset, yOffset,flags)
|
||
Drawable drawable;
|
||
Tix_DItem * iPtr;
|
||
int x;
|
||
int y;
|
||
int width;
|
||
int height;
|
||
int xOffset;
|
||
int yOffset;
|
||
int flags;
|
||
{
|
||
iPtr->base.diTypePtr->displayProc(drawable, iPtr, x, y,
|
||
width, height, xOffset, yOffset, flags);
|
||
}
|
||
|
||
void Tix_DItemFree(iPtr)
|
||
Tix_DItem * iPtr;
|
||
{
|
||
iPtr->base.diTypePtr->freeProc(iPtr);
|
||
|
||
/*
|
||
* When it comes to here, iPtr is no longer a valid pointer!
|
||
*/
|
||
}
|
||
|
||
void Tix_DItemCalculateSize(iPtr)
|
||
Tix_DItem * iPtr;
|
||
{
|
||
iPtr->base.diTypePtr->calculateSizeProc(iPtr);
|
||
}
|
||
|
||
char * Tix_DItemComponent(iPtr, x, y)
|
||
Tix_DItem * iPtr;
|
||
int x;
|
||
int y;
|
||
{
|
||
return (iPtr->base.diTypePtr->componentProc(iPtr, x, y));
|
||
}
|
||
|
||
|
||
/*----------------------------------------------------------------------
|
||
* Tix_FreeArgumentList --
|
||
*
|
||
* Free the argument lists allocated by Tix_SplitConfig;
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
void
|
||
Tix_FreeArgumentList(argListPtr)
|
||
Tix_ArgumentList *argListPtr;
|
||
{
|
||
int i;
|
||
|
||
for (i=0; i<argListPtr->numLists; i++) {
|
||
ckfree((char*)argListPtr->arg[i].argv);
|
||
}
|
||
if (argListPtr->arg != argListPtr->preAlloc) {
|
||
ckfree((char*)argListPtr->arg);
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* Tix_SplitConfig --
|
||
*
|
||
* Split the command line arguments according for several configurable
|
||
* objects.
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
int
|
||
Tix_SplitConfig(interp, tkwin, specsList, numLists, argc, argv, argListPtr)
|
||
Tcl_Interp * interp;
|
||
Tk_Window tkwin;
|
||
Tk_ConfigSpec ** specsList; /* a list of two or more config spec
|
||
* arrays */
|
||
int numLists;
|
||
int argc;
|
||
CONST84 char ** argv;
|
||
Tix_ArgumentList * argListPtr;
|
||
{
|
||
Tix_Argument *arg;
|
||
int i, n, code = TCL_OK;
|
||
Tk_ConfigSpec *specPtr;
|
||
size_t len;
|
||
int found;
|
||
|
||
if (argc % 2) {
|
||
Tcl_AppendResult(interp, "value for \"", argv[argc-1],
|
||
"\" missing", (char *) NULL);
|
||
return TCL_ERROR;
|
||
}
|
||
|
||
if (numLists > FIXED_SIZE) {
|
||
arg = (Tix_Argument*)ckalloc(numLists * sizeof(Tix_Argument));
|
||
} else {
|
||
arg = argListPtr->preAlloc;
|
||
}
|
||
argListPtr->arg = arg;
|
||
argListPtr->numLists = numLists;
|
||
for (i=0; i<numLists; i++) {
|
||
arg[i].argc = 0;
|
||
arg[i].argv = (CONST84 char**)ckalloc(argc * sizeof(char*));
|
||
}
|
||
|
||
/* Split the arguments for the appropriate objects */
|
||
for (n=0; n<argc; n+=2) {
|
||
len = strlen(argv[n]);
|
||
found = 0;
|
||
|
||
for (i=0; i<numLists; i++) {
|
||
for (specPtr=specsList[i];
|
||
specPtr->type != TK_CONFIG_END;
|
||
specPtr++) {
|
||
|
||
if (specPtr->argvName == NULL) {
|
||
continue;
|
||
}
|
||
|
||
if (strncmp(argv[n], specPtr->argvName, len) == 0) {
|
||
arg[i].argv[arg[i].argc++] = argv[n ];
|
||
arg[i].argv[arg[i].argc++] = argv[n+1];
|
||
found = 1;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (found == 0) {
|
||
Tcl_AppendResult(interp, "unknown option \"", argv[n],
|
||
"\"", (char *) NULL);
|
||
code = TCL_ERROR;
|
||
goto done;
|
||
}
|
||
}
|
||
|
||
done:
|
||
if (code == TCL_ERROR) {
|
||
Tix_FreeArgumentList(argListPtr);
|
||
}
|
||
return code;
|
||
}
|
||
|
||
int
|
||
Tix_MultiConfigureInfo(interp, tkwin, specsList, numLists, widgRecList,
|
||
argvName, flags, request)
|
||
Tcl_Interp *interp; /* Interpreter for error reporting. */
|
||
Tk_Window tkwin; /* Window corresponding to widgRec. */
|
||
Tk_ConfigSpec **specsList; /* Describes legal options. */
|
||
int numLists;
|
||
CONST84 char **widgRecList; /* Record whose fields contain current
|
||
* values for options. */
|
||
CONST84 char *argvName; /* If non-NULL, indicates a single option
|
||
* whose info is to be returned. Otherwise
|
||
* info is returned for all options. */
|
||
int flags; /* Used to specify additional flags
|
||
* that must be present in config specs
|
||
* for them to be considered. */
|
||
int request;
|
||
{
|
||
int i, found;
|
||
Tk_ConfigSpec *specPtr;
|
||
Tcl_DString dString;
|
||
size_t len;
|
||
CONST84 char *result;
|
||
|
||
if (argvName != NULL) {
|
||
len = strlen(argvName);
|
||
for (found=0,i=0; i<numLists; i++) {
|
||
for (specPtr=specsList[i];
|
||
specPtr->type != TK_CONFIG_END;
|
||
specPtr++) {
|
||
|
||
if (specPtr->argvName == NULL) {
|
||
continue;
|
||
}
|
||
|
||
if (strncmp(argvName, specPtr->argvName, len) == 0) {
|
||
found = 1;
|
||
goto done;
|
||
}
|
||
}
|
||
}
|
||
done:
|
||
if (!found) {
|
||
Tcl_AppendResult(interp, "unknown option \"", argvName,
|
||
"\"", (char *) NULL);
|
||
return TCL_ERROR;
|
||
}
|
||
if (request == TIX_CONFIG_INFO) {
|
||
if (widgRecList[i] != NULL) {
|
||
return Tk_ConfigureInfo(interp, tkwin, specsList[i],
|
||
(char *) widgRecList[i], argvName, flags);
|
||
} else {
|
||
return TCL_OK;
|
||
}
|
||
} else {
|
||
if (widgRecList[i] != NULL) {
|
||
return Tk_ConfigureValue(interp, tkwin, specsList[i],
|
||
(char *) widgRecList[i], argvName, flags);
|
||
} else {
|
||
return TCL_OK;
|
||
}
|
||
}
|
||
}
|
||
|
||
Tcl_DStringInit(&dString);
|
||
for (i=0; i<numLists; i++) {
|
||
if (i != 0) {
|
||
Tcl_DStringAppend(&dString, " ", 1);
|
||
}
|
||
if (widgRecList[i] != NULL) {
|
||
Tk_ConfigureInfo(interp, tkwin, specsList[i],
|
||
(char *) widgRecList[i], NULL, flags);
|
||
}
|
||
result = Tcl_GetStringResult(interp);
|
||
Tcl_DStringAppend(&dString, result, (int) strlen(result));
|
||
}
|
||
Tcl_ResetResult(interp);
|
||
Tcl_DStringResult(interp, &dString);
|
||
Tcl_DStringFree(&dString);
|
||
|
||
return TCL_OK;
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* Tix_ConfigureValue2 --
|
||
*
|
||
*
|
||
* Returns the config information of a entry element (of an HList,
|
||
* for example) and its display item.
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
int
|
||
Tix_ConfigureValue2(interp, tkwin, entRec, entConfigSpecs, iPtr,
|
||
argvName, flags)
|
||
Tcl_Interp *interp; /* Interpreter for error reporting. */
|
||
Tk_Window tkwin; /* Window corresponding to widgRec. */
|
||
CONST84 char * entRec;
|
||
Tk_ConfigSpec *entConfigSpecs; /* Describes legal options of the entry */
|
||
Tix_DItem * iPtr; /* points to the entry's data record */
|
||
CONST84 char *argvName; /* If non-NULL, indicates a single option
|
||
* whose info is to be returned. Otherwise
|
||
* info is returned for all options. */
|
||
int flags; /* Used to specify additional flags
|
||
* that must be present in config specs
|
||
* for them to be considered. */
|
||
{
|
||
Tk_ConfigSpec *specsList[2];
|
||
CONST84 char *widgRecList[2];
|
||
|
||
specsList[0] = entConfigSpecs;
|
||
specsList[1] = Tix_DItemConfigSpecs(iPtr);
|
||
widgRecList[1] = (CONST84 char*)iPtr;
|
||
widgRecList[0] = entRec;
|
||
|
||
return Tix_MultiConfigureInfo(interp, tkwin, specsList, 2, widgRecList,
|
||
argvName, flags, TIX_CONFIG_VALUE);
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* Tix_ConfigureInfo2 --
|
||
*
|
||
*
|
||
* Returns the config information of a entry element (of an HList,
|
||
* for example) and its display item.
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
int
|
||
Tix_ConfigureInfo2(interp, tkwin, entRec, entConfigSpecs, iPtr,
|
||
argvName, flags)
|
||
Tcl_Interp *interp; /* Interpreter for error reporting. */
|
||
Tk_Window tkwin; /* Window corresponding to widgRec. */
|
||
CONST84 char * entRec;
|
||
Tk_ConfigSpec *entConfigSpecs; /* Describes legal options of the entry */
|
||
Tix_DItem * iPtr; /* points to the entry's data record */
|
||
CONST84 char *argvName; /* If non-NULL, indicates a single option
|
||
* whose info is to be returned. Otherwise
|
||
* info is returned for all options. */
|
||
int flags; /* Used to specify additional flags
|
||
* that must be present in config specs
|
||
* for them to be considered. */
|
||
{
|
||
Tk_ConfigSpec *specsList[2];
|
||
CONST84 char *widgRecList[2];
|
||
|
||
specsList[0] = entConfigSpecs;
|
||
specsList[1] = Tix_DItemConfigSpecs(iPtr);
|
||
widgRecList[1] = (CONST84 char*)iPtr;
|
||
widgRecList[0] = (CONST84 char*)entRec;
|
||
|
||
return Tix_MultiConfigureInfo(interp, tkwin, specsList, 2, widgRecList,
|
||
argvName, flags, TIX_CONFIG_INFO);
|
||
}
|
||
|
||
int
|
||
Tix_WidgetConfigure2(interp, tkwin, entRec, entConfigSpecs, iPtr,
|
||
argc, argv, flags, forced, sizeChanged_ret)
|
||
Tcl_Interp *interp; /* Interpreter for error reporting. */
|
||
Tk_Window tkwin; /* Window corresponding to widgRec. */
|
||
CONST84 char * entRec;
|
||
Tk_ConfigSpec *entConfigSpecs; /* Describes legal options of the entry */
|
||
Tix_DItem * iPtr; /* points to the entry's data record */
|
||
int argc;
|
||
CONST84 char ** argv;
|
||
int flags;
|
||
int forced; /* forced configure of DItem? */
|
||
int * sizeChanged_ret;
|
||
{
|
||
Tix_ArgumentList argList;
|
||
Tk_ConfigSpec *specsList[2];
|
||
CONST84 char *widgRecList[2];
|
||
int code = TCL_OK;
|
||
int dummy;
|
||
|
||
if (sizeChanged_ret == NULL) {
|
||
sizeChanged_ret = &dummy;
|
||
}
|
||
|
||
specsList[0] = entConfigSpecs;
|
||
specsList[1] = Tix_DItemConfigSpecs(iPtr);
|
||
widgRecList[0] = (CONST84 char*)entRec;
|
||
widgRecList[1] = (CONST84 char*)iPtr;
|
||
|
||
if (Tix_SplitConfig(interp, tkwin, specsList,
|
||
2, argc, argv, &argList) != TCL_OK) {
|
||
return TCL_ERROR;
|
||
}
|
||
|
||
/* Handle the info specific to the entry */
|
||
if (argList.arg[0].argc > 0) {
|
||
if (Tk_ConfigureWidget(interp, tkwin,
|
||
entConfigSpecs, argList.arg[0].argc, argList.arg[0].argv,
|
||
(char*)entRec, flags) != TCL_OK) {
|
||
|
||
code = TCL_ERROR;
|
||
goto done;
|
||
}
|
||
}
|
||
|
||
if (iPtr == NULL) {
|
||
goto done;
|
||
}
|
||
if (argList.arg[1].argc > 0 || forced) {
|
||
int oldSize[2];
|
||
oldSize[0] = iPtr->base.size[0];
|
||
oldSize[1] = iPtr->base.size[1];
|
||
if (Tix_DItemConfigure(iPtr, argList.arg[1].argc,
|
||
argList.arg[1].argv, flags) != TCL_OK) {
|
||
code = TCL_ERROR;
|
||
goto done;
|
||
}
|
||
|
||
if (oldSize[0] != iPtr->base.size[0] ||
|
||
oldSize[1] != iPtr->base.size[1]) {
|
||
* sizeChanged_ret = 1;
|
||
} else {
|
||
* sizeChanged_ret = 0;
|
||
}
|
||
}
|
||
|
||
done:
|
||
|
||
Tix_FreeArgumentList(&argList);
|
||
return code;
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
*
|
||
* The Tix Customed Config Options
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
/*
|
||
* The global data structures to use in widget configSpecs arrays
|
||
*
|
||
* These are declared in <tixConfig.h>
|
||
*/
|
||
|
||
Tk_CustomOption tixConfigItemType = {
|
||
DItemParseProc, DItemPrintProc, 0,
|
||
};
|
||
|
||
/*----------------------------------------------------------------------
|
||
* DItemParseProc --
|
||
*
|
||
* Parse the text string and store the Tix_DItemType information
|
||
* inside the widget record.
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
static int DItemParseProc(clientData, interp, tkwin, value, widRec,offset)
|
||
ClientData clientData;
|
||
Tcl_Interp *interp;
|
||
Tk_Window tkwin;
|
||
CONST84 char *value;
|
||
char *widRec;
|
||
int offset;
|
||
{
|
||
Tix_DItemInfo *newPtr;
|
||
Tix_DItemInfo **ptr = (Tix_DItemInfo **)(widRec + offset);
|
||
|
||
if (value == NULL) {
|
||
newPtr = NULL;
|
||
} else {
|
||
newPtr = Tix_GetDItemType(interp, value);
|
||
if (newPtr == NULL) {
|
||
return TCL_ERROR;
|
||
}
|
||
}
|
||
*ptr = newPtr;
|
||
|
||
return TCL_OK;
|
||
}
|
||
|
||
static char *DItemPrintProc(clientData, tkwin, widRec,offset, freeProcPtr)
|
||
ClientData clientData;
|
||
Tk_Window tkwin;
|
||
char *widRec;
|
||
int offset;
|
||
Tcl_FreeProc **freeProcPtr;
|
||
{
|
||
Tix_DItemInfo *diTypePtr = *((Tix_DItemInfo**)(widRec+offset));
|
||
|
||
if (diTypePtr != NULL) {
|
||
return diTypePtr->name;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
/*----------------------------------------------------------------------
|
||
*
|
||
*
|
||
* PRIVATE INTERFACE
|
||
*
|
||
*
|
||
* The following functions are called by display type implementors
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
/* The priority is selected > disabled > active > normal */
|
||
|
||
void
|
||
TixGetColorDItemGC(iPtr, backGC_ret, foreGC_ret, anchorGC_ret, flags)
|
||
Tix_DItem * iPtr;
|
||
GC * backGC_ret;
|
||
GC * foreGC_ret;
|
||
GC * anchorGC_ret;
|
||
int flags;
|
||
{
|
||
TixColorStyle * stylePtr = (TixColorStyle *) iPtr->base.stylePtr;
|
||
GC dummy;
|
||
int bg = 0;
|
||
|
||
if (backGC_ret == NULL) {
|
||
backGC_ret = &dummy;
|
||
}
|
||
if (foreGC_ret == NULL) {
|
||
foreGC_ret = &dummy;
|
||
}
|
||
if (anchorGC_ret == NULL) {
|
||
anchorGC_ret = &dummy;
|
||
}
|
||
|
||
if (flags & TIX_DITEM_SELECTED_FG) {
|
||
*foreGC_ret = stylePtr->colors[TIX_DITEM_SELECTED].foreGC;
|
||
}
|
||
else if (flags & TIX_DITEM_DISABLED_FG) {
|
||
*foreGC_ret = stylePtr->colors[TIX_DITEM_DISABLED].foreGC;
|
||
}
|
||
else if (flags & TIX_DITEM_ACTIVE_FG) {
|
||
*foreGC_ret = stylePtr->colors[TIX_DITEM_ACTIVE].foreGC;
|
||
}
|
||
else if (flags & TIX_DITEM_NORMAL_FG) {
|
||
*foreGC_ret = stylePtr->colors[TIX_DITEM_NORMAL].foreGC;
|
||
}
|
||
else {
|
||
*foreGC_ret = None;
|
||
}
|
||
|
||
if (flags & TIX_DITEM_SELECTED_BG) {
|
||
bg = TIX_DITEM_SELECTED;
|
||
} else if (flags & TIX_DITEM_DISABLED_BG) {
|
||
bg = TIX_DITEM_DISABLED;
|
||
} else if (flags & TIX_DITEM_ACTIVE_BG) {
|
||
bg = TIX_DITEM_ACTIVE;
|
||
} else if (flags & TIX_DITEM_NORMAL_BG) {
|
||
bg = TIX_DITEM_NORMAL;
|
||
} else {
|
||
bg = -1;
|
||
}
|
||
|
||
if (bg != -1) {
|
||
*backGC_ret = stylePtr->colors[bg].backGC;
|
||
} else {
|
||
*backGC_ret = None;
|
||
}
|
||
|
||
|
||
if ((flags & TIX_DITEM_ANCHOR) && (bg != -1)) {
|
||
*anchorGC_ret = stylePtr->colors[bg].anchorGC;
|
||
} else {
|
||
*anchorGC_ret = None;
|
||
}
|
||
}
|
||
|
||
/*----------------------------------------------------------------------
|
||
* TixDItemGetAnchor --
|
||
*
|
||
* Calculate the position of the element according to its anchor
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
void
|
||
TixDItemGetAnchor(anchor, x, y, cav_w, cav_h, width, height, x_ret, y_ret)
|
||
Tk_Anchor anchor;
|
||
int x;
|
||
int y;
|
||
int cav_w;
|
||
int cav_h;
|
||
int width;
|
||
int height;
|
||
int * x_ret;
|
||
int * y_ret;
|
||
{
|
||
if (width > cav_w) {
|
||
* x_ret = x;
|
||
} else {
|
||
int rem = cav_w - width;
|
||
|
||
switch (anchor) {
|
||
case TK_ANCHOR_NW: case TK_ANCHOR_W: case TK_ANCHOR_SW:
|
||
* x_ret = x;
|
||
break;
|
||
case TK_ANCHOR_N: case TK_ANCHOR_CENTER: case TK_ANCHOR_S:
|
||
* x_ret = x + rem/2;
|
||
break;
|
||
default:
|
||
* x_ret = x + rem;
|
||
}
|
||
}
|
||
if (height > cav_h) {
|
||
* y_ret = y;
|
||
}
|
||
else {
|
||
int rem = cav_h - height;
|
||
switch (anchor) {
|
||
case TK_ANCHOR_NW: case TK_ANCHOR_N: case TK_ANCHOR_NE:
|
||
* y_ret = y;
|
||
break;
|
||
case TK_ANCHOR_W: case TK_ANCHOR_CENTER: case TK_ANCHOR_E:
|
||
* y_ret = y + rem/2;
|
||
if ((rem % 2) == 1) {
|
||
/* Usually it looks better if we shift down one pixel
|
||
* if the hight of the region is an odd number of pixels
|
||
*/
|
||
* y_ret += 1;
|
||
}
|
||
break;
|
||
default:
|
||
* y_ret = y + rem;
|
||
}
|
||
}
|
||
}
|
||
|
||
int
|
||
Tix_DItemFillNormalBG(drawable, subRegPtr, iPtr, x, y, width, height,
|
||
xOffset, yOffset, flags)
|
||
Drawable drawable; /* Where to display this item */
|
||
TixpSubRegion *subRegPtr;
|
||
Tix_DItem * iPtr; /* Item to display */
|
||
int x; /* x pos of top-left corner of region
|
||
* to display item in */
|
||
int y; /* y pos of top-left corner of region */
|
||
int width; /* width of region */
|
||
int height; /* height of region */
|
||
int xOffset; /* X offset of item within region */
|
||
int yOffset; /* Y offset of item within region */
|
||
int flags; /* Controls how fg/bg/anchor lines are
|
||
* drawn */
|
||
{
|
||
GC gc;
|
||
|
||
if ((flags & TIX_DITEM_NORMAL_BG) == 0) {
|
||
return 0;
|
||
}
|
||
|
||
if (width == iPtr->base.size[0] && height == iPtr->base.size[1] &&
|
||
xOffset == 0 && yOffset == 0 &&
|
||
(flags & TIX_DITEM_OTHER_BG) != 0) {
|
||
/*
|
||
* The background area will be filled by another bg color, so
|
||
* there's no need to fill it with NORMAL_BG here.
|
||
*/
|
||
|
||
return 0;
|
||
}
|
||
|
||
gc = iPtr->base.stylePtr->colors[TIX_DITEM_NORMAL].backGC;
|
||
if (gc != None) {
|
||
TixpSubRegFillRectangle(iPtr->base.ddPtr->display, drawable,
|
||
gc, subRegPtr, x, y, width, height);
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* Tix_DItemDrawBackground --
|
||
*
|
||
* Display the background color of the item. The background and
|
||
* foreground of the item are displayed according to the flags
|
||
* parameter:
|
||
*
|
||
* If TIX_DITEM_NORMAL_BG is specified in flags, the entire {x, y,
|
||
* width, height} region is filled with the NORMAL_BG.
|
||
*
|
||
* If one of the following is specified, a filled highlight rect
|
||
* is drawn around the selectable area of the item.
|
||
*
|
||
* TIX_DITEM_ACTIVE_BG
|
||
* TIX_DITEM_SELECTED_BG
|
||
* TIX_DITEM_DISABLED_BG
|
||
*
|
||
* In addition, if TIX_DITEM_ANCHOR is specified in flags, an
|
||
* anchor rectangle is drawn around the selectable area of the
|
||
* item.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
Tix_DItemDrawBackground(drawable, subRegPtr, iPtr, x, y, width, height,
|
||
xOffset, yOffset, flags)
|
||
Drawable drawable; /* Where to display this item */
|
||
TixpSubRegion *subRegPtr;
|
||
Tix_DItem * iPtr; /* Item to display */
|
||
int x; /* x pos of top-left corner of region
|
||
* to display item in */
|
||
int y; /* y pos of top-left corner of region */
|
||
int width; /* width of region */
|
||
int height; /* height of region */
|
||
int xOffset; /* X offset of item within region */
|
||
int yOffset; /* Y offset of item within region */
|
||
int flags; /* Controls how fg/bg/anchor lines are
|
||
* drawn */
|
||
{
|
||
Display * display = iPtr->base.ddPtr->display;
|
||
GC backGC, anchorGC;
|
||
int bodyX, bodyY, bodyW, bodyH;
|
||
|
||
TixGetColorDItemGC(iPtr, &backGC, NULL, &anchorGC, flags);
|
||
|
||
/*
|
||
* Fill the entire region with the normal background color first
|
||
* (if necessary).
|
||
*/
|
||
|
||
Tix_DItemFillNormalBG(drawable, subRegPtr, iPtr, x, y, width, height,
|
||
xOffset, yOffset, flags);
|
||
|
||
/*
|
||
* Calculate the location of the item body.
|
||
*/
|
||
|
||
TixDItemGetAnchor(iPtr->base.stylePtr->anchor, x, y, width, height,
|
||
iPtr->base.size[0], iPtr->base.size[1], &x, &y);
|
||
|
||
x += xOffset;
|
||
y += yOffset;
|
||
|
||
bodyX = x + iPtr->base.selX;
|
||
bodyY = y + iPtr->base.selY;
|
||
bodyW = iPtr->base.selW;
|
||
bodyH = iPtr->base.selH;
|
||
|
||
/*
|
||
* Fill the selected background and draw anchor lines only around
|
||
* the item body itself
|
||
*/
|
||
|
||
if ((flags & TIX_DITEM_OTHER_BG) && (backGC != None)) {
|
||
TixpSubRegSetClip(display, subRegPtr, backGC);
|
||
TixpSubRegFillRectangle(display, drawable, backGC,
|
||
subRegPtr, bodyX, bodyY, bodyW, bodyH);
|
||
TixpSubRegUnsetClip(display, subRegPtr, backGC);
|
||
}
|
||
|
||
if (anchorGC != None) {
|
||
TixpSubRegSetClip(display, subRegPtr, anchorGC);
|
||
TixpSubRegDrawAnchorLines(display, drawable,
|
||
anchorGC, subRegPtr, bodyX, bodyY, bodyW, bodyH);
|
||
TixpSubRegUnsetClip(display, subRegPtr, anchorGC);
|
||
}
|
||
}
|