source: trunk/kitgen/8.x/blt/generic/bltGrGrid.c@ 175

Last change on this file since 175 was 175, checked in by demin, 12 years ago

initial commit

File size: 13.5 KB
RevLine 
[175]1
2/*
3 * bltGrGrid.c --
4 *
5 * This module implements grid lines for the BLT graph widget.
6 *
7 * Copyright 1995-1998 Lucent Technologies, Inc.
8 *
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose and without fee is hereby
11 * granted, provided that the above copyright notice appear in all
12 * copies and that both that the copyright notice and warranty
13 * disclaimer appear in supporting documentation, and that the names
14 * of Lucent Technologies any of their entities not be used in
15 * advertising or publicity pertaining to distribution of the software
16 * without specific, written prior permission.
17 *
18 * Lucent Technologies disclaims all warranties with regard to this
19 * software, including all implied warranties of merchantability and
20 * fitness. In no event shall Lucent Technologies be liable for any
21 * special, indirect or consequential damages or any damages
22 * whatsoever resulting from loss of use, data or profits, whether in
23 * an action of contract, negligence or other tortuous action, arising
24 * out of or in connection with the use or performance of this
25 * software.
26 *
27 * Graph widget created by Sani Nassif and George Howlett.
28 */
29
30#include "bltGraph.h"
31
32extern Tk_CustomOption bltDistanceOption;
33extern Tk_CustomOption bltDashesOption;
34extern Tk_CustomOption bltAnyXAxisOption;
35extern Tk_CustomOption bltAnyYAxisOption;
36
37
38#define DEF_GRID_DASHES "dot"
39#define DEF_GRID_FOREGROUND RGB_GREY64
40#define DEF_GRID_FG_MONO RGB_BLACK
41#define DEF_GRID_LINE_WIDTH "0"
42#define DEF_GRID_HIDE_BARCHART "no"
43#define DEF_GRID_HIDE_GRAPH "yes"
44#define DEF_GRID_MINOR "yes"
45#define DEF_GRID_MAP_X_GRAPH "x"
46#define DEF_GRID_MAP_X_BARCHART (char *)NULL
47#define DEF_GRID_MAP_Y "y"
48#define DEF_GRID_POSITION (char *)NULL
49
50static Tk_ConfigSpec configSpecs[] =
51{
52 {TK_CONFIG_COLOR, "-color", "color", "Color",
53 DEF_GRID_FOREGROUND, Tk_Offset(Grid, colorPtr),
54 TK_CONFIG_COLOR_ONLY | ALL_GRAPHS},
55 {TK_CONFIG_COLOR, "-color", "color", "color",
56 DEF_GRID_FG_MONO, Tk_Offset(Grid, colorPtr),
57 TK_CONFIG_MONO_ONLY | ALL_GRAPHS},
58 {TK_CONFIG_CUSTOM, "-dashes", "dashes", "Dashes",
59 DEF_GRID_DASHES, Tk_Offset(Grid, dashes),
60 TK_CONFIG_NULL_OK | ALL_GRAPHS, &bltDashesOption},
61 {TK_CONFIG_BOOLEAN, "-hide", "hide", "Hide",
62 DEF_GRID_HIDE_BARCHART, Tk_Offset(Grid, hidden), BARCHART},
63 {TK_CONFIG_BOOLEAN, "-hide", "hide", "Hide",
64 DEF_GRID_HIDE_GRAPH, Tk_Offset(Grid, hidden), GRAPH | STRIPCHART},
65 {TK_CONFIG_CUSTOM, "-linewidth", "lineWidth", "Linewidth",
66 DEF_GRID_LINE_WIDTH, Tk_Offset(Grid, lineWidth),
67 TK_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS, &bltDistanceOption},
68 {TK_CONFIG_CUSTOM, "-mapx", "mapX", "MapX",
69 DEF_GRID_MAP_X_GRAPH, Tk_Offset(Grid, axes.x),
70 GRAPH | STRIPCHART, &bltAnyXAxisOption},
71 {TK_CONFIG_CUSTOM, "-mapx", "mapX", "MapX",
72 DEF_GRID_MAP_X_BARCHART, Tk_Offset(Grid, axes.x),
73 BARCHART, &bltAnyXAxisOption},
74 {TK_CONFIG_CUSTOM, "-mapy", "mapY", "MapY",
75 DEF_GRID_MAP_Y, Tk_Offset(Grid, axes.y),
76 ALL_GRAPHS, &bltAnyYAxisOption},
77 {TK_CONFIG_BOOLEAN, "-minor", "minor", "Minor",
78 DEF_GRID_MINOR, Tk_Offset(Grid, minorGrid),
79 TK_CONFIG_DONT_SET_DEFAULT | ALL_GRAPHS},
80 {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0}
81};
82
83/*
84 *----------------------------------------------------------------------
85 *
86 * ConfigureGrid --
87 *
88 * Configures attributes of the grid such as line width,
89 * dashes, and position. The grid are first turned off
90 * before any of the attributes changes.
91 *
92 * Results:
93 * None
94 *
95 * Side Effects:
96 * Crosshair GC is allocated.
97 *
98 *----------------------------------------------------------------------
99 */
100static void
101ConfigureGrid(graphPtr, gridPtr)
102 Graph *graphPtr;
103 Grid *gridPtr;
104{
105 XGCValues gcValues;
106 unsigned long gcMask;
107 GC newGC;
108
109 gcValues.background = gcValues.foreground = gridPtr->colorPtr->pixel;
110 gcValues.line_width = LineWidth(gridPtr->lineWidth);
111 gcMask = (GCForeground | GCBackground | GCLineWidth);
112 if (LineIsDashed(gridPtr->dashes)) {
113 gcValues.line_style = LineOnOffDash;
114 gcMask |= GCLineStyle;
115 }
116 newGC = Blt_GetPrivateGC(graphPtr->tkwin, gcMask, &gcValues);
117 if (LineIsDashed(gridPtr->dashes)) {
118 Blt_SetDashes(graphPtr->display, newGC, &(gridPtr->dashes));
119 }
120 if (gridPtr->gc != NULL) {
121 Blt_FreePrivateGC(graphPtr->display, gridPtr->gc);
122 }
123 gridPtr->gc = newGC;
124}
125
126/*
127 *----------------------------------------------------------------------
128 *
129 * MapGrid --
130 *
131 * Determines the coordinates of the line segments corresponding
132 * to the grid lines for each axis.
133 *
134 * Results:
135 * None.
136 *
137 *----------------------------------------------------------------------
138 */
139void
140Blt_MapGrid(graphPtr)
141 Graph *graphPtr;
142{
143 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
144 int nSegments;
145 Segment2D *segments;
146
147 if (gridPtr->x.segments != NULL) {
148 Blt_Free(gridPtr->x.segments);
149 gridPtr->x.segments = NULL;
150 }
151 if (gridPtr->y.segments != NULL) {
152 Blt_Free(gridPtr->y.segments);
153 gridPtr->y.segments = NULL;
154 }
155 gridPtr->x.nSegments = gridPtr->y.nSegments = 0;
156 /*
157 * Generate line segments to represent the grid. Line segments
158 * are calculated from the major tick intervals of each axis mapped.
159 */
160 Blt_GetAxisSegments(graphPtr, gridPtr->axes.x, &segments, &nSegments);
161 if (nSegments > 0) {
162 gridPtr->x.nSegments = nSegments;
163 gridPtr->x.segments = segments;
164 }
165 Blt_GetAxisSegments(graphPtr, gridPtr->axes.y, &segments, &nSegments);
166 if (nSegments > 0) {
167 gridPtr->y.nSegments = nSegments;
168 gridPtr->y.segments = segments;
169 }
170}
171
172/*
173 *----------------------------------------------------------------------
174 *
175 * DrawGrid --
176 *
177 * Draws the grid lines associated with each axis.
178 *
179 * Results:
180 * None.
181 *
182 *----------------------------------------------------------------------
183 */
184void
185Blt_DrawGrid(graphPtr, drawable)
186 Graph *graphPtr;
187 Drawable drawable; /* Pixmap or window to draw into */
188{
189 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
190
191 if (gridPtr->hidden) {
192 return;
193 }
194 if (gridPtr->x.nSegments > 0) {
195 Blt_Draw2DSegments(graphPtr->display, drawable, gridPtr->gc,
196 gridPtr->x.segments, gridPtr->x.nSegments);
197 }
198 if (gridPtr->y.nSegments > 0) {
199 Blt_Draw2DSegments(graphPtr->display, drawable, gridPtr->gc,
200 gridPtr->y.segments, gridPtr->y.nSegments);
201 }
202}
203
204/*
205 *----------------------------------------------------------------------
206 *
207 * Blt_GridToPostScript --
208 *
209 * Prints the grid lines associated with each axis.
210 *
211 * Results:
212 * None.
213 *
214 *----------------------------------------------------------------------
215 */
216void
217Blt_GridToPostScript(graphPtr, psToken)
218 Graph *graphPtr;
219 PsToken psToken;
220{
221 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
222
223 if (gridPtr->hidden) {
224 return;
225 }
226 Blt_LineAttributesToPostScript(psToken, gridPtr->colorPtr,
227 gridPtr->lineWidth, &(gridPtr->dashes), CapButt, JoinMiter);
228 if (gridPtr->x.nSegments > 0) {
229 Blt_2DSegmentsToPostScript(psToken, gridPtr->x.segments,
230 gridPtr->x.nSegments);
231 }
232 if (gridPtr->y.nSegments > 0) {
233 Blt_2DSegmentsToPostScript(psToken, gridPtr->y.segments,
234 gridPtr->y.nSegments);
235 }
236}
237
238/*
239 *----------------------------------------------------------------------
240 *
241 * Blt_DestroyGrid --
242 *
243 * Results:
244 * None
245 *
246 * Side Effects:
247 * Grid GC is released.
248 *
249 *----------------------------------------------------------------------
250 */
251void
252Blt_DestroyGrid(graphPtr)
253 Graph *graphPtr;
254{
255 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
256
257 Tk_FreeOptions(configSpecs, (char *)gridPtr, graphPtr->display,
258 Blt_GraphType(graphPtr));
259 if (gridPtr->gc != NULL) {
260 Blt_FreePrivateGC(graphPtr->display, gridPtr->gc);
261 }
262 if (gridPtr->x.segments != NULL) {
263 Blt_Free(gridPtr->x.segments);
264 }
265 if (gridPtr->y.segments != NULL) {
266 Blt_Free(gridPtr->y.segments);
267 }
268 Blt_Free(gridPtr);
269}
270
271/*
272 *----------------------------------------------------------------------
273 *
274 * Blt_CreateGrid --
275 *
276 * Creates and initializes a new grid structure.
277 *
278 * Results:
279 * Returns TCL_ERROR if the configuration failed, otherwise TCL_OK.
280 *
281 * Side Effects:
282 * Memory for grid structure is allocated.
283 *
284 *----------------------------------------------------------------------
285 */
286int
287Blt_CreateGrid(graphPtr)
288 Graph *graphPtr;
289{
290 Grid *gridPtr;
291
292 gridPtr = Blt_Calloc(1, sizeof(Grid));
293 assert(gridPtr);
294 gridPtr->minorGrid = TRUE;
295 graphPtr->gridPtr = gridPtr;
296
297 if (Blt_ConfigureWidgetComponent(graphPtr->interp, graphPtr->tkwin, "grid",
298 "Grid", configSpecs, 0, (char **)NULL, (char *)gridPtr,
299 Blt_GraphType(graphPtr)) != TCL_OK) {
300 return TCL_ERROR;
301 }
302 ConfigureGrid(graphPtr, gridPtr);
303 return TCL_OK;
304}
305
306/*
307 *----------------------------------------------------------------------
308 *
309 * CgetOp --
310 *
311 * Queries configuration attributes of the grid such as line
312 * width, dashes, and position.
313 *
314 * Results:
315 * A standard Tcl result.
316 *
317 *----------------------------------------------------------------------
318 */
319/* ARGSUSED */
320static int
321CgetOp(graphPtr, interp, argc, argv)
322 Graph *graphPtr;
323 Tcl_Interp *interp;
324 int argc;
325 char **argv;
326{
327 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
328
329 return Tk_ConfigureValue(interp, graphPtr->tkwin, configSpecs,
330 (char *)gridPtr, argv[3], Blt_GraphType(graphPtr));
331}
332
333/*
334 *----------------------------------------------------------------------
335 *
336 * ConfigureOp --
337 *
338 * Queries or resets configuration attributes of the grid
339 * such as line width, dashes, and position.
340 *
341 * Results:
342 * A standard Tcl result.
343 *
344 * Side Effects:
345 * Grid attributes are reset. The graph is redrawn at the
346 * next idle point.
347 *
348 *----------------------------------------------------------------------
349 */
350static int
351ConfigureOp(graphPtr, interp, argc, argv)
352 Graph *graphPtr;
353 Tcl_Interp *interp;
354 int argc;
355 char **argv;
356{
357 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
358 int flags;
359
360 flags = Blt_GraphType(graphPtr) | TK_CONFIG_ARGV_ONLY;
361 if (argc == 3) {
362 return Tk_ConfigureInfo(interp, graphPtr->tkwin, configSpecs,
363 (char *)gridPtr, (char *)NULL, flags);
364 } else if (argc == 4) {
365 return Tk_ConfigureInfo(interp, graphPtr->tkwin, configSpecs,
366 (char *)gridPtr, argv[3], flags);
367 }
368 if (Tk_ConfigureWidget(graphPtr->interp, graphPtr->tkwin, configSpecs,
369 argc - 3, argv + 3, (char *)gridPtr, flags) != TCL_OK) {
370 return TCL_ERROR;
371 }
372 ConfigureGrid(graphPtr, gridPtr);
373 graphPtr->flags |= REDRAW_BACKING_STORE;
374 Blt_EventuallyRedrawGraph(graphPtr);
375 return TCL_OK;
376}
377
378/*
379 *----------------------------------------------------------------------
380 *
381 * MapOp --
382 *
383 * Maps the grid.
384 *
385 * Results:
386 * A standard Tcl result.
387 *
388 * Side Effects:
389 * Grid attributes are reset and the graph is redrawn if necessary.
390 *
391 *----------------------------------------------------------------------
392 */
393/*ARGSUSED*/
394static int
395MapOp(graphPtr, interp, argc, argv)
396 Graph *graphPtr;
397 Tcl_Interp *interp;
398 int argc;
399 char **argv;
400{
401 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
402
403 if (gridPtr->hidden) {
404 gridPtr->hidden = FALSE;/* Changes "-hide" configuration option */
405 graphPtr->flags |= REDRAW_BACKING_STORE;
406 Blt_EventuallyRedrawGraph(graphPtr);
407 }
408 return TCL_OK;
409}
410
411/*
412 *----------------------------------------------------------------------
413 *
414 * MapOp --
415 *
416 * Maps or unmaps the grid (off or on).
417 *
418 * Results:
419 * A standard Tcl result.
420 *
421 * Side Effects:
422 * Grid attributes are reset and the graph is redrawn if necessary.
423 *
424 *----------------------------------------------------------------------
425 */
426/*ARGSUSED*/
427static int
428UnmapOp(graphPtr, interp, argc, argv)
429 Graph *graphPtr;
430 Tcl_Interp *interp;
431 int argc;
432 char **argv;
433{
434 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
435
436 if (!gridPtr->hidden) {
437 gridPtr->hidden = TRUE; /* Changes "-hide" configuration option */
438 graphPtr->flags |= REDRAW_BACKING_STORE;
439 Blt_EventuallyRedrawGraph(graphPtr);
440 }
441 return TCL_OK;
442}
443
444/*
445 *----------------------------------------------------------------------
446 *
447 * ToggleOp --
448 *
449 * Toggles the state of the grid shown/hidden.
450 *
451 * Results:
452 * A standard Tcl result.
453 *
454 * Side Effects:
455 * Grid is hidden/displayed. The graph is redrawn at the next
456 * idle time.
457 *
458 *----------------------------------------------------------------------
459 */
460/*ARGSUSED*/
461static int
462ToggleOp(graphPtr, interp, argc, argv)
463 Graph *graphPtr;
464 Tcl_Interp *interp;
465 int argc;
466 char **argv;
467{
468 Grid *gridPtr = (Grid *)graphPtr->gridPtr;
469
470 gridPtr->hidden = (!gridPtr->hidden);
471 graphPtr->flags |= REDRAW_BACKING_STORE;
472 Blt_EventuallyRedrawGraph(graphPtr);
473 return TCL_OK;
474}
475
476
477static Blt_OpSpec gridOps[] =
478{
479 {"cget", 2, (Blt_Op)CgetOp, 4, 4, "option",},
480 {"configure", 2, (Blt_Op)ConfigureOp, 3, 0, "?options...?",},
481 {"off", 2, (Blt_Op)UnmapOp, 3, 3, "",},
482 {"on", 2, (Blt_Op)MapOp, 3, 3, "",},
483 {"toggle", 1, (Blt_Op)ToggleOp, 3, 3, "",},
484};
485static int nGridOps = sizeof(gridOps) / sizeof(Blt_OpSpec);
486
487/*
488 *----------------------------------------------------------------------
489 *
490 * Blt_GridOp --
491 *
492 * User routine to configure grid lines. Grids are drawn
493 * at major tick intervals across the graph.
494 *
495 * Results:
496 * The return value is a standard Tcl result.
497 *
498 * Side Effects:
499 * Grid may be drawn in the plotting area.
500 *
501 *----------------------------------------------------------------------
502 */
503int
504Blt_GridOp(graphPtr, interp, argc, argv)
505 Graph *graphPtr;
506 Tcl_Interp *interp;
507 int argc;
508 char **argv;
509{
510 Blt_Op proc;
511
512 proc = Blt_GetOp(interp, nGridOps, gridOps, BLT_OP_ARG2, argc, argv, 0);
513 if (proc == NULL) {
514 return TCL_ERROR;
515 }
516 return (*proc) (graphPtr, interp, argc, argv);
517}
Note: See TracBrowser for help on using the repository browser.