diff options
author | joye <joye> | 2014-02-26 17:06:34 (GMT) |
---|---|---|
committer | joye <joye> | 2014-02-26 17:06:34 (GMT) |
commit | abc503d7baf8ad69d6a21fb1c00fd428cb9c94d2 (patch) | |
tree | a99d2718274502cedd0b645570770ee31a00a11c /src | |
parent | 42b9ec29fb3511127ff686e58d59e8233cac37a3 (diff) | |
download | blt-abc503d7baf8ad69d6a21fb1c00fd428cb9c94d2.zip blt-abc503d7baf8ad69d6a21fb1c00fd428cb9c94d2.tar.gz blt-abc503d7baf8ad69d6a21fb1c00fd428cb9c94d2.tar.bz2 |
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r-- | src/bltGrElemOp.C | 392 | ||||
-rw-r--r-- | src/bltGrElemOp.h | 17 | ||||
-rw-r--r-- | src/bltGrHairs.C | 123 | ||||
-rw-r--r-- | src/bltGrLegd.C | 468 | ||||
-rw-r--r-- | src/bltGrPenOp.C | 28 | ||||
-rw-r--r-- | src/bltGraph.C | 211 | ||||
-rw-r--r-- | src/bltGraph.h | 21 |
7 files changed, 594 insertions, 666 deletions
diff --git a/src/bltGrElemOp.C b/src/bltGrElemOp.C index 8ca9e8c..5e954ad 100644 --- a/src/bltGrElemOp.C +++ b/src/bltGrElemOp.C @@ -54,8 +54,14 @@ static int GetPenStyleFromObj(Tcl_Interp *interp, Graph *graphPtr, PenStyle *stylePtr); static int GetVectorData(Tcl_Interp *interp, ElemValues *valuesPtr, const char *vecName); +static void DestroyElement(Element *elemPtr); +static int ElementObjConfigure(Tcl_Interp *interp, Graph* graphPtr, + Element* elemPtr, + int objc, Tcl_Obj* const objv[]); +typedef int (GraphElementProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, + Tcl_Obj *const *objv); -//** +// OptionSpecs // Fill char* fillObjOption[] = {"none", "x", "y", "both", NULL}; @@ -274,26 +280,149 @@ Tcl_Obj* StyleGetProc(ClientData clientData, Tk_Window tkwin, return listObjPtr; } -//** - -/* Along */ -static Blt_OptionParseProc ObjToAlong; -static Blt_OptionPrintProc AlongToObj; -static Blt_CustomOption alongOption = - { - ObjToAlong, AlongToObj, NULL, (ClientData)0 - }; +// Configure static Blt_VectorChangedProc VectorChangedProc; -static Tcl_FreeProc FreeElement; +static int CreateElement(Graph *graphPtr, Tcl_Interp *interp, int objc, + Tcl_Obj *const *objv, ClassId classId) +{ + Element *elemPtr; + Tcl_HashEntry *hPtr; + int isNew; + char *string; + + string = Tcl_GetString(objv[3]); + if (string[0] == '-') { + Tcl_AppendResult(graphPtr->interp, "name of element \"", string, + "\" can't start with a '-'", (char *)NULL); + return TCL_ERROR; + } + hPtr = Tcl_CreateHashEntry(&graphPtr->elements.table, string, &isNew); + if (!isNew) { + Tcl_AppendResult(interp, "element \"", string, + "\" already exists in \"", Tcl_GetString(objv[0]), + "\"", (char *)NULL); + return TCL_ERROR; + } + switch (classId) { + case CID_ELEM_BAR: + elemPtr = Blt_BarElement(graphPtr, string, classId); + break; + case CID_ELEM_LINE: + elemPtr = Blt_LineElement(graphPtr, string, classId); + break; + default: + return TCL_ERROR; + } + if (!elemPtr) + return TCL_ERROR; + + elemPtr->hashPtr = hPtr; + Tcl_SetHashValue(hPtr, elemPtr); + + if ((Tk_InitOptions(graphPtr->interp, (char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4) != TCL_OK)) { + DestroyElement(elemPtr); + return TCL_ERROR; + } + + elemPtr->link = Blt_Chain_Append(graphPtr->elements.displayList, elemPtr); + graphPtr->flags |= CACHE_DIRTY; + Blt_EventuallyRedrawGraph(graphPtr); + elemPtr->flags |= MAP_ITEM; + graphPtr->flags |= RESET_AXES; + Tcl_SetObjResult(interp, objv[3]); + return TCL_OK; +} + +static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "cget option"); + return TCL_ERROR; + } + + Element *elemPtr; + if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) + return TCL_ERROR; + + Tcl_Obj* objPtr = Tk_GetOptionValue(interp, (char*)elemPtr, + elemPtr->optionTable, + objv[4], graphPtr->tkwin); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; +} + +static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + Element* elemPtr; + if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) + return TCL_ERROR; + + if (objc <= 5) { + Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp, (char*)elemPtr, + elemPtr->optionTable, + (objc == 5) ? objv[4] : NULL, + graphPtr->tkwin); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } + else + return ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4); +} static int ElementObjConfigure(Tcl_Interp *interp, Graph* graphPtr, Element* elemPtr, - int objc, Tcl_Obj* const objv[]); -typedef int (GraphElementProc)(Graph *graphPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const *objv); + int objc, Tcl_Obj* const objv[]) +{ + Tk_SavedOptions savedOptions; + int mask =0; + int error; + Tcl_Obj* errorResult; + + for (error=0; error<=1; error++) { + if (!error) { + if (Tk_SetOptions(interp, (char*)elemPtr, elemPtr->optionTable, + objc, objv, graphPtr->tkwin, &savedOptions, &mask) + != TCL_OK) + continue; + } + else { + errorResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(errorResult); + Tk_RestoreSavedOptions(&savedOptions); + } + + graphPtr->flags |= mask; + graphPtr->flags |= CACHE_DIRTY; + if ((*elemPtr->procsPtr->configProc) (graphPtr, elemPtr) != TCL_OK) + return TCL_ERROR; + Blt_EventuallyRedrawGraph(graphPtr); + + break; + } + + if (!error) { + Tk_FreeSavedOptions(&savedOptions); + return TCL_OK; + } + else { + Tcl_SetObjResult(interp, errorResult); + Tcl_DecrRefCount(errorResult); + return TCL_ERROR; + } +} + +// Support static int GetPenStyleFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, ClassId classId, @@ -522,52 +651,6 @@ double Blt_FindElemValuesMinimum(ElemValues *valuesPtr, double minLimit) return min; } -static int ObjToAlong(ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, Tcl_Obj *objPtr, char *widgRec, - int offset, int flags) -{ - int *intPtr = (int *)(widgRec + offset); - char *string; - - string = Tcl_GetString(objPtr); - if ((string[0] == 'x') && (string[1] == '\0')) { - *intPtr = SEARCH_X; - } else if ((string[0] == 'y') && (string[1] == '\0')) { - *intPtr = SEARCH_Y; - } else if ((string[0] == 'b') && (strcmp(string, "both") == 0)) { - *intPtr = SEARCH_BOTH; - } else { - Tcl_AppendResult(interp, "bad along value \"", string, "\"", - (char *)NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -static Tcl_Obj *AlongToObj(ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, char *widgRec, int offset, - int flags) -{ - int along = *(int *)(widgRec + offset); - Tcl_Obj *objPtr; - - switch (along) { - case SEARCH_X: - objPtr = Tcl_NewStringObj("x", 1); - break; - case SEARCH_Y: - objPtr = Tcl_NewStringObj("y", 1); - break; - case SEARCH_BOTH: - objPtr = Tcl_NewStringObj("both", 4); - break; - default: - objPtr = Tcl_NewStringObj("unknown along value", 4); - break; - } - return objPtr; -} - void Blt_FreeStylePalette(Blt_Chain stylePalette) { Blt_ChainLink link; @@ -714,57 +797,6 @@ static void FreeElement(char* data) DestroyElement(elemPtr); } -static int CreateElement(Graph *graphPtr, Tcl_Interp *interp, int objc, - Tcl_Obj *const *objv, ClassId classId) -{ - Element *elemPtr; - Tcl_HashEntry *hPtr; - int isNew; - char *string; - - string = Tcl_GetString(objv[3]); - if (string[0] == '-') { - Tcl_AppendResult(graphPtr->interp, "name of element \"", string, - "\" can't start with a '-'", (char *)NULL); - return TCL_ERROR; - } - hPtr = Tcl_CreateHashEntry(&graphPtr->elements.table, string, &isNew); - if (!isNew) { - Tcl_AppendResult(interp, "element \"", string, - "\" already exists in \"", Tcl_GetString(objv[0]), - "\"", (char *)NULL); - return TCL_ERROR; - } - switch (classId) { - case CID_ELEM_BAR: - elemPtr = Blt_BarElement(graphPtr, string, classId); - break; - case CID_ELEM_LINE: - elemPtr = Blt_LineElement(graphPtr, string, classId); - break; - default: - return TCL_ERROR; - } - if (!elemPtr) - return TCL_ERROR; - - elemPtr->hashPtr = hPtr; - Tcl_SetHashValue(hPtr, elemPtr); - - if ((Tk_InitOptions(graphPtr->interp, (char*)elemPtr, elemPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4) != TCL_OK)) { - DestroyElement(elemPtr); - return TCL_ERROR; - } - - elemPtr->link = Blt_Chain_Append(graphPtr->elements.displayList, elemPtr); - graphPtr->flags |= CACHE_DIRTY; - Blt_EventuallyRedrawGraph(graphPtr); - elemPtr->flags |= MAP_ITEM; - graphPtr->flags |= RESET_AXES; - Tcl_SetObjResult(interp, objv[3]); - return TCL_OK; -} - void Blt_DestroyElements(Graph *graphPtr) { Tcl_HashEntry *hPtr; @@ -896,91 +928,6 @@ ClientData Blt_MakeElementTag(Graph *graphPtr, const char *tagName) return Tcl_GetHashKey(&graphPtr->elements.tagTable, hPtr); } -static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - if (objc != 5) { - Tcl_WrongNumArgs(interp, 3, objv, "cget option"); - return TCL_ERROR; - } - - Element *elemPtr; - if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) - return TCL_ERROR; - - Tcl_Obj* objPtr = Tk_GetOptionValue(interp, (char*)elemPtr, - elemPtr->optionTable, - objv[4], graphPtr->tkwin); - if (objPtr == NULL) - return TCL_ERROR; - else - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; -} - -static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - Element* elemPtr; - if (Blt_GetElement(interp, graphPtr, objv[3], &elemPtr) != TCL_OK) - return TCL_ERROR; - - if (objc <= 5) { - Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp, (char*)elemPtr, - elemPtr->optionTable, - (objc == 5) ? objv[4] : NULL, - graphPtr->tkwin); - if (objPtr == NULL) - return TCL_ERROR; - else - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; - } - else - return ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4); -} - -static int ElementObjConfigure(Tcl_Interp *interp, Graph* graphPtr, - Element* elemPtr, - int objc, Tcl_Obj* const objv[]) -{ - Tk_SavedOptions savedOptions; - int mask =0; - int error; - Tcl_Obj* errorResult; - - for (error=0; error<=1; error++) { - if (!error) { - if (Tk_SetOptions(interp, (char*)elemPtr, elemPtr->optionTable, - objc, objv, graphPtr->tkwin, &savedOptions, &mask) - != TCL_OK) - continue; - } - else { - errorResult = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(errorResult); - Tk_RestoreSavedOptions(&savedOptions); - } - - graphPtr->flags |= mask; - graphPtr->flags |= CACHE_DIRTY; - if ((*elemPtr->procsPtr->configProc) (graphPtr, elemPtr) != TCL_OK) - return TCL_ERROR; - Blt_EventuallyRedrawGraph(graphPtr); - - break; - } - - if (!error) { - Tk_FreeSavedOptions(&savedOptions); - return TCL_OK; - } - else { - Tcl_SetObjResult(interp, errorResult); - Tcl_DecrRefCount(errorResult); - return TCL_ERROR; - } -} // waj /* if (Blt_ConfigModified(elemPtr->configSpecs, "-hide", (char *)NULL)) { @@ -1091,6 +1038,59 @@ static int CreateOp(Graph *graphPtr, Tcl_Interp *interp, return CreateElement(graphPtr, interp, objc, objv, classId); } +static Blt_OptionParseProc ObjToAlong; +static Blt_OptionPrintProc AlongToObj; +static Blt_CustomOption alongOption = + { + ObjToAlong, AlongToObj, NULL, (ClientData)0 + }; + +static int ObjToAlong(ClientData clientData, Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj *objPtr, char *widgRec, + int offset, int flags) +{ + int *intPtr = (int *)(widgRec + offset); + char *string; + + string = Tcl_GetString(objPtr); + if ((string[0] == 'x') && (string[1] == '\0')) { + *intPtr = SEARCH_X; + } else if ((string[0] == 'y') && (string[1] == '\0')) { + *intPtr = SEARCH_Y; + } else if ((string[0] == 'b') && (strcmp(string, "both") == 0)) { + *intPtr = SEARCH_BOTH; + } else { + Tcl_AppendResult(interp, "bad along value \"", string, "\"", + (char *)NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +static Tcl_Obj *AlongToObj(ClientData clientData, Tcl_Interp *interp, + Tk_Window tkwin, char *widgRec, int offset, + int flags) +{ + int along = *(int *)(widgRec + offset); + Tcl_Obj *objPtr; + + switch (along) { + case SEARCH_X: + objPtr = Tcl_NewStringObj("x", 1); + break; + case SEARCH_Y: + objPtr = Tcl_NewStringObj("y", 1); + break; + case SEARCH_BOTH: + objPtr = Tcl_NewStringObj("both", 4); + break; + default: + objPtr = Tcl_NewStringObj("unknown along value", 4); + break; + } + return objPtr; +} + static Blt_ConfigSpec closestSpecs[] = { {BLT_CONFIG_PIXELS, "-halo", (char *)NULL, (char *)NULL, (char *)NULL, Tk_Offset(ClosestSearch, halo), 0}, diff --git a/src/bltGrElemOp.h b/src/bltGrElemOp.h index 1919041..46186eb 100644 --- a/src/bltGrElemOp.h +++ b/src/bltGrElemOp.h @@ -83,6 +83,23 @@ typedef struct { int nSegments; } ErrorBarSegments; +struct _Pen { + const char *name; /* Pen style identifier. If NULL pen + * was statically allocated. */ + ClassId classId; /* Type element using this pen. */ + const char *typeId; /* String token identifying the type of + * pen. */ + unsigned int flags; /* Indicates if the pen element is + * active or normal. */ + int refCount; /* Reference count for elements using + * this pen. */ + Tcl_HashEntry *hashPtr; + Tk_OptionTable optionTable; /* Configuration specifications */ + PenConfigureProc *configProc; + PenDestroyProc *destroyProc; + Graph *graphPtr; /* Graph that the pen is associated*/ +}; + /* * An element has one or more vectors plus several attributes, such as line * style, thickness, color, and symbol type. It has an identifier which diff --git a/src/bltGrHairs.C b/src/bltGrHairs.C index 38f8e86..e5de09d 100644 --- a/src/bltGrHairs.C +++ b/src/bltGrHairs.C @@ -44,7 +44,7 @@ struct _Crosshairs { XPoint hotSpot; /* Hot spot for crosshairs */ int visible; /* Internal state of crosshairs. If non-zero, * crosshairs are displayed. */ - int hidden; /* If non-zero, crosshairs are not displayed. + int hide; /* If non-zero, crosshairs are not displayed. * This is not necessarily consistent with the * internal state variable. This is true when * the hot spot is off the graph. */ @@ -60,48 +60,64 @@ struct _Crosshairs { * GXxor to not require redraws of graph */ }; -#define DEF_HAIRS_DASHES NULL -#define DEF_HAIRS_FOREGROUND black -#define DEF_HAIRS_LINE_WIDTH "0" -#define DEF_HAIRS_HIDE "yes" -#define DEF_HAIRS_POSITION NULL +static int CrosshairsObjConfigure(Tcl_Interp* interp, Graph* graphPtr, + int objc, Tcl_Obj* const objv[]); +static void ConfigureCrosshairs(Graph *graphPtr); +static void TurnOffHairs(Tk_Window tkwin, Crosshairs *chPtr); +static void TurnOnHairs(Graph *graphPtr, Crosshairs *chPtr); + +// OptionSpecs static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_COLOR, "-color", "color", "Color", - DEF_HAIRS_FOREGROUND, - -1, Tk_Offset(Crosshairs, colorPtr), 0, NULL, 0}, + "green", -1, Tk_Offset(Crosshairs, colorPtr), 0, NULL, 0}, {TK_OPTION_CUSTOM, "-dashes", "dashes", "Dashes", - DEF_HAIRS_DASHES, - -1, Tk_Offset(Crosshairs, dashes), TK_OPTION_NULL_OK, &dashesObjOption, 0}, + NULL, -1, Tk_Offset(Crosshairs, dashes), + TK_OPTION_NULL_OK, &dashesObjOption, 0}, {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide", - DEF_HAIRS_HIDE, - -1, Tk_Offset(Crosshairs, hidden), 0, NULL, 0}, + "yes", -1, Tk_Offset(Crosshairs, hide), 0, NULL, 0}, {TK_OPTION_PIXELS, "-linewidth", "lineWidth", "Linewidth", - DEF_HAIRS_LINE_WIDTH, - -1, Tk_Offset(Crosshairs, lineWidth), 0, NULL, 0}, + "0", -1, Tk_Offset(Crosshairs, lineWidth), 0, NULL, 0}, {TK_OPTION_CUSTOM, "-position", "position", "Position", - DEF_HAIRS_POSITION, - -1, Tk_Offset(Crosshairs, hotSpot), 0, &pointObjOption, 0}, + NULL, -1, Tk_Offset(Crosshairs, hotSpot), + TK_OPTION_NULL_OK, &pointObjOption, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static int CrosshairsObjConfigure(Tcl_Interp* interp, Graph* graphPtr, - int objc, Tcl_Obj* const objv[]); -static void ConfigureCrosshairs(Graph *graphPtr); -static void TurnOffHairs(Tk_Window tkwin, Crosshairs *chPtr); -static void TurnOnHairs(Graph *graphPtr, Crosshairs *chPtr); +// Create int Blt_CreateCrosshairs(Graph* graphPtr) { Crosshairs* chPtr = calloc(1, sizeof(Crosshairs)); chPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); - chPtr->hidden = TRUE; + chPtr->hide = TRUE; chPtr->hotSpot.x = chPtr->hotSpot.y = -1; graphPtr->crosshairs = chPtr; return TCL_OK; } +void Blt_DeleteCrosshairs(Graph* graphPtr) +{ + Crosshairs *chPtr = graphPtr->crosshairs; + if (chPtr != NULL) + Tk_FreeConfigOptions((char*)chPtr, chPtr->optionTable, graphPtr->tkwin); +} + +void Blt_DestroyCrosshairs(Graph* graphPtr) +{ + Crosshairs *chPtr = graphPtr->crosshairs; + if (chPtr != NULL) { + Tk_DeleteOptionTable(chPtr->optionTable); + if (chPtr->gc != NULL) + Blt_FreePrivateGC(graphPtr->display, chPtr->gc); + + free(chPtr); + } +} + +// Configure + int Blt_ConfigureObjCrosshairs(Graph* graphPtr, int objc, Tcl_Obj* const objv[]) { @@ -110,22 +126,6 @@ int Blt_ConfigureObjCrosshairs(Graph* graphPtr, graphPtr->tkwin); } -static Blt_OpSpec xhairOps[]; -static int nXhairOps; -typedef int (GraphCrosshairProc)(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]); - -int Blt_CrosshairsOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) -{ - GraphCrosshairProc* proc = Blt_GetOpFromObj(interp, nXhairOps, xhairOps, - BLT_OP_ARG2, objc, objv, 0); - if (proc == NULL) - return TCL_ERROR; - - return (*proc)(graphPtr, interp, objc, objv); -} - static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { @@ -242,27 +242,26 @@ static void ConfigureCrosshairs(Graph *graphPtr) chPtr->segArr[1].x1 = graphPtr->left; chPtr->segArr[1].x2 = graphPtr->right; - if (!chPtr->hidden) + if (!chPtr->hide) TurnOnHairs(graphPtr, chPtr); } -void Blt_DeleteCrosshairs(Graph* graphPtr) -{ - Crosshairs *chPtr = graphPtr->crosshairs; - if (chPtr != NULL) - Tk_FreeConfigOptions((char*)chPtr, chPtr->optionTable, graphPtr->tkwin); -} +// Ops -void Blt_DestroyCrosshairs(Graph* graphPtr) +static Blt_OpSpec xhairOps[]; +static int nXhairOps; +typedef int (GraphCrosshairProc)(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]); + +int Blt_CrosshairsOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { - Crosshairs *chPtr = graphPtr->crosshairs; - if (chPtr != NULL) { - Tk_DeleteOptionTable(chPtr->optionTable); - if (chPtr->gc != NULL) - Blt_FreePrivateGC(graphPtr->display, chPtr->gc); + GraphCrosshairProc* proc = Blt_GetOpFromObj(interp, nXhairOps, xhairOps, + BLT_OP_ARG2, objc, objv, 0); + if (proc == NULL) + return TCL_ERROR; - free(chPtr); - } + return (*proc)(graphPtr, interp, objc, objv); } // Widget commands @@ -272,9 +271,9 @@ static int OnOp(Graph *graphPtr, Tcl_Interp *interp, { Crosshairs *chPtr = graphPtr->crosshairs; - if (chPtr->hidden) { + if (chPtr->hide) { TurnOnHairs(graphPtr, chPtr); - chPtr->hidden = FALSE; + chPtr->hide = FALSE; } return TCL_OK; } @@ -284,9 +283,9 @@ static int OffOp(Graph *graphPtr, Tcl_Interp *interp, { Crosshairs *chPtr = graphPtr->crosshairs; - if (!chPtr->hidden) { + if (!chPtr->hide) { TurnOffHairs(graphPtr->tkwin, chPtr); - chPtr->hidden = TRUE; + chPtr->hide = TRUE; } return TCL_OK; } @@ -296,8 +295,8 @@ static int ToggleOp(Graph *graphPtr, Tcl_Interp *interp, { Crosshairs *chPtr = graphPtr->crosshairs; - chPtr->hidden = (chPtr->hidden == 0); - if (chPtr->hidden) + chPtr->hide = (chPtr->hide == 0); + if (chPtr->hide) TurnOffHairs(graphPtr->tkwin, chPtr); else TurnOnHairs(graphPtr, chPtr); @@ -340,14 +339,12 @@ static void TurnOnHairs(Graph *graphPtr, Crosshairs *chPtr) void Blt_EnableCrosshairs(Graph *graphPtr) { - if (!graphPtr->crosshairs->hidden) { + if (!graphPtr->crosshairs->hide) TurnOnHairs(graphPtr, graphPtr->crosshairs); - } } void Blt_DisableCrosshairs(Graph *graphPtr) { - if (!graphPtr->crosshairs->hidden) { + if (!graphPtr->crosshairs->hide) TurnOffHairs(graphPtr->tkwin, graphPtr->crosshairs); - } } diff --git a/src/bltGrLegd.C b/src/bltGrLegd.C index a63a0d6..eb283be 100644 --- a/src/bltGrLegd.C +++ b/src/bltGrLegd.C @@ -67,7 +67,11 @@ #define SELECT_BLTMASK (SELECT_SET | SELECT_CLEAR) #define SELECT_SORTED (1<<20) -typedef enum {SELECT_MODE_SINGLE, SELECT_MODE_MULTIPLE} SelectMode; +#define LABEL_PAD 2 + +typedef enum { + SELECT_MODE_SINGLE, SELECT_MODE_MULTIPLE +} SelectMode; struct _Legend { Tk_OptionTable optionTable; @@ -137,7 +141,6 @@ struct _Legend { GC focusGC; /* Graphics context for the active * label. */ - const char *takeFocus; int focus; /* Position of the focus entry. */ int cursorX, cursorY; /* Position of the insertion cursor in @@ -183,43 +186,6 @@ struct _Legend { TextStyle titleStyle; /* Legend title attributes */ }; -#define LABEL_PAD 2 - -#define DEF_LEGEND_ACTIVEBACKGROUND skyblue4 -#define DEF_LEGEND_ACTIVEBORDERWIDTH STD_BORDERWIDTH -#define DEF_LEGEND_ACTIVEFOREGROUND white -#define DEF_LEGEND_ACTIVERELIEF "flat" -#define DEF_LEGEND_ANCHOR "n" -#define DEF_LEGEND_BACKGROUND NULL -#define DEF_LEGEND_BORDERWIDTH STD_BORDERWIDTH -#define DEF_LEGEND_COLUMNS "0" -#define DEF_LEGEND_EXPORTSELECTION "no" -#define DEF_LEGEND_FONT "hevetica 8 normal roman" -#define DEF_LEGEND_FOREGROUND STD_NORMAL_FOREGROUND -#define DEF_LEGEND_HIDE "no" -#define DEF_LEGEND_IPADX "1" -#define DEF_LEGEND_IPADY "1" -#define DEF_LEGEND_PADX "1" -#define DEF_LEGEND_PADY "1" -#define DEF_LEGEND_POSITION "rightmargin" -#define DEF_LEGEND_RAISED "no" -#define DEF_LEGEND_RELIEF "flat" -#define DEF_LEGEND_ROWS "0" -#define DEF_LEGEND_SELECTBACKGROUND skyblue4 -#define DEF_LEGEND_SELECTBORDERWIDTH "1" -#define DEF_LEGEND_SELECTCOMMAND NULL -#define DEF_LEGEND_SELECTMODE "multiple" -#define DEF_LEGEND_SELECTFOREGROUND white -#define DEF_LEGEND_SELECTRELIEF "flat" -#define DEF_LEGEND_FOCUSDASHES "dot" -#define DEF_LEGEND_FOCUSEDIT "no" -#define DEF_LEGEND_FOCUSFOREGROUND STD_ACTIVE_FOREGROUND -#define DEF_LEGEND_TAKEFOCUS "1" -#define DEF_LEGEND_TITLE NULL -#define DEF_LEGEND_TITLEANCHOR "nw" -#define DEF_LEGEND_TITLECOLOR STD_NORMAL_FOREGROUND -#define DEF_LEGEND_TITLEFONT STD_FONT_SMALL - static int LegendObjConfigure(Tcl_Interp *interp, Graph* graphPtr, int objc, Tcl_Obj* const objv[]); static void ConfigureLegend(Graph *graphPtr); @@ -234,13 +200,23 @@ static void SelectEntry(Legend *legendPtr, Element *elemPtr); static int CreateLegendWindow(Tcl_Interp *interp, Legend *legendPtr, const char *pathName); -// SelectMode +static Tcl_IdleProc DisplayLegend; +static Blt_BindPickProc PickEntryProc; +static Tk_EventProc LegendEventProc; +static Tcl_TimerProc BlinkCursorProc; +static Tk_LostSelProc LostSelectionProc; +static Tk_SelectionProc SelectionProc; + +extern Tcl_ObjCmdProc Blt_GraphInstCmdProc; + +typedef int (GraphLegendProc)(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]); + +// OptionSpecs static char* selectmodeObjOption[] = {"single", "multiple", NULL}; -// Position - static Tk_CustomOptionSetProc PositionSetProc; static Tk_CustomOptionGetProc PositionGetProc; Tk_ObjCustomOption positionObjOption = @@ -345,133 +321,87 @@ static Tcl_Obj* PositionGetProc(ClientData clientData, Tk_Window tkwin, static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BORDER, "-activebackground", "activeBackground", "ActiveBackground", - DEF_LEGEND_ACTIVEBACKGROUND, - -1, Tk_Offset(Legend, activeBg), 0, NULL, 0}, + "skyblue4", -1, Tk_Offset(Legend, activeBg), 0, NULL, 0}, {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth", "ActiveBorderWidth", - DEF_LEGEND_BORDERWIDTH, - -1, Tk_Offset(Legend, entryBW), 0, NULL, 0}, + STD_BORDERWIDTH, -1, Tk_Offset(Legend, entryBW), 0, NULL, 0}, {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "ActiveForeground", - DEF_LEGEND_ACTIVEFOREGROUND, - -1, Tk_Offset(Legend, activeFgColor), 0, NULL, 0}, + "white", -1, Tk_Offset(Legend, activeFgColor), 0, NULL, 0}, {TK_OPTION_RELIEF, "-activerelief", "activeRelief", "ActiveRelief", - DEF_LEGEND_ACTIVERELIEF, - -1, Tk_Offset(Legend, activeRelief), 0, NULL, 0}, + "flat", -1, Tk_Offset(Legend, activeRelief), 0, NULL, 0}, {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", - DEF_LEGEND_ANCHOR, - -1, Tk_Offset(Legend, anchor), 0, NULL, 0}, - {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, - -1, 0, 0, "-background", 0}, + "n", -1, Tk_Offset(Legend, anchor), 0, NULL, 0}, + {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, -1, 0, 0, "-background", 0}, {TK_OPTION_BORDER, "-background", "background", "Background", - DEF_LEGEND_BACKGROUND, - -1, Tk_Offset(Legend, normalBg), TK_OPTION_NULL_OK, NULL, 0}, + NULL, -1, Tk_Offset(Legend, normalBg), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_LEGEND_BORDERWIDTH, - -1, Tk_Offset(Legend, borderWidth), 0, NULL, 0}, - {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, - -1, 0, 0, "-borderwidth", 0}, + STD_BORDERWIDTH, -1, Tk_Offset(Legend, borderWidth), 0, NULL, 0}, + {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, -1, 0, 0, "-borderwidth", 0}, {TK_OPTION_INT, "-columns", "columns", "columns", - DEF_LEGEND_COLUMNS, - -1, Tk_Offset(Legend, reqColumns), 0, NULL, 0}, + 0, -1, Tk_Offset(Legend, reqColumns), 0, NULL, 0}, {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", - DEF_LEGEND_EXPORTSELECTION, - -1, Tk_Offset(Legend, exportSelection), 0, NULL, 0}, + "no", -1, Tk_Offset(Legend, exportSelection), 0, NULL, 0}, {TK_OPTION_CUSTOM, "-focusdashes", "focusDashes", "FocusDashes", - DEF_LEGEND_FOCUSDASHES, - -1, Tk_Offset(Legend, focusDashes), TK_OPTION_NULL_OK, &dashesObjOption, 0}, + "dot", -1, Tk_Offset(Legend, focusDashes), + TK_OPTION_NULL_OK, &dashesObjOption, 0}, {TK_OPTION_COLOR, "-focusforeground", "focusForeground", "FocusForeground", - DEF_LEGEND_FOCUSFOREGROUND, - -1, Tk_Offset(Legend, focusColor), 0, NULL, 0}, + STD_ACTIVE_FOREGROUND, -1, Tk_Offset(Legend, focusColor), 0, NULL, 0}, {TK_OPTION_FONT, "-font", "font", "Font", - DEF_LEGEND_FONT, - -1, Tk_Offset(Legend, style.font), 0, NULL, 0}, - {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, - -1, 0, 0, "-foreground", 0}, + STD_FONT_SMALL, -1, Tk_Offset(Legend, style.font), 0, NULL, 0}, + {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL, -1, 0, 0, "-foreground", 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", - DEF_LEGEND_FOREGROUND, - -1, Tk_Offset(Legend, fgColor), 0, NULL, 0}, + STD_NORMAL_FOREGROUND, -1, Tk_Offset(Legend, fgColor), 0, NULL, 0}, {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide", - DEF_LEGEND_HIDE, - -1, Tk_Offset(Legend, hide), 0, NULL, 0}, + "no", -1, Tk_Offset(Legend, hide), 0, NULL, 0}, {TK_OPTION_PIXELS, "-ipadx", "iPadX", "Pad", - DEF_LEGEND_IPADX, - -1, Tk_Offset(Legend, ixPad), 0, NULL, 0}, + "1", -1, Tk_Offset(Legend, ixPad), 0, NULL, 0}, {TK_OPTION_PIXELS, "-ipady", "iPadY", "Pad", - DEF_LEGEND_IPADY, - -1, Tk_Offset(Legend, iyPad), 0, NULL, 0}, + "1", -1, Tk_Offset(Legend, iyPad), 0, NULL, 0}, {TK_OPTION_BORDER, "-nofocusselectbackground", "noFocusSelectBackground", "NoFocusSelectBackground", - DEF_LEGEND_SELECTBACKGROUND, - -1, Tk_Offset(Legend, selOutFocusBg), 0, NULL, 0}, + "skyblue4", -1, Tk_Offset(Legend, selOutFocusBg), 0, NULL, 0}, {TK_OPTION_COLOR, "-nofocusselectforeground", "noFocusSelectForeground", "NoFocusSelectForeground", - DEF_LEGEND_SELECTFOREGROUND, - -1, Tk_Offset(Legend, selOutFocusFgColor), 0, NULL, 0}, + "white", -1, Tk_Offset(Legend, selOutFocusFgColor), 0, NULL, 0}, {TK_OPTION_PIXELS, "-padx", "padX", "Pad", - DEF_LEGEND_PADX, - -1, Tk_Offset(Legend, xPad), 0, NULL, 0}, + "1", -1, Tk_Offset(Legend, xPad), 0, NULL, 0}, {TK_OPTION_PIXELS, "-pady", "padY", "Pad", - DEF_LEGEND_PADY, - -1, Tk_Offset(Legend, yPad), 0, NULL, 0}, + "1", -1, Tk_Offset(Legend, yPad), 0, NULL, 0}, {TK_OPTION_CUSTOM, "-position", "position", "Position", - DEF_LEGEND_POSITION, - -1, 0, 0, &positionObjOption, 0}, + "rightmargin", -1, 0, 0, &positionObjOption, 0}, {TK_OPTION_BOOLEAN, "-raised", "raised", "Raised", - DEF_LEGEND_RAISED, - -1, Tk_Offset(Legend, raised), 0, NULL, 0}, + "no", -1, Tk_Offset(Legend, raised), 0, NULL, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - DEF_LEGEND_RELIEF, - -1, Tk_Offset(Legend, relief), 0, NULL, 0}, + "flat", -1, Tk_Offset(Legend, relief), 0, NULL, 0}, {TK_OPTION_INT, "-rows", "rows", "rows", - DEF_LEGEND_ROWS, - -1, Tk_Offset(Legend, reqRows), 0, NULL, 0}, + 0, -1, Tk_Offset(Legend, reqRows), 0, NULL, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "SelectBackground", - DEF_LEGEND_SELECTBACKGROUND, - -1, Tk_Offset(Legend, selInFocusBg), 0, NULL, 0}, + "skyblue4", -1, Tk_Offset(Legend, selInFocusBg), 0, NULL, 0}, {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", "SelectBorderWidth", - DEF_LEGEND_SELECTBORDERWIDTH, - -1, Tk_Offset(Legend, selBW), 0, NULL, 0}, + "1", -1, Tk_Offset(Legend, selBW), 0, NULL, 0}, {TK_OPTION_STRING, "-selectcommand", "selectCommand", "SelectCommand", - DEF_LEGEND_SELECTCOMMAND, - -1, Tk_Offset(Legend, selectCmd), TK_OPTION_NULL_OK, NULL, 0}, + NULL, -1, Tk_Offset(Legend, selectCmd), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "SelectForeground", - DEF_LEGEND_SELECTFOREGROUND, - -1, Tk_Offset(Legend, selInFocusFgColor), 0, NULL, 0}, + "white", -1, Tk_Offset(Legend, selInFocusFgColor), 0, NULL, 0}, {TK_OPTION_STRING_TABLE, "-selectmode", "selectMode", "SelectMode", - DEF_LEGEND_SELECTMODE, - -1, Tk_Offset(Legend, selectMode), 0, &selectmodeObjOption, 0}, + "multiple", -1, Tk_Offset(Legend, selectMode), 0, &selectmodeObjOption, 0}, {TK_OPTION_RELIEF, "-selectrelief", "selectRelief", "SelectRelief", - DEF_LEGEND_SELECTRELIEF, - -1, Tk_Offset(Legend, selRelief), 0, NULL, 0}, - {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_LEGEND_TAKEFOCUS, - -1, Tk_Offset(Legend, takeFocus), TK_OPTION_NULL_OK, NULL, 0}, + "flat", -1, Tk_Offset(Legend, selRelief), 0, NULL, 0}, {TK_OPTION_STRING, "-title", "title", "Title", - DEF_LEGEND_TITLE, - -1, Tk_Offset(Legend, title), TK_OPTION_NULL_OK, NULL, 0}, + NULL, -1, Tk_Offset(Legend, title), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_ANCHOR, "-titleanchor", "titleAnchor", "TitleAnchor", - DEF_LEGEND_TITLEANCHOR, - -1, Tk_Offset(Legend, titleStyle.anchor), 0, NULL, 0}, + "nw", -1, Tk_Offset(Legend, titleStyle.anchor), 0, NULL, 0}, {TK_OPTION_COLOR, "-titlecolor", "titleColor", "TitleColor", - DEF_LEGEND_TITLECOLOR, - -1, Tk_Offset(Legend, titleStyle.color), 0, NULL, 0}, + STD_NORMAL_FOREGROUND, -1, Tk_Offset(Legend, titleStyle.color), 0, NULL, 0}, {TK_OPTION_FONT, "-titlefont", "titleFont", "TitleFont", - DEF_LEGEND_TITLEFONT, - -1, Tk_Offset(Legend, titleStyle.font), 0, NULL, 0}, + STD_FONT_SMALL, -1, Tk_Offset(Legend, titleStyle.font), 0, NULL, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static Tcl_IdleProc DisplayLegend; -static Blt_BindPickProc PickEntryProc; -static Tk_EventProc LegendEventProc; -static Tcl_TimerProc BlinkCursorProc; -static Tk_LostSelProc LostSelectionProc; -static Tk_SelectionProc SelectionProc; - -extern Tcl_ObjCmdProc Blt_GraphInstCmdProc; +// Create int Blt_CreateLegend(Graph* graphPtr) { @@ -513,27 +443,120 @@ int Blt_CreateLegend(Graph* graphPtr) return TCL_OK; } -int Blt_ConfigureObjLegend(Graph* graphPtr, int objc, Tcl_Obj* const objv[]) +void Blt_DeleteLegend(Graph* graphPtr) { - Legend* legendPtr = graphPtr->legend; - return Tk_InitOptions(graphPtr->interp, (char*)legendPtr, - legendPtr->optionTable, graphPtr->tkwin); + Legend *legendPtr = graphPtr->legend; + if (legendPtr != NULL) + Tk_FreeConfigOptions((char*)legendPtr, legendPtr->optionTable, + graphPtr->tkwin); } -static Blt_OpSpec legendOps[]; -static int nLegendOps; -typedef int (GraphLegendProc)(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]); +void Blt_DestroyLegend(Graph *graphPtr) +{ + Legend* legendPtr = graphPtr->legend; + if (legendPtr == NULL) + return; + Tk_DeleteOptionTable(legendPtr->optionTable); -int Blt_LegendOp(Graph* graphPtr, Tcl_Interp* interp, - int objc, Tcl_Obj* const objv[]) + Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->style); + Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->titleStyle); + Blt_DestroyBindingTable(legendPtr->bindTable); + + if (legendPtr->focusGC != NULL) { + Blt_FreePrivateGC(graphPtr->display, legendPtr->focusGC); + } + if (legendPtr->timerToken != NULL) { + Tcl_DeleteTimerHandler(legendPtr->timerToken); + } + if (legendPtr->tkwin != NULL) { + Tk_DeleteSelHandler(legendPtr->tkwin, XA_PRIMARY, XA_STRING); + } + if (legendPtr->site == LEGEND_WINDOW) { + Tk_Window tkwin; + + /* The graph may be in the process of being torn down */ + if (legendPtr->cmdToken != NULL) { + Tcl_DeleteCommandFromToken(graphPtr->interp, legendPtr->cmdToken); + } + if (legendPtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(DisplayLegend, legendPtr); + legendPtr->flags &= ~REDRAW_PENDING; + } + tkwin = legendPtr->tkwin; + legendPtr->tkwin = NULL; + if (tkwin != NULL) { + Tk_DeleteEventHandler(tkwin, ExposureMask | StructureNotifyMask, + LegendEventProc, graphPtr); + Tk_DestroyWindow(tkwin); + } + } + free(legendPtr); +} + +static void LegendEventProc(ClientData clientData, XEvent *eventPtr) { - GraphLegendProc *proc = Blt_GetOpFromObj(interp, nLegendOps, legendOps, - BLT_OP_ARG2, objc, objv,0); - if (proc == NULL) - return TCL_ERROR; + Graph *graphPtr = clientData; + Legend *legendPtr; - return (*proc) (graphPtr, interp, objc, objv); + legendPtr = graphPtr->legend; + if (eventPtr->type == Expose) { + if (eventPtr->xexpose.count == 0) { + Blt_Legend_EventuallyRedraw(graphPtr); + } + } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { + if (eventPtr->xfocus.detail == NotifyInferior) { + return; + } + if (eventPtr->type == FocusIn) { + legendPtr->flags |= FOCUS; + } else { + legendPtr->flags &= ~FOCUS; + } + Tcl_DeleteTimerHandler(legendPtr->timerToken); + if ((legendPtr->active) && (legendPtr->flags & FOCUS)) { + legendPtr->cursorOn = TRUE; + if (legendPtr->offTime != 0) { + legendPtr->timerToken = Tcl_CreateTimerHandler(legendPtr->onTime, + BlinkCursorProc, + graphPtr); + } + } else { + legendPtr->cursorOn = FALSE; + legendPtr->timerToken = (Tcl_TimerToken)NULL; + } + Blt_Legend_EventuallyRedraw(graphPtr); + } else if (eventPtr->type == DestroyNotify) { + Graph *graphPtr = legendPtr->graphPtr; + + if (legendPtr->site == LEGEND_WINDOW) { + if (legendPtr->cmdToken != NULL) { + Tcl_DeleteCommandFromToken(graphPtr->interp, + legendPtr->cmdToken); + legendPtr->cmdToken = NULL; + } + legendPtr->tkwin = graphPtr->tkwin; + } + if (legendPtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(DisplayLegend, legendPtr); + legendPtr->flags &= ~REDRAW_PENDING; + } + legendPtr->site = LEGEND_RIGHT; + legendPtr->hide = 1; + graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); + Blt_MoveBindingTable(legendPtr->bindTable, graphPtr->tkwin); + Blt_EventuallyRedrawGraph(graphPtr); + } else if (eventPtr->type == ConfigureNotify) { + Blt_Legend_EventuallyRedraw(graphPtr); + } +} + +// Configure + +int Blt_ConfigureObjLegend(Graph* graphPtr, int objc, Tcl_Obj* const objv[]) +{ + Legend* legendPtr = graphPtr->legend; + return Tk_InitOptions(graphPtr->interp, (char*)legendPtr, + legendPtr->optionTable, graphPtr->tkwin); } static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, @@ -636,139 +659,22 @@ static void ConfigureLegend(Graph *graphPtr) legendPtr->focusGC = newGC; } -static void DisplayLegend(ClientData clientData) -{ - Legend *legendPtr = clientData; - Graph *graphPtr; +// Ops - legendPtr->flags &= ~REDRAW_PENDING; - if (legendPtr->tkwin == NULL) { - return; /* Window has been destroyed. */ - } - graphPtr = legendPtr->graphPtr; - if (legendPtr->site == LEGEND_WINDOW) { - int w, h; - - w = Tk_Width(legendPtr->tkwin); - h = Tk_Height(legendPtr->tkwin); - if ((w != legendPtr->width) || (h != legendPtr->height)) { - Blt_MapLegend(graphPtr, w, h); - } - } - if (Tk_IsMapped(legendPtr->tkwin)) { - Blt_DrawLegend(graphPtr, Tk_WindowId(legendPtr->tkwin)); - } -} - -static void LegendEventProc(ClientData clientData, XEvent *eventPtr) -{ - Graph *graphPtr = clientData; - Legend *legendPtr; - - legendPtr = graphPtr->legend; - if (eventPtr->type == Expose) { - if (eventPtr->xexpose.count == 0) { - Blt_Legend_EventuallyRedraw(graphPtr); - } - } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { - if (eventPtr->xfocus.detail == NotifyInferior) { - return; - } - if (eventPtr->type == FocusIn) { - legendPtr->flags |= FOCUS; - } else { - legendPtr->flags &= ~FOCUS; - } - Tcl_DeleteTimerHandler(legendPtr->timerToken); - if ((legendPtr->active) && (legendPtr->flags & FOCUS)) { - legendPtr->cursorOn = TRUE; - if (legendPtr->offTime != 0) { - legendPtr->timerToken = Tcl_CreateTimerHandler(legendPtr->onTime, - BlinkCursorProc, - graphPtr); - } - } else { - legendPtr->cursorOn = FALSE; - legendPtr->timerToken = (Tcl_TimerToken)NULL; - } - Blt_Legend_EventuallyRedraw(graphPtr); - } else if (eventPtr->type == DestroyNotify) { - Graph *graphPtr = legendPtr->graphPtr; - - if (legendPtr->site == LEGEND_WINDOW) { - if (legendPtr->cmdToken != NULL) { - Tcl_DeleteCommandFromToken(graphPtr->interp, - legendPtr->cmdToken); - legendPtr->cmdToken = NULL; - } - legendPtr->tkwin = graphPtr->tkwin; - } - if (legendPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayLegend, legendPtr); - legendPtr->flags &= ~REDRAW_PENDING; - } - legendPtr->site = LEGEND_RIGHT; - legendPtr->hide = 1; - graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); - Blt_MoveBindingTable(legendPtr->bindTable, graphPtr->tkwin); - Blt_EventuallyRedrawGraph(graphPtr); - } else if (eventPtr->type == ConfigureNotify) { - Blt_Legend_EventuallyRedraw(graphPtr); - } -} - -void Blt_DeleteLegend(Graph* graphPtr) -{ - Legend *legendPtr = graphPtr->legend; - if (legendPtr != NULL) - Tk_FreeConfigOptions((char*)legendPtr, legendPtr->optionTable, - graphPtr->tkwin); -} +static Blt_OpSpec legendOps[]; +static int nLegendOps; -void Blt_DestroyLegend(Graph *graphPtr) +int Blt_LegendOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { - Legend* legendPtr = graphPtr->legend; - if (legendPtr == NULL) - return; - Tk_DeleteOptionTable(legendPtr->optionTable); + GraphLegendProc *proc = Blt_GetOpFromObj(interp, nLegendOps, legendOps, + BLT_OP_ARG2, objc, objv,0); + if (proc == NULL) + return TCL_ERROR; - Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->style); - Blt_Ts_FreeStyle(graphPtr->display, &legendPtr->titleStyle); - Blt_DestroyBindingTable(legendPtr->bindTable); - - if (legendPtr->focusGC != NULL) { - Blt_FreePrivateGC(graphPtr->display, legendPtr->focusGC); - } - if (legendPtr->timerToken != NULL) { - Tcl_DeleteTimerHandler(legendPtr->timerToken); - } - if (legendPtr->tkwin != NULL) { - Tk_DeleteSelHandler(legendPtr->tkwin, XA_PRIMARY, XA_STRING); - } - if (legendPtr->site == LEGEND_WINDOW) { - Tk_Window tkwin; - - /* The graph may be in the process of being torn down */ - if (legendPtr->cmdToken != NULL) { - Tcl_DeleteCommandFromToken(graphPtr->interp, legendPtr->cmdToken); - } - if (legendPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayLegend, legendPtr); - legendPtr->flags &= ~REDRAW_PENDING; - } - tkwin = legendPtr->tkwin; - legendPtr->tkwin = NULL; - if (tkwin != NULL) { - Tk_DeleteEventHandler(tkwin, ExposureMask | StructureNotifyMask, - LegendEventProc, graphPtr); - Tk_DestroyWindow(tkwin); - } - } - free(legendPtr); + return (*proc) (graphPtr, interp, objc, objv); } -// Widget commands - static int ActivateOp(Graph *graphPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { @@ -1167,6 +1073,30 @@ static int nSelectionOps = sizeof(selectionOps) / sizeof(Blt_OpSpec); // Support +static void DisplayLegend(ClientData clientData) +{ + Legend *legendPtr = clientData; + Graph *graphPtr; + + legendPtr->flags &= ~REDRAW_PENDING; + if (legendPtr->tkwin == NULL) { + return; /* Window has been destroyed. */ + } + graphPtr = legendPtr->graphPtr; + if (legendPtr->site == LEGEND_WINDOW) { + int w, h; + + w = Tk_Width(legendPtr->tkwin); + h = Tk_Height(legendPtr->tkwin); + if ((w != legendPtr->width) || (h != legendPtr->height)) { + Blt_MapLegend(graphPtr, w, h); + } + } + if (Tk_IsMapped(legendPtr->tkwin)) { + Blt_DrawLegend(graphPtr, Tk_WindowId(legendPtr->tkwin)); + } +} + void Blt_Legend_EventuallyRedraw(Graph *graphPtr) { Legend *legendPtr = graphPtr->legend; diff --git a/src/bltGrPenOp.C b/src/bltGrPenOp.C index d72b7e3..e1d5ec7 100644 --- a/src/bltGrPenOp.C +++ b/src/bltGrPenOp.C @@ -38,12 +38,9 @@ #include "bltInt.h" #include "bltGraph.h" +#include "bltGrElem.h" #include "bltOp.h" -typedef int (GraphPenProc)(Tcl_Interp *interp, Graph *graphPtr, int objc, - Tcl_Obj *const *objv); - -//*** static Tk_CustomOptionSetProc PenSetProc; static Tk_CustomOptionGetProc PenGetProc; Tk_ObjCustomOption barPenObjOption = @@ -95,6 +92,12 @@ static Tcl_Obj* PenGetProc(ClientData clientData, Tk_Window tkwin, return Tcl_NewStringObj(penPtr->name, -1); }; +static int PenObjConfigure(Tcl_Interp *interp, Graph* graphPtr, + Pen* penPtr, + int objc, Tcl_Obj* const objv[]); +typedef int (GraphPenProc)(Tcl_Interp *interp, Graph *graphPtr, int objc, + Tcl_Obj *const *objv); + static int GetPenFromObj(Tcl_Interp *interp, Graph *graphPtr, Tcl_Obj *objPtr, Pen **penPtrPtr) { @@ -207,19 +210,16 @@ Pen* Blt_CreatePen(Graph* graphPtr, const char* penName, ClassId classId, penPtr->graphPtr = graphPtr; Tcl_SetHashValue(hPtr, penPtr); } + /* - // waj - configFlags = (penPtr->flags & (ACTIVE_PEN | NORMAL_PEN)); - if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, - penPtr->name, "Pen", penPtr->configSpecs, objc, objv, - (char *)penPtr, configFlags) != TCL_OK) { - if (isNew) { - DestroyPen(penPtr); - } - return NULL; + if ((Tk_InitOptions(graphPtr->interp, (char*)penPtr, penPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (PenObjConfigure(interp, graphPtr, penPtr, objc-4, objv+4) != TCL_OK)) { + if (isNew) + DestroyElement(penPtr); + return TCL_ERROR; } */ - (*penPtr->configProc) (graphPtr, penPtr); + + // (*penPtr->configProc) (graphPtr, penPtr); return penPtr; } diff --git a/src/bltGraph.C b/src/bltGraph.C index 6238812..3409c5f 100644 --- a/src/bltGraph.C +++ b/src/bltGraph.C @@ -107,6 +107,28 @@ static const char* objectClassNames[] = { #define DEF_GRAPH_TITLE_COLOR STD_NORMAL_FOREGROUND #define DEF_GRAPH_WIDTH "5i" +static Tcl_IdleProc DisplayGraph; +static Tcl_FreeProc DestroyGraph; +static Tk_EventProc GraphEventProc; +Tcl_ObjCmdProc Blt_GraphInstCmdProc; + +static Tcl_ObjCmdProc BarchartObjCmd; +static Tcl_ObjCmdProc GraphObjCmd; +static Tcl_CmdDeleteProc GraphInstCmdDeleteProc; + +static Blt_BindPickProc PickEntry; + +static int NewGraph(ClientData clientData, Tcl_Interp*interp, + int objc, Tcl_Obj* const objv[], ClassId classId); +static int GraphObjConfigure(Tcl_Interp* interp, Graph* graphPtr, + int objc, Tcl_Obj* const objv[]); +static void AdjustAxisPointers(Graph* graphPtr); +static void ConfigureGraph(Graph* graphPtr); +static void DrawPlot(Graph* graphPtr, Drawable drawable); +static void UpdateMarginTraces(Graph* graphPtr); + +// OptionSpecs + static char* barmodeObjOption[] = {"normal", "stacked", "aligned", "overlap", NULL}; @@ -236,9 +258,6 @@ static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BOOLEAN, "-stackaxes", "stackAxes", "StackAxes", DEF_GRAPH_STACK_AXES, -1, Tk_Offset(Graph, stackAxes), 0, NULL, 0}, - {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_GRAPH_TAKE_FOCUS, - -1, Tk_Offset(Graph, takeFocus), TK_OPTION_NULL_OK, NULL, 0}, {TK_OPTION_STRING, "-title", "title", "Title", DEF_GRAPH_TITLE, -1, Tk_Offset(Graph, title), TK_OPTION_NULL_OK, NULL, @@ -267,27 +286,7 @@ static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -static Tcl_IdleProc DisplayGraph; -static Tcl_FreeProc DestroyGraph; -static Tk_EventProc GraphEventProc; -Tcl_ObjCmdProc Blt_GraphInstCmdProc; - -static Tcl_ObjCmdProc BarchartObjCmd; -static Tcl_ObjCmdProc GraphObjCmd; -static Tcl_CmdDeleteProc GraphInstCmdDeleteProc; - -static Blt_BindPickProc PickEntry; - -static int NewGraph(ClientData clientData, Tcl_Interp*interp, - int objc, Tcl_Obj* const objv[], ClassId classId); -static int GraphObjConfigure(Tcl_Interp* interp, Graph* graphPtr, - int objc, Tcl_Obj* const objv[]); -static void AdjustAxisPointers(Graph* graphPtr); -static void ConfigureGraph(Graph* graphPtr); -static void DrawPlot(Graph* graphPtr, Drawable drawable); -static void UpdateMarginTraces(Graph* graphPtr); - -// Graph Widget +// Create int Blt_GraphCmdInitProc(Tcl_Interp* interp) { @@ -446,6 +445,87 @@ int Blt_GraphInstCmdProc(ClientData clientData, Tcl_Interp* interp, return result; } +// called by Tcl_DeleteCommandx +static void GraphInstCmdDeleteProc(ClientData clientData) +{ + Graph* graphPtr = clientData; + + // NULL indicates window has already been destroyed. + if (graphPtr->tkwin != NULL) { + Tk_Window tkwin = graphPtr->tkwin; + graphPtr->tkwin = NULL; + Tk_DestroyWindow(tkwin); + } +} + +// called by Tcl_EventuallyFree and others +static void DestroyGraph(char* dataPtr) +{ + Graph* graphPtr = (Graph*)dataPtr; + Tk_DeleteOptionTable(graphPtr->optionTable); + + Blt_DestroyCrosshairs(graphPtr); + Blt_DestroyMarkers(graphPtr); + Blt_DestroyElements(graphPtr); // must come before legend and others + Blt_DestroyLegend(graphPtr); + Blt_DestroyAxes(graphPtr); + Blt_DestroyPens(graphPtr); + Blt_DestroyPageSetup(graphPtr); + Blt_DestroyBarSets(graphPtr); + if (graphPtr->bindTable != NULL) + Blt_DestroyBindingTable(graphPtr->bindTable); + + if (graphPtr->drawGC != NULL) + Tk_FreeGC(graphPtr->display, graphPtr->drawGC); + + Blt_Ts_FreeStyle(graphPtr->display, &graphPtr->titleTextStyle); + if (graphPtr->cache != None) + Tk_FreePixmap(graphPtr->display, graphPtr->cache); + + free(graphPtr); +} + +static void GraphEventProc(ClientData clientData, XEvent* eventPtr) +{ + Graph* graphPtr = clientData; + + if (eventPtr->type == Expose) { + if (eventPtr->xexpose.count == 0) { + graphPtr->flags |= REDRAW_WORLD; + Blt_EventuallyRedrawGraph(graphPtr); + } + } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { + if (eventPtr->xfocus.detail != NotifyInferior) { + if (eventPtr->type == FocusIn) { + graphPtr->flags |= FOCUS; + } else { + graphPtr->flags &= ~FOCUS; + } + graphPtr->flags |= REDRAW_WORLD; + Blt_EventuallyRedrawGraph(graphPtr); + } + } else if (eventPtr->type == DestroyNotify) { + if (graphPtr->tkwin != NULL) { + Tk_FreeConfigOptions((char*)graphPtr, graphPtr->optionTable, + graphPtr->tkwin); + Blt_DeleteCrosshairs(graphPtr); + Blt_DeleteLegend(graphPtr); + + graphPtr->tkwin = NULL; + Tcl_DeleteCommandFromToken(graphPtr->interp, graphPtr->cmdToken); + } + if (graphPtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(DisplayGraph, graphPtr); + } + Tcl_EventuallyFree(graphPtr, DestroyGraph); + } else if (eventPtr->type == ConfigureNotify) { + graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); + Blt_EventuallyRedrawGraph(graphPtr); + } +} + +// Configure + static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) { @@ -569,6 +649,8 @@ static void ConfigureGraph(Graph* graphPtr) } } +// Support + static void DisplayGraph(ClientData clientData) { Graph* graphPtr = clientData; @@ -675,86 +757,7 @@ static void DisplayGraph(ClientData clientData) UpdateMarginTraces(graphPtr); } -static void GraphEventProc(ClientData clientData, XEvent* eventPtr) -{ - Graph* graphPtr = clientData; - - if (eventPtr->type == Expose) { - if (eventPtr->xexpose.count == 0) { - graphPtr->flags |= REDRAW_WORLD; - Blt_EventuallyRedrawGraph(graphPtr); - } - } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { - if (eventPtr->xfocus.detail != NotifyInferior) { - if (eventPtr->type == FocusIn) { - graphPtr->flags |= FOCUS; - } else { - graphPtr->flags &= ~FOCUS; - } - graphPtr->flags |= REDRAW_WORLD; - Blt_EventuallyRedrawGraph(graphPtr); - } - } else if (eventPtr->type == DestroyNotify) { - if (graphPtr->tkwin != NULL) { - Tk_FreeConfigOptions((char*)graphPtr, graphPtr->optionTable, - graphPtr->tkwin); - Blt_DeleteCrosshairs(graphPtr); - Blt_DeleteLegend(graphPtr); - - graphPtr->tkwin = NULL; - Tcl_DeleteCommandFromToken(graphPtr->interp, graphPtr->cmdToken); - } - if (graphPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayGraph, graphPtr); - } - Tcl_EventuallyFree(graphPtr, DestroyGraph); - } else if (eventPtr->type == ConfigureNotify) { - graphPtr->flags |= (MAP_WORLD | REDRAW_WORLD); - Blt_EventuallyRedrawGraph(graphPtr); - } -} - -// called by Tcl_DeleteCommandx -static void GraphInstCmdDeleteProc(ClientData clientData) -{ - Graph* graphPtr = clientData; - - // NULL indicates window has already been destroyed. - if (graphPtr->tkwin != NULL) { - Tk_Window tkwin = graphPtr->tkwin; - graphPtr->tkwin = NULL; - Tk_DestroyWindow(tkwin); - } -} - -// called by Tcl_EventuallyFree and others -static void DestroyGraph(char* dataPtr) -{ - Graph* graphPtr = (Graph*)dataPtr; - Tk_DeleteOptionTable(graphPtr->optionTable); - - Blt_DestroyCrosshairs(graphPtr); - Blt_DestroyMarkers(graphPtr); - Blt_DestroyElements(graphPtr); // must come before legend and others - Blt_DestroyLegend(graphPtr); - Blt_DestroyAxes(graphPtr); - Blt_DestroyPens(graphPtr); - Blt_DestroyPageSetup(graphPtr); - Blt_DestroyBarSets(graphPtr); - if (graphPtr->bindTable != NULL) - Blt_DestroyBindingTable(graphPtr->bindTable); - - if (graphPtr->drawGC != NULL) - Tk_FreeGC(graphPtr->display, graphPtr->drawGC); - - Blt_Ts_FreeStyle(graphPtr->display, &graphPtr->titleTextStyle); - if (graphPtr->cache != None) - Tk_FreePixmap(graphPtr->display, graphPtr->cache); - - free(graphPtr); -} - -// Widget commands +// Ops static int XAxisOp(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]) diff --git a/src/bltGraph.h b/src/bltGraph.h index 14c307f..2907965 100644 --- a/src/bltGraph.h +++ b/src/bltGraph.h @@ -176,23 +176,6 @@ typedef Pen *(PenCreateProc)(void); typedef int (PenConfigureProc)(Graph *graphPtr, Pen *penPtr); typedef void (PenDestroyProc)(Graph *graphPtr, Pen *penPtr); -struct _Pen { - const char *name; /* Pen style identifier. If NULL pen - * was statically allocated. */ - ClassId classId; /* Type element using this pen. */ - const char *typeId; /* String token identifying the type of - * pen. */ - unsigned int flags; /* Indicates if the pen element is - * active or normal. */ - int refCount; /* Reference count for elements using - * this pen. */ - Tcl_HashEntry *hashPtr; - Tk_OptionTable optionTable; /* Configuration specifications */ - PenConfigureProc *configProc; - PenDestroyProc *destroyProc; - Graph *graphPtr; /* Graph that the pen is associated*/ -}; - /* *--------------------------------------------------------------------------- * @@ -283,9 +266,7 @@ struct _Graph { TextStyle titleTextStyle; /* Title attributes: font, color, * etc.*/ - const char *takeFocus; /* Not used in C code, indicates if - * widget should be included in focus - * traversal. */ + Axis *focusPtr; /* The axis that currently has focus. */ int reqWidth, reqHeight; /* Requested size of graph window */ |