1 /*
2 * Copyright (C) 1996 by Rob McMullen
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 *
19 * Author: Rob McMullen <rwmcm@orion.ae.utexas.edu>
20 * http://www.ae.utexas.edu/~rwmcm
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <time.h>
29 #include <X11/Intrinsic.h>
30 #include <X11/Shell.h>
31 #include <X11/StringDefs.h>
32 #include <Xm/Xm.h>
33 #include <Xm/Label.h>
34 #include <Xm/TextF.h>
35 #include <Xm/RowColumn.h>
36 #include <Xm/Form.h>
37 #include <Xm/PushB.h>
38 #include <Xm/DialogS.h>
39 #include <Xm/MainW.h>
40 #include <Xm/PanedW.h>
41
42 #include "SciPlot.h"
43
44 /* Globals */
45 static int DialogCount=0; /* Number of dialogs on screen */
46
47
48 typedef struct {
49 char *text;
50 int num;
51 } textnumpair;
52
53 textnumpair colors_list[] =
54 {
55 {"blue", 0},
56 {"red", 0},
57 {"ForestGreen", 0},
58 {"DarkGoldenrod", 0},
59 {"orange", 0},
60 {"magenta", 0},
61 {"grey", 0},
62 {"purple", 0},
63 };
64
65 #define NUM_COLORS 8
66
67 textnumpair marker_list[] =
68 {
69 {"XtMARKER_SQUARE", XtMARKER_SQUARE},
70 {"XtMARKER_CIRCLE", XtMARKER_CIRCLE},
71 {"XtMARKER_UTRIANG ", XtMARKER_UTRIANGLE},
72 {"XtMARKER_DTRIANG ", XtMARKER_DTRIANGLE},
73 {"XtMARKER_DIAMOND", XtMARKER_DIAMOND},
74 {"XtMARKER_HOURGLA ", XtMARKER_HOURGLASS},
75 {"XtMARKER_BOWTIE", XtMARKER_BOWTIE},
76 {"XtMARKER_LTRIANG ", XtMARKER_LTRIANGLE},
77 {"XtMARKER_RTRIANG", XtMARKER_RTRIANGLE},
78 {"XtMARKER_FCIRCLE ", XtMARKER_FCIRCLE},
79 {"XtMARKER_FSQUARE", XtMARKER_FSQUARE},
80 {"XtMARKER_FUTRIAN", XtMARKER_FUTRIANGLE},
81 {"XtMARKER_FDTRIAN ", XtMARKER_FDTRIANGLE},
82 {"XtMARKER_FDIAMON ", XtMARKER_FDIAMOND},
83 {"XtMARKER_FHOURGL", XtMARKER_FHOURGLASS},
84 {"XtMARKER_FBOWTIE", XtMARKER_FBOWTIE},
85 {"XtMARKER_FLTRIAN", XtMARKER_FLTRIANGLE},
86 {"XtMARKER_FRTRIAN", XtMARKER_FRTRIANGLE}
87 };
88
89 #define NUM_MARKERS 18
90
91
92 /* String Utilities */
93
94 #ifndef TRUE
95 #define TRUE 1
96 #endif
97
98 #ifndef FALSE
99 #define FALSE 0
100 #endif
101
102 #define MAXFIELD 40
103 #define STRING_MAX 63
104
105 char field[MAXFIELD][STRING_MAX+1];
106 float ffield[MAXFIELD];
107
108 #define PARSE_SEPARATORS ",= \t\n"
109
110 static void
upper(char * str)111 upper(char *str)
112 {
113 int i;
114 char *dest;
115
116 dest = str;
117 for (i = strlen(str); i > 0; i--) {
118 if (*str != ' ')
119 *dest++ = toupper(*str);
120 str++;
121 }
122 *dest = (char) 0;
123 }
124
125 static char *
strparse(char * str,char * primary)126 strparse(char *str, char *primary)
127 {
128 static int start, len;
129 static char *save;
130 static char quotes[] = "'\"";
131 int skip, i, plen, qlen;
132 char c, *begin;
133
134 if (primary) {
135 if (str) {
136 save = str;
137 len = strlen(str);
138 start = 0;
139 }
140 if (start >= len)
141 return NULL;
142 plen = strlen(primary);
143 qlen = strlen(quotes);
144
145 /* find first valid character: */
146 skip = TRUE;
147 while ((start < len) && (skip)) {
148 c = save[start];
149 skip = FALSE;
150 for (i = 0; i < plen; i++) {
151 if (c == primary[i]) {
152 skip = TRUE;
153 break;
154 }
155 }
156 if (skip)
157 start++;
158 }
159 if (start >= len)
160 return NULL;
161
162 begin = &save[start];
163
164 /* OK, are pointing to first delimeter */
165
166 if (*begin == '\"') {
167 begin++;
168 start++;
169 while (start < len) {
170 c = save[start];
171 if (c == '\"') {
172 save[start] = '\0';
173 start++;
174 break;
175 }
176 else if (c == '\0') {
177 break;
178 }
179 start++;
180 }
181 }
182 else {
183 skip = FALSE;
184 while ((start < len) && (!skip)) {
185 c = save[start];
186 skip = FALSE;
187 for (i = 0; i < plen; i++)
188 if (c == primary[i]) {
189 skip = TRUE;
190 break;
191 }
192 if (skip) {
193 save[start] = '\0';
194 start++;
195 break;
196 }
197 else
198 start++;
199 }
200 }
201 return begin;
202 }
203 return NULL;
204 }
205
206 static int
sepfield(char * str,int count)207 sepfield(char *str, int count)
208 {
209 char *ptr, *end;
210 char tmpval[1024];
211
212 strcpy(tmpval, str);
213 ptr = strchr(tmpval, '#');
214 end = tmpval + strlen(tmpval);
215 if (ptr)
216 *ptr = (char) 0;
217 ptr = strparse(tmpval, PARSE_SEPARATORS);
218 while (ptr) {
219 strncpy(field[count], ptr, STRING_MAX - 1);
220 field[count][STRING_MAX - 1] = (char) 0;
221 count++;
222 ptr = strparse((char *) NULL, PARSE_SEPARATORS);
223 }
224 #ifdef DEBUG
225 printf("sepfield: %d\t", count);
226 for (j = 0; j < count; j++)
227 printf("->%s<-", field[j]);
228 printf("\n");
229 #endif
230 return count;
231 }
232
233 static void
tofloat(int count)234 tofloat(int count)
235 {
236 int i;
237 float val;
238
239 for (i = 0; i < count; i++) {
240 val = (float) atof(field[i]);
241 ffield[i] = val;
242 }
243 for (i = count; i < MAXFIELD; i++)
244 ffield[i] = 0.0;
245 #ifdef DEBUG
246 if (1) {
247 int j;
248
249 printf("tofloat: (%d)", count);
250 for (j = 0; j < count; j++)
251 printf("->%f<-", ffield[j]);
252 printf("\n");
253 }
254 #endif
255 }
256
257 #define isfloat(c) (isdigit(c) || c=='.' || c=='-')
258 #define isfloatany(c) (isdigit(c) || c=='.' || c=='e' || c=='E' || c=='-' || c=='+')
259
260 static int
checkfloat(int loc)261 checkfloat(int loc)
262 {
263 char *c;
264
265 c = field[loc];
266 if (*c && (isfloat(*c))) {
267 c++;
268 while (*c) {
269 if (!isfloatany(*c))
270 return 0;
271 c++;
272 }
273 }
274 else {
275 return 0;
276 }
277 #ifdef DEBUG
278 printf("%s is a float\n", field[loc]);
279 #endif
280 return 1;
281 }
282
283 static int
reads(int fd,char * buf,int num)284 reads(int fd, char *buf, int num)
285 {
286 int count;
287
288 count = 0;
289 while (count < num) {
290 if (read(fd, buf, 1) == 1) {
291 count++;
292 if (*buf == '\n')
293 break;
294 buf++;
295 }
296 else if (count > 0)
297 break;
298 else {
299 count = -1;
300 break;
301 }
302 }
303 *buf = '\0';
304 return count;
305 }
306
307 /*
308 * Read a line (ended by \n) from the specified file and call sepfield() to
309 * break the line up into fields.
310 */
311 int
getfields(FILE * fd)312 getfields(FILE *fd)
313 {
314 int count;
315 static char cmdline[1024];
316
317 do {
318 count = reads(fileno(fd), cmdline, 1000);
319 if (count<=0)
320 return -1;
321 count = sepfield(cmdline, 0);
322 } while (count==0);
323
324 return count;
325 }
326
327
328
329
330
331 /*
332 * Utils
333 */
334
335 /* Internal structure for each plot dialog */
336
337 typedef struct {
338 Widget label1;
339 Widget label2;
340 Widget label3;
341 Widget title;
342 Widget xlabel;
343 Widget ylabel;
344 Widget shell;
345 Widget plot;
346 Widget text;
347 } PlotDialogData;
348
349 static void
QuitCallback(Widget btn,XtPointer client,XtPointer call)350 QuitCallback(Widget btn, XtPointer client, XtPointer call)
351 {
352 exit(0);
353 }
354
355 static void
DismissCallback(Widget btn,XtPointer client,XtPointer call)356 DismissCallback(Widget btn, XtPointer client, XtPointer call)
357 {
358 PlotDialogData *stuff = (PlotDialogData *) client;
359
360 XtPopdown(stuff->shell);
361 XtDestroyWidget(stuff->shell);
362 free(stuff);
363 DialogCount--;
364 if (DialogCount == 0)
365 exit(0);
366 }
367
368 static void
LogXCallback(Widget btn,XtPointer client,XtPointer call)369 LogXCallback(Widget btn, XtPointer client, XtPointer call)
370 {
371 PlotDialogData *stuff = (PlotDialogData *) client;
372 Boolean state;
373
374 XtVaGetValues(stuff->plot,
375 XtNxLog, &state,
376 NULL);
377 state=!state;
378 XtVaSetValues(stuff->plot,
379 XtNxLog, state,
380 NULL);
381 }
382
383 static void
LogYCallback(Widget btn,XtPointer client,XtPointer call)384 LogYCallback(Widget btn, XtPointer client, XtPointer call)
385 {
386 PlotDialogData *stuff = (PlotDialogData *) client;
387 Boolean state;
388
389 XtVaGetValues(stuff->plot,
390 XtNyLog, &state,
391 NULL);
392 state=!state;
393 XtVaSetValues(stuff->plot,
394 XtNyLog, state,
395 NULL);
396 }
397
398 static void
NumbersXCallback(Widget btn,XtPointer client,XtPointer call)399 NumbersXCallback(Widget btn, XtPointer client, XtPointer call)
400 {
401 PlotDialogData *stuff = (PlotDialogData *) client;
402 Boolean state;
403
404 XtVaGetValues(stuff->plot,
405 XtNxAxisNumbers, &state,
406 NULL);
407 state=!state;
408 XtVaSetValues(stuff->plot,
409 XtNxAxisNumbers, state,
410 NULL);
411 }
412
413 static void
NumbersYCallback(Widget btn,XtPointer client,XtPointer call)414 NumbersYCallback(Widget btn, XtPointer client, XtPointer call)
415 {
416 PlotDialogData *stuff = (PlotDialogData *) client;
417 Boolean state;
418
419 XtVaGetValues(stuff->plot,
420 XtNyAxisNumbers, &state,
421 NULL);
422 state=!state;
423 XtVaSetValues(stuff->plot,
424 XtNyAxisNumbers, state,
425 NULL);
426 }
427
428 static void
OriginXCallback(Widget btn,XtPointer client,XtPointer call)429 OriginXCallback(Widget btn, XtPointer client, XtPointer call)
430 {
431 PlotDialogData *stuff = (PlotDialogData *) client;
432 Boolean state;
433
434 XtVaGetValues(stuff->plot,
435 XtNxOrigin, &state,
436 NULL);
437 state=!state;
438 XtVaSetValues(stuff->plot,
439 XtNxOrigin, state,
440 NULL);
441 }
442
443 static void
OriginYCallback(Widget btn,XtPointer client,XtPointer call)444 OriginYCallback(Widget btn, XtPointer client, XtPointer call)
445 {
446 PlotDialogData *stuff = (PlotDialogData *) client;
447 Boolean state;
448
449 XtVaGetValues(stuff->plot,
450 XtNyOrigin, &state,
451 NULL);
452 state=!state;
453 XtVaSetValues(stuff->plot,
454 XtNyOrigin, state,
455 NULL);
456 }
457
458 static void
MajorCallback(Widget btn,XtPointer client,XtPointer call)459 MajorCallback(Widget btn, XtPointer client, XtPointer call)
460 {
461 PlotDialogData *stuff = (PlotDialogData *) client;
462 Boolean state;
463
464 XtVaGetValues(stuff->plot,
465 XtNdrawMajor, &state,
466 NULL);
467 state=!state;
468 XtVaSetValues(stuff->plot,
469 XtNdrawMajor, state,
470 NULL);
471 }
472
473 static void
MinorCallback(Widget btn,XtPointer client,XtPointer call)474 MinorCallback(Widget btn, XtPointer client, XtPointer call)
475 {
476 PlotDialogData *stuff = (PlotDialogData *) client;
477 Boolean state;
478
479 XtVaGetValues(stuff->plot,
480 XtNdrawMinor, &state,
481 NULL);
482 state=!state;
483 XtVaSetValues(stuff->plot,
484 XtNdrawMinor, state,
485 NULL);
486 }
487
488 static void
LegendCallback(Widget btn,XtPointer client,XtPointer call)489 LegendCallback(Widget btn, XtPointer client, XtPointer call)
490 {
491 PlotDialogData *stuff = (PlotDialogData *) client;
492 Boolean state;
493
494 XtVaGetValues(stuff->plot,
495 XtNshowLegend, &state,
496 NULL);
497 state=!state;
498 XtVaSetValues(stuff->plot,
499 XtNshowLegend, state,
500 NULL);
501 }
502
503 static void
TitleChangeCallback(Widget btn,XtPointer client,XtPointer call)504 TitleChangeCallback(Widget btn, XtPointer client, XtPointer call)
505 {
506 PlotDialogData *stuff = (PlotDialogData *) client;
507 char *ret;
508
509 ret=XmTextFieldGetString(btn);
510 XtVaSetValues(stuff->plot,
511 XtNplotTitle, ret,
512 NULL);
513 XtFree(ret);
514 }
515
516 static void
TitleCallback(Widget btn,XtPointer client,XtPointer call)517 TitleCallback(Widget btn, XtPointer client, XtPointer call)
518 {
519 PlotDialogData *stuff = (PlotDialogData *) client;
520 Boolean state;
521
522 XtVaGetValues(stuff->plot,
523 XtNshowTitle, &state,
524 NULL);
525 state=!state;
526 XtVaSetValues(stuff->plot,
527 XtNshowTitle, state,
528 NULL);
529 #ifdef DEBUG
530 if (1) {
531 char label[256],*txt1,*txt2,*txt3;
532 static int count=0;
533
534 sprintf(label,"Title #%d",++count);
535 XtVaSetValues(stuff->plot,
536 XtNplotTitle, label,
537 NULL);
538 XtVaGetValues(stuff->plot,
539 XtNplotTitle, &txt1,
540 XtNxLabel, &txt2,
541 XtNyLabel, &txt3,
542 NULL);
543 printf("title=%s\nx label=%s\ny label=%s\n",txt);
544 #endif
545 }
546
547 static void
548 LabelXChangeCallback(Widget btn, XtPointer client, XtPointer call)
549 {
550 PlotDialogData *stuff = (PlotDialogData *) client;
551 char *ret;
552
553 ret=XmTextFieldGetString(btn);
554 XtVaSetValues(stuff->plot,
555 XtNxLabel, ret,
556 NULL);
557 XtFree(ret);
558 }
559
560 static void
561 LabelXCallback(Widget btn, XtPointer client, XtPointer call)
562 {
563 PlotDialogData *stuff = (PlotDialogData *) client;
564 Boolean state;
565
566 XtVaGetValues(stuff->plot,
567 XtNshowXLabel, &state,
568 NULL);
569 state=!state;
570 XtVaSetValues(stuff->plot,
571 XtNshowXLabel, state,
572 NULL);
573 #ifdef DEBUG
574 if (1) {
575 char label[256];
576 static int count=0;
577
578 sprintf(label,"X Label #%d",++count);
579 XtVaSetValues(stuff->plot,
580 XtNxLabel, label,
581 NULL);
582 }
583 #endif
584 }
585
586 static void
587 LabelYChangeCallback(Widget btn, XtPointer client, XtPointer call)
588 {
589 PlotDialogData *stuff = (PlotDialogData *) client;
590 char *ret;
591
592 ret=XmTextFieldGetString(btn);
593 XtVaSetValues(stuff->plot,
594 XtNyLabel, ret,
595 NULL);
596 XtFree(ret);
597 }
598
599 static void
600 LabelYCallback(Widget btn, XtPointer client, XtPointer call)
601 {
602 PlotDialogData *stuff = (PlotDialogData *) client;
603 Boolean state;
604
605 XtVaGetValues(stuff->plot,
606 XtNshowYLabel, &state,
607 NULL);
608 state=!state;
609 XtVaSetValues(stuff->plot,
610 XtNshowYLabel, state,
611 NULL);
612 #ifdef DEBUG
613 if (1) {
614 char label[256];
615 static int count=0;
616
617 sprintf(label,"Y Label #%d",++count);
618 XtVaSetValues(stuff->plot,
619 XtNyLabel, label,
620 NULL);
621 }
622 #endif
623 }
624
625 static void
626 PSCallback(Widget btn, XtPointer client, XtPointer call)
627 {
628 PlotDialogData *stuff = (PlotDialogData *) client;
629 char *filename;
630
631 #ifdef EXTRA_FANCY
632 char txt[1024],*ptr;
633
634 ptr=XmTextFieldGetString(stuff->label1);
635 strcpy(txt,ptr);
636 strcat(txt,"\n");
637 XtFree(ptr);
638 ptr=XmTextFieldGetString(stuff->label2);
639 strcat(txt,ptr);
640 strcat(txt,"\n\n");
641 XtFree(ptr);
642 ptr=XmTextFieldGetString(stuff->label3);
643 strcat(txt,ptr);
644 strcat(txt,"\n");
645 XtFree(ptr);
646
647 filename = XmTextFieldGetString(stuff->text);
648 if (strlen(filename) > 0)
649 SciPlotPSCreateFancy(stuff->plot,filename,
650 TRUE,txt,NULL);
651 XtFree(filename);
652 #else
653 filename = XmTextFieldGetString(stuff->text);
654 if (strlen(filename) > 0)
655 SciPlotPSCreateColor(stuff->plot,filename);
656 XtFree(filename);
657 #endif
658 }
659
660
661 /*
662 * Create an plot dialog using Motif widgets
663 */
664 static PlotDialogData *
665 SciPlotDialogInternal(Widget parent, char *title)
666 {
667 Widget paned, box, topbox, botbox, btn, t1;
668 PlotDialogData *info;
669 char *text;
670 #ifdef EXTRA_FANCY
671 char buf[256];
672 time_t now;
673 struct tm *t;
674 #endif
675
676 info = (PlotDialogData *) malloc(sizeof(PlotDialogData));
677 DialogCount++;
678
679 text = malloc(strlen(title) + 256);
680 sprintf(text, "Plot #%d: %s ", DialogCount, title);
681
682 paned=XmCreateFormDialog(parent,text,NULL,0);
683 info->shell=XtParent(paned);
684 XtVaSetValues(paned,
685 XmNdialogStyle,XmDIALOG_MODELESS,
686 XmNnoResize,False,
687 XmNautoUnmanage,False,
688 NULL);
689
690 topbox = box = XtVaCreateManagedWidget("box",
691 xmRowColumnWidgetClass,paned,
692 XmNleftAttachment, XmATTACH_FORM,
693 XmNrightAttachment, XmATTACH_FORM,
694 XmNtopAttachment, XmATTACH_FORM,
695 XmNpacking, XmPACK_COLUMN,
696 XmNnumColumns, 2,
697 XmNorientation, XmVERTICAL,
698 NULL);
699
700 #ifdef EXTRA_FANCY
701 btn = XtVaCreateManagedWidget("Desc 1:",
702 xmLabelWidgetClass, box,
703 NULL);
704 btn = XtVaCreateManagedWidget("Desc 2:",
705 xmLabelWidgetClass, box,
706 NULL);
707 btn = XtVaCreateManagedWidget("Desc 3:",
708 xmLabelWidgetClass, box,
709 NULL);
710 #endif
711 btn = XtVaCreateManagedWidget("Xlabel:",
712 xmLabelWidgetClass, box,
713 NULL);
714 btn = XtVaCreateManagedWidget("Ylabel:",
715 xmLabelWidgetClass, box,
716 NULL);
717 btn = XtVaCreateManagedWidget("Title:",
718 xmLabelWidgetClass, box,
719 NULL);
720
721 #ifdef EXTRA_FANCY
722 info->label1 = XtVaCreateManagedWidget("entry",
723 xmTextFieldWidgetClass, box,
724 XmNskipAdjust, True,
725 NULL);
726 info->label2 = XtVaCreateManagedWidget("entry",
727 xmTextFieldWidgetClass, box,
728 XmNskipAdjust, True,
729 NULL);
730 now=time(NULL);
731 t=localtime(&now);
732 strftime(buf,256,"%c",t);
733 info->label3 = XtVaCreateManagedWidget("entry",
734 xmTextFieldWidgetClass, box,
735 XmNvalue, buf,
736 XmNcursorPosition, 100,
737 XmNskipAdjust, True,
738 NULL);
739 #endif
740 info->xlabel = XtVaCreateManagedWidget("entry",
741 xmTextFieldWidgetClass, box,
742 NULL);
743 info->ylabel = XtVaCreateManagedWidget("entry",
744 xmTextFieldWidgetClass, box,
745 NULL);
746 info->title = XtVaCreateManagedWidget("entry",
747 xmTextFieldWidgetClass, box,
748 NULL);
749 XtAddCallback(info->xlabel, XmNactivateCallback, LabelXChangeCallback, (XtPointer) info);
750 XtAddCallback(info->ylabel, XmNactivateCallback, LabelYChangeCallback, (XtPointer) info);
751 XtAddCallback(info->title, XmNactivateCallback, TitleChangeCallback, (XtPointer) info);
752
753 box = XtVaCreateManagedWidget("box",
754 xmRowColumnWidgetClass,paned,
755 XmNleftAttachment, XmATTACH_FORM,
756 XmNrightAttachment, XmATTACH_FORM,
757 XmNbottomAttachment, XmATTACH_FORM,
758 XmNorientation, XmHORIZONTAL,
759 XmNpacking, XmPACK_TIGHT,
760 NULL);
761 btn = XtVaCreateManagedWidget("Quit",
762 xmPushButtonWidgetClass, box,
763 NULL);
764 XtAddCallback(btn, XmNactivateCallback, QuitCallback, (XtPointer) NULL);
765
766 btn = XtVaCreateManagedWidget("Dismiss",
767 xmPushButtonWidgetClass, box,
768 NULL);
769 XtAddCallback(btn, XmNactivateCallback, DismissCallback, (XtPointer) info);
770
771 btn = XtVaCreateManagedWidget("Make Postscript",
772 xmPushButtonWidgetClass, box,
773 NULL);
774 sprintf(text, "plot%d.ps", DialogCount);
775 t1 = XtVaCreateManagedWidget("entry",
776 xmTextFieldWidgetClass, box,
777 XmNwidth, 200,
778 XmNvalue, text,
779 XmNcursorPosition, 100,
780 NULL);
781 info->text = t1;
782 XtAddCallback(btn, XmNactivateCallback, PSCallback, (XtPointer) info);
783
784 botbox = box = XtVaCreateManagedWidget("box",
785 xmRowColumnWidgetClass,paned,
786 XmNleftAttachment, XmATTACH_FORM,
787 XmNrightAttachment, XmATTACH_FORM,
788 XmNbottomAttachment, XmATTACH_WIDGET,
789 XmNbottomWidget, box,
790 XmNorientation, XmHORIZONTAL,
791 XmNpacking, XmPACK_TIGHT,
792 NULL);
793 btn = XtVaCreateManagedWidget("Log",
794 xmLabelWidgetClass, box,
795 NULL);
796 btn = XtVaCreateManagedWidget("X",
797 xmPushButtonWidgetClass, box,
798 NULL);
799 XtAddCallback(btn, XmNactivateCallback, LogXCallback, (XtPointer) info);
800 btn = XtVaCreateManagedWidget("Y",
801 xmPushButtonWidgetClass, box,
802 NULL);
803 XtAddCallback(btn, XmNactivateCallback, LogYCallback, (XtPointer) info);
804
805 btn = XtVaCreateManagedWidget("Origin",
806 xmLabelWidgetClass, box,
807 NULL);
808 btn = XtVaCreateManagedWidget("X",
809 xmPushButtonWidgetClass, box,
810 NULL);
811 XtAddCallback(btn, XmNactivateCallback, OriginXCallback, (XtPointer) info);
812 btn = XtVaCreateManagedWidget("Y",
813 xmPushButtonWidgetClass, box,
814 NULL);
815 XtAddCallback(btn, XmNactivateCallback, OriginYCallback, (XtPointer) info);
816
817 btn = XtVaCreateManagedWidget("Numbers",
818 xmLabelWidgetClass, box,
819 NULL);
820 btn = XtVaCreateManagedWidget("X",
821 xmPushButtonWidgetClass, box,
822 NULL);
823 XtAddCallback(btn, XmNactivateCallback, NumbersXCallback, (XtPointer) info);
824 btn = XtVaCreateManagedWidget("Y",
825 xmPushButtonWidgetClass, box,
826 NULL);
827 XtAddCallback(btn, XmNactivateCallback, NumbersYCallback, (XtPointer) info);
828
829 btn = XtVaCreateManagedWidget("Major",
830 xmPushButtonWidgetClass, box,
831 NULL);
832 XtAddCallback(btn, XmNactivateCallback, MajorCallback, (XtPointer) info);
833 btn = XtVaCreateManagedWidget("Minor",
834 xmPushButtonWidgetClass, box,
835 NULL);
836 XtAddCallback(btn, XmNactivateCallback, MinorCallback, (XtPointer) info);
837 btn = XtVaCreateManagedWidget("Title",
838 xmPushButtonWidgetClass, box,
839 NULL);
840 XtAddCallback(btn, XmNactivateCallback, TitleCallback, (XtPointer) info);
841 btn = XtVaCreateManagedWidget("X Label",
842 xmPushButtonWidgetClass, box,
843 NULL);
844 XtAddCallback(btn, XmNactivateCallback, LabelXCallback, (XtPointer) info);
845 btn = XtVaCreateManagedWidget("Y Label",
846 xmPushButtonWidgetClass, box,
847 NULL);
848 XtAddCallback(btn, XmNactivateCallback, LabelYCallback, (XtPointer) info);
849 btn = XtVaCreateManagedWidget("Legend",
850 xmPushButtonWidgetClass, box,
851 NULL);
852 XtAddCallback(btn, XmNactivateCallback, LegendCallback, (XtPointer) info);
853
854 info->plot = XtVaCreateManagedWidget("plot",
855 sciplotWidgetClass, paned,
856 XmNleftAttachment, XmATTACH_FORM,
857 XmNrightAttachment, XmATTACH_FORM,
858 XmNtopAttachment, XmATTACH_WIDGET,
859 XmNtopWidget, topbox,
860 XmNbottomAttachment, XmATTACH_WIDGET,
861 XmNbottomWidget, botbox,
862 XtNheight, (XtArgVal) 600,
863 XtNwidth, (XtArgVal) 500,
864 XtNplotTitle, title,
865 /* XtNlabelFont, XtFONT_TIMES|8, */
866 /* XtNtitleFont, XtFONT_TIMES|8, */
867 /* XtNtitleMargin, 4, */
868 /* XtNaxisFont, XtFONT_TIMES|8, */
869 NULL);
870
871 free(text);
872 XtManageChild(paned);
873 XtManageChild(info->shell);
874 return info;
875 }
876
877 static void
878 SciPlotDialogInternalPopup(PlotDialogData *info)
879 {
880 char *x,*y,*t;
881
882 XtVaGetValues(info->plot,
883 XtNplotTitle, &t,
884 XtNxLabel, &x,
885 XtNyLabel, &y,
886 NULL);
887 XmTextFieldSetString(info->title,t);
888 XmTextFieldSetString(info->xlabel,x);
889 XmTextFieldSetString(info->ylabel,y);
890
891 XtManageChild(info->shell);
892 }
893
894 Widget
895 SciPlotDialog(Widget parent, char *title)
896 {
897 PlotDialogData *info;
898
899 info = SciPlotDialogInternal(parent,title);
900 return info->plot;
901 }
902
903 void
904 SciPlotDialogPopup(Widget w)
905 {
906 XtManageChild(XtParent(XtParent(w)));
907 }
908
909 /*
910 * Process a text input stream for plot commands
911 */
912 void
913 SciPlotReadDataFile(Widget parent, FILE * fd)
914 {
915 int count;
916 PlotDialogData *working;
917 float xlist[10], ylist[10];
918 int line[256], linecount;
919 Boolean readnext;
920 int num, i;
921
922 working = NULL;
923 count = getfields(fd);
924 while (count > 0) {
925 if (count > 0) {
926 readnext = True;
927 upper(field[0]);
928 if (strcmp(field[0], "TITLE") == 0 || strcmp(field[0], "NEW") == 0 ) {
929 /* Pop up the last dialog if it exists */
930 if (working) SciPlotDialogInternalPopup(working);
931
932 working = SciPlotDialogInternal(parent, field[1]);
933 for (i = 0; i < NUM_COLORS; i++) {
934 colors_list[i].num = SciPlotAllocNamedColor(working->plot, colors_list[i].text);
935 }
936 linecount = 0;
937 }
938 else if (strcmp(field[0], "POLAR") == 0) {
939 Boolean degflag;
940
941 degflag = True;
942 if (count > 1) {
943 upper(field[1]);
944 if (strncmp(field[1], "RAD", 3) == 0)
945 degflag = False;
946 }
947 XtVaSetValues(working->plot,
948 XtNchartType, XtPOLAR,
949 XtNdegrees, degflag,
950 NULL);
951 }
952 else if (strcmp(field[0], "XAXIS") == 0) {
953 if (working) {
954 if (count > 1) XtVaSetValues(working->plot, XtNxLabel, field[1], NULL);
955 if (count>2) {
956 for (i=2; i<count; i++) {
957 upper(field[i]);
958 if (strcmp(field[i], "LOG") == 0)
959 XtVaSetValues(working->plot, XtNxLog, True, NULL);
960 else if (strcmp(field[i], "NOZERO") == 0)
961 XtVaSetValues(working->plot, XtNxOrigin, False, NULL);
962 }
963 }
964 }
965 }
966 else if (strcmp(field[0], "YAXIS") == 0) {
967 if (working) {
968 if (count > 1) XtVaSetValues(working->plot, XtNyLabel, field[1], NULL);
969 if (count>2) {
970 for (i=2; i<count; i++) {
971 upper(field[i]);
972 if (strcmp(field[i], "LOG") == 0)
973 XtVaSetValues(working->plot, XtNyLog, True, NULL);
974 else if (strcmp(field[i], "NOZERO") == 0)
975 XtVaSetValues(working->plot, XtNyOrigin, False, NULL);
976 }
977 }
978 }
979 }
980 else if (strcmp(field[0], "LEGEND") == 0) {
981 int colorcount, markercount, linestyle;
982
983 if (working && count > 1) {
984 if (count >= 4) {
985 XtVaSetValues(working->plot,
986 XtNxLabel, field[2],
987 XtNyLabel, field[3],
988 NULL);
989 }
990 line[0] = SciPlotListCreateFromFloat(working->plot, 0, NULL, NULL, field[1]);
991 do {
992 count = getfields(fd);
993 readnext = False;
994
995 num = checkfloat(0);
996 if (count > 0 && num) {
997 tofloat(count);
998 xlist[0] = ffield[0];
999 ylist[0] = ffield[1];
1000 SciPlotListAddFloat(working->plot, line[0], 1, xlist, ylist);
1001 }
1002
1003 } while (count > 0 && num);
1004 colorcount = linecount % NUM_COLORS;
1005 markercount = linecount % NUM_MARKERS;
1006 linestyle = -1;
1007 SciPlotListSetStyle(working->plot, line[0],
1008 colors_list[colorcount].num, marker_list[markercount].num,
1009 colors_list[colorcount].num, linestyle);
1010 linecount++;
1011 }
1012
1013 }
1014 else if (strcmp(field[0], "LINE") == 0) {
1015 int colorcount, markercount, linestyle, maxlines;
1016 Boolean skip;
1017
1018 if (working && count > 1) {
1019 for (i = 1; i < count; i++) {
1020 line[i] = SciPlotListCreateFromFloat(working->plot, 0, NULL, NULL, field[i]);
1021 }
1022 maxlines = count;
1023
1024 do {
1025 count = getfields(fd);
1026 readnext = False;
1027
1028 num = checkfloat(0);
1029 if (strcmp(field[0],"skip")==0) skip=True;
1030 else skip=False;
1031
1032 if (count > 0 && (num || skip)) {
1033 if (skip) {
1034 for (i = 1; i < maxlines; i++) {
1035 xlist[0] = ylist[0] = SCIPLOT_SKIP_VAL;
1036 SciPlotListAddFloat(working->plot, line[i], 1, xlist, ylist);
1037 }
1038 }
1039 else {
1040 tofloat(count);
1041 xlist[0] = ffield[0];
1042 for (i = 1; i < maxlines; i++) {
1043 ylist[0] = ffield[i];
1044 SciPlotListAddFloat(working->plot, line[i], 1, xlist, ylist);
1045 }
1046 }
1047
1048 }
1049 } while (count > 0 && (num || skip));
1050 for (i = 1; i < maxlines; i++) {
1051 linecount++;
1052 colorcount = linecount % NUM_COLORS;
1053 markercount = linecount % NUM_MARKERS;
1054 linestyle = -1;
1055 SciPlotListSetStyle(working->plot, line[i],
1056 colors_list[colorcount].num, marker_list[markercount].num,
1057 colors_list[colorcount].num, linestyle);
1058 /* SciPlotListSetMarkerSize(working->plot, line[i], (float) linecount*4); */
1059 }
1060 }
1061
1062 }
1063 }
1064 if (readnext)
1065 count = getfields(fd);
1066 }
1067 if (working) SciPlotDialogInternalPopup(working);
1068 }
1069