summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorjoye <joye>2014-02-10 20:54:27 (GMT)
committerjoye <joye>2014-02-10 20:54:27 (GMT)
commitf096c3b93516f43a685fc7ced6aa5f617d714288 (patch)
tree6d8ff55d4f58fe9e30dc21b5ecb6dd25305d9e3b /src
parentd70ede214a8a06f5c3f8472f563796b1137eed42 (diff)
downloadblt-f096c3b93516f43a685fc7ced6aa5f617d714288.zip
blt-f096c3b93516f43a685fc7ced6aa5f617d714288.tar.gz
blt-f096c3b93516f43a685fc7ced6aa5f617d714288.tar.bz2
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/bltGrHairs.C642
-rw-r--r--src/bltGrMisc.C78
-rw-r--r--src/bltGraph.C20
-rw-r--r--src/bltGraph.h4
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);