URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [insight/] [tix/] [generic/] [tixHLHdr.c] - Rev 1780
Go to most recent revision | Compare with Previous | Blame | View Log
/* * tixHLHdr.c --- * * * Implements headers for tixHList widgets * * Copyright (c) 1996, Expert Interface Technologies * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * */ #include <tixPort.h> #include <tixInt.h> #include <tixHList.h> #include <tixDef.h> static TIX_DECLARE_SUBCMD(Tix_HLHdrCreate); static TIX_DECLARE_SUBCMD(Tix_HLHdrConfig); static TIX_DECLARE_SUBCMD(Tix_HLHdrCGet); static TIX_DECLARE_SUBCMD(Tix_HLHdrDelete); static TIX_DECLARE_SUBCMD(Tix_HLHdrExist); static TIX_DECLARE_SUBCMD(Tix_HLHdrSize); static void FreeWindowItem _ANSI_ARGS_((Tcl_Interp *interp, WidgetPtr wPtr, HListHeader *hPtr)); static void FreeHeader _ANSI_ARGS_((Tcl_Interp *interp, WidgetPtr wPtr, HListHeader *hPtr)); static HListHeader* AllocHeader _ANSI_ARGS_((Tcl_Interp *interp, WidgetPtr wPtr)); static HListHeader* Tix_HLGetHeader _ANSI_ARGS_((Tcl_Interp * interp, WidgetPtr wPtr, char * string, int requireIPtr)); static Tk_ConfigSpec headerConfigSpecs[] = { {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL, (char *) NULL, 0, 0}, {TK_CONFIG_PIXELS, "-borderwidth", "headerBorderWidth", "BorderWidth", DEF_HLISTHEADER_BORDER_WIDTH, Tk_Offset(HListHeader, borderWidth), 0}, {TK_CONFIG_BORDER, "-headerbackground", "headerBackground", "Background", DEF_HLISTHEADER_BG_COLOR, Tk_Offset(HListHeader, background), TK_CONFIG_COLOR_ONLY}, {TK_CONFIG_BORDER, "-headerbackground", "headerBackground", "Background", DEF_HLISTHEADER_BG_MONO, Tk_Offset(HListHeader, background), TK_CONFIG_MONO_ONLY}, {TK_CONFIG_RELIEF, "-relief", "headerRelief", "Relief", DEF_HLISTHEADER_RELIEF, Tk_Offset(HListHeader, relief), 0}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0} }; /*---------------------------------------------------------------------- * * Local functions * *---------------------------------------------------------------------- */ static HListHeader* AllocHeader(interp, wPtr) Tcl_Interp *interp; WidgetPtr wPtr; { HListHeader * hPtr = (HListHeader*)ckalloc(sizeof(HListHeader)); hPtr->type = HLTYPE_HEADER; hPtr->self = (char*)hPtr; hPtr->wPtr = wPtr; hPtr->iPtr = NULL; hPtr->width = 0; hPtr->background = NULL; hPtr->relief = TK_RELIEF_RAISED; hPtr->borderWidth = 2; if (Tk_ConfigureWidget(interp, wPtr->dispData.tkwin, headerConfigSpecs, 0, 0, (char *)hPtr, 0) != TCL_OK) { /* some unrecoverable errors */ return NULL; } return hPtr; } static void FreeWindowItem(interp, wPtr, hPtr) Tcl_Interp *interp; WidgetPtr wPtr; HListHeader *hPtr; { Tix_WindowItemListRemove(&wPtr->mappedWindows, hPtr->iPtr); } static void FreeHeader(interp, wPtr, hPtr) Tcl_Interp *interp; WidgetPtr wPtr; HListHeader *hPtr; { if (hPtr->iPtr) { if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) { FreeWindowItem(interp, wPtr, hPtr); } Tix_DItemFree(hPtr->iPtr); } Tk_FreeOptions(headerConfigSpecs, (char *)hPtr, wPtr->dispData.display, 0); ckfree((char*) hPtr); } static HListHeader* Tix_HLGetHeader(interp, wPtr, string, requireIPtr) Tcl_Interp * interp; WidgetPtr wPtr; char * string; int requireIPtr; { int column; if (Tcl_GetInt(interp, string, &column) != TCL_OK) { return NULL; } if (column >= wPtr->numColumns || column < 0) { Tcl_AppendResult(interp, "Column \"", string, "\" does not exist", (char*)NULL); return NULL; } if (requireIPtr && wPtr->headers[column]->iPtr == NULL) { Tcl_AppendResult(interp, "Column \"", string, "\" does not have a header", (char*)NULL); return NULL; } return wPtr->headers[column]; } int Tix_HLCreateHeaders(interp, wPtr) Tcl_Interp *interp; WidgetPtr wPtr; { int i; wPtr->headers = (HListHeader**) ckalloc(sizeof(HListHeader*) * wPtr->numColumns); for (i=0; i<wPtr->numColumns; i++) { wPtr->headers[i] = NULL; } for (i=0; i<wPtr->numColumns; i++) { if ((wPtr->headers[i] = AllocHeader(interp, wPtr)) == NULL) { return TCL_ERROR; } } wPtr->headerDirty = 1; return TCL_OK; } void Tix_HLFreeHeaders(interp, wPtr) Tcl_Interp *interp; WidgetPtr wPtr; { int i; if (wPtr->headers == NULL) { return; } for (i=0; i<wPtr->numColumns; i++) { if (wPtr->headers[i] != NULL) { FreeHeader(interp, wPtr, wPtr->headers[i]); } } ckfree((char*)wPtr->headers); } void Tix_HLDrawHeader(wPtr, pixmap, gc, hdrX, hdrY, hdrW, hdrH, xOffset) WidgetPtr wPtr; Pixmap pixmap; GC gc; int hdrX; int hdrY; int hdrW; int hdrH; int xOffset; { int i, x, y; int drawnWidth; /* how much of the header have I drawn? */ int width; /* width of the current header item */ int winItemExtra; /* window items need a bit extra offset * because they must be places relative to * the main window, not the header subwindow */ x = hdrX - xOffset; y = hdrY; drawnWidth = 0; winItemExtra = wPtr->borderWidth + wPtr->highlightWidth; if (wPtr->needToRaise) { /* the needToRaise flag is set every time a new window item is * created inside the header of the HList. * * We need to make sure that the windows items in the list * body are clipped by the header subwindow. However, the window * items inside the header should be over the header subwindow. * * The two XRaiseWindow calls in this function make sure that * the stacking relationship as described above always hold */ XRaiseWindow(Tk_Display(wPtr->headerWin), Tk_WindowId(wPtr->headerWin)); } for (i=0; i<wPtr->numColumns; i++) { HListHeader * hPtr = wPtr->headers[i]; width = wPtr->actualSize[i].width; if (i == wPtr->numColumns-1) { /* If the widget is wider than required, * We need to extend the last item to the end of the list, * or otherwise we'll see a curtailed header */ if (drawnWidth + width <hdrW) { width = hdrW - drawnWidth; } } Tk_Fill3DRectangle(wPtr->dispData.tkwin, pixmap, hPtr->background, x, y, width, wPtr->headerHeight, hPtr->borderWidth, hPtr->relief); /* Note when we draw the item, we use the * wPtr->actualSize[i].width instead of the (possibly extended) width * so that the header is well-aligned with the element columns. */ if (hPtr->iPtr) { int itemX, itemY; itemX = x+hPtr->borderWidth; itemY = y+hPtr->borderWidth; if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) { itemX += winItemExtra; itemY += winItemExtra; } Tix_DItemDisplay(pixmap, gc, hPtr->iPtr, itemX, itemY, wPtr->actualSize[i].width - 2*hPtr->borderWidth, wPtr->headerHeight - 2*hPtr->borderWidth, TIX_DITEM_NORMAL_FG); if (wPtr->needToRaise && Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) { TixWindowItem * wiPtr; wiPtr = (TixWindowItem *)hPtr->iPtr; if (Tk_WindowId(wiPtr->tkwin) == None) { Tk_MakeWindowExist(wiPtr->tkwin); } XRaiseWindow(Tk_Display(wiPtr->tkwin), Tk_WindowId(wiPtr->tkwin)); } } x += width; drawnWidth += width; #if 0 /* %% funny, doesn't work */ if (drawnWidth >= hdrW) { /* The rest is invisible. Don't bother to draw */ break; } #endif } wPtr->needToRaise = 0; } void Tix_HLComputeHeaderGeometry(wPtr) WidgetPtr wPtr; { int i; wPtr->headerHeight = 0; for (i=0; i<wPtr->numColumns; i++) { int height; int width; if (wPtr->headers[i]->iPtr) { width = Tix_DItemWidth (wPtr->headers[i]->iPtr); height = Tix_DItemHeight(wPtr->headers[i]->iPtr); } else { width = 0; height = 0; } width += wPtr->headers[i]->borderWidth * 2; height += wPtr->headers[i]->borderWidth * 2; wPtr->headers[i]->width = width; if (height > wPtr->headerHeight) { wPtr->headerHeight = height; } } wPtr->headerDirty = 0; } /*---------------------------------------------------------------------- * "header" sub command *---------------------------------------------------------------------- */ int Tix_HLHeader(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { static Tix_SubCmdInfo subCmdInfo[] = { {TIX_DEFAULT_LEN, "cget", 2, 2, Tix_HLHdrCGet, "column option"}, {TIX_DEFAULT_LEN, "configure", 1, TIX_VAR_ARGS, Tix_HLHdrConfig, "column ?option? ?value ...?"}, {TIX_DEFAULT_LEN, "create", 1, TIX_VAR_ARGS, Tix_HLHdrCreate, "column ?option value ...?"}, {TIX_DEFAULT_LEN, "delete", 1, 1, Tix_HLHdrDelete, "column"}, {TIX_DEFAULT_LEN, "exist", 1, 1, Tix_HLHdrExist, "column"}, {TIX_DEFAULT_LEN, "size", 1, 1, Tix_HLHdrSize, "column"}, }; static Tix_CmdInfo cmdInfo = { Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?", }; return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData, interp, argc+1, argv-1); } /*---------------------------------------------------------------------- * "header cget" sub command *---------------------------------------------------------------------- */ static int Tix_HLHdrCGet(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { WidgetPtr wPtr = (WidgetPtr) clientData; HListHeader * hPtr; if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) { return TCL_ERROR; } return Tix_ConfigureValue2(interp, wPtr->dispData.tkwin, (char*)hPtr, headerConfigSpecs, hPtr->iPtr, argv[1], 0); } /*---------------------------------------------------------------------- * "header configure" sub command *---------------------------------------------------------------------- */ static int Tix_HLHdrConfig(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { WidgetPtr wPtr = (WidgetPtr) clientData; HListHeader * hPtr; if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) { return TCL_ERROR; } if (argc == 1) { return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin, (char*)hPtr, headerConfigSpecs, hPtr->iPtr, (char *) NULL, 0); } else if (argc == 2) { return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin, (char*)hPtr, headerConfigSpecs, hPtr->iPtr, (char *) argv[1], 0); } else { int sizeChanged = 0; if (Tix_WidgetConfigure2(interp, wPtr->dispData.tkwin, (char*)hPtr, headerConfigSpecs, hPtr->iPtr, argc-1, argv+1, TK_CONFIG_ARGV_ONLY, 0, &sizeChanged) != TCL_OK) { return TCL_ERROR; } if (sizeChanged) { wPtr->headerDirty = 1; Tix_HLResizeWhenIdle(wPtr); } return TCL_OK; } } /*---------------------------------------------------------------------- * "header create" sub command *---------------------------------------------------------------------- */ static int Tix_HLHdrCreate(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { WidgetPtr wPtr = (WidgetPtr) clientData; HListHeader * hPtr; int i; Tix_DItem * iPtr; char * ditemType = NULL; if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 0)) == NULL) { return TCL_ERROR; } if ((argc %2) == 0) { Tcl_AppendResult(interp, "value for \"", argv[argc-1], "\" missing", NULL); return TCL_ERROR; } for (i=1; i<argc; i+=2) { if (strncmp(argv[i], "-itemtype", strlen(argv[i])) == 0) { ditemType = argv[i+1]; } } if (ditemType == NULL) { ditemType = wPtr->diTypePtr->name; } iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType); if (iPtr == NULL) { return TCL_ERROR; } if (Tix_DItemType(iPtr) == TIX_DITEM_WINDOW) { wPtr->needToRaise = 1; } /* * mark clientData to NULL. This will tell DItemSizeChanged() * that ths item belongs to the header */ iPtr->base.clientData = (ClientData)hPtr; if (hPtr->iPtr != NULL) { if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) { FreeWindowItem(interp, wPtr, hPtr); } Tix_DItemFree(hPtr->iPtr); } hPtr->iPtr = iPtr; if (Tix_WidgetConfigure2(wPtr->dispData.interp, wPtr->dispData.tkwin, (char*)hPtr, headerConfigSpecs, hPtr->iPtr, argc-1, argv+1, 0, 1, NULL) != TCL_OK) { return TCL_ERROR; } wPtr->headerDirty = 1; Tix_HLResizeWhenIdle(wPtr); return TCL_OK; } /*---------------------------------------------------------------------- * "header delete" sub command *---------------------------------------------------------------------- */ static int Tix_HLHdrDelete(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { WidgetPtr wPtr = (WidgetPtr) clientData; HListHeader * hPtr; if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) { return TCL_ERROR; } if (Tix_DItemType(hPtr->iPtr) == TIX_DITEM_WINDOW) { FreeWindowItem(interp, wPtr, hPtr); } /* Free the item and leave a blank! */ Tix_DItemFree(hPtr->iPtr); hPtr->iPtr = NULL; wPtr->headerDirty = 1; Tix_HLResizeWhenIdle(wPtr); return TCL_OK; } /*---------------------------------------------------------------------- * "header exist" sub command *---------------------------------------------------------------------- */ static int Tix_HLHdrExist(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { WidgetPtr wPtr = (WidgetPtr) clientData; HListHeader * hPtr; if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 0)) == NULL) { return TCL_ERROR; } if (hPtr->iPtr == NULL) { Tcl_AppendResult(interp, "0", NULL); } else { Tcl_AppendResult(interp, "1", NULL); } return TCL_OK; } /*---------------------------------------------------------------------- * "header size" sub command *---------------------------------------------------------------------- */ static int Tix_HLHdrSize(clientData, interp, argc, argv) ClientData clientData; Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { WidgetPtr wPtr = (WidgetPtr) clientData; HListHeader * hPtr; char buff[128]; if ((hPtr=Tix_HLGetHeader(interp, wPtr, argv[0], 1)) == NULL) { return TCL_ERROR; } if (hPtr->iPtr == NULL) { Tcl_AppendResult(interp, "entry \"", argv[0], "\" does not have a header", (char*)NULL); return TCL_ERROR; } sprintf(buff, "%d %d", Tix_DItemWidth(hPtr->iPtr), Tix_DItemHeight(hPtr->iPtr)); Tcl_AppendResult(interp, buff, NULL); return TCL_OK; }
Go to most recent revision | Compare with Previous | Blame | View Log