/brlcad/tags/rel-7-8-0/src/other/blt/src/bltGrHairs.c
C | 544 lines | 261 code | 40 blank | 243 comment | 33 complexity | 128fe1bb3678a207675efb33e8d8124d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
- /*
- * bltGrHairs.c --
- *
- * This module implements crosshairs for the BLT graph widget.
- *
- * Copyright 1993-1998 Lucent Technologies, Inc.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that the copyright notice and warranty
- * disclaimer appear in supporting documentation, and that the names
- * of Lucent Technologies any of their entities not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission.
- *
- * Lucent Technologies disclaims all warranties with regard to this
- * software, including all implied warranties of merchantability and
- * fitness. In no event shall Lucent Technologies be liable for any
- * special, indirect or consequential damages or any damages
- * whatsoever resulting from loss of use, data or profits, whether in
- * an action of contract, negligence or other tortuous action, arising
- * out of or in connection with the use or performance of this
- * software.
- *
- * Graph widget created by Sani Nassif and George Howlett.
- */
- #include "bltGraph.h"
- extern Tk_CustomOption bltPointOption;
- extern Tk_CustomOption bltDistanceOption;
- extern Tk_CustomOption bltDashesOption;
- /*
- * -------------------------------------------------------------------
- *
- * Crosshairs
- *
- * Contains the line segments positions and graphics context used
- * to simulate crosshairs (by XORing) on the graph.
- *
- * -------------------------------------------------------------------
- */
- struct CrosshairsStruct {
- 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
- * 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
- * simulated crosshairs. */
- 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_FOREGROUND RGB_BLACK
- #define DEF_HAIRS_FG_MONO RGB_BLACK
- #define DEF_HAIRS_LINE_WIDTH "0"
- #define DEF_HAIRS_HIDE "yes"
- #define DEF_HAIRS_POSITION (char *)NULL
- static Tk_ConfigSpec configSpecs[] =
- {
- {TK_CONFIG_COLOR, "-color", "color", "Color",
- DEF_HAIRS_FOREGROUND, Tk_Offset(Crosshairs, colorPtr), TK_CONFIG_COLOR_ONLY},
- {TK_CONFIG_COLOR, "-color", "color", "Color",
- DEF_HAIRS_FG_MONO, Tk_Offset(Crosshairs, colorPtr), TK_CONFIG_MONO_ONLY},
- {TK_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes",
- DEF_HAIRS_DASHES, Tk_Offset(Crosshairs, dashes),
- TK_CONFIG_NULL_OK, &bltDashesOption},
- {TK_CONFIG_BOOLEAN, "-hide", "hide", "Hide",
- DEF_HAIRS_HIDE, Tk_Offset(Crosshairs, hidden),
- TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_CUSTOM, "-linewidth", "lineWidth", "Linewidth",
- DEF_HAIRS_LINE_WIDTH, Tk_Offset(Crosshairs, lineWidth),
- TK_CONFIG_DONT_SET_DEFAULT, &bltDistanceOption},
- {TK_CONFIG_CUSTOM, "-position", "position", "Position",
- DEF_HAIRS_POSITION, Tk_Offset(Crosshairs, hotSpot),
- 0, &bltPointOption},
- {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 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(tkwin, chPtr)
- Tk_Window tkwin;
- Crosshairs *chPtr;
- {
- if (Tk_IsMapped(tkwin) && (chPtr->visible)) {
- XDrawSegments(Tk_Display(tkwin), Tk_WindowId(tkwin), chPtr->gc,
- chPtr->segArr, 2);
- chPtr->visible = FALSE;
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * 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(graphPtr, chPtr)
- 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 */
- }
- XDrawSegments(graphPtr->display, Tk_WindowId(graphPtr->tkwin),
- chPtr->gc, chPtr->segArr, 2);
- chPtr->visible = TRUE;
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * 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(graphPtr)
- Graph *graphPtr;
- {
- XGCValues gcValues;
- unsigned long gcMask;
- GC newGC;
- long colorValue;
- 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);
- gcValues.function = GXxor;
- if (graphPtr->plotBg == NULL) {
- /* The graph's color option may not have been set yet */
- colorValue = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin));
- } else {
- colorValue = graphPtr->plotBg->pixel;
- }
- gcValues.background = colorValue;
- gcValues.foreground = (colorValue ^ 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);
- }
- }
- void
- Blt_EnableCrosshairs(graphPtr)
- Graph *graphPtr;
- {
- if (!graphPtr->crosshairs->hidden) {
- TurnOnHairs(graphPtr, graphPtr->crosshairs);
- }
- }
- void
- Blt_DisableCrosshairs(graphPtr)
- Graph *graphPtr;
- {
- if (!graphPtr->crosshairs->hidden) {
- TurnOffHairs(graphPtr->tkwin, graphPtr->crosshairs);
- }
- }
- /*
- *----------------------------------------------------------------------
- *
- * UpdateCrosshairs --
- *
- * Update the length of the hairs (not the hot spot).
- *
- * Results:
- * None.
- *
- *----------------------------------------------------------------------
- */
- void
- Blt_UpdateCrosshairs(graphPtr)
- 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;
- }
- /*
- *----------------------------------------------------------------------
- *
- * Blt_DestroyCrosshairs --
- *
- * Results:
- * None
- *
- * Side Effects:
- * Crosshair GC is allocated.
- *
- *----------------------------------------------------------------------
- */
- void
- Blt_DestroyCrosshairs(graphPtr)
- Graph *graphPtr;
- {
- Crosshairs *chPtr = graphPtr->crosshairs;
- Tk_FreeOptions(configSpecs, (char *)chPtr, graphPtr->display, 0);
- if (chPtr->gc != NULL) {
- Blt_FreePrivateGC(graphPtr->display, chPtr->gc);
- }
- Blt_Free(chPtr);
- }
- /*
- *----------------------------------------------------------------------
- *
- * Blt_CreateCrosshairs --
- *
- * Creates and initializes a new crosshair structure.
- *
- * Results:
- * Returns TCL_ERROR if the crosshair structure can't be created,
- * otherwise TCL_OK.
- *
- * Side Effects:
- * Crosshair GC is allocated.
- *
- *----------------------------------------------------------------------
- */
- int
- Blt_CreateCrosshairs(graphPtr)
- Graph *graphPtr;
- {
- Crosshairs *chPtr;
- chPtr = Blt_Calloc(1, sizeof(Crosshairs));
- assert(chPtr);
- chPtr->hidden = TRUE;
- chPtr->hotSpot.x = chPtr->hotSpot.y = -1;
- graphPtr->crosshairs = chPtr;
- if (Blt_ConfigureWidgetComponent(graphPtr->interp, graphPtr->tkwin,
- "crosshairs", "Crosshairs", configSpecs, 0, (char **)NULL,
- (char *)chPtr, 0) != TCL_OK) {
- 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(graphPtr, interp, argc, argv)
- Graph *graphPtr;
- Tcl_Interp *interp;
- int argc; /* Not used. */
- char **argv;
- {
- Crosshairs *chPtr = graphPtr->crosshairs;
- return Tk_ConfigureValue(interp, graphPtr->tkwin, configSpecs,
- (char *)chPtr, argv[3], 0);
- }
- /*
- *----------------------------------------------------------------------
- *
- * 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(graphPtr, interp, argc, argv)
- Graph *graphPtr;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- Crosshairs *chPtr = graphPtr->crosshairs;
- if (argc == 3) {
- return Tk_ConfigureInfo(interp, graphPtr->tkwin, configSpecs,
- (char *)chPtr, (char *)NULL, 0);
- } else if (argc == 4) {
- return Tk_ConfigureInfo(interp, graphPtr->tkwin, configSpecs,
- (char *)chPtr, argv[3], 0);
- }
- if (Tk_ConfigureWidget(interp, graphPtr->tkwin, configSpecs, argc - 3,
- argv + 3, (char *)chPtr, TK_CONFIG_ARGV_ONLY) != TCL_OK) {
- return TCL_ERROR;
- }
- Blt_ConfigureCrosshairs(graphPtr);
- return TCL_OK;
- }
- /*
- *----------------------------------------------------------------------
- *
- * OnOp --
- *
- * Maps the crosshairs.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side Effects:
- * Crosshairs are reset if necessary.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- static int
- OnOp(graphPtr, interp, argc, argv)
- Graph *graphPtr;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- Crosshairs *chPtr = graphPtr->crosshairs;
- if (chPtr->hidden) {
- TurnOnHairs(graphPtr, chPtr);
- chPtr->hidden = FALSE;
- }
- return TCL_OK;
- }
- /*
- *----------------------------------------------------------------------
- *
- * OffOp --
- *
- * Unmaps the crosshairs.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side Effects:
- * Crosshairs are reset if necessary.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- static int
- OffOp(graphPtr, interp, argc, argv)
- Graph *graphPtr;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- Crosshairs *chPtr = graphPtr->crosshairs;
- if (!chPtr->hidden) {
- TurnOffHairs(graphPtr->tkwin, chPtr);
- chPtr->hidden = TRUE;
- }
- return TCL_OK;
- }
- /*
- *----------------------------------------------------------------------
- *
- * ToggleOp --
- *
- * Toggles the state of the crosshairs.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side Effects:
- * Crosshairs are reset.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- static int
- ToggleOp(graphPtr, interp, argc, argv)
- Graph *graphPtr;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- 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[] =
- {
- {"cget", 2, (Blt_Op)CgetOp, 4, 4, "option",},
- {"configure", 2, (Blt_Op)ConfigureOp, 3, 0, "?options...?",},
- {"off", 2, (Blt_Op)OffOp, 3, 3, "",},
- {"on", 2, (Blt_Op)OnOp, 3, 3, "",},
- {"toggle", 1, (Blt_Op)ToggleOp, 3, 3, "",},
- };
- 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(graphPtr, interp, argc, argv)
- Graph *graphPtr;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- Blt_Op proc;
- proc = Blt_GetOp(interp, nXhairOps, xhairOps, BLT_OP_ARG2, argc, argv, 0);
- if (proc == NULL) {
- return TCL_ERROR;
- }
- return (*proc) (graphPtr, interp, argc, argv);
- }