1
2 /*
3 * Include ./configure's header file
4 */
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 /*
10 * Simple GrADS GUI interface based on libsx. The script interpreter
11 * Custom_GUI() is implemented in file "gsgui.c".
12 *
13 * REVISION HISTORY:
14 *
15 * 22May97 da Silva First alpha version.
16 * 09Jun97 da Silva Fixed CB_Cmd which cause the command string
17 * to be destroyed on the first click;
18 * Fixed small bug on the CB_VAR window: now
19 * the user can type an expression with blanks.
20 * 10Jun97 da Silva Added CmdWin() callback.
21 * 19Sep97 da Silva Fixed small bug in CB_Display().
22 * 10Oct97 da Silva Revised Default_GUI().
23 *
24 * --
25 * (c) 1997 by Arlindo da Silva
26 *
27 * Permission is granted to any individual or institution to use,
28 * modify, copy, or redistribute this software so long as it is not
29 * sold for profit, and provided this notice is retained.
30 *
31 */
32
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include <time.h>
39
40 #include "X11/libsx/libsx.h"
41 #include "X11/libsx/freq.h"
42 #include "grads.h"
43 #include "gx.h"
44
45 extern struct gacmn gcmn;
46
47 #include "gagui.h"
48
49 static char default_var[128]; /* default variable for display */
50
51 static char last_path_open[512]; /* remember last path names */
52 static char last_path_sdfopen[512];
53 static char last_path_exec[512];
54 static char last_path_run[512];
55
56 static Widget var_window; /* window for variable selection */
57 static Widget file_window; /* window for file selection */
58 static Widget expr_window; /* window for variable selection */
59 static int hold_on = 0; /* controls 'clear' before displaying */
60
61 #define MAXROWS 256 /* for temporary mem aloocation */
62 #define MAXCOLS 256
63
64 #define NCMD 64 /* Sixe of command buffer */
65 #define LCMD 132 /* Max length of command */
66 static int CmdWinON = 0; /* Make sure there is only one
67 Command Win up */
68 static char **CmdWinList; /* Command buffer */
69 static Widget Cmd_window, CmdExpr_window, CmdList_window;
70
71 /*---------------------------------------------------------------------*
72
73 /*
74 * This is the GaGUI entry point. Return is thru the quit button.
75 *
76 */
77
gagui_main(int argc,char ** argv)78 int gagui_main(int argc, char **argv)
79 {
80
81 /*
82 static char *argv[] = { "GrADS", "-bg", "gray", NULL, NULL };
83 static int argc = 3;
84 */
85
86 char *path;
87
88 if ( gcmn.batflg ) return 0; /* batch mode */
89
90 argc = OpenDisplay(argc, argv);
91 if (argc == FALSE)
92 return argc;
93
94 /*
95 printf("Athena Widgets Support, (c) 1997 by Arlindo da Silva\n");
96 printf("Data Assimilation Office, NASA/GSFC\n\n");
97 */
98
99 /* Default path for file loads */
100 strcpy(last_path_open,"./");
101 strcpy(last_path_sdfopen,"./");
102 strcpy(last_path_exec,"./");
103 strcpy(last_path_run,"./");
104 if ( path = getenv("GADATA") ) {
105 strcpy(last_path_open,path);
106 strcpy(last_path_sdfopen,path);
107 }
108 if ( path = getenv("GASCRP") ) {
109 strcpy(last_path_exec,path);
110 strcpy(last_path_run,path);
111 }
112 default_var[0] = '\0';
113
114 /* Widget request on startup */
115 if ( path = getenv( "GAGUI" ) ) {
116
117 /* Built in default GUI interface */
118 if ( !strcmp(path,"default") ) {
119 argc = Default_GUI(argc, argv, NULL);
120 if (argc == 0) exit(0);
121 printf(" <<< Click on the RED button for the 'ga>' prompt >>>\n\n");
122 MainLoop();
123
124 /* Widget set from a script */
125 } else {
126 if(Custom_GUI(path)) return 1;
127 MainLoop();
128 }
129
130 }
131
132 }
133
134
135 /* List() - Allocates memory for character list */
List(int rows,int cols)136 char **List(int rows,int cols)
137 {
138 int i;
139 char **p;
140
141 /* Allocate pointers to rows */
142 p = ( char ** ) calloc ( rows, sizeof(char *) );
143 if(!p) {
144 printf("Error: cannot allocate memory for list (rows)\n");
145 return (char **)NULL;
146 }
147
148 /* Allocate rows and set pointers to them */
149 for(i=0; i<rows; i++) {
150 p[i] = ( char * ) calloc ( cols, sizeof(char) );
151 if(!p[i]) {
152 printf("Error: cannot allocate memory for list (cols)\n");
153 return (char **)NULL;
154 }
155 }
156
157 return (char **)p;
158 }
159
160 /* Free_List() - De-allocates memory for character list */
Free_List(char ** list,int rows)161 void Free_List(char **list, int rows)
162 {
163 int i;
164 for(i=0;i<rows;i++) free((char *)list[i]);
165 free((char *)list);
166 }
167
168 /*
169 * Return the directory component of a string or NULL if it's in
170 * the current directory.
171 */
dirname(char * str)172 char *dirname(char *str)
173 {
174 char *ptr, *tmp;
175
176 ptr = strrchr(str, '/');
177 if (ptr == NULL)
178 return NULL;
179
180 *ptr = '\0';
181 tmp = strdup(str);
182
183 *ptr = '/';
184
185 return tmp;
186 }
187
188
189
190 /*
191 * Default_GUI() - sets up default widget set.
192 */
193
194 int
Default_GUI(int argc,char ** argv,void * data)195 Default_GUI(int argc, char **argv, void *data)
196 {
197 Widget root, file, print, options, quit, reinit,prompt;
198 Widget clear, hold, prev, play, next, dim, var;
199 char str[256];
200 int i, gold, blue, gray;
201
202 /*
203 argc = OpenDisplay(argc, argv);
204 if (argc == FALSE)
205 return argc;
206 */
207
208 sprintf (str, "GrADS Version " GRADS_VERSION "\n");
209 root = MakeLabel(str);
210
211 file = MakeMenu ( "File" );
212 MakeMenuItem(file, "Open", CB_Load, "open");
213 MakeMenuItem(file, "SDF Open", CB_Load, "sdfopen");
214 MakeMenuItem(file, "XDF Open", CB_Load, "xdfopen");
215 MakeMenuItem(file, "File Selection ", CB_FileSel, NULL );
216 MakeMenuItem(file, "_______________", NULL, NULL );
217 MakeMenuItem(file, "Exec", CB_Load, "exec");
218 MakeMenuItem(file, "Run", CB_Load, "run");
219 MakeMenuItem(file, "GUI", CB_Load, "gui");
220 MakeMenuItem(file, "_______________", NULL, NULL );
221 MakeMenuItem(file, "Refresh", CB_Cmd, " ");
222 MakeMenuItem(file, "Reinit", CB_Cmd, "reinit");
223 MakeMenuItem(file, "Exit", CB_Exit, NULL );
224
225 print = MakeMenu ( "Print" );
226 MakeMenuItem(print, "Print", CB_Cmd, "print");
227 MakeMenuItem(print, "Enable Print", CB_Load, "enable print");
228 MakeMenuItem(print, "Disable Print", CB_Cmd, "disabled print");
229
230 options = MakeMenu ( "Options" );
231 MakeMenuItem(options, "Shaded", CB_Cmd, "set gxout shaded" );
232 MakeMenuItem(options, "Contour", CB_Cmd, "set gxout contour" );
233 MakeMenuItem(options, "Grid Fill", CB_Cmd, "set gxout grfill" );
234 MakeMenuItem(options, "Grid Values", CB_Cmd, "set gxout grid" );
235 MakeMenuItem(options, "Vector", CB_Cmd, "set gxout vector" );
236 MakeMenuItem(options, "Streamlines", CB_Cmd, "set gxout stream" );
237 MakeMenuItem(options, "Bar Chart", CB_Cmd, "set gxout bar" );
238 MakeMenuItem(options, "Line Plot", CB_Cmd, "set gxout line" );
239 MakeMenuItem(options, "Wind Barbs", CB_Cmd, "set gxout barb" );
240 MakeMenuItem(options, "_______________", NULL, NULL );
241 MakeMenuItem(options, "Contour Interval", CB_CmdStr, "set cint" );
242 MakeMenuItem(options, "Draw Title", CB_CmdStr, "draw title " );
243 MakeMenuItem(options, "Color Bar", CB_Cmd, "run cbarn" );
244
245 reinit = MakeButton("Reinit", CB_Cmd, "reinit" );
246 clear = MakeButton("Clear", CB_Cmd, "clear" );
247 quit = MakeButton("Quit", CB_Cmd, "quit" );
248 prompt = MakeButton("ga>", CB_CmdWin, NULL );
249
250 dim = MakeMenu("Dim");
251 MakeMenuItem(dim, "Longitude", CB_CmdStr, "set lon " );
252 MakeMenuItem(dim, "Latitude", CB_CmdStr, "set lat " );
253 MakeMenuItem(dim, "Level", CB_CmdStr, "set lev " );
254 MakeMenuItem(dim, "Time", CB_CmdStr, "set time " );
255 MakeMenuItem(dim, "_________", NULL, NULL );
256 MakeMenuItem(dim, "x", CB_CmdStr, "set x " );
257 MakeMenuItem(dim, "y", CB_CmdStr, "set y " );
258 MakeMenuItem(dim, "z", CB_CmdStr, "set z " );
259 MakeMenuItem(dim, "t", CB_CmdStr, "set t " );
260
261 var = MakeButton("Var", CB_VarSel, NULL );
262 hold = MakeToggle("Hold", FALSE, NULL, CB_Toggle, "hold" );
263 prev = MakeButton("<<", CB_Display, "<<" );
264 play = MakeButton("Display", CB_Display, "DISPLAY" );
265 next = MakeButton(">>", CB_Display, ">>" );
266
267
268 /* First row */
269 SetWidgetPos(file, PLACE_UNDER, root, NO_CARE, NULL);
270 SetWidgetPos(print, PLACE_UNDER, root, PLACE_RIGHT, file );
271 SetWidgetPos(options, PLACE_UNDER, root, PLACE_RIGHT, print );
272 SetWidgetPos(dim, PLACE_UNDER, root, PLACE_RIGHT, options );
273 SetWidgetPos(reinit, PLACE_UNDER, root, PLACE_RIGHT, dim);
274 SetWidgetPos(prompt, PLACE_UNDER, root, PLACE_RIGHT, reinit );
275
276 /* Second row */
277 SetWidgetPos(hold, PLACE_UNDER, file, NO_CARE, NULL);
278 SetWidgetPos(var, PLACE_UNDER, file, PLACE_RIGHT, hold );
279 SetWidgetPos(prev, PLACE_UNDER, file, PLACE_RIGHT, var );
280 SetWidgetPos(play, PLACE_UNDER, file, PLACE_RIGHT, prev );
281 SetWidgetPos(next, PLACE_UNDER, file, PLACE_RIGHT, play );
282 SetWidgetPos(clear, PLACE_UNDER, file, PLACE_RIGHT, next );
283 SetWidgetPos(quit, PLACE_UNDER, file, PLACE_RIGHT, clear );
284
285 ShowDisplay();
286
287 GetStandardColors();
288 gold = GetNamedColor("gold");
289 blue = GetNamedColor("LightSkyBlue");
290 gray = GetNamedColor("gray");
291
292 /* Color of widgets */
293 SetFgColor(root,RED);
294 SetFgColor(prompt,YELLOW);
295 SetBgColor(prompt,RED);
296
297 SetBgColor(file,blue);
298 SetBgColor(print,blue);
299 SetBgColor(options,blue);
300 SetBgColor(dim,blue);
301
302 SetBgColor(reinit,gray);
303 SetBgColor(var,gray);
304 SetBgColor(hold,gray);
305 SetBgColor(clear,gray);
306 SetBgColor(quit,gray);
307
308 SetBgColor(prev,gold);
309 SetBgColor(play,gold);
310 SetBgColor(next,gold);
311
312 return argc;
313 }
314
315 /*
316 * CB_Open() - Callback function for (sdf) opening a file. The opened file
317 * becomes the default and the user is asked to select a
318 * variable from the file. Unlike CB_Load(), the user must
319 * provide the file name.
320 *
321 */
CB_Open(Widget w,void * data)322 void CB_Open(Widget w, void *data)
323 {
324
325 char cmd[1024];
326 int rc;
327
328 printf("%s\n", data);
329 gcmn.sig = 0;
330 strncpy(cmd,data,1024);
331 rc = gacmd(cmd,&gcmn,0);
332 if(rc) Beep();
333 else if (cmpwrd("open",data)||cmpwrd("sdfopen",data))
334 {
335 sprintf(cmd,"set dfile %d", gcmn.fnum);
336 gcmn.sig = 0;
337 gacmd(cmd,&gcmn,0); /* new file becomes default */
338 CB_VarSel(w, data);
339 }
340
341 }
342
343 /*
344 * CB_Load() - Callback function for the load button. This just calls
345 * GetFile() to get a file name. In case of "open" or "sdfopen",
346 * the file becomes the default and the user is asked to select a
347 * variable from this file.
348 */
CB_Load(Widget w,void * data)349 void CB_Load(Widget w, void *data)
350 {
351 char *fname, *dname, *last_path, cmd[1024];
352 int i,rc;
353
354 if(strstr(data,"open")) last_path = last_path_open;
355 else if(strstr(data,"sdfopen")) last_path = last_path_sdfopen;
356 else if(strstr(data,"exec")) last_path = last_path_exec;
357 else if(strstr(data,"run")) last_path = last_path_run;
358 else last_path = NULL;
359 fname = GetFile(last_path);
360
361 if(fname)
362 {
363
364 /* save retrieved directory name for next time */
365 dname = dirname(fname);
366 if(strstr(data,"open")) strcpy(last_path_open,dname);
367 else if(strstr(data,"sdfopen")) strcpy(last_path_sdfopen,dname);
368 else if(strstr(data,"exec")) strcpy(last_path_exec,dname);
369 else if(strstr(data,"run")) strcpy(last_path_run,dname);
370 if(dname) free(dname);
371
372 sprintf(cmd,"%s %s", data, fname);
373 printf("%s\n", cmd);
374 gcmn.sig = 0;
375 rc = gacmd(cmd,&gcmn,0);
376 if(rc) Beep();
377 else if (cmpwrd("open",cmd)||cmpwrd("sdfopen",cmd))
378 {
379 sprintf(cmd,"set dfile %d", gcmn.fnum);
380 gcmn.sig = 0;
381 gacmd(cmd,&gcmn,0); /* new file becomes default */
382 CB_VarSel(w, data);
383 }
384
385 free(fname);
386 }
387 else {
388 printf("%s cancelled\n", data);
389 Beep();
390 }
391
392 }
393
394
395 /*
396 * CB_Cmd() - Callback funtion for a generic grads command button.
397 */
CB_Cmd(Widget w,void * data)398 void CB_Cmd(Widget w, void *data)
399 {
400
401 char cmd[1024]; /* temp space */
402 int rc;
403 if(data) {
404 gcmn.sig = 0;
405 strncpy(cmd,data,1024); /* need this or data will be overitten */
406 printf("%s\n", cmd);
407 rc=gacmd(cmd,&gcmn,0);
408 if(rc<0) {
409 if(GetYesNo("About to exit GrADS. Really?") == TRUE ) {
410 gxend();
411 exit(0); /* not sure if needed */
412 }
413 }
414 if(rc) Beep();
415 } else {
416 Beep();
417 printf("\n ***** GUI option not implemented yet *****\n\n");
418 }
419 }
420
421
422 /*
423 * CB_CmdLine() - Callback funtion for the command line button.
424 */
CB_CmdLine(Widget w,void * data)425 void CB_CmdLine(Widget w, void *data)
426 {
427
428 char cmd[1024];
429 int rc=0;
430
431 printf("\n <<< Enter '.' to leave the command line interface >>>\n\n");
432
433 while (rc>-1) {
434 #if READLINE == 1
435 nxrdln(&cmd[0],"ga->> ");
436 #else
437 nxtcmd(&cmd[0],"ga>>");
438 #endif
439 if ( cmd[0] == '.' )
440 {
441 printf(" <<< Click on the RED button for the 'ga>' prompt >>>\n\n");
442 return;
443 }
444 gcmn.sig = 0;
445 rc = gacmd(cmd,&gcmn,0);
446 /* if(rc<0)
447 if(GetYesNo("About to exit GrADS. Really?") == FALSE ) rc=0;
448 */ /* Command liners know what they are doing ... */
449 }
450 gxend();
451 exit(0); /* not sure if needed */
452
453 }
454
455
456 /*
457 * CB_VarSel() - Callback for selecting a variable.
458 *
459 */
CB_VarSel(Widget W,void * data)460 void CB_VarSel(Widget W, void *data)
461 {
462 Widget w[8];
463 struct gacmn *pcm;
464 struct gafile *pfi;
465 struct gavar *pvar;
466 int i;
467 char **item_list, *var, tmp[MAXROWS];
468
469 /* Make Variable List from GrADS data structures */
470 pcm = &gcmn;
471 if (pcm->pfi1==NULL) {
472 Beep();
473 printf("No Files Open\n");
474 return;
475 }
476 pfi = pcm->pfid;
477 pvar = pfi->pvar1;
478 item_list = (char **) List(pfi->vnum+1,MAXCOLS);
479 if(!item_list) return;
480 for (i=0;i<pfi->vnum;i++) {
481 /* printf (" %s %i %i %s\n",
482 pvar->abbrv,pvar->levels,pvar->units[0],pvar->varnm);
483 */
484 /* item_list[i] = pvar->abbrv; */
485 sprintf(item_list[i], "%12.12s %3i %s",
486 pvar->abbrv, pvar->levels, pvar->varnm);
487 pvar++;
488
489 }
490 item_list[pfi->vnum]=(char *)NULL; /* terminate list */
491
492
493 /* Creates widgets, etc... */
494 var_window = MakeWindow("Select a Variable", SAME_DISPLAY, EXCLUSIVE_WINDOW);
495
496 w[0] = MakeLabel(pfi->title);
497 w[2] = MakeScrollList(item_list, 500, 250, (void *)CB_VarList, item_list);
498 w[3] = MakeLabel("GrADS Expression: ");
499 w[4] = MakeStringEntry("", 300, (void *)CB_VarStr, &item_list);
500 expr_window = w[4];
501 w[5] = MakeButton("OK", (void *)CB_VarOK, NULL);
502 w[6] = MakeLabel("Click on a Variable from the List or Enter an Expression");
503 w[7] = MakeButton("Cancel", (void *)CB_VarCancel, &item_list);
504
505 SetWidgetPos(w[2], PLACE_UNDER, w[0], NO_CARE, NULL);
506 SetWidgetPos(w[3], PLACE_UNDER, w[2], NO_CARE, NULL);
507 SetWidgetPos(w[4], PLACE_UNDER, w[2], PLACE_RIGHT, w[3]);
508 SetWidgetPos(w[5], PLACE_UNDER, w[3], NO_CARE, NULL);
509 SetWidgetPos(w[6], PLACE_UNDER, w[3], PLACE_RIGHT, w[5]);
510 SetWidgetPos(w[7], PLACE_UNDER, w[3], PLACE_RIGHT, w[6]);
511
512 ShowDisplay();
513 SetFgColor(w[0],BLUE);
514 SetFgColor(w[6],RED);
515
516
517 if(default_var[0]) var = default_var;
518 else {
519 strcpy(tmp,item_list[0]);
520 var = strtok(tmp," ");
521 }
522 SetStringEntry(expr_window, var);
523
524 MainLoop();
525
526 SetCurrentWindow(ORIGINAL_WINDOW);
527
528 Free_List(item_list,pfi->vnum+1);
529
530 }
531
532
533 /*
534 * CB_VarList() - Callback routine for Clicking on variable list button
535 */
536
537
CB_VarList(Widget w,char * str,int index,void * data)538 void CB_VarList(Widget w, char *str, int index, void *data)
539 {
540 char *var, cmd[1024];
541 var = strtok(str," ");
542 strcpy(default_var,var);
543 SetCurrentWindow(var_window);
544 CloseWindow();
545 if(!hold_on) CB_Cmd(w,"clear");
546 sprintf(cmd,"display %s", default_var);
547 CB_Cmd(w,cmd); /* display the variable */
548 }
549
CB_VarStr(Widget w,char * str,int index,void * data)550 void CB_VarStr(Widget w, char *str, int index, void *data)
551 {
552 char cmd[1024];
553 strcpy(default_var,str);
554 SetCurrentWindow(var_window);
555 CloseWindow();
556 SyncDisplay();
557 if(!hold_on) CB_Cmd(w,"clear");
558 sprintf(cmd,"display %s", default_var);
559 CB_Cmd(w,cmd); /* display the variable */
560 }
561
CB_VarOK(Widget w,void * data)562 void CB_VarOK(Widget w, void *data)
563 {
564 int index=1;
565 char *str, *tmp;
566 str = GetStringEntry(expr_window);
567 if(str==NULL) {
568 Beep();
569 return;
570 }
571 CB_VarStr(w, str, index, data);
572 if(str!=NULL) free(str);
573 }
574
CB_VarCancel(Widget w,void * data)575 void CB_VarCancel(Widget w, void *data)
576 {
577 SetCurrentWindow(var_window);
578 CloseWindow();
579 Beep();
580 printf("Variable selection cancelled\n");
581 return;
582
583 }
584
585 /*-----------------------------------------------------------------------*/
586
587 /*
588 * CB_CmdWin() - Callback for a command window.
589 *
590 */
CB_CmdWin(Widget W,void * data)591 void CB_CmdWin(Widget W, void *data)
592 {
593 Widget w[8];
594 int i;
595
596 if(CmdWinON) {
597 Beep();
598 printf("Error: Command window already up!\n");
599 return;
600 }
601
602 /* Initialize Command Win buffer */
603 CmdWinList = (char **) List(NCMD+1,LCMD);
604 if(!CmdWinList) return;
605 for(i=0;i<NCMD;i++) CmdWinList[i][0] = '\0';
606 CmdWinList[NCMD] = (char *) NULL;
607 strncpy(CmdWinList[0], "clear", LCMD);
608 strncpy(CmdWinList[1], "reinit", LCMD);
609 strncpy(CmdWinList[2], "set gxout shaded", LCMD);
610 strncpy(CmdWinList[3], "set gxout contour", LCMD);
611 strncpy(CmdWinList[4], "print", LCMD);
612 strncpy(CmdWinList[5], "quit", LCMD);
613
614
615 /* Creates widgets, etc... */
616 Cmd_window = MakeWindow("GrADS Command Window", SAME_DISPLAY,
617 NONEXCLUSIVE_WINDOW);
618
619 w[0] = MakeLabel("GrADS Command Window");
620 w[1] = MakeLabel("ga> ");
621 w[2] = MakeStringEntry("", 450, (void *)CB_CmdWinStr, NULL);
622 CmdExpr_window = w[2];
623
624 w[3] = MakeScrollList(CmdWinList, 500, 200, (void *)CB_CmdWinList,
625 CmdWinList);
626 CmdList_window = w[3];
627 w[4] = MakeButton("OK", (void *)CB_CmdWinOK, NULL);
628 w[5] = MakeButton("Clear", (void *)CB_CmdWinClear, NULL);
629 w[6] = MakeButton("Classic Cmd Line", (void *)CB_CmdLine, NULL);
630 w[7] = MakeButton("Quit", (void *)CB_Cmd, "quit");
631
632 SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
633 SetWidgetPos(w[2], PLACE_UNDER, w[0], PLACE_RIGHT, w[1]);
634 SetWidgetPos(w[3], PLACE_UNDER, w[1], NO_CARE, NULL);
635 SetWidgetPos(w[4], PLACE_UNDER, w[3], NO_CARE, NULL);
636 SetWidgetPos(w[5], PLACE_UNDER, w[3], PLACE_RIGHT, w[4]);
637 SetWidgetPos(w[6], PLACE_UNDER, w[3], PLACE_RIGHT, w[5]);
638 SetWidgetPos(w[7], PLACE_UNDER, w[3], PLACE_RIGHT, w[6]);
639
640 ShowDisplay();
641
642 SetFgColor(w[0],BLUE);
643 SetFgColor(w[1],YELLOW);
644 SetBgColor(w[1],RED);
645 SetFgColor(w[4],BLUE);
646 SetFgColor(w[5],BLUE);
647 SetFgColor(w[6],BLUE);
648 SetFgColor(w[7],BLUE);
649
650 CmdWinON = 1;
651
652 }
653
654
Add_CmdList(char * cmd)655 void Add_CmdList( char *cmd )
656 {
657 int i;
658 char *tmp;
659 tmp = CmdWinList[NCMD-1];
660 for(i=NCMD-1;i>0;i--) CmdWinList[i] = CmdWinList[i-1];
661 CmdWinList[0] = tmp;
662 strncpy(CmdWinList[0],cmd,LCMD);
663 ChangeScrollList(CmdList_window, CmdWinList);
664 }
665
CB_CmdWinList(Widget w,char * str,int index,void * data)666 void CB_CmdWinList(Widget w, char *str, int index, void *data)
667 {
668 static time_t cur_click, last_click=0, tloc=0;
669 float tdiff;
670 char cmd[1024];
671
672
673 cur_click = time(&tloc);
674 tdiff = (float)(cur_click - last_click);
675 strncpy(cmd,str,1024);
676 if(tdiff > 1. ) /* not a double click */
677 {
678 last_click = cur_click;
679 SetStringEntry(CmdExpr_window, cmd );
680 }
681 else {
682 CB_Cmd(w,cmd);
683 Add_CmdList(cmd);
684 SetStringEntry(CmdExpr_window, " " );
685 last_click = 0;
686 }
687
688 }
689
CB_CmdWinStr(Widget w,char * str,int index,void * data)690 void CB_CmdWinStr(Widget w, char *str, int index, void *data)
691 {
692 char cmd[1024];
693 strncpy(cmd,str,1024);
694 CB_Cmd(w,cmd);
695 Add_CmdList(cmd);
696 SetStringEntry(CmdExpr_window, " " );
697 }
698
CB_CmdWinClear(Widget w,void * data)699 void CB_CmdWinClear(Widget w, void *data)
700 {
701 char cmd[1024] = "clear";
702 Add_CmdList(cmd);
703 CB_Cmd(w,cmd);
704 SetStringEntry(CmdExpr_window, " " );
705 }
706
CB_CmdWinOK(Widget w,void * data)707 void CB_CmdWinOK(Widget w, void *data)
708 {
709 int index=1;
710 char *str;
711 str = GetStringEntry(CmdExpr_window);
712 if(str==NULL) {
713 Beep();
714 return;
715 }
716 CB_CmdWinStr(w, str, index, data);
717 if(str!=NULL) free(str);
718 }
719
CB_CmdWinDone(Widget w,void * data)720 void CB_CmdWinDone(Widget w, void *data)
721 {
722 SetCurrentWindow(Cmd_window);
723 CloseWindow();
724 printf("Command Window closed\n");
725 CmdWinON = 0;
726 Free_List(CmdWinList,NCMD+1);
727 return;
728 }
729
730
731 /*-----------------------------------------------------------------------*/
732
733 /*
734 * CB_Display() - Callback function for displaying the default variable.
735 *
736 */
737
CB_Display(Widget w,void * data)738 void CB_Display(Widget w, void *data)
739 {
740
741 struct gacmn *pcm;
742 struct gafile *pfi;
743 int rc, t, tbeg, tend, tlast;
744 int v1, v2;
745 char cmd[256];
746
747 /* Any file open? */
748 pcm = &gcmn;
749 if (pcm->pfi1==NULL) {
750 Beep();
751 printf("No Files Open\n");
752 return;
753 }
754 pfi = pcm->pfid;
755
756 /* Default variable? */
757 if(!default_var[0]) {
758 Beep();
759 printf("No default variable\n");
760 return;
761 }
762
763
764 /* Just Display current variable */
765 if ( strstr(data,"display") || strstr(data,"DISPLAY") ) {
766 if(!hold_on) CB_Cmd(w,"clear");
767 sprintf(cmd,"display %s", default_var );
768 CB_Cmd(w,cmd);
769 return;
770 }
771
772
773 /* Advance time or animate... */
774
775 v1 = (int) t2gr(pfi->abvals[3],&(pcm->tmin));
776 v2 = (int) t2gr(pfi->abvals[3],&(pcm->tmax));
777 tlast = pfi->dnum[3];
778
779 /* If dimenions are not varying ... */
780 if ( v1 == v2 ) {
781
782 if ( strstr(data,"<<") ) {
783 v1--;
784 tbeg = v1;
785 tend = tbeg;
786 }
787 else if ( strstr(data,">>") ) {
788 v1++;
789 tbeg = v1;
790 tend = tbeg;
791 }
792 else if ( strstr(data,"PLAY") ) {
793 tbeg = v1;
794 tend = tlast;
795 }
796
797 /* time dim is varying, keep it */
798 } else {
799 tbeg = v1;
800 tend = v2;
801 }
802
803 /* make sure all is within range */
804 if(tbeg<1) tbeg = 1;
805 if(tbeg>tlast) tbeg = tlast;
806 if(tend<1) tend = 1;
807 if(tend>tlast) tend = tlast;
808
809 /* Set time range and display variable */
810 sprintf(cmd,"set t %d %d", tbeg, tend);
811 CB_Cmd(w,cmd);
812 if(!hold_on) CB_Cmd(w,"clear");
813
814 /* Display the variable: one frame or (continuous) animation */
815 sprintf(cmd,"display %s", default_var );
816 CB_Cmd(w,cmd);
817
818 /* If we setup a time range for PLAY, restore time to what it
819 was before the animation. */
820 if(v1==v2&&strstr(data,"PLAY")) {
821 sprintf(cmd,"set t %d %d", v1, v1);
822 CB_Cmd(w,cmd);
823 }
824
825 }
826
827
828 /*
829 * CB_Toggle() - Callback funtion for a generic toggle button.
830 */
CB_Toggle(Widget w,void * data)831 void CB_Toggle(Widget w, void *data)
832 {
833
834 if ( strstr(data,"hold") ) {
835 hold_on = 1 - hold_on;
836 if(hold_on) printf("Hold ON: no clear screen before display\n");
837 else printf("Hold OFF: clear screen before display\n");
838 }
839 }
840
841
842 /*
843 * CB_FileSel() - Callback for selecting an already open file.
844 *
845 */
CB_FileSel(Widget W,void * data)846 void CB_FileSel(Widget W, void *data)
847 {
848 Widget w[8];
849 struct gacmn *pcm;
850 struct gafile *pfi;
851 int j;
852 char **item_list;
853
854 /* Make File List from GrADS data structures */
855 pcm = &gcmn;
856 if (pcm->pfi1==NULL) {
857 Beep();
858 printf("No Files Open\n");
859 return;
860 } else {
861 pfi = pcm->pfi1;
862 item_list = (char **) List(MAXROWS,MAXCOLS);
863 j = 0;
864 while (pfi!=NULL && j<MAXROWS-1) {
865 sprintf(item_list[j],"%12s %s", pfi->name, pfi->title);
866 pfi = pfi->pforw;
867 j++;
868 }
869 item_list[j] = (char *) NULL;
870 }
871
872 /* Creates widgets, etc... */
873 file_window = MakeWindow("Select a File", SAME_DISPLAY, EXCLUSIVE_WINDOW);
874
875 w[0] = MakeLabel("Files Open:");
876 w[2] = MakeScrollList(item_list, 500, 250, (void *)CB_FileList, item_list);
877 w[6] = MakeLabel("Click on a File");
878
879 SetWidgetPos(w[2], PLACE_UNDER, w[0], NO_CARE, NULL);
880 SetWidgetPos(w[6], PLACE_UNDER, w[2], NO_CARE, NULL);
881
882 ShowDisplay();
883 SetFgColor(w[0],BLUE);
884 SetFgColor(w[6],RED);
885
886 MainLoop();
887
888 SetCurrentWindow(ORIGINAL_WINDOW);
889
890 Free_List(item_list,MAXROWS);
891
892 }
893
894
895 /*
896 * CB_FileList() - Callback routine for file list.
897 */
898
899
CB_FileList(Widget w,char * str,int index,void * data)900 void CB_FileList(Widget w, char *str, int index, void *data)
901 {
902 char cmd[1024];
903 SetCurrentWindow(file_window);
904 CloseWindow();
905 sprintf(cmd,"set dfile %d", index+1);
906 CB_Cmd(w,cmd); /* set file as default */
907 }
908
909
910 /*
911 * CB_CmdStr() - Callback funtion for a generic grads command with user input.
912 */
CB_CmdStr(Widget w,void * data)913 void CB_CmdStr(Widget w, void *data)
914 {
915 char cmd[1024], *str;
916
917 str = GetString(data, NULL);
918 if(str!=NULL) {
919 sprintf(cmd,"%s %s", data, str);
920 CB_Cmd(w,cmd);
921 free(str);
922 }
923
924 }
925
926 /*
927 * CB_Exit() - Exits GUI, well... fake it.
928 * NOTE: not working properly yet.
929 */
930
CB_Exit(Widget w,void * data)931 void CB_Exit(Widget w, void *data)
932 {
933
934 /* if(GetYesNo("About to exit Graphical User Interface. Really?") == FALSE)
935 return;
936 */
937
938 /* Get rid of GUI window */
939 CloseWindow();
940 SetCurrentWindow(ORIGINAL_WINDOW);
941
942 }
943
944 /*
945 * CB_CloseWindow - what it says.
946 */
947
CB_CloseWindow(Widget w,void * data)948 void CB_CloseWindow(Widget w, void *data)
949 {
950 CloseWindow();
951 return;
952
953 }
954
955
956 /*----------------------- Text Viewer/Edit Widget --------------------*/
957
958 /* The code below is based on xmore.c by Dominic Giampolo */
959
Editor_Quit(Widget foo,void * arg)960 void Editor_Quit(Widget foo, void *arg)
961 {
962 WinInfo *wi=(WinInfo *)arg;
963
964 *(wi->num_windows) = *(wi->num_windows) - 1;
965
966 SetCurrentWindow(XtParent(XtParent(foo)));
967 CloseWindow();
968
969 /* if (*(wi->num_windows) == 0) exit(0); */
970
971 }
972
973
974 /*
975 * Open a new file in the same window.
976 */
Editor_File(Widget foo,void * arg)977 void Editor_File(Widget foo, void *arg)
978 {
979 WinInfo *wi=(WinInfo *)arg;
980 char *fname;
981
982 fname = GetFile(wi->cur_path);
983 if (fname)
984 {
985 SetTextWidgetText(wi->text_widget, fname, TRUE);
986 SetLabel(wi->label_widget, fname);
987
988 if (wi->cur_path)
989 free(wi->cur_path);
990
991 wi->cur_path = dirname(fname);
992 }
993 }
994
995
996
997 #define MAXLABEL 80
998
make_text_viewer(char * fname,WinInfo * arg)999 void make_text_viewer(char *fname, WinInfo *arg)
1000 {
1001 Widget w[10];
1002 static char dummy_label[MAXLABEL];
1003 int i, width;
1004 XFont xf;
1005
1006 for(i=0; i < MAXLABEL-1; i++)
1007 dummy_label[i] = ' ';
1008 dummy_label[i] = '\0';
1009
1010 w[0] = MakeLabel(dummy_label);
1011
1012 /* xf = GetWidgetFont(w[0]);
1013 if (xf != NULL)
1014 width = TextWidth(xf, dummy_label);
1015 else */
1016 width = 600;
1017
1018 w[1] = MakeTextWidget(fname, TRUE, FALSE, width, 400);
1019 w[2] = MakeButton("Open", Editor_File, arg);
1020 w[3] = MakeButton("Quit", Editor_Quit, arg);
1021
1022 SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
1023 SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL);
1024 SetWidgetPos(w[3], PLACE_UNDER, w[1], PLACE_RIGHT, w[2]);
1025
1026 AttachEdge(w[0], RIGHT_EDGE, ATTACH_LEFT);
1027 AttachEdge(w[0], BOTTOM_EDGE, ATTACH_TOP);
1028
1029 AttachEdge(w[1], LEFT_EDGE, ATTACH_LEFT);
1030 AttachEdge(w[1], RIGHT_EDGE, ATTACH_RIGHT);
1031 AttachEdge(w[1], TOP_EDGE, ATTACH_TOP);
1032 AttachEdge(w[1], BOTTOM_EDGE, ATTACH_BOTTOM);
1033
1034 AttachEdge(w[2], LEFT_EDGE, ATTACH_LEFT);
1035 AttachEdge(w[2], RIGHT_EDGE, ATTACH_LEFT);
1036 AttachEdge(w[2], TOP_EDGE, ATTACH_BOTTOM);
1037 AttachEdge(w[2], BOTTOM_EDGE, ATTACH_BOTTOM);
1038
1039 AttachEdge(w[3], LEFT_EDGE, ATTACH_LEFT);
1040 AttachEdge(w[3], RIGHT_EDGE, ATTACH_LEFT);
1041 AttachEdge(w[3], TOP_EDGE, ATTACH_BOTTOM);
1042 AttachEdge(w[3], BOTTOM_EDGE, ATTACH_BOTTOM);
1043
1044 arg->text_widget = w[1];
1045 arg->label_widget = w[0];
1046
1047 ShowDisplay();
1048
1049 SetLabel(w[0], fname); /* set the real filename */
1050 }
1051
1052
make_text_editor(char * fname,WinInfo * arg)1053 void make_text_editor(char *fname, WinInfo *arg)
1054 {
1055 Widget w[10];
1056 static char dummy_label[MAXLABEL];
1057 int i, width;
1058 XFont xf;
1059
1060 for(i=0; i < MAXLABEL-1; i++)
1061 dummy_label[i] = ' ';
1062 dummy_label[i] = '\0';
1063
1064 w[0] = MakeLabel(dummy_label);
1065
1066 /* xf = GetWidgetFont(w[0]);
1067 if (xf != NULL)
1068 width = TextWidth(xf, dummy_label);
1069 else */
1070 width = 600;
1071
1072 w[1] = MakeTextWidget(fname, TRUE, TRUE, width, 400);
1073 w[2] = MakeButton("Open", Editor_File, arg);
1074 w[3] = MakeButton("Save", NULL, arg);
1075 w[4] = MakeButton("Save as", NULL, arg);
1076 w[5] = MakeButton("Exec", NULL, arg);
1077 w[6] = MakeButton("Run", NULL, arg);
1078 w[7] = MakeButton("GUI", NULL, arg);
1079 w[8] = MakeButton("Quit", Editor_Quit, arg);
1080
1081 SetWidgetPos(w[1], PLACE_UNDER, w[0], NO_CARE, NULL);
1082 SetWidgetPos(w[2], PLACE_UNDER, w[1], NO_CARE, NULL);
1083 SetWidgetPos(w[3], PLACE_UNDER, w[1], PLACE_RIGHT, w[2]);
1084 SetWidgetPos(w[4], PLACE_UNDER, w[1], PLACE_RIGHT, w[3]);
1085 SetWidgetPos(w[5], PLACE_UNDER, w[1], PLACE_RIGHT, w[4]);
1086 SetWidgetPos(w[6], PLACE_UNDER, w[1], PLACE_RIGHT, w[5]);
1087 SetWidgetPos(w[7], PLACE_UNDER, w[1], PLACE_RIGHT, w[6]);
1088 SetWidgetPos(w[8], PLACE_UNDER, w[1], PLACE_RIGHT, w[7]);
1089
1090 AttachEdge(w[0], RIGHT_EDGE, ATTACH_LEFT);
1091 AttachEdge(w[0], BOTTOM_EDGE, ATTACH_TOP);
1092
1093 AttachEdge(w[1], LEFT_EDGE, ATTACH_LEFT);
1094 AttachEdge(w[1], RIGHT_EDGE, ATTACH_RIGHT);
1095 AttachEdge(w[1], TOP_EDGE, ATTACH_TOP);
1096 AttachEdge(w[1], BOTTOM_EDGE, ATTACH_BOTTOM);
1097
1098 for(i=2;i<=8;i++) {
1099 AttachEdge(w[i], LEFT_EDGE, ATTACH_LEFT);
1100 AttachEdge(w[i], RIGHT_EDGE, ATTACH_LEFT);
1101 AttachEdge(w[i], TOP_EDGE, ATTACH_BOTTOM);
1102 AttachEdge(w[i], BOTTOM_EDGE, ATTACH_BOTTOM);
1103 }
1104
1105 arg->text_widget = w[1];
1106 arg->label_widget = w[0];
1107
1108 ShowDisplay();
1109
1110 SetLabel(w[0], fname); /* set the real filename */
1111 }
1112
1113
1114 /*
1115 * CB_Browse() - Text viewer callback. Ideal for help files.
1116 *
1117 */
1118
CB_Browse(Widget w,void * data)1119 void CB_Browse(Widget w, void *data)
1120 {
1121
1122 char *fname;
1123 int num_windows=1;
1124 Widget this;
1125 WinInfo *wi;
1126
1127
1128 fname = (char *) data;
1129 if ( !strcmp(fname,"NULL") ) fname = GetFile(NULL);
1130 if ( !fname ) return;
1131
1132 this = MakeWindow("GrADS Text Viewer", SAME_DISPLAY, NONEXCLUSIVE_WINDOW);
1133 if ( w == NULL ) return;
1134
1135 wi = (WinInfo *)calloc(sizeof(WinInfo), 1);
1136 if (wi == NULL) return;
1137
1138 wi->num_windows = &num_windows;
1139 wi->cur_path = dirname(fname);
1140
1141 make_text_viewer(fname, wi);
1142
1143 }
1144
CB_Edit(Widget w,void * data)1145 void CB_Edit(Widget w, void *data)
1146 {
1147
1148 char *fname;
1149 int num_windows=1;
1150 Widget this;
1151 WinInfo *wi;
1152
1153 fname = (char *)data;
1154 if ( !strcmp(fname,"NULL") ) fname = GetFile(NULL);
1155 if ( !fname ) return;
1156
1157 this = MakeWindow("GrADS Text Editor", SAME_DISPLAY, NONEXCLUSIVE_WINDOW);
1158 if ( w == NULL ) return;
1159
1160 wi = (WinInfo *)calloc(sizeof(WinInfo), 1);
1161 if (wi == NULL) return;
1162
1163 wi->num_windows = &num_windows;
1164 wi->cur_path = dirname(fname);
1165
1166 make_text_editor(fname, wi);
1167
1168 }
1169
1170
1171