PageRenderTime 66ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/brlcad/tags/rel-7-12-6/src/other/blt/src/bltGrHairs.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
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
  1. /*
  2. * bltGrHairs.c --
  3. *
  4. * This module implements crosshairs for the BLT graph widget.
  5. *
  6. * Copyright 1993-1998 Lucent Technologies, Inc.
  7. *
  8. * Permission to use, copy, modify, and distribute this software and
  9. * its documentation for any purpose and without fee is hereby
  10. * granted, provided that the above copyright notice appear in all
  11. * copies and that both that the copyright notice and warranty
  12. * disclaimer appear in supporting documentation, and that the names
  13. * of Lucent Technologies any of their entities not be used in
  14. * advertising or publicity pertaining to distribution of the software
  15. * without specific, written prior permission.
  16. *
  17. * Lucent Technologies disclaims all warranties with regard to this
  18. * software, including all implied warranties of merchantability and
  19. * fitness. In no event shall Lucent Technologies be liable for any
  20. * special, indirect or consequential damages or any damages
  21. * whatsoever resulting from loss of use, data or profits, whether in
  22. * an action of contract, negligence or other tortuous action, arising
  23. * out of or in connection with the use or performance of this
  24. * software.
  25. *
  26. * Graph widget created by Sani Nassif and George Howlett.
  27. */
  28. #include "bltGraph.h"
  29. extern Tk_CustomOption bltPointOption;
  30. extern Tk_CustomOption bltDistanceOption;
  31. extern Tk_CustomOption bltDashesOption;
  32. /*
  33. * -------------------------------------------------------------------
  34. *
  35. * Crosshairs
  36. *
  37. * Contains the line segments positions and graphics context used
  38. * to simulate crosshairs (by XORing) on the graph.
  39. *
  40. * -------------------------------------------------------------------
  41. */
  42. struct CrosshairsStruct {
  43. XPoint hotSpot; /* Hot spot for crosshairs */
  44. int visible; /* Internal state of crosshairs. If non-zero,
  45. * crosshairs are displayed. */
  46. int hidden; /* If non-zero, crosshairs are not displayed.
  47. * This is not necessarily consistent with the
  48. * internal state variable. This is true when
  49. * the hot spot is off the graph. */
  50. Blt_Dashes dashes; /* Dashstyle of the crosshairs. This represents
  51. * an array of alternatingly drawn pixel
  52. * values. If NULL, the hairs are drawn as a
  53. * solid line */
  54. int lineWidth; /* Width of the simulated crosshair lines */
  55. XSegment segArr[2]; /* Positions of line segments representing the
  56. * simulated crosshairs. */
  57. XColor *colorPtr; /* Foreground color of crosshairs */
  58. GC gc; /* Graphics context for crosshairs. Set to
  59. * GXxor to not require redraws of graph */
  60. };
  61. #define DEF_HAIRS_DASHES (char *)NULL
  62. #define DEF_HAIRS_FOREGROUND RGB_BLACK
  63. #define DEF_HAIRS_FG_MONO RGB_BLACK
  64. #define DEF_HAIRS_LINE_WIDTH "0"
  65. #define DEF_HAIRS_HIDE "yes"
  66. #define DEF_HAIRS_POSITION (char *)NULL
  67. static Tk_ConfigSpec configSpecs[] =
  68. {
  69. {TK_CONFIG_COLOR, "-color", "color", "Color",
  70. DEF_HAIRS_FOREGROUND, Tk_Offset(Crosshairs, colorPtr), TK_CONFIG_COLOR_ONLY},
  71. {TK_CONFIG_COLOR, "-color", "color", "Color",
  72. DEF_HAIRS_FG_MONO, Tk_Offset(Crosshairs, colorPtr), TK_CONFIG_MONO_ONLY},
  73. {TK_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes",
  74. DEF_HAIRS_DASHES, Tk_Offset(Crosshairs, dashes),
  75. TK_CONFIG_NULL_OK, &bltDashesOption},
  76. {TK_CONFIG_BOOLEAN, "-hide", "hide", "Hide",
  77. DEF_HAIRS_HIDE, Tk_Offset(Crosshairs, hidden),
  78. TK_CONFIG_DONT_SET_DEFAULT},
  79. {TK_CONFIG_CUSTOM, "-linewidth", "lineWidth", "Linewidth",
  80. DEF_HAIRS_LINE_WIDTH, Tk_Offset(Crosshairs, lineWidth),
  81. TK_CONFIG_DONT_SET_DEFAULT, &bltDistanceOption},
  82. {TK_CONFIG_CUSTOM, "-position", "position", "Position",
  83. DEF_HAIRS_POSITION, Tk_Offset(Crosshairs, hotSpot),
  84. 0, &bltPointOption},
  85. {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
  86. };
  87. /*
  88. *----------------------------------------------------------------------
  89. *
  90. * TurnOffHairs --
  91. *
  92. * XOR's the existing line segments (representing the crosshairs),
  93. * thereby erasing them. The internal state of the crosshairs is
  94. * tracked.
  95. *
  96. * Results:
  97. * None
  98. *
  99. * Side Effects:
  100. * Crosshairs are erased.
  101. *
  102. *----------------------------------------------------------------------
  103. */
  104. static void
  105. TurnOffHairs(tkwin, chPtr)
  106. Tk_Window tkwin;
  107. Crosshairs *chPtr;
  108. {
  109. if (Tk_IsMapped(tkwin) && (chPtr->visible)) {
  110. XDrawSegments(Tk_Display(tkwin), Tk_WindowId(tkwin), chPtr->gc,
  111. chPtr->segArr, 2);
  112. chPtr->visible = FALSE;
  113. }
  114. }
  115. /*
  116. *----------------------------------------------------------------------
  117. *
  118. * TurnOnHairs --
  119. *
  120. * Draws (by XORing) new line segments, creating the effect of
  121. * crosshairs. The internal state of the crosshairs is tracked.
  122. *
  123. * Results:
  124. * None
  125. *
  126. * Side Effects:
  127. * Crosshairs are displayed.
  128. *
  129. *----------------------------------------------------------------------
  130. */
  131. static void
  132. TurnOnHairs(graphPtr, chPtr)
  133. Graph *graphPtr;
  134. Crosshairs *chPtr;
  135. {
  136. if (Tk_IsMapped(graphPtr->tkwin) && (!chPtr->visible)) {
  137. if (!PointInGraph(graphPtr, chPtr->hotSpot.x, chPtr->hotSpot.y)) {
  138. return; /* Coordinates are off the graph */
  139. }
  140. XDrawSegments(graphPtr->display, Tk_WindowId(graphPtr->tkwin),
  141. chPtr->gc, chPtr->segArr, 2);
  142. chPtr->visible = TRUE;
  143. }
  144. }
  145. /*
  146. *----------------------------------------------------------------------
  147. *
  148. * ConfigureCrosshairs --
  149. *
  150. * Configures attributes of the crosshairs such as line width,
  151. * dashes, and position. The crosshairs are first turned off
  152. * before any of the attributes changes.
  153. *
  154. * Results:
  155. * None
  156. *
  157. * Side Effects:
  158. * Crosshair GC is allocated.
  159. *
  160. *----------------------------------------------------------------------
  161. */
  162. void
  163. Blt_ConfigureCrosshairs(graphPtr)
  164. Graph *graphPtr;
  165. {
  166. XGCValues gcValues;
  167. unsigned long gcMask;
  168. GC newGC;
  169. long colorValue;
  170. Crosshairs *chPtr = graphPtr->crosshairs;
  171. /*
  172. * Turn off the crosshairs temporarily. This is in case the new
  173. * configuration changes the size, style, or position of the lines.
  174. */
  175. TurnOffHairs(graphPtr->tkwin, chPtr);
  176. gcValues.function = GXxor;
  177. if (graphPtr->plotBg == NULL) {
  178. /* The graph's color option may not have been set yet */
  179. colorValue = WhitePixelOfScreen(Tk_Screen(graphPtr->tkwin));
  180. } else {
  181. colorValue = graphPtr->plotBg->pixel;
  182. }
  183. gcValues.background = colorValue;
  184. gcValues.foreground = (colorValue ^ chPtr->colorPtr->pixel);
  185. gcValues.line_width = LineWidth(chPtr->lineWidth);
  186. gcMask = (GCForeground | GCBackground | GCFunction | GCLineWidth);
  187. if (LineIsDashed(chPtr->dashes)) {
  188. gcValues.line_style = LineOnOffDash;
  189. gcMask |= GCLineStyle;
  190. }
  191. newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
  192. if (LineIsDashed(chPtr->dashes)) {
  193. Blt_SetDashes(graphPtr->display, newGC, &(chPtr->dashes));
  194. }
  195. if (chPtr->gc != NULL) {
  196. Blt_FreePrivateGC(graphPtr->display, chPtr->gc);
  197. }
  198. chPtr->gc = newGC;
  199. /*
  200. * Are the new coordinates on the graph?
  201. */
  202. chPtr->segArr[0].x2 = chPtr->segArr[0].x1 = chPtr->hotSpot.x;
  203. chPtr->segArr[0].y1 = graphPtr->bottom;
  204. chPtr->segArr[0].y2 = graphPtr->top;
  205. chPtr->segArr[1].y2 = chPtr->segArr[1].y1 = chPtr->hotSpot.y;
  206. chPtr->segArr[1].x1 = graphPtr->left;
  207. chPtr->segArr[1].x2 = graphPtr->right;
  208. if (!chPtr->hidden) {
  209. TurnOnHairs(graphPtr, chPtr);
  210. }
  211. }
  212. void
  213. Blt_EnableCrosshairs(graphPtr)
  214. Graph *graphPtr;
  215. {
  216. if (!graphPtr->crosshairs->hidden) {
  217. TurnOnHairs(graphPtr, graphPtr->crosshairs);
  218. }
  219. }
  220. void
  221. Blt_DisableCrosshairs(graphPtr)
  222. Graph *graphPtr;
  223. {
  224. if (!graphPtr->crosshairs->hidden) {
  225. TurnOffHairs(graphPtr->tkwin, graphPtr->crosshairs);
  226. }
  227. }
  228. /*
  229. *----------------------------------------------------------------------
  230. *
  231. * UpdateCrosshairs --
  232. *
  233. * Update the length of the hairs (not the hot spot).
  234. *
  235. * Results:
  236. * None.
  237. *
  238. *----------------------------------------------------------------------
  239. */
  240. void
  241. Blt_UpdateCrosshairs(graphPtr)
  242. Graph *graphPtr;
  243. {
  244. Crosshairs *chPtr = graphPtr->crosshairs;
  245. chPtr->segArr[0].y1 = graphPtr->bottom;
  246. chPtr->segArr[0].y2 = graphPtr->top;
  247. chPtr->segArr[1].x1 = graphPtr->left;
  248. chPtr->segArr[1].x2 = graphPtr->right;
  249. }
  250. /*
  251. *----------------------------------------------------------------------
  252. *
  253. * Blt_DestroyCrosshairs --
  254. *
  255. * Results:
  256. * None
  257. *
  258. * Side Effects:
  259. * Crosshair GC is allocated.
  260. *
  261. *----------------------------------------------------------------------
  262. */
  263. void
  264. Blt_DestroyCrosshairs(graphPtr)
  265. Graph *graphPtr;
  266. {
  267. Crosshairs *chPtr = graphPtr->crosshairs;
  268. Tk_FreeOptions(configSpecs, (char *)chPtr, graphPtr->display, 0);
  269. if (chPtr->gc != NULL) {
  270. Blt_FreePrivateGC(graphPtr->display, chPtr->gc);
  271. }
  272. Blt_Free(chPtr);
  273. }
  274. /*
  275. *----------------------------------------------------------------------
  276. *
  277. * Blt_CreateCrosshairs --
  278. *
  279. * Creates and initializes a new crosshair structure.
  280. *
  281. * Results:
  282. * Returns TCL_ERROR if the crosshair structure can't be created,
  283. * otherwise TCL_OK.
  284. *
  285. * Side Effects:
  286. * Crosshair GC is allocated.
  287. *
  288. *----------------------------------------------------------------------
  289. */
  290. int
  291. Blt_CreateCrosshairs(graphPtr)
  292. Graph *graphPtr;
  293. {
  294. Crosshairs *chPtr;
  295. chPtr = Blt_Calloc(1, sizeof(Crosshairs));
  296. assert(chPtr);
  297. chPtr->hidden = TRUE;
  298. chPtr->hotSpot.x = chPtr->hotSpot.y = -1;
  299. graphPtr->crosshairs = chPtr;
  300. if (Blt_ConfigureWidgetComponent(graphPtr->interp, graphPtr->tkwin,
  301. "crosshairs", "Crosshairs", configSpecs, 0, (char **)NULL,
  302. (char *)chPtr, 0) != TCL_OK) {
  303. return TCL_ERROR;
  304. }
  305. return TCL_OK;
  306. }
  307. /*
  308. *----------------------------------------------------------------------
  309. *
  310. * CgetOp --
  311. *
  312. * Queries configuration attributes of the crosshairs such as
  313. * line width, dashes, and position.
  314. *
  315. * Results:
  316. * A standard Tcl result.
  317. *
  318. *----------------------------------------------------------------------
  319. */
  320. /* ARGSUSED */
  321. static int
  322. CgetOp(graphPtr, interp, argc, argv)
  323. Graph *graphPtr;
  324. Tcl_Interp *interp;
  325. int argc; /* Not used. */
  326. char **argv;
  327. {
  328. Crosshairs *chPtr = graphPtr->crosshairs;
  329. return Tk_ConfigureValue(interp, graphPtr->tkwin, configSpecs,
  330. (char *)chPtr, argv[3], 0);
  331. }
  332. /*
  333. *----------------------------------------------------------------------
  334. *
  335. * ConfigureOp --
  336. *
  337. * Queries or resets configuration attributes of the crosshairs
  338. * such as line width, dashes, and position.
  339. *
  340. * Results:
  341. * A standard Tcl result.
  342. *
  343. * Side Effects:
  344. * Crosshairs are reset.
  345. *
  346. *----------------------------------------------------------------------
  347. */
  348. static int
  349. ConfigureOp(graphPtr, interp, argc, argv)
  350. Graph *graphPtr;
  351. Tcl_Interp *interp;
  352. int argc;
  353. char **argv;
  354. {
  355. Crosshairs *chPtr = graphPtr->crosshairs;
  356. if (argc == 3) {
  357. return Tk_ConfigureInfo(interp, graphPtr->tkwin, configSpecs,
  358. (char *)chPtr, (char *)NULL, 0);
  359. } else if (argc == 4) {
  360. return Tk_ConfigureInfo(interp, graphPtr->tkwin, configSpecs,
  361. (char *)chPtr, argv[3], 0);
  362. }
  363. if (Tk_ConfigureWidget(interp, graphPtr->tkwin, configSpecs, argc - 3,
  364. argv + 3, (char *)chPtr, TK_CONFIG_ARGV_ONLY) != TCL_OK) {
  365. return TCL_ERROR;
  366. }
  367. Blt_ConfigureCrosshairs(graphPtr);
  368. return TCL_OK;
  369. }
  370. /*
  371. *----------------------------------------------------------------------
  372. *
  373. * OnOp --
  374. *
  375. * Maps the crosshairs.
  376. *
  377. * Results:
  378. * A standard Tcl result.
  379. *
  380. * Side Effects:
  381. * Crosshairs are reset if necessary.
  382. *
  383. *----------------------------------------------------------------------
  384. */
  385. /*ARGSUSED*/
  386. static int
  387. OnOp(graphPtr, interp, argc, argv)
  388. Graph *graphPtr;
  389. Tcl_Interp *interp;
  390. int argc;
  391. char **argv;
  392. {
  393. Crosshairs *chPtr = graphPtr->crosshairs;
  394. if (chPtr->hidden) {
  395. TurnOnHairs(graphPtr, chPtr);
  396. chPtr->hidden = FALSE;
  397. }
  398. return TCL_OK;
  399. }
  400. /*
  401. *----------------------------------------------------------------------
  402. *
  403. * OffOp --
  404. *
  405. * Unmaps the crosshairs.
  406. *
  407. * Results:
  408. * A standard Tcl result.
  409. *
  410. * Side Effects:
  411. * Crosshairs are reset if necessary.
  412. *
  413. *----------------------------------------------------------------------
  414. */
  415. /*ARGSUSED*/
  416. static int
  417. OffOp(graphPtr, interp, argc, argv)
  418. Graph *graphPtr;
  419. Tcl_Interp *interp;
  420. int argc;
  421. char **argv;
  422. {
  423. Crosshairs *chPtr = graphPtr->crosshairs;
  424. if (!chPtr->hidden) {
  425. TurnOffHairs(graphPtr->tkwin, chPtr);
  426. chPtr->hidden = TRUE;
  427. }
  428. return TCL_OK;
  429. }
  430. /*
  431. *----------------------------------------------------------------------
  432. *
  433. * ToggleOp --
  434. *
  435. * Toggles the state of the crosshairs.
  436. *
  437. * Results:
  438. * A standard Tcl result.
  439. *
  440. * Side Effects:
  441. * Crosshairs are reset.
  442. *
  443. *----------------------------------------------------------------------
  444. */
  445. /*ARGSUSED*/
  446. static int
  447. ToggleOp(graphPtr, interp, argc, argv)
  448. Graph *graphPtr;
  449. Tcl_Interp *interp;
  450. int argc;
  451. char **argv;
  452. {
  453. Crosshairs *chPtr = graphPtr->crosshairs;
  454. chPtr->hidden = (chPtr->hidden == 0);
  455. if (chPtr->hidden) {
  456. TurnOffHairs(graphPtr->tkwin, chPtr);
  457. } else {
  458. TurnOnHairs(graphPtr, chPtr);
  459. }
  460. return TCL_OK;
  461. }
  462. static Blt_OpSpec xhairOps[] =
  463. {
  464. {"cget", 2, (Blt_Op)CgetOp, 4, 4, "option",},
  465. {"configure", 2, (Blt_Op)ConfigureOp, 3, 0, "?options...?",},
  466. {"off", 2, (Blt_Op)OffOp, 3, 3, "",},
  467. {"on", 2, (Blt_Op)OnOp, 3, 3, "",},
  468. {"toggle", 1, (Blt_Op)ToggleOp, 3, 3, "",},
  469. };
  470. static int nXhairOps = sizeof(xhairOps) / sizeof(Blt_OpSpec);
  471. /*
  472. *----------------------------------------------------------------------
  473. *
  474. * Blt_CrosshairsOp --
  475. *
  476. * User routine to configure crosshair simulation. Crosshairs
  477. * are simulated by drawing line segments parallel to both axes
  478. * using the XOR drawing function. The allows the lines to be
  479. * erased (by drawing them again) without redrawing the entire
  480. * graph. Care must be taken to erase crosshairs before redrawing
  481. * the graph and redraw them after the graph is redraw.
  482. *
  483. * Results:
  484. * The return value is a standard Tcl result.
  485. *
  486. * Side Effects:
  487. * Crosshairs may be drawn in the plotting area.
  488. *
  489. *----------------------------------------------------------------------
  490. */
  491. int
  492. Blt_CrosshairsOp(graphPtr, interp, argc, argv)
  493. Graph *graphPtr;
  494. Tcl_Interp *interp;
  495. int argc;
  496. char **argv;
  497. {
  498. Blt_Op proc;
  499. proc = Blt_GetOp(interp, nXhairOps, xhairOps, BLT_OP_ARG2, argc, argv, 0);
  500. if (proc == NULL) {
  501. return TCL_ERROR;
  502. }
  503. return (*proc) (graphPtr, interp, argc, argv);
  504. }