diff options
author | joye <joye> | 2014-02-10 20:54:27 (GMT) |
---|---|---|
committer | joye <joye> | 2014-02-10 20:54:27 (GMT) |
commit | f096c3b93516f43a685fc7ced6aa5f617d714288 (patch) | |
tree | 6d8ff55d4f58fe9e30dc21b5ecb6dd25305d9e3b /src | |
parent | d70ede214a8a06f5c3f8472f563796b1137eed42 (diff) | |
download | blt-f096c3b93516f43a685fc7ced6aa5f617d714288.zip blt-f096c3b93516f43a685fc7ced6aa5f617d714288.tar.gz blt-f096c3b93516f43a685fc7ced6aa5f617d714288.tar.bz2 |
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r-- | src/bltGrHairs.C | 642 | ||||
-rw-r--r-- | src/bltGrMisc.C | 78 | ||||
-rw-r--r-- | src/bltGraph.C | 20 | ||||
-rw-r--r-- | src/bltGraph.h | 4 |
4 files changed, 261 insertions, 483 deletions
diff --git a/src/bltGrHairs.C b/src/bltGrHairs.C index 15ec4ff..190260e 100644 --- a/src/bltGrHairs.C +++ b/src/bltGrHairs.C @@ -39,430 +39,270 @@ #include "bltOp.h" #include "bltConfig.h" -typedef int (GraphCrosshairProc)(Graph *graphPtr, Tcl_Interp *interp, - int objc, Tcl_Obj *const *objv); - -/* - *--------------------------------------------------------------------------- - * - * Crosshairs - * - * Contains the line segments positions and graphics context used - * to simulate crosshairs (by XORing) on the graph. - * - *--------------------------------------------------------------------------- - */ - 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. + Tk_OptionTable optionTable; + 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. * This is not necessarily consistent with the * internal state variable. This is true when * the hot spot is off the graph. */ - Blt_Dashes dashes; /* Dashstyle of the crosshairs. This represents + Blt_Dashes dashes; /* Dashstyle of the crosshairs. This represents * an array of alternatingly drawn pixel * values. If NULL, the hairs are drawn as a * solid line */ - int lineWidth; /* Width of the simulated crosshair lines */ - XSegment segArr[2]; /* Positions of line segments representing the + int lineWidth; /* Width of the simulated crosshair lines */ + XSegment segArr[2]; /* Positions of line segments representing the * simulated crosshairs. */ - XColor *colorPtr; /* Foreground color of crosshairs */ - GC gc; /* Graphics context for crosshairs. Set to + XColor *colorPtr; /* Foreground color of crosshairs */ + GC gc; /* Graphics context for crosshairs. Set to * GXxor to not require redraws of graph */ }; -#define DEF_HAIRS_DASHES (char *)NULL +#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 (char *)NULL - -extern Blt_CustomOption bltPointOption; - -static Blt_ConfigSpec configSpecs[] = { - {BLT_CONFIG_COLOR, "-color", "color", "Color", DEF_HAIRS_FOREGROUND, - Tk_Offset(Crosshairs, colorPtr), 0}, - {BLT_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes", DEF_HAIRS_DASHES, - Tk_Offset(Crosshairs, dashes), BLT_CONFIG_NULL_OK, &dashesOption}, - {BLT_CONFIG_BOOLEAN, "-hide", "hide", "Hide", DEF_HAIRS_HIDE, - Tk_Offset(Crosshairs, hidden), BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_PIXELS, "-linewidth", "lineWidth", "Linewidth", - DEF_HAIRS_LINE_WIDTH, Tk_Offset(Crosshairs, lineWidth), - BLT_CONFIG_DONT_SET_DEFAULT}, - {BLT_CONFIG_CUSTOM, "-position", "position", "Position", - DEF_HAIRS_POSITION, Tk_Offset(Crosshairs, hotSpot), 0, &bltPointOption}, - {BLT_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0} +#define DEF_HAIRS_POSITION NULL + +static Tk_OptionSpec optionSpecs[] = { + {TK_OPTION_COLOR, "-color", "color", "Color", + DEF_HAIRS_FOREGROUND, + -1, Tk_Offset(Crosshairs, colorPtr), 0, NULL, 0}, + {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide", + DEF_HAIRS_HIDE, + -1, Tk_Offset(Crosshairs, hidden), 0, NULL, 0}, + {TK_OPTION_PIXELS, "-linewidth", "lineWidth", "Linewidth", + DEF_HAIRS_LINE_WIDTH, + -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}, + {TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0} }; -/* - *--------------------------------------------------------------------------- - * - * TurnOffHairs -- - * - * XOR's the existing line segments (representing the crosshairs), - * thereby erasing them. The internal state of the crosshairs is - * tracked. - * - * Results: - * None - * - * Side Effects: - * Crosshairs are erased. - * - *--------------------------------------------------------------------------- - */ -static void -TurnOffHairs(Tk_Window tkwin, Crosshairs *chPtr) +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); + +int Blt_CreateCrosshairs(Graph* graphPtr) { - if (Tk_IsMapped(tkwin) && (chPtr->visible)) { - XDrawSegments(Tk_Display(tkwin), Tk_WindowId(tkwin), chPtr->gc, - chPtr->segArr, 2); - chPtr->visible = FALSE; - } + Crosshairs* chPtr = calloc(1, sizeof(Crosshairs)); + chPtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs); + chPtr->hidden = TRUE; + chPtr->hotSpot.x = chPtr->hotSpot.y = -1; + graphPtr->crosshairs = chPtr; + return TCL_OK; } -/* - *--------------------------------------------------------------------------- - * - * TurnOnHairs -- - * - * Draws (by XORing) new line segments, creating the effect of - * crosshairs. The internal state of the crosshairs is tracked. - * - * Results: - * None - * - * Side Effects: - * Crosshairs are displayed. - * - *--------------------------------------------------------------------------- - */ -static void -TurnOnHairs(Graph *graphPtr, Crosshairs *chPtr) +int Blt_ConfigureObjCrosshairs(Graph* graphPtr, + int objc, Tcl_Obj* const objv[]) { - if (Tk_IsMapped(graphPtr->tkwin) && (!chPtr->visible)) { - if (!PointInGraph(graphPtr, chPtr->hotSpot.x, chPtr->hotSpot.y)) { - return; /* Coordinates are off the graph */ - } - XDrawSegments(graphPtr->display, Tk_WindowId(graphPtr->tkwin), - chPtr->gc, chPtr->segArr, 2); - chPtr->visible = TRUE; - } + Crosshairs* chPtr = graphPtr->crosshairs; + return Tk_InitOptions(graphPtr->interp, (char*)chPtr, chPtr->optionTable, + graphPtr->tkwin); } -/* - *--------------------------------------------------------------------------- - * - * ConfigureCrosshairs -- - * - * Configures attributes of the crosshairs such as line width, - * dashes, and position. The crosshairs are first turned off - * before any of the attributes changes. - * - * Results: - * None - * - * Side Effects: - * Crosshair GC is allocated. - * - *--------------------------------------------------------------------------- - */ -void -Blt_ConfigureCrosshairs(Graph *graphPtr) -{ - XGCValues gcValues; - unsigned long gcMask; - GC newGC; - unsigned long int pixel; - Crosshairs *chPtr = graphPtr->crosshairs; - - /* - * Turn off the crosshairs temporarily. This is in case the new - * configuration changes the size, style, or position of the lines. - */ - TurnOffHairs(graphPtr->tkwin, chPtr); +static Blt_OpSpec xhairOps[]; +static int nXhairOps; +typedef int (GraphCrosshairProc)(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]); - gcValues.function = GXxor; +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; - if (graphPtr->plotBg == NULL) { - /* The graph's color option may not have been set yet */ - pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin)); - } else { - pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel; - } - gcValues.background = pixel; - gcValues.foreground = (pixel ^ chPtr->colorPtr->pixel); - - gcValues.line_width = LineWidth(chPtr->lineWidth); - gcMask = (GCForeground | GCBackground | GCFunction | GCLineWidth); - if (LineIsDashed(chPtr->dashes)) { - gcValues.line_style = LineOnOffDash; - gcMask |= GCLineStyle; - } - newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); - if (LineIsDashed(chPtr->dashes)) { - Blt_SetDashes(graphPtr->display, newGC, &chPtr->dashes); - } - if (chPtr->gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, chPtr->gc); - } - chPtr->gc = newGC; - - /* - * Are the new coordinates on the graph? - */ - chPtr->segArr[0].x2 = chPtr->segArr[0].x1 = chPtr->hotSpot.x; - chPtr->segArr[0].y1 = graphPtr->bottom; - chPtr->segArr[0].y2 = graphPtr->top; - chPtr->segArr[1].y2 = chPtr->segArr[1].y1 = chPtr->hotSpot.y; - chPtr->segArr[1].x1 = graphPtr->left; - chPtr->segArr[1].x2 = graphPtr->right; - - if (!chPtr->hidden) { - TurnOnHairs(graphPtr, chPtr); - } + return (*proc)(graphPtr, interp, objc, objv); } -void -Blt_EnableCrosshairs(Graph *graphPtr) +static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { - if (!graphPtr->crosshairs->hidden) { - TurnOnHairs(graphPtr, graphPtr->crosshairs); - } -} + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "cget option"); + return TCL_ERROR; + } -void -Blt_DisableCrosshairs(Graph *graphPtr) -{ - if (!graphPtr->crosshairs->hidden) { - TurnOffHairs(graphPtr->tkwin, graphPtr->crosshairs); - } + Crosshairs* chPtr = graphPtr->crosshairs; + Tcl_Obj* objPtr = Tk_GetOptionValue(interp, (char*)chPtr, + chPtr->optionTable, + objv[3], graphPtr->tkwin); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; } -/* - *--------------------------------------------------------------------------- - * - * UpdateCrosshairs -- - * - * Update the length of the hairs (not the hot spot). - * - * Results: - * None. - * - *--------------------------------------------------------------------------- - */ -void -Blt_UpdateCrosshairs(Graph *graphPtr) +static int ConfigureOp(Graph *graphPtr, Tcl_Interp *interp, + int objc, Tcl_Obj* const objv[]) { - Crosshairs *chPtr = graphPtr->crosshairs; - - chPtr->segArr[0].y1 = graphPtr->bottom; - chPtr->segArr[0].y2 = graphPtr->top; - chPtr->segArr[1].x1 = graphPtr->left; - chPtr->segArr[1].x2 = graphPtr->right; + Crosshairs* chPtr = graphPtr->crosshairs; + if (objc <= 4) { + Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp, (char*)chPtr, + chPtr->optionTable, + (objc == 4) ? objv[3] : NULL, + graphPtr->tkwin); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } + else + return CrosshairsObjConfigure(interp, graphPtr, objc-3, objv+3); } -void Blt_DestroyCrosshairs(Graph *graphPtr) +static int CrosshairsObjConfigure(Tcl_Interp *interp, Graph* graphPtr, + int objc, Tcl_Obj* const objv[]) { - if (graphPtr->crosshairs != NULL) { - Crosshairs *chPtr = graphPtr->crosshairs; - - Blt_FreeOptions(configSpecs, (char *)chPtr, graphPtr->display, 0); - if (chPtr->gc != NULL) { - Blt_FreePrivateGC(graphPtr->display, chPtr->gc); - } - free(chPtr); + Crosshairs* chPtr = graphPtr->crosshairs; + Tk_SavedOptions savedOptions; + int mask =0; + int error; + Tcl_Obj* errorResult; + + for (error=0; error<=1; error++) { + if (!error) { + if (Tk_SetOptions(interp, (char*)chPtr, chPtr->optionTable, + objc, objv, graphPtr->tkwin, &savedOptions, &mask) + != TCL_OK) + continue; + } + else { + errorResult = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(errorResult); + Tk_RestoreSavedOptions(&savedOptions); } -} -int Blt_CreateCrosshairs(Graph *graphPtr) -{ - Crosshairs *chPtr = calloc(1, sizeof(Crosshairs)); - chPtr->hidden = TRUE; - chPtr->hotSpot.x = chPtr->hotSpot.y = -1; - graphPtr->crosshairs = chPtr; - return TCL_OK; -} + ConfigureCrosshairs(graphPtr); + break; + } -int Blt_ConfigureObjCrosshairs(Graph *graphPtr) -{ - if (Blt_ConfigureComponentFromObj(graphPtr->interp, graphPtr->tkwin, - "crosshairs", "Crosshairs", - configSpecs, 0, (Tcl_Obj**)NULL, - (char*)graphPtr->crosshairs, 0) != TCL_OK) { + if (!error) { + Tk_FreeSavedOptions(&savedOptions); + return TCL_OK; + } + else { + Tcl_SetObjResult(interp, errorResult); + Tcl_DecrRefCount(errorResult); return TCL_ERROR; } - return TCL_OK; } -/* - *--------------------------------------------------------------------------- - * - * CgetOp -- - * - * Queries configuration attributes of the crosshairs such as - * line width, dashes, and position. - * - * Results: - * A standard TCL result. - * - *--------------------------------------------------------------------------- - */ -/* ARGSUSED */ -static int -CgetOp( - Graph *graphPtr, - Tcl_Interp *interp, - int objc, /* Not used. */ - Tcl_Obj *const *objv) +static void ConfigureCrosshairs(Graph *graphPtr) { - Crosshairs *chPtr = graphPtr->crosshairs; + Crosshairs *chPtr = graphPtr->crosshairs; + + // Turn off the crosshairs temporarily. This is in case the new + // configuration changes the size, style, or position of the lines. + TurnOffHairs(graphPtr->tkwin, chPtr); - return Blt_ConfigureValueFromObj(interp, graphPtr->tkwin, configSpecs, - (char *)chPtr, objv[3], 0); + XGCValues gcValues; + gcValues.function = GXxor; + + unsigned long int pixel; + if (graphPtr->plotBg == NULL) { + // The graph's color option may not have been set yet + pixel = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin)); + } else { + pixel = Blt_BackgroundBorderColor(graphPtr->plotBg)->pixel; + } + gcValues.background = pixel; + gcValues.foreground = (pixel ^ chPtr->colorPtr->pixel); + + gcValues.line_width = LineWidth(chPtr->lineWidth); + unsigned long gcMask = + (GCForeground | GCBackground | GCFunction | GCLineWidth); + if (LineIsDashed(chPtr->dashes)) { + gcValues.line_style = LineOnOffDash; + gcMask |= GCLineStyle; + } + GC newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues); + if (LineIsDashed(chPtr->dashes)) + Blt_SetDashes(graphPtr->display, newGC, &chPtr->dashes); + + if (chPtr->gc != NULL) + Blt_FreePrivateGC(graphPtr->display, chPtr->gc); + + chPtr->gc = newGC; + + // Are the new coordinates on the graph? + chPtr->segArr[0].x2 = chPtr->segArr[0].x1 = chPtr->hotSpot.x; + chPtr->segArr[0].y1 = graphPtr->bottom; + chPtr->segArr[0].y2 = graphPtr->top; + chPtr->segArr[1].y2 = chPtr->segArr[1].y1 = chPtr->hotSpot.y; + chPtr->segArr[1].x1 = graphPtr->left; + chPtr->segArr[1].x2 = graphPtr->right; + + if (!chPtr->hidden) + TurnOnHairs(graphPtr, chPtr); } -/* - *--------------------------------------------------------------------------- - * - * ConfigureOp -- - * - * Queries or resets configuration attributes of the crosshairs - * such as line width, dashes, and position. - * - * Results: - * A standard TCL result. - * - * Side Effects: - * Crosshairs are reset. - * - *--------------------------------------------------------------------------- - */ -static int -ConfigureOp( - Graph *graphPtr, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const *objv) +void Blt_DeleteCrosshairs(Graph* graphPtr) { - Crosshairs *chPtr = graphPtr->crosshairs; - - if (objc == 3) { - return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, - (char *)chPtr, (Tcl_Obj *)NULL, 0); - } else if (objc == 4) { - return Blt_ConfigureInfoFromObj(interp, graphPtr->tkwin, configSpecs, - (char *)chPtr, objv[3], 0); - } - if (Blt_ConfigureWidgetFromObj(interp, graphPtr->tkwin, configSpecs, - objc - 3, objv + 3, (char *)chPtr, BLT_CONFIG_OBJV_ONLY) != TCL_OK) { - return TCL_ERROR; - } - Blt_ConfigureCrosshairs(graphPtr); - return TCL_OK; + Crosshairs *chPtr = graphPtr->crosshairs; + if (chPtr != NULL) + Tk_FreeConfigOptions((char*)chPtr, chPtr->optionTable, graphPtr->tkwin); } -/* - *--------------------------------------------------------------------------- - * - * OnOp -- - * - * Maps the crosshairs. - * - * Results: - * A standard TCL result. - * - * Side Effects: - * Crosshairs are reset if necessary. - * - *--------------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static int -OnOp( - Graph *graphPtr, - Tcl_Interp *interp, /* Not used. */ - int objc, /* Not used. */ - Tcl_Obj *const *objv) /* Not used. */ +void Blt_DestroyCrosshairs(Graph* graphPtr) { - Crosshairs *chPtr = graphPtr->crosshairs; + Crosshairs *chPtr = graphPtr->crosshairs; + if (chPtr != NULL) { + if (chPtr->gc != NULL) + Blt_FreePrivateGC(graphPtr->display, chPtr->gc); - if (chPtr->hidden) { - TurnOnHairs(graphPtr, chPtr); - chPtr->hidden = FALSE; - } - return TCL_OK; + free(chPtr); + } } -/* - *--------------------------------------------------------------------------- - * - * OffOp -- - * - * Unmaps the crosshairs. - * - * Results: - * A standard TCL result. - * - * Side Effects: - * Crosshairs are reset if necessary. - * - *--------------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static int -OffOp( - Graph *graphPtr, - Tcl_Interp *interp, /* Not used. */ - int objc, /* Not used. */ - Tcl_Obj *const *objv) /* Not used. */ +// Widget commands + +static int OnOp(Graph *graphPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv) { - Crosshairs *chPtr = graphPtr->crosshairs; + Crosshairs *chPtr = graphPtr->crosshairs; - if (!chPtr->hidden) { - TurnOffHairs(graphPtr->tkwin, chPtr); - chPtr->hidden = TRUE; - } - return TCL_OK; + if (chPtr->hidden) { + TurnOnHairs(graphPtr, chPtr); + chPtr->hidden = FALSE; + } + return TCL_OK; } -/* - *--------------------------------------------------------------------------- - * - * ToggleOp -- - * - * Toggles the state of the crosshairs. - * - * Results: - * A standard TCL result. - * - * Side Effects: - * Crosshairs are reset. - * - *--------------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static int -ToggleOp( - Graph *graphPtr, - Tcl_Interp *interp, /* Not used. */ - int objc, /* Not used. */ - Tcl_Obj *const *objv) /* Not used. */ +static int OffOp(Graph *graphPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv) { - Crosshairs *chPtr = graphPtr->crosshairs; + Crosshairs *chPtr = graphPtr->crosshairs; - chPtr->hidden = (chPtr->hidden == 0); - if (chPtr->hidden) { - TurnOffHairs(graphPtr->tkwin, chPtr); - } else { - TurnOnHairs(graphPtr, chPtr); - } - return TCL_OK; + if (!chPtr->hidden) { + TurnOffHairs(graphPtr->tkwin, chPtr); + chPtr->hidden = TRUE; + } + return TCL_OK; } +static int ToggleOp(Graph *graphPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *const *objv) +{ + Crosshairs *chPtr = graphPtr->crosshairs; + + chPtr->hidden = (chPtr->hidden == 0); + if (chPtr->hidden) + TurnOffHairs(graphPtr->tkwin, chPtr); + else + TurnOnHairs(graphPtr, chPtr); + + return TCL_OK; +} static Blt_OpSpec xhairOps[] = { @@ -474,39 +314,49 @@ static Blt_OpSpec xhairOps[] = }; static int nXhairOps = sizeof(xhairOps) / sizeof(Blt_OpSpec); -/* - *--------------------------------------------------------------------------- - * - * Blt_CrosshairsOp -- - * - * User routine to configure crosshair simulation. Crosshairs - * are simulated by drawing line segments parallel to both axes - * using the XOR drawing function. The allows the lines to be - * erased (by drawing them again) without redrawing the entire - * graph. Care must be taken to erase crosshairs before redrawing - * the graph and redraw them after the graph is redraw. - * - * Results: - * The return value is a standard TCL result. - * - * Side Effects: - * Crosshairs may be drawn in the plotting area. - * - *--------------------------------------------------------------------------- - */ -int -Blt_CrosshairsOp( - Graph *graphPtr, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const *objv) +// Support + +static void TurnOffHairs(Tk_Window tkwin, Crosshairs *chPtr) { - GraphCrosshairProc *proc; + if (Tk_IsMapped(tkwin) && (chPtr->visible)) { + XDrawSegments(Tk_Display(tkwin), Tk_WindowId(tkwin), chPtr->gc, + chPtr->segArr, 2); + chPtr->visible = FALSE; + } +} - proc = Blt_GetOpFromObj(interp, nXhairOps, xhairOps, BLT_OP_ARG2, - objc, objv, 0); - if (proc == NULL) { - return TCL_ERROR; +static void TurnOnHairs(Graph *graphPtr, Crosshairs *chPtr) +{ + if (Tk_IsMapped(graphPtr->tkwin) && (!chPtr->visible)) { + if (!PointInGraph(graphPtr, chPtr->hotSpot.x, chPtr->hotSpot.y)) { + return; /* Coordinates are off the graph */ } - return (*proc) (graphPtr, interp, objc, objv); + XDrawSegments(graphPtr->display, Tk_WindowId(graphPtr->tkwin), + chPtr->gc, chPtr->segArr, 2); + chPtr->visible = TRUE; + } +} + +void Blt_EnableCrosshairs(Graph *graphPtr) +{ + if (!graphPtr->crosshairs->hidden) { + TurnOnHairs(graphPtr, graphPtr->crosshairs); + } +} + +void Blt_DisableCrosshairs(Graph *graphPtr) +{ + if (!graphPtr->crosshairs->hidden) { + TurnOffHairs(graphPtr->tkwin, graphPtr->crosshairs); + } +} + +void Blt_UpdateCrosshairs(Graph *graphPtr) +{ + Crosshairs *chPtr = graphPtr->crosshairs; + + chPtr->segArr[0].y1 = graphPtr->bottom; + chPtr->segArr[0].y2 = graphPtr->top; + chPtr->segArr[1].x1 = graphPtr->left; + chPtr->segArr[1].x2 = graphPtr->right; } diff --git a/src/bltGrMisc.C b/src/bltGrMisc.C index 84fe991..cc300bb 100644 --- a/src/bltGrMisc.C +++ b/src/bltGrMisc.C @@ -40,13 +40,6 @@ #include "bltInt.h" #include "bltGraph.h" -static Blt_OptionParseProc ObjToPoint; -static Blt_OptionPrintProc PointToObj; -Blt_CustomOption bltPointOption = -{ - ObjToPoint, PointToObj, NULL, (ClientData)0 -}; - /* *--------------------------------------------------------------------------- * Custom option parse and print procedures @@ -106,77 +99,6 @@ Blt_GetXY(Tcl_Interp *interp, Tk_Window tkwin, const char *string, return TCL_ERROR; } -/* - *--------------------------------------------------------------------------- - * - * ObjToPoint -- - * - * Convert the string representation of a legend XY position into window - * coordinates. The form of the string must be "@x,y" or none. - * - * Results: - * A standard TCL result. The symbol type is written into the - * widget record. - * - *--------------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static int -ObjToPoint( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Interpreter to send results back to */ - Tk_Window tkwin, /* Not used. */ - Tcl_Obj *objPtr, /* New legend position string */ - char *widgRec, /* Widget record */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ -{ - XPoint *pointPtr = (XPoint *)(widgRec + offset); - int x, y; - - if (Blt_GetXY(interp, tkwin, Tcl_GetString(objPtr), &x, &y) != TCL_OK) { - return TCL_ERROR; - } - pointPtr->x = x, pointPtr->y = y; - return TCL_OK; -} - -/* - *--------------------------------------------------------------------------- - * - * PointToObj -- - * - * Convert the window coordinates into a string. - * - * Results: - * The string representing the coordinate position is returned. - * - *--------------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static Tcl_Obj * -PointToObj( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Not used. */ - Tk_Window tkwin, /* Not used. */ - char *widgRec, /* Widget record */ - int offset, /* Offset to field in structure */ - int flags) /* Not used. */ -{ - XPoint *pointPtr = (XPoint *)(widgRec + offset); - Tcl_Obj *objPtr; - - if ((pointPtr->x != -SHRT_MAX) && (pointPtr->y != -SHRT_MAX)) { - char string[200]; - - sprintf_s(string, 200, "@%d,%d", pointPtr->x, pointPtr->y); - objPtr = Tcl_NewStringObj(string, -1); - } else { - objPtr = Tcl_NewStringObj("", -1); - } - return objPtr; -} - int Blt_PointInSegments( Point2d *samplePtr, diff --git a/src/bltGraph.C b/src/bltGraph.C index 6ea98bd..6f78cb4 100644 --- a/src/bltGraph.C +++ b/src/bltGraph.C @@ -404,7 +404,7 @@ static int NewGraph(ClientData clientData, Tcl_Interp*interp, (GraphObjConfigure(interp, graphPtr, objc-2, objv+2) != TCL_OK)) goto error; - if (Blt_ConfigureObjCrosshairs(graphPtr) != TCL_OK) + if (Blt_ConfigureObjCrosshairs(graphPtr, objc, objv) != TCL_OK) goto error; if (Blt_ConfigurePageSetup(graphPtr) != TCL_OK) goto error; @@ -428,8 +428,8 @@ static int nGraphOps; typedef int (GraphCmdProc)(Graph* graphPtr, Tcl_Interp* interp, int objc, Tcl_Obj* const objv[]); -int Blt_GraphInstCmdProc(ClientData clientData, Tcl_Interp* interp, int objc, - Tcl_Obj* const objv[]) +int Blt_GraphInstCmdProc(ClientData clientData, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { Graph* graphPtr = clientData; GraphCmdProc* proc = Blt_GetOpFromObj(interp, nGraphOps, graphOps, @@ -443,8 +443,8 @@ int Blt_GraphInstCmdProc(ClientData clientData, Tcl_Interp* interp, int objc, return result; } -static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, int objc, - Tcl_Obj* const objv[]) +static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "cget option"); @@ -460,8 +460,8 @@ static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, int objc, return TCL_OK; } -static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, int objc, - Tcl_Obj* const objv[]) +static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) { if (objc <= 3) { Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char*)graphPtr, @@ -708,6 +708,8 @@ static void GraphEventProc(ClientData clientData, XEvent* eventPtr) if (graphPtr->tkwin != NULL) { Tk_FreeConfigOptions((char*)graphPtr, graphPtr->optionTable, graphPtr->tkwin); + Blt_DeleteCrosshairs(graphPtr); + graphPtr->tkwin = NULL; Tcl_DeleteCommandFromToken(graphPtr->interp, graphPtr->cmdToken); } @@ -721,6 +723,7 @@ static void GraphEventProc(ClientData clientData, XEvent* eventPtr) } } +// called by Tcl_DeleteCommandx static void GraphInstCmdDeleteProc(ClientData clientData) { Graph* graphPtr = clientData; @@ -733,16 +736,17 @@ static void GraphInstCmdDeleteProc(ClientData clientData) } } +// called by Tcl_EventuallyFree and others static void DestroyGraph(char* dataPtr) { Graph* graphPtr = (Graph*)dataPtr; + Blt_DestroyCrosshairs(graphPtr); Blt_DestroyMarkers(graphPtr); Blt_DestroyElements(graphPtr); Blt_DestroyLegend(graphPtr); Blt_DestroyAxes(graphPtr); Blt_DestroyPens(graphPtr); - Blt_DestroyCrosshairs(graphPtr); Blt_DestroyPageSetup(graphPtr); Blt_DestroyBarSets(graphPtr); if (graphPtr->bindTable != NULL) diff --git a/src/bltGraph.h b/src/bltGraph.h index 59b6764..7f1e9bf 100644 --- a/src/bltGraph.h +++ b/src/bltGraph.h @@ -507,7 +507,9 @@ extern int Blt_CreatePageSetup(Graph *graphPtr); extern int Blt_ConfigurePageSetup(Graph *graphPtr); extern int Blt_CreateCrosshairs(Graph *graphPtr); -extern int Blt_ConfigureObjCrosshairs(Graph *graphPtr); +extern int Blt_ConfigureObjCrosshairs(Graph *graphPtr, + int objc, Tcl_Obj* const objv[]); +extern void Blt_DeleteCrosshairs(Graph* graphPtr); extern double Blt_InvHMap(Axis *axisPtr, double x); |