1 /*! File to contain functions for creating interface
2 for mapping data to color maps. Lots of functions from
3 xim.c display.c and pbar.c*/
4 
5 #include "SUMA_suma.h"
6 #include "SUMA_plot.h"
7 
8 /*!
9    \brief Reads a ppm image and turns i into an rgba vector for ease of
10    use with OpenGL.
11    Depends heavily on afni's mri_read_ppm
12 */
SUMA_read_ppm(char * fname,int * width,int * height,int verb)13 unsigned char *SUMA_read_ppm(char *fname, int *width, int *height, int verb)
14 {
15    static char FuncName[]={"SUMA_read_ppm"};
16    char stmp[500];
17    unsigned char *imar = NULL;
18    byte * rgb , *cp=NULL;
19    float alf = 0;
20    MRI_IMAGE * im=NULL;
21    int ir, ic, i1d, i1df, imx, i1d3, i1d4;
22    SUMA_Boolean LocalHead = NOPE;
23 
24    SUMA_ENTRY;
25 
26    if (!fname) { if (verb) SUMA_SL_Err("NULL fname");  SUMA_RETURN(imar); }
27    im = mri_read_ppm( fname ) ;
28    if (!im) {
29       if (verb) {
30          SUMA_SL_Err("Failed to read %s", fname); }
31       SUMA_RETURN(imar);
32    }
33 
34    rgb = MRI_RGB_PTR(im) ;
35    *height = im->ny ;
36    *width = im->nx ;
37    imx = im->ny * im->nx;
38 
39    if (LocalHead)
40       fprintf (SUMA_STDERR,"%s:\nNx (width) = %d, Ny (height) = %d\n",
41                   FuncName, im->nx, im->ny);
42 
43    imar = (unsigned char *)
44             SUMA_malloc(sizeof(unsigned char) * im->nx * im->ny * 4);
45    if (!imar) {
46       SUMA_SL_Crit("Failed to allocate.");
47       mri_free(im) ;
48       SUMA_RETURN(imar);
49    }
50 
51    for (ir = 0; ir < im->ny; ++ir) {
52       for (ic = 0; ic < im->nx; ++ic) {
53          i1d = ic + ir * im->nx; /* equiv. 1d index into row major image data */
54          i1df = ic + (im->ny - ir - 1) * im->nx; /* column flipped index */
55          i1d4 = 4 * i1d; i1d3 = 3*i1df;
56          imar[i1d4] = (unsigned char)rgb[i1d3];
57             alf  = (float)imar[i1d4];   ++i1d3; ++i1d4;
58          imar[i1d4] = (unsigned char)rgb[i1d3];
59             alf += (float)imar[i1d4];   ++i1d3; ++i1d4;
60          imar[i1d4] = (unsigned char)rgb[i1d3];
61             alf += (float)imar[i1d4];            ++i1d4;
62          imar[i1d4] = (unsigned char)(alf/3.0);
63       }
64    }
65 
66    mri_free(im) ; im = NULL;
67 
68    SUMA_RETURN(imar);
69 }
70 
SUMA_cmap_wid_graphicsInit(Widget w,XtPointer clientData,XtPointer call)71 void SUMA_cmap_wid_graphicsInit (Widget w, XtPointer clientData, XtPointer call)
72 {
73    static char FuncName[]={"SUMA_cmap_wid_graphicsInit"};
74    XVisualInfo *SUMAg_cVISINFO=NULL;
75    SUMA_ALL_DO *ado=NULL;
76    SUMA_X_SurfCont *SurfCont=NULL;
77    SUMA_Boolean LocalHead = NOPE;
78 
79    SUMA_ENTRY;
80 
81    SUMA_LH("called");
82 
83    ado = (SUMA_ALL_DO *)clientData;
84    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
85    if (!(SurfCont=SUMA_ADO_Cont(ado))) {
86       SUMA_S_Err("NULL Cont!!!"); SUMA_RETURNe;
87    }
88 
89    XtVaGetValues(w, GLwNvisualInfo, &SUMAg_cVISINFO, NULL);
90    SurfCont->cmp_ren->cmap_context =
91       glXCreateContext( XtDisplay(w), SUMAg_cVISINFO,
92                         0,                  /* No sharing. */
93                         True);              /* Direct rendering if possible. */
94 
95    /* Setup OpenGL state. */
96    if (!SUMA_glXMakeCurrent( XtDisplay(w), XtWindow(w),
97                         SurfCont->cmp_ren->cmap_context,
98                         FuncName, "some cmap init", 1)) {
99       fprintf (SUMA_STDERR,
100                "Error %s: Failed in SUMA_glXMakeCurrent.\n \tContinuing ...\n",
101                FuncName);
102       SUMA_GL_ERRS;
103       SUMA_RETURNe;
104    }
105 
106    /* call context_Init to setup colors and lighting */
107    SUMA_cmap_context_Init(ado);
108 
109    SUMA_RETURNe;
110 }
111 
112 /*!
113    Originally intended to setup for an Ortho2D mode for an image display
114    But we don't like 2D. So this ends up being very much like
115    SUMA_context_Init, lookt here for reference if need be.
116 */
SUMA_cmap_context_Init(SUMA_ALL_DO * ado)117 void SUMA_cmap_context_Init(SUMA_ALL_DO *ado)
118 {
119    static char FuncName[]={"SUMA_cmap_context_Init"};
120    GLfloat mat_specular[] = { 0.0, 0.0, 0.0, 1.0};
121    GLfloat mat_shininess[] = { 0 };
122    GLfloat mat_ambient[] = { 0.0, 0.0, 0.0, 1.0};
123    GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
124    GLfloat mat_emission[] = { SUMA_MAT_EMISSION_INIT  };
125    GLfloat clear_color[] = { 0.0, 0.0, 0.0, 0.0};
126    GLfloat light0_color[] = { 1.0, 1.0, 1.0, 1.0};
127    GLfloat lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
128    GLfloat light0_position[] = {0.0, 0.0, -1.0, 0.0};
129    GLfloat ViewFrom[]={0.0, 0.0, 300};
130    GLfloat ViewCenter[]={0.0, 0.0, 0.0};
131    GLfloat ViewCamUp[]={0.0, 1.0, 0.0};
132    GLfloat CmapOrig[]={SUMA_CMAP_ORIGIN};
133    GLfloat CmapTL[]={SUMA_CMAP_TOPLEFT};
134    int i;
135 
136    SUMA_ENTRY;
137 
138    glClearColor (clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
139    glShadeModel (GL_SMOOTH);
140 
141    SUMA_SET_GL_RENDER_MODE(SRM_Fill);
142 
143 
144    /* Set the material properties*/
145    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
146    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
147    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
148    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
149    glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
150 
151    /* set the directional light properties */
152    glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
153    glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_color);
154    glLightfv(GL_LIGHT0, GL_SPECULAR, light0_color);
155 
156    /* set the ambient light */
157    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
158 
159    glEnable(GL_LIGHTING); /* prepare GL to perform lighting calculations */
160    glEnable(GL_LIGHT0); /*Turn lights ON */
161    glEnable(GL_DEPTH_TEST);
162 
163    /*setup the view point and then setup the lights.
164    Those lights will remain in place regardless of the rotations/translations
165    done on the surface */
166    for (i=0; i<2; ++i) { ViewCenter[i] = (CmapTL[i] - CmapOrig[i]) / 2.0;  }
167    ViewFrom[0] = ViewCenter[0];
168    ViewFrom[1] = ViewCenter[1]; ViewFrom[2] =
169    SUMA_CMAP_VIEW_FROM;
170 
171    glMatrixMode(GL_MODELVIEW);
172    glLoadIdentity();
173    gluLookAt ( ViewFrom[0], ViewFrom[1], ViewFrom[2],
174                ViewCenter[0], ViewCenter[1], ViewCenter[2],
175                ViewCamUp[0], ViewCamUp[1], ViewCamUp[2] );
176 
177 
178    SUMA_RETURNe;
179 
180 }
181 
SUMA_DrawCmap(SUMA_COLOR_MAP * Cmap)182 void SUMA_DrawCmap(SUMA_COLOR_MAP *Cmap)
183 {
184    static char FuncName[]={"SUMA_DrawCmap"};
185    float orig[3]={ SUMA_CMAP_ORIGIN };
186    float topright[3] = { SUMA_CMAP_TOPLEFT };
187    int i;
188    SUMA_Boolean LocalHead = NOPE;
189 
190    SUMA_ENTRY;
191 
192    SUMA_LH("called");
193 
194    if (!Cmap->SO) {
195       SUMA_LH("Creating Cmap's SO");
196       Cmap->SO = SUMA_Cmap_To_SO(Cmap, orig, topright, 0);
197       if (!Cmap->SO) { SUMA_SL_Err("Failed to create SO"); }
198    }
199 
200    /* initialize the context to be safe;
201    sometimes there is conflict with the viewer's context
202    and that causes the colormaps to be absent...   ZSS Nov. 28 06
203    But that is too radical and kills translation toys ZSS Mar. 06 08*/
204    /* Turned off, may no longer cause trouble...  ZSS Mar. 07 08*/
205    /* SUMA_cmap_context_Init((SUMA_ALL_DO*)Cmap->SO); */
206 
207    /* This allows each node to follow the color specified when it was drawn */
208    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
209    glEnable(GL_COLOR_MATERIAL);
210 
211    /*Now setup various pointers*/
212    glEnableClientState (GL_COLOR_ARRAY);
213    glEnableClientState (GL_VERTEX_ARRAY);
214    glEnableClientState (GL_NORMAL_ARRAY);
215    glColorPointer (4, GL_FLOAT, 0, Cmap->SO->PermCol);
216    glVertexPointer (3, GL_FLOAT, 0, Cmap->SO->glar_NodeList);
217    glNormalPointer (GL_FLOAT, 0, Cmap->SO->glar_NodeNormList);
218 
219    SUMA_SET_GL_RENDER_MODE(SRM_Fill);
220    glDrawElements (GL_TRIANGLES, (GLsizei)Cmap->SO->N_FaceSet*3,
221                    GL_UNSIGNED_INT, Cmap->SO->glar_FaceSetList);
222 
223    /* Here you could draw a contour around the color cells.
224    But you'll need to raise the contour over the filled polygons
225    because they'll get
226    covered otherwise */
227    #if 0
228    {
229       GLfloat *LineCol=NULL;
230       LineCol = (GLfloat *)SUMA_calloc(Cmap->SO->N_Node*4, sizeof(GLfloat));
231       for (i=0; i<Cmap->SO->N_Node; ++i) {
232          LineCol[4*i] = LineCol[4*i+1] = LineCol[4*i+2] = 0.1;
233          LineCol[4*i+3] = 1.0; }
234       glColorPointer (4, GL_FLOAT, 0, LineCol);
235       SUMA_SET_GL_RENDER_MODE(SRM_Line);
236       glDrawElements (  GL_TRIANGLES, (GLsizei)Cmap->SO->N_FaceSet*3,
237                         GL_UNSIGNED_INT, Cmap->SO->glar_FaceSetList);
238       SUMA_free(LineCol); LineCol = NULL;
239    }
240    #endif
241 
242    SUMA_RETURNe;
243 }
244 
SUMA_cmap_wid_display(SUMA_ALL_DO * ado)245 void SUMA_cmap_wid_display(SUMA_ALL_DO *ado)
246 {
247    static char FuncName[]={"SUMA_cmap_wid_display"};
248    int i;
249    GLfloat rotationMatrix[4][4];
250    float currentQuat[]={0.0, 0.0, 0.0, 1.0};
251    GLfloat clear_color[] = { 0.8, 0.8, 0.8, 0.0};
252    GLfloat RotaCenter[]={0.0, 0.0, 0.0};
253    SUMA_COLOR_MAP *Cmap = NULL;
254    SUMA_X_SurfCont *SurfCont=NULL;
255    SUMA_OVERLAYS *curColPlane=NULL;
256    SUMA_Boolean LocalHead = NOPE; /* local headline debugging messages */
257 
258    SUMA_ENTRY;
259 
260    SUMA_LH("in, lots of inefficiencies here, make sure you revisit");
261 
262    SurfCont = SUMA_ADO_Cont(ado);
263    curColPlane = SUMA_ADO_CurColPlane(ado);
264 
265    /* is surface controller closed? */
266    if (!SurfCont->Open) {
267       SUMA_LHv("SurfCont closed for %s, trying to open it\n",
268                SUMA_ADO_Label(ado));
269       if (!SUMA_viewSurfaceCont(NULL, ado, SUMA_BestViewerForADO(ado))) {
270          SUMA_S_Warn("No SurfCont");
271          SUMA_DUMP_TRACE("No SurfCont");
272          SUMA_RETURNe;
273       }
274    }
275    /* now you need to set the clear_color since it can be
276       changed per viewer Thu Dec 12 2002 */
277    glClearColor (clear_color[0], clear_color[1],clear_color[2],clear_color[3]);
278 
279    if (LocalHead)
280       fprintf (SUMA_STDOUT,"%s: Building Rotation matrix ...\n", FuncName);
281    SUMA_build_rotmatrix(rotationMatrix, currentQuat);
282 
283    if (LocalHead)
284       fprintf (SUMA_STDOUT,"%s: performing glClear ...\n", FuncName);
285    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* clear the Color Buffer                                                          and the depth buffer */
286 
287    /* careful here, you might want to turn
288       the next block into a macro like SUMA_SET_GL_PROJECTION */
289    if (LocalHead)
290       fprintf (SUMA_STDOUT,
291                "%s: Setting up matrix mode and perspective ...\nFOV=%f\n"
292                "Translation is %f %f %f\n",
293                FuncName, SUMA_CMAP_FOV_INITIAL,
294                SurfCont->cmp_ren->translateVec[0],
295                SurfCont->cmp_ren->translateVec[1],
296                SurfCont->cmp_ren->translateVec[2] );
297    glMatrixMode (GL_PROJECTION);
298    glLoadIdentity ();
299    gluPerspective(SurfCont->cmp_ren->FOV,
300                   (double)SUMA_CMAP_WIDTH/SUMA_CMAP_HEIGHT,
301                   SUMA_PERSPECTIVE_NEAR, SUMA_PERSPECTIVE_FAR);
302                   /*lower angle is larger zoom,*/
303 
304    glMatrixMode(GL_MODELVIEW);
305    glPushMatrix();
306    glTranslatef ( SurfCont->cmp_ren->translateVec[0],
307                   SurfCont->cmp_ren->translateVec[1],
308                   SurfCont->cmp_ren->translateVec[2] );
309    if (0){
310    SUMA_SL_Note("no need for shananigans\n"
311                   "But to illustrate ...\n");
312    glTranslatef (RotaCenter[0], RotaCenter[1], RotaCenter[2]);
313    glMultMatrixf(&rotationMatrix[0][0]);
314    glTranslatef (-RotaCenter[0], -RotaCenter[1], -RotaCenter[2]);
315    }
316 
317 
318    /* find out what colormap is to be displayed */
319    if (curColPlane) {
320       /* what's the Cmap for that plane ? */
321       Cmap = SUMA_CmapOfPlane (curColPlane );
322       if (Cmap) SUMA_DrawCmap(Cmap); /* create the colormap */
323    } else {
324       SUMA_SL_Err("NULL curColPlane");
325    }
326    glPopMatrix();
327 
328    if (LocalHead)
329       fprintf (SUMA_STDERR,
330                "%s: Flushing or swapping ...\n"
331                "cmp_ren %p, cmap_wid %p\n",
332                FuncName,
333                SurfCont ? SurfCont->cmp_ren : NULL,
334                (SurfCont && SurfCont->cmp_ren ) ?
335                   SurfCont->cmp_ren->cmap_wid : NULL );
336 
337    if (SUMAg_SVv[0].X->DOUBLEBUFFER)
338       glXSwapBuffers(XtDisplay(SurfCont->cmp_ren->cmap_wid),
339                      XtWindow(SurfCont->cmp_ren->cmap_wid));
340    else
341       glFlush();
342 
343    /* Avoid indirect rendering latency from queuing. */
344 
345    if (!glXIsDirect( XtDisplay(SurfCont->cmp_ren->cmap_wid),
346                      SurfCont->cmp_ren->cmap_context)) {
347       SUMA_LH("GLfinish time");
348       glFinish();
349    } else {
350       SUMA_LH("No finish call");
351    }
352 
353    SUMA_RETURNe;
354 }
355 
SUMA_cmap_wid_handleRedisplay(XtPointer clientData)356 Boolean SUMA_cmap_wid_handleRedisplay(XtPointer clientData)
357 {
358    static char FuncName[]={"SUMA_cmap_wid_handleRedisplay"};
359    SUMA_ALL_DO *ado=NULL;
360    SUMA_X_SurfCont *SurfCont=NULL;
361    SUMA_Boolean LocalHead = NOPE;
362 
363    SUMA_ENTRY;
364 
365    SUMA_LH("Called");
366 
367    ado = (SUMA_ALL_DO *)clientData;
368    if (!ado) { SUMA_SL_Err("NULL DO"); SUMA_RETURN(NOPE); }
369 
370    SurfCont = SUMA_ADO_Cont(ado);
371    SUMA_LHv("Called with ado %s, SurfCont->Open: %d\n",
372             SUMA_ADO_Label(ado), SurfCont->Open);
373    if (SurfCont->Open) { /* Otherwise it causes a crash on linux
374                                  when yoking L/R stuff */
375       SUMA_LHv("Making cmap_wid current %p %p\n",
376                SurfCont->cmp_ren->cmap_wid,
377                SurfCont->cmp_ren->cmap_context);
378       if (!SUMA_glXMakeCurrent( XtDisplay(SurfCont->cmp_ren->cmap_wid),
379                            XtWindow(SurfCont->cmp_ren->cmap_wid),
380             SurfCont->cmp_ren->cmap_context, FuncName, "some cmap resize", 1)) {
381          SUMA_S_Err("Failed in SUMA_glXMakeCurrent.\n \tContinuing ...");
382       }
383       SUMA_LH("Calling wid display");
384       SUMA_cmap_wid_display(ado);
385       glFinish();
386 
387       /* insist on a glXMakeCurrent for surface viewer */
388       SUMA_LH("Making sv's GLXAREA current\n");
389       SUMA_SiSi_I_Insist();
390    }
391 
392    SUMA_RETURN(YUP);
393 }
394 
SUMA_cmap_wid_postRedisplay(Widget w,XtPointer clientData,XtPointer call)395 void SUMA_cmap_wid_postRedisplay(Widget w, XtPointer clientData, XtPointer call)
396 {
397    static char FuncName[]={"SUMA_cmap_wid_postRedisplay"};
398    static XtPointer elvis;
399    int isv;
400    SUMA_ALL_DO *ado=NULL;
401    SUMA_Boolean LocalHead = NOPE;
402 
403    SUMA_ENTRY;
404 
405    SUMA_LH("cold");
406 
407    ado = (SUMA_ALL_DO *)clientData;
408    if (!ado) { SUMA_SL_Err("NULL DO"); SUMA_RETURNe; }
409 
410    SUMA_register_workproc(SUMA_cmap_wid_handleRedisplay , (XtPointer)ado );
411 
412    SUMA_RETURNe;
413 }
414 
SUMA_cmap_wid_expose(Widget w,XtPointer clientData,XtPointer call)415 void SUMA_cmap_wid_expose(Widget w, XtPointer clientData, XtPointer call)
416 {
417    static char FuncName[]={"SUMA_cmap_wid_expose"};
418    SUMA_ALL_DO *ado=NULL;
419    SUMA_Boolean LocalHead = NOPE;
420 
421    SUMA_ENTRY;
422 
423    SUMA_LH("called");
424    ado = (SUMA_ALL_DO *)clientData;
425    if (!ado) { SUMA_SL_Err("NULL DO"); SUMA_RETURNe; }
426 
427    SUMA_cmap_wid_postRedisplay(w, (XtPointer)ado, NULL);
428 
429    SUMA_RETURNe;
430 }
431 
432 /* An attempt to render colormap using X11 and Motif rather than openGL.
433 This is only for the purpose of taking an autosnapshot of the whole widget
434 Based on AFNI's PBAR_bigexpose_CB()*/
SUMA_PBAR_bigexpose_CB(Widget wiw,XtPointer clientData,XtPointer calliw)435 void SUMA_PBAR_bigexpose_CB(Widget wiw, XtPointer clientData, XtPointer calliw)
436 {
437    static char FuncName[]={"SUMA_PBAR_bigexpose_CB"};
438    SUMA_ALL_DO *ado=NULL;
439    XVisualInfo *SUMAg_cVISINFO=NULL;
440    static MCW_DC *dc = NULL;
441    static XImage *bigxim = NULL;
442    SUMA_X_SurfCont *SurfCont = NULL;
443    int  ww = SUMA_CMAP_WIDTH, hh = SUMA_CMAP_HEIGHT;
444    int ii , jj , kk;
445    MRI_IMAGE *cim, *dim;
446    byte      *car , r,g,b ;
447    static SUMA_COLOR_MAP *CMd=NULL;
448    SUMA_COLOR_MAP *CM=NULL;
449    SUMA_OVERLAYS *curColPlane=NULL;
450    SUMA_Boolean LocalHead = NOPE;
451 
452    SUMA_ENTRY;
453 
454    SUMA_LH("called");
455    ado = (SUMA_ALL_DO *)clientData;
456    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) {
457       SUMA_SL_Err("NULL DO or Cont"); SUMA_RETURNe;
458    }
459 
460    /* Get colormap of plane, if possible */
461    if ((curColPlane = SUMA_ADO_CurColPlane(ado))) {
462       CM = SUMA_CmapOfPlane (curColPlane );
463    }
464    /* get some default */
465    if (!CM) {
466       if (!(CM = SUMA_FindNamedColMap("byr64"))) {
467          SUMA_S_Err("Failed to get byr64");
468          SUMA_RETURNe;
469       }
470    }
471 
472    if (!CMd || CM != CMd) {
473       SUMA_LH("Setting CMd");
474       CMd = CM;
475       if (bigxim) {
476          SUMA_LH("Killing bigxim");
477          MCW_kill_XImage( bigxim ); bigxim = NULL;
478       }
479    }
480 
481    if (!bigxim) {
482       float fac; int mm;
483       cim = mri_new( ww, 256 , MRI_rgb ) ;
484       car = MRI_RGB_PTR(cim) ;
485       fac = (float)CM->N_M[0]/256.0;
486       for( kk=ii=0 ; ii < 256 ; ii++ ){
487          mm = CM->N_M[0]-1-(int)((float)ii*fac);
488          if (mm>=CM->N_M[0]) mm = CM->N_M[0]-1;
489          if (mm<0) mm = 0;
490          r=(byte)(CM->M[mm][0]*255.0);
491          g=(byte)(CM->M[mm][1]*255.0);
492          b=(byte)(CM->M[mm][2]*255.0);
493          if( CM->M[mm][0] >= 0 || CM->M[mm][1] >= 0 || CM->M[mm][2] >= 0 ){
494             for( jj=0 ; jj < ww ; jj++ ){
495               car[kk++] = r; car[kk++] = g; car[kk++] = b;
496             }
497          } else {
498             for( jj=0 ; jj < ww ; jj++ ){
499               car[kk++]=128; car[kk++]=128; car[kk++]=128;
500             }
501          }
502       }
503       dim = mri_resize( cim , ww,hh ) ;
504       if (!dc) {
505          dc = MCW_new_DC( SurfCont->Fake_pbar, 4,0, NULL,NULL, 1.0,0 );
506       }
507       bigxim = mri_to_XImage( dc , dim ) ;
508       mri_free(dim) ;
509    }
510 
511    /* actually show the image to the window pane */
512    if( XtIsManaged(SurfCont->Fake_pbar) )
513      XPutImage( SUMAg_CF->X->DPY_controller1 ,
514                 XtWindow(SurfCont->Fake_pbar) ,
515                 dc->origGC , bigxim , 0,0,0,0 ,
516                 ww , hh ) ;
517 
518    SUMA_RETURNe;
519 }
520 
SUMA_PBAR_biginput_CB(Widget w,XtPointer clientData,XtPointer call)521 void SUMA_PBAR_biginput_CB(Widget w, XtPointer clientData, XtPointer call)
522 {
523    static char FuncName[]={"SUMA_PBAR_biginput_CB"};
524    SUMA_ALL_DO *ado=NULL;
525    SUMA_X_SurfCont *SurfCont = NULL;
526    SUMA_Boolean LocalHead = NOPE;
527 
528    SUMA_ENTRY;
529 
530    SUMA_LH("called");
531    ado = (SUMA_ALL_DO *)clientData;
532    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) {
533       SUMA_SL_Err("NULL DO or Cont"); SUMA_RETURNe;
534    }
535    SUMA_RETURNe;
536 }
537 
SUMA_PBAR_bigresize_CB(Widget w,XtPointer clientData,XtPointer call)538 void SUMA_PBAR_bigresize_CB(Widget w, XtPointer clientData, XtPointer call)
539 {
540    static char FuncName[]={"SUMA_PBAR_bigresize_CB"};
541    SUMA_ALL_DO *ado=NULL;
542    SUMA_X_SurfCont *SurfCont = NULL;
543    SUMA_Boolean LocalHead = NOPE;
544 
545    SUMA_ENTRY;
546 
547    SUMA_LH("called");
548    ado = (SUMA_ALL_DO *)clientData;
549    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) {
550       SUMA_SL_Err("NULL DO or Cont"); SUMA_RETURNe;
551    }
552    SUMA_RETURNe;
553 }
554 
555 
SUMA_cmap_wid_resize(Widget w,XtPointer clientData,XtPointer call)556 void SUMA_cmap_wid_resize(Widget w, XtPointer clientData, XtPointer call)
557 {
558    static char FuncName[]={"SUMA_cmap_wid_resize"};
559    SUMA_ALL_DO *ado=NULL;
560    SUMA_Boolean LocalHead = NOPE;
561 
562    SUMA_ENTRY;
563 
564    SUMA_LH("called");
565    ado = (SUMA_ALL_DO *)clientData;
566    if (!ado) { SUMA_SL_Err("NULL DO"); SUMA_RETURNe; }
567 
568    SUMA_RETURNe;
569 }
570 
SUMA_cmap_wid_input(Widget w,XtPointer clientData,XtPointer callData)571 void SUMA_cmap_wid_input(Widget w, XtPointer clientData, XtPointer callData)
572 {
573    static char FuncName[]={"SUMA_cmap_wid_input"};
574    GLwDrawingAreaCallbackStruct *cd;
575    KeySym keysym;
576    XKeyEvent Kev;
577    XButtonEvent Bev;
578    XMotionEvent Mev;
579    char buffer[10], cbuf = '\0', cbuf2='\0';
580    SUMA_ALL_DO *ado=NULL;
581    int xls;
582    static Time B1time = 0;
583    static int pButton, mButton, rButton;
584    static SUMA_Boolean DoubleClick = NOPE;
585    DList *list = NULL;
586    SUMA_EngineData *ED = NULL;
587    static float height_two_col, width;
588    int ncol;
589    SUMA_COLOR_MAP *ColMap = NULL;
590    static float fov_lim = -1.0;
591    static SUMA_SurfaceObject *SOcmap=NULL;
592    SUMA_X_SurfCont *SurfCont=NULL;
593    SUMA_OVERLAYS *curColPlane=NULL;
594    SUMA_Boolean LocalHead = NOPE;
595 
596    SUMA_ENTRY;
597 
598    SUMA_LH("called");
599    ado = (SUMA_ALL_DO *)clientData;
600       /* THIS ado is for the main surface/DO, NOT THE colormap's */
601    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
602 
603    SurfCont = SUMA_ADO_Cont(ado);
604    curColPlane = SUMA_ADO_CurColPlane(ado);
605 
606    ColMap = SUMA_CmapOfPlane (curColPlane );
607    if (!ColMap) { SUMA_SL_Err("No Cmap"); SUMA_RETURNe; };
608    if (ColMap->SO != SOcmap) {
609       SUMA_LH("New colormap SO");
610       /* calculate FOV limit for zooming in */
611       SOcmap = ColMap->SO;
612       ncol = SOcmap->N_FaceSet / 2;
613       height_two_col =  (SOcmap->MaxDims[1] - SOcmap->MinDims[1]) /
614                         (float)ncol * 2.0;
615                         /* no need to show more than 2 cols */
616       width = (SOcmap->MaxDims[0] - SOcmap->MinDims[0]);
617       fov_lim = 2.0 * atan( (double)height_two_col /
618                ( 2.0 * (double)SUMA_CMAP_VIEW_FROM ) ) * 180 / SUMA_PI;
619       if (LocalHead) {
620          SUMA_Print_Surface_Object(SOcmap, NULL);
621          fprintf( SUMA_STDERR,
622                   "%s: ncol=%d, height = %f, height of 2 col =%f\n"
623                   ", width=%f, d = %d, fov_lim = %f\n",
624                   FuncName, ncol, (SOcmap->MaxDims[1] - SOcmap->MinDims[1]),
625                   height_two_col,  width, SUMA_CMAP_VIEW_FROM, fov_lim);
626       }
627    }
628 
629    /* make sure the color map is the current context */
630    if (!SUMA_glXMakeCurrent( XtDisplay(w),
631                         XtWindow(w),
632             SurfCont->cmp_ren->cmap_context, FuncName, "some cmap input", 1)) {
633       SUMA_S_Err("Failed in SUMA_glXMakeCurrent.\n ");
634       SUMA_RETURNe;
635    }
636 
637    /* get the callData pointer */
638    cd = (GLwDrawingAreaCallbackStruct *) callData;
639 
640    Kev = *(XKeyEvent *) &cd->event->xkey; /* RickR's suggestion to comply with
641                                              ANSI C, no type casting of
642                                              structures July 04*/
643    Bev = *(XButtonEvent *) &cd->event->xbutton;
644    Mev = *(XMotionEvent *) &cd->event->xmotion;
645 
646    switch (Kev.type) { /* switch event type */
647    case KeyPress:
648       xls = XLookupString((XKeyEvent *) cd->event, buffer, 8, &keysym, NULL);
649 
650       /* XK_* are found in keysymdef.h */
651       switch (keysym) { /* keysym */
652          case XK_h:
653             if (Kev.state & ControlMask){
654               if (!list) list = SUMA_CreateList();
655               ED = SUMA_InitializeEngineListData (SE_Help_Cmap);
656               SUMA_RegisterEngineListCommand ( list, ED,
657                                          SEF_vp, (void *)ColMap,
658                                          SES_SumaWidget, NULL, NOPE,
659                                          SEI_Head, NULL);
660               if (!SUMA_Engine (&list)) {
661                   fprintf(stderr,
662                            "Error %s: SUMA_Engine call failed.\n", FuncName);
663               }
664             }
665             break;
666          case XK_f:
667             {
668                if (1) {
669                   SUMA_LH("Flipping colormap");
670                   SUMA_Flip_Color_Map(
671                      SUMA_CmapOfPlane(curColPlane));
672                   SUMA_LH("Switching colormap");
673                   SUMA_SwitchCmap(ado,
674                          SUMA_CmapOfPlane(curColPlane), 0);
675                }
676             }
677             break;
678          case XK_r:
679             {
680                GLvoid *pixels;
681                SUMA_LH("Recording");
682                if (SUMAg_SVv[0].X->DOUBLEBUFFER)
683                   glXSwapBuffers(XtDisplay(SurfCont->cmp_ren->cmap_wid),
684                                  XtWindow(SurfCont->cmp_ren->cmap_wid));
685                pixels = SUMA_grabPixels(3, SUMA_CMAP_WIDTH, SUMA_CMAP_HEIGHT);
686                if (SUMAg_SVv[0].X->DOUBLEBUFFER)
687                   glXSwapBuffers(XtDisplay(SurfCont->cmp_ren->cmap_wid),
688                                  XtWindow(SurfCont->cmp_ren->cmap_wid));
689                if (pixels) {
690                  ISQ_snapsave (SUMA_CMAP_WIDTH, -SUMA_CMAP_HEIGHT,
691                               (unsigned char *)pixels,
692                               SurfCont->cmp_ren->cmap_wid );
693                  SUMA_free(pixels);
694                }else {
695                   SUMA_SLP_Err("Failed to record image.");
696                }
697             }
698             break;
699          case XK_w:
700             {
701                char *sss=NULL;
702                SUMA_COLOR_MAP * ColMap =
703                      SUMA_CmapOfPlane(curColPlane);
704                if (LocalHead) {
705                   if ((sss = SUMA_ColorMapVec_Info(&ColMap, 1, 1))) {
706                      SUMA_LHv("To be written:\n%s\n", sss);
707                      SUMA_free(sss); sss = NULL;
708                   }
709                }
710                if (!SUMA_Write_Color_Map_1D(ColMap, NULL)) {
711                   SUMA_S_Errv("Failed to write colmap %s\n",
712                            curColPlane->Name);
713                }else {
714                   SUMA_S_Notev("Wrote colormap %s to file.\n",
715                            curColPlane->Name);
716                }
717             }
718             break;
719          case XK_Z:
720             {
721                static SUMA_Boolean BeepedAlready = NOPE;
722                SurfCont->cmp_ren->FOV /= FOV_IN_FACT;
723                if (SurfCont->cmp_ren->FOV < fov_lim) {
724                   if (!BeepedAlready) {
725                      SUMA_BEEP; BeepedAlready = YUP;
726                   }
727                   SurfCont->cmp_ren->FOV = fov_lim;
728                } else BeepedAlready = NOPE;
729                if (LocalHead)
730                   fprintf(SUMA_STDERR,
731                            "%s: Zoom in FOV = %f\n",
732                            FuncName, SurfCont->cmp_ren->FOV);
733                SUMA_cmap_wid_postRedisplay(w, (XtPointer)ado, NULL);
734             }
735             break;
736 
737          case XK_z:
738             {
739                static SUMA_Boolean BeepedAlready = NOPE;
740                SurfCont->cmp_ren->FOV /= FOV_OUT_FACT;
741                if (SurfCont->cmp_ren->FOV > SUMA_CMAP_FOV_INITIAL) {
742                   if (!BeepedAlready) {
743                      SUMA_BEEP; BeepedAlready = YUP;
744                   }
745                   SurfCont->cmp_ren->FOV = SUMA_CMAP_FOV_INITIAL;
746                } else BeepedAlready = NOPE;
747                if (LocalHead)
748                   fprintf( SUMA_STDERR,
749                            "%s: Zoom out FOV = %f\n",
750                            FuncName, SurfCont->cmp_ren->FOV);
751                SUMA_cmap_wid_postRedisplay(w, (XtPointer)ado, NULL);
752             }
753             break;
754          case XK_Home:
755             SurfCont->cmp_ren->FOV = SUMA_CMAP_FOV_INITIAL;
756             SurfCont->cmp_ren->translateVec[0] =
757             SurfCont->cmp_ren->translateVec[1] =
758             SurfCont->cmp_ren->translateVec[2] = 0.0;
759             {
760                SUMA_COLOR_MAP *CM = SUMA_CmapOfPlane(curColPlane);
761                if (SUMA_Rotate_Color_Map(CM, 0) % CM->N_M[0]) {
762                   SUMA_SwitchCmap(ado,
763                          SUMA_CmapOfPlane(curColPlane), 0);
764                } else {
765                   SUMA_cmap_wid_postRedisplay(w, (XtPointer)ado, NULL);
766                }
767             }
768             break;
769          case XK_Up:   /*KEY_UP:*/
770             {
771                if (Kev.state & ShiftMask){
772                   static SUMA_Boolean BeepedAlready = NOPE;
773                   float tstep = height_two_col / 2.0 *
774                                  SurfCont->cmp_ren->FOV /
775                                  (float)SUMA_CMAP_FOV_INITIAL;
776                   SurfCont->cmp_ren->translateVec[1] += tstep ;
777                   if (LocalHead)
778                      fprintf(SUMA_STDERR,
779                               "%s: translateVec[1] = %f (%d)\n",
780                               FuncName,
781                               SurfCont->cmp_ren->translateVec[1],
782                               SUMA_CMAP_HEIGHT - 20);
783                   if (  SurfCont->cmp_ren->translateVec[1] >
784                         SUMA_CMAP_HEIGHT - 20) {
785                      if (!BeepedAlready) {
786                         SUMA_BEEP; BeepedAlready = YUP;
787                      }
788                         SurfCont->cmp_ren->translateVec[1] -= tstep;
789                   } else BeepedAlready = NOPE;
790                   SUMA_cmap_wid_postRedisplay(w, (XtPointer)ado, NULL);
791                } else {
792                   float frac = 0.0;
793                   if (Kev.state & ControlMask) {
794                      frac = 1;
795                   }else {
796                      frac = SUMAg_CF->CmapRotaFrac;
797                   }
798                   SUMA_LH("Rotating colormap");
799                   SUMA_Rotate_Color_Map(
800                      SUMA_CmapOfPlane(curColPlane), frac);
801                   SUMA_LH("Switching colormap");
802                   SUMA_SwitchCmap(ado,
803                          SUMA_CmapOfPlane(curColPlane), 0);
804                }
805             }
806             break;
807          case XK_Down:   /*KEY_DOWN:*/
808             {
809                if (Kev.state & ShiftMask){
810                   static SUMA_Boolean BeepedAlready = NOPE;
811                   float tstep =  height_two_col / 2.0 *
812                                  SurfCont->cmp_ren->FOV /
813                                  (float)SUMA_CMAP_FOV_INITIAL;
814                   SurfCont->cmp_ren->translateVec[1] -=  tstep;
815                   if (  SurfCont->cmp_ren->translateVec[1] <
816                         -SUMA_CMAP_HEIGHT + 20) {
817                      if (!BeepedAlready) {
818                         SUMA_BEEP; BeepedAlready = YUP;
819                      }
820                         SurfCont->cmp_ren->translateVec[1] += tstep;
821                   } else BeepedAlready = NOPE;
822                   SUMA_cmap_wid_postRedisplay(w, (XtPointer)ado, NULL);
823                } else {
824                   float frac = 0.0;
825                   if (Kev.state & ControlMask) {
826                      frac = 1;
827                   }else {
828                      frac = SUMAg_CF->CmapRotaFrac;
829                   }
830                   SUMA_Rotate_Color_Map(
831                      SUMA_CmapOfPlane(curColPlane), -frac);
832                   SUMA_SwitchCmap(ado,
833                          SUMA_CmapOfPlane(curColPlane), 0);
834                }
835             }
836             break;
837 
838       } /* keysym */
839    break;
840 
841    case ButtonPress:
842       if (LocalHead) fprintf(stdout,"In ButtonPress\n");
843       pButton = Bev.button;
844       if (SUMAg_CF->SwapButtons_1_3 ||
845           (SUMAg_CF->ROI_mode && SUMAg_CF->Pen_mode)) {
846          if (pButton == Button1) pButton = Button3;
847          else if (pButton == Button3) pButton = Button1;
848       }
849 
850      /* trap for double click */
851       if (Bev.time - B1time < SUMA_DOUBLE_CLICK_MAX_DELAY) {
852          if (LocalHead) fprintf(SUMA_STDERR, "%s: Double click.\n", FuncName);
853          DoubleClick = YUP;
854       } else {
855          DoubleClick = NOPE;
856       }
857       B1time = Bev.time;
858 
859       switch (pButton) { /* switch type of button Press */
860          case Button1:
861             break;
862          default:
863             break;
864       } /* switch type of button Press */
865       break;
866 
867    case ButtonRelease:
868       if (LocalHead) fprintf(SUMA_STDERR,"%s: In ButtonRelease\n", FuncName);
869       rButton = Bev.button;
870       if (SUMAg_CF->SwapButtons_1_3 ||
871           (SUMAg_CF->ROI_mode && SUMAg_CF->Pen_mode) ) {
872          if (rButton == Button1) rButton = Button3;
873          else if (rButton == Button3) rButton = Button1;
874       }
875       switch (rButton) { /* switch type of button Press */
876          case Button3:
877             break;
878          default:
879             break;
880       } /* switch type of button Press */
881       break;
882 
883    case MotionNotify:
884       if (LocalHead) fprintf(stdout,"In MotionNotify\n");
885       if (SUMAg_CF->SwapButtons_1_3 ||
886           (SUMAg_CF->ROI_mode && SUMAg_CF->Pen_mode)) {
887         if (((Mev.state & Button3MotionMask) && (Mev.state & Button2MotionMask))
888          || ((Mev.state & Button2MotionMask) && (Mev.state & ShiftMask))) {
889             mButton = SUMA_Button_12_Motion;
890          } else if(Mev.state & Button3MotionMask) {
891             mButton = SUMA_Button_1_Motion;
892          }else if(Mev.state & Button2MotionMask) {
893             mButton = SUMA_Button_2_Motion;
894          }else if(Mev.state & Button1MotionMask) {
895             mButton = SUMA_Button_3_Motion;
896          }else {
897             break;
898          }
899       } else {
900          if (((Mev.state & Button1MotionMask) && (Mev.state & Button2MotionMask)) || ((Mev.state & Button2MotionMask) && (Mev.state & ShiftMask))) {
901             mButton = SUMA_Button_12_Motion;
902          } else if(Mev.state & Button1MotionMask) {
903             mButton = SUMA_Button_1_Motion;
904          }else if(Mev.state & Button2MotionMask) {
905             mButton = SUMA_Button_2_Motion;
906          } else if(Mev.state & Button3MotionMask) {
907             mButton = SUMA_Button_3_Motion;
908          }else {
909             break;
910          }
911       }
912 
913       switch (mButton) {
914          case SUMA_Button_12_Motion:
915          case SUMA_Button_2_Shift_Motion:
916             break;
917          default:
918             break;
919       }
920 
921 
922       break;
923   }/* switch event type */
924 
925   /* set up flag to make sure sv regains context */
926   SUMA_SiSi_I_Insist();
927 
928   SUMA_RETURNe;
929 }
930 
SUMA_set_threshold_label(SUMA_ALL_DO * ado,float val,float val2)931 int SUMA_set_threshold_label(SUMA_ALL_DO *ado, float val, float val2)
932 {
933    static char FuncName[]={"SUMA_set_threshold_label"};
934    char slabel[100];
935    SUMA_X_SurfCont *SurfCont=NULL;
936    SUMA_OVERLAYS *curColPlane=NULL;
937    SUMA_Boolean LocalHead = NOPE;
938 
939    SUMA_ENTRY;
940 
941    SUMA_LH("called");
942 
943    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURN(0); }
944 
945    SurfCont = SUMA_ADO_Cont(ado);
946    curColPlane = SUMA_ADO_CurColPlane(ado);
947 
948    switch (curColPlane->OptScl->ThrMode) {
949       case SUMA_LESS_THAN:
950          sprintf(slabel, "%5s", MV_format_fval(val));
951          break;
952       case SUMA_ABS_LESS_THAN:
953          /* used to use this:
954          sprintf(slabel, "|%5s|", ....
955          but that does not work in the editable field ... */
956          sprintf(slabel, "%5s", MV_format_fval(val));
957          break;
958       case SUMA_THRESH_INSIDE_RANGE:
959          /* This is just a place holder for now */
960          sprintf(slabel, "<%5s..%5s>",
961                        MV_format_fval(val), MV_format_fval(val2));
962          break;
963       case SUMA_THRESH_OUTSIDE_RANGE:
964          /* This is just a place holder for now */
965          sprintf(slabel, ">%5s..%5s<",
966                        MV_format_fval(val), MV_format_fval(val2));
967          break;
968       case SUMA_NO_THRESH:
969          break;
970       default:
971          /* This is just a place holder for now */
972          sprintf(slabel, "?%5s??%5s?<",
973                        MV_format_fval(val), MV_format_fval(val2));
974          break;
975    }
976    /* SUMA_SET_LABEL(SurfCont->thr_lb,  slabel);*/
977       SUMA_INSERT_CELL_STRING(SurfCont->SetThrScaleTable, 0,0,slabel);
978 
979 
980    /* You must use the line below if you are calling this function on the fly */
981    /* SUMA_FORCE_SCALE_HEIGHT(SUMA_ADO_Cont(ado));  */
982 
983    #if SUMA_SEPARATE_SURF_CONTROLLERS
984       SUMA_UpdateColPlaneShellAsNeeded(ado);
985    #endif
986 
987    /* Will need to ponder Pvalue field when I start using
988       SUMA_THRESH_INSIDE_RANGE and SUMA_THRESH_OUTSIDE_RANGE.
989       Also, should also consider one tail versus two tail...*/
990    SUMA_UpdatePvalueField (ado, val);
991 
992    SUMA_RETURN(1);
993 }
994 
SUMA_cb_set_threshold_label(Widget w,XtPointer clientData,XtPointer call)995 void SUMA_cb_set_threshold_label(Widget w, XtPointer clientData, XtPointer call)
996 {
997    static char FuncName[]={"SUMA_cb_set_threshold_label"};
998    SUMA_ALL_DO *ado=NULL;
999    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
1000    float fff ;
1001    int dec=0;
1002    char slabel[100];
1003    SUMA_Boolean LocalHead = NOPE;
1004 
1005    SUMA_ENTRY;
1006 
1007    SUMA_LH("called");
1008    ado = (SUMA_ALL_DO *)clientData;
1009    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
1010 
1011    XtVaGetValues(w, XmNuserData, &dec, NULL);
1012    fff = (float)cbs->value / pow(10.0, dec);
1013 
1014    SUMA_set_threshold_label(ado, fff, 0.0);
1015 
1016    SUMA_RETURNe;
1017 }
1018 
SUMA_set_threshold(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,float * val)1019 int SUMA_set_threshold(SUMA_ALL_DO *ado, SUMA_OVERLAYS *colp,
1020                            float *val)
1021 {
1022    static char FuncName[]={"SUMA_set_threshold"};
1023    SUMA_SurfaceObject *SOC=NULL, *SO=NULL;
1024    SUMA_OVERLAYS *colpC=NULL;
1025    SUMA_Boolean LocalHead = NOPE;
1026 
1027    SUMA_ENTRY;
1028 
1029    if (!SUMA_set_threshold_one(ado, colp, val)) SUMA_RETURN(0);
1030    if (!colp) colp = SUMA_ADO_CurColPlane(ado);
1031    if (!colp) SUMA_RETURN(0);
1032 
1033    if (ado->do_type == SO_type) {
1034       /* do we have a contralateral SO and overlay? */
1035       SO = (SUMA_SurfaceObject *)ado;
1036       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
1037       if (colpC && SOC) {
1038          SUMA_LHv("Found contralateral equivalent to:\n"
1039                       " %s and %s in\n"
1040                       " %s and %s\n",
1041                       SO->Label, CHECK_NULL_STR(colp->Label),
1042                       SOC->Label, CHECK_NULL_STR(colpC->Label));
1043          if (!SUMA_SetScaleThr_one((SUMA_ALL_DO *)SOC, colpC, val, 1, 1)) {
1044             SUMA_S_Warn("Failed in contralateral");
1045             SUMA_RETURN(0);
1046          }
1047       }
1048    }
1049 
1050    /* CIFTI yoking outline
1051 
1052    if (colp->dset_link) is CIFTI subdomain (see a. below)
1053       Look up the parent cifti dset (cdset) by using MD_parent_ID
1054 
1055       Look up also the CIFTI DO (CO) that goes with cdset using
1056       SUMA_Fetch_OverlayPointerByDset()
1057 
1058       For each subdomain in CO and each corresponding dset and color plane
1059 
1060       If the subdomain and the colorplane are different from ado , adoC (that
1061       would be (SUMA_ALL_DO *)SOC above), colp and colpC
1062 
1063       call  SUMA_SetScaleThr_one() as per above
1064 
1065 
1066 
1067    a. One way to find out if a dset is a subdomain would be to look for one of the MD_* attribute of dset->ngr that are created in SUMA_CIFTI_2_edset()
1068 
1069    */
1070 
1071    SUMA_RETURN(1);
1072 }
1073 
SUMA_set_threshold_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,float * valp)1074 int SUMA_set_threshold_one(SUMA_ALL_DO *ado, SUMA_OVERLAYS *colp,
1075                            float *valp)
1076 {
1077    static char FuncName[]={"SUMA_set_threshold_one"};
1078    float oval, val;
1079    SUMA_X_SurfCont *SurfCont=NULL;
1080    SUMA_Boolean LocalHead = NOPE;
1081 
1082    SUMA_ENTRY;
1083 
1084    if (!ado) SUMA_RETURN(0);
1085    SurfCont = SUMA_ADO_Cont(ado);
1086    if (!colp) colp = SUMA_ADO_CurColPlane(ado);
1087    if (!colp) SUMA_RETURN(0);
1088 
1089    oval = colp->OptScl->ThreshRange[0];
1090    if (!valp) val = oval; /* a dirty trick to force scale height */
1091    else val = *valp;
1092    colp->OptScl->ThreshRange[0] = val;
1093 
1094    if (LocalHead) {
1095       fprintf( SUMA_STDERR,
1096                "%s:\nThreshold set to %f\n",
1097                FuncName,
1098                colp->OptScl->ThreshRange[0]);
1099    }
1100 
1101    if (  colp->OptScl->UseThr &&
1102          colp->OptScl->tind >=0) {
1103       if (oval != colp->OptScl->ThreshRange[0] &&
1104           colp->OptScl->Clusterize) {
1105          /* Need a new clusterizing effort*/
1106          colp->OptScl->RecomputeClust = 1;
1107       }
1108       SUMA_ColorizePlane(colp);
1109       SUMA_Remixedisplay(ado);
1110    }
1111 
1112    /* call this one since it is not being called as the slider is dragged. */
1113    SUMA_set_threshold_label(ado, val, 0.0);
1114 
1115    /* sad as it is */
1116    SUMA_FORCE_SCALE_HEIGHT(SUMA_ADO_Cont(ado));
1117 
1118    SUMA_ADO_Flush_Pick_Buffer(ado, NULL);
1119 
1120    #if SUMA_SEPARATE_SURF_CONTROLLERS
1121       SUMA_UpdateColPlaneShellAsNeeded(ado);
1122    #endif
1123 
1124    SUMA_UpdateNodeValField(ado);
1125    SUMA_UpdateNodeLblField(ado);
1126    SUMA_UpdatePvalueField (ado, colp->OptScl->ThreshRange[0]);
1127 
1128    SUMA_RETURN(1);
1129 }
1130 
SUMA_cb_set_threshold(Widget w,XtPointer clientData,XtPointer call)1131 void SUMA_cb_set_threshold(Widget w, XtPointer clientData, XtPointer call)
1132 {
1133    static char FuncName[]={"SUMA_cb_set_threshold"};
1134    SUMA_ALL_DO *ado=NULL;
1135    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
1136    float fff=0.0;
1137    int dec=-1;
1138    SUMA_Boolean LocalHead = NOPE;
1139 
1140    SUMA_ENTRY;
1141 
1142    SUMA_LH("called");
1143    ado = (SUMA_ALL_DO *)clientData;
1144    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
1145    XtVaGetValues(w, XmNuserData, &dec, NULL);
1146    fff = (float)cbs->value / pow(10.0, dec);
1147    SUMA_LHv("Have %f\n", fff);
1148    SUMA_set_threshold(ado, NULL, &fff);
1149 
1150    SUMA_RETURNe;
1151 }
1152 
SUMA_SwitchColPlaneIntensity(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int ind,int setmen)1153 int SUMA_SwitchColPlaneIntensity(
1154          SUMA_ALL_DO *ado,
1155          SUMA_OVERLAYS *colp,
1156          int ind, int setmen)
1157 {
1158    static char FuncName[]={"SUMA_SwitchColPlaneIntensity"};
1159    char srange[500];
1160    double range[2];
1161    int loc[2];
1162    SUMA_Boolean LocalHead = NOPE;
1163 
1164    SUMA_ENTRY;
1165 
1166    if (!SUMA_SwitchColPlaneIntensity_one(ado, colp, ind, setmen)) {
1167       SUMA_S_Err("Failed in _one");
1168       SUMA_RETURN(0);
1169    }
1170 
1171    if (ado->do_type == SO_type) {
1172       SUMA_SurfaceObject *SOC=NULL, *SO=NULL;
1173       SUMA_OVERLAYS *colpC=NULL;
1174       /* do we have a contralateral SO and overlay? */
1175       SO = (SUMA_SurfaceObject *)ado;
1176       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
1177       if (colpC && SOC) {
1178          SUMA_LHv("Found contralateral equivalent to:\n"
1179                       " %s and %s in\n"
1180                       " %s and %s\n",
1181                       SO->Label, CHECK_NULL_STR(colp->Label),
1182                       SOC->Label, CHECK_NULL_STR(colpC->Label));
1183          if (!SUMA_SwitchColPlaneIntensity_one(
1184                            (SUMA_ALL_DO *)SOC, colpC, ind, 1)) {
1185             SUMA_S_Warn("Failed in contralateral");
1186          }
1187       }
1188    }
1189 
1190    SUMA_RETURN(1);
1191 }
1192 
1193 
1194 /* changes you do here should be reflected under SE_SetSurfCont in SUMA_Engine*/
SUMA_SwitchColPlaneIntensity_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int ind,int setmen)1195 int SUMA_SwitchColPlaneIntensity_one (
1196          SUMA_ALL_DO *ado,
1197          SUMA_OVERLAYS *colp,
1198          int ind, int setmen)
1199 {
1200    static char FuncName[]={"SUMA_SwitchColPlaneIntensity_one"};
1201    char srange[500];
1202    double range[2];
1203    int loc[2];
1204    float pp = 0.0;
1205    SUMA_DSET *dset=NULL;
1206    char *Label=NULL;
1207    SUMA_X_SurfCont *SurfCont=NULL;
1208    SUMA_OVERLAYS *curColPlane=NULL;
1209    SUMA_Boolean LocalHead = NOPE;
1210 
1211    SUMA_ENTRY;
1212 
1213 
1214    SurfCont = SUMA_ADO_Cont(ado);
1215    curColPlane = SUMA_ADO_CurColPlane(ado);
1216    Label = SUMA_ADO_Label(ado);
1217 
1218    if (  !ado || !SurfCont ||
1219          !curColPlane ||
1220          !colp || !colp->dset_link || !colp->OptScl) { SUMA_RETURN(0); }
1221 
1222    if (ind < 0) {
1223       if (ind == SUMA_BACK_ONE_SUBBRICK) {/* --1 */
1224          ind = colp->OptScl->find-1;
1225          if (ind < 0 || ind >= SDSET_VECNUM(colp->dset_link)) {
1226             SUMA_LH("Reached end");
1227             SUMA_BEEP;
1228             SUMA_RETURN(1);
1229          }
1230       } else if (ind == SUMA_FORWARD_ONE_SUBBRICK) {/* ++1 */
1231          ind = colp->OptScl->find+1;
1232          if (ind < 0 || ind >= SDSET_VECNUM(colp->dset_link)) {
1233             SUMA_LH("Reached end, return without complaint");
1234             SUMA_BEEP;
1235             SUMA_RETURN(1);
1236          }
1237       } else { SUMA_RETURN(0); }
1238    }
1239 
1240    if (LocalHead) {
1241       fprintf( SUMA_STDERR,
1242                "%s:\n request to switch intensity to col. %d\n",
1243                FuncName, ind);
1244       fprintf(SUMA_STDERR, "ADO->Label = %s\n", Label);
1245    }
1246 
1247    if (SDSET_TYPE(colp->dset_link) == SUMA_NODE_RGB) {
1248       SUMA_S_Err("This is a NODE_RGB dataset, cannot switch columns.\n");
1249       SUMA_RETURN(0);
1250    }
1251    if (ind >= SDSET_VECNUM(colp->dset_link)) {
1252       SUMA_S_Errv("Col. Index of %d exceeds maximum of %d for this dset.\n",
1253                    ind, SDSET_VECNUM(colp->dset_link)-1);
1254       SUMA_RETURN(0);
1255    }
1256    if (ind != colp->OptScl->find &&
1257           colp->OptScl->Clusterize) {
1258          /* Need a new clusterizing effort*/
1259          colp->OptScl->RecomputeClust = 1;
1260    }
1261    colp->OptScl->find = ind;
1262    if (setmen && colp == curColPlane && SurfCont->SwitchIntMenu) {
1263       SUMA_LHv("Setting menu values, %d\n", colp->OptScl->find+1);
1264       SUMA_Set_Menu_Widget(SurfCont->SwitchIntMenu, colp->OptScl->find+1);
1265    }
1266 
1267 
1268    dset=colp->dset_link;
1269    switch(curColPlane->LinkMode) {/* corresponding threshold sb */
1270       case SW_LinkMode_Stat:
1271             {
1272          char *lab=SUMA_DsetColLabelCopy(dset, ind, 0), *lab2=NULL, *ext=NULL;
1273          int ind2=-1, ipair=0;
1274          static char *exta[50]={ "_Coef",    "_Tstat",   /* 3dDeconvolve */
1275                                  "_mean",    "_Tstat",   /* 3dttest++ */
1276                                  ":Mean",    ":t-stat",  /* 3dANOVA */
1277                                  ":Contr",   ":t-stat",  /* 3dANOVA */
1278                                  ":Inten",   ":F-stat",  /* 3dANOVA */
1279                                  ":Diff",    ":t-stat",  /* 3dANOVA */
1280                                  ":b",       ":t",       /* 3dMEMA */
1281                                  "_mean",    "_Zscr",    /* GICOR */
1282                                  "_meanNC",  "_ZscrNC",  /* GICOR */
1283                                  "",         " t",       /* 3dMVM */
1284                                  NULL, NULL }; /* leave always at the bottom*/
1285          SUMA_LHv("Looking for decent match for %s\n", lab);
1286          if (lab) {
1287             ipair=0;
1288             while(ind2 < 0 && (ext = exta[ipair*2])) {
1289                if ((strcmp(ext, "")==0) || STRING_HAS_SUFFIX(lab,ext)) {
1290                   lab[strlen(lab)-strlen(ext)]='\0';
1291                   lab2 = SUMA_append_string(lab,exta[ipair*2+1]);
1292                   SUMA_LHv("  Looking for %s\n", lab2);
1293                   if ((ind2 = SUMA_FindDsetColLabeled(dset, lab2)) >= 0) {
1294                      SUMA_LHv("Sub-brick %s%s has %s go with it.\n",
1295                                  lab, ext, lab2);
1296                      colp->OptScl->tind = ind2;
1297                      if (colp == curColPlane && SurfCont->SwitchThrMenu){
1298                                           /* must set this
1299                                              regardless of setmen, but not if
1300                                        SwitchThrMenu has not be been set yet */
1301                         SUMA_LH("Setting threshold values");
1302                         SUMA_Set_Menu_Widget(SurfCont->SwitchThrMenu,
1303                                       colp->OptScl->tind+1);
1304                         if (SUMA_GetDsetColRange(colp->dset_link,
1305                                              colp->OptScl->tind, range, loc)) {
1306                            SUMA_SetScaleRange(ado, range );
1307                            SUMA_InitRangeTable(ado, -1) ;
1308                            SUMA_UpdateNodeValField(ado);
1309                         }else {
1310                            SUMA_S_Err("Failed to get range");
1311                         }
1312                         if ((pp=SUMA_floatEnv("SUMA_pval_at_switch", -1.0))
1313                                                                         >= 0) {
1314                            pp = (float)SUMA_Pval2ThreshVal (ado, (double)pp);
1315                            /* This function will cause undue redisplays, but
1316                            keeps code clean */
1317                            if ( pp != 0.0) {
1318                               SUMA_set_threshold_one(ado, colp, &pp);
1319                            }
1320                         }
1321                      }
1322                   } SUMA_free(lab2); lab2=NULL;
1323                   /* put lab back together */
1324                   lab[strlen(lab)]=ext[0];
1325                }
1326                ++ipair;
1327             }
1328          }
1329             }
1330          break;
1331       case SW_LinkMode_Same:
1332          colp->OptScl->tind = ind;
1333          if (colp == curColPlane ) {/* must set this
1334                                  regardless of setmen */
1335             SUMA_LH("Setting threshold values");
1336             SUMA_Set_Menu_Widget(SurfCont->SwitchThrMenu,
1337                           colp->OptScl->tind+1) ;
1338             if (SUMA_GetDsetColRange(colp->dset_link,
1339                                  colp->OptScl->tind, range, loc)) {
1340                SUMA_SetScaleRange(ado, range );
1341                SUMA_InitRangeTable(ado, -1) ;
1342                SUMA_UpdateNodeValField(ado);
1343             }else {
1344                SUMA_S_Err("Failed to get range");
1345             }
1346             if ((pp=SUMA_floatEnv("SUMA_pval_at_switch", -1.0)) >= 0) {
1347                pp = (float)SUMA_Pval2ThreshVal (ado, (double)pp);
1348                /* This function will cause undue redisplays, but
1349                keeps code clean */
1350                if ( pp != 0.0) {
1351                   SUMA_set_threshold_one(ado, colp, &pp);
1352                }
1353             }
1354          }
1355          break;
1356       case SW_LinkMode_Pls1:
1357             {
1358          if (ind+1 >= SDSET_VECNUM(dset)) break;
1359          colp->OptScl->tind = ind+1;
1360          if (colp == curColPlane ) {/* must set this
1361                                  regardless of setmen */
1362             SUMA_LH("Setting threshold values");
1363             SUMA_Set_Menu_Widget(SurfCont->SwitchThrMenu,
1364                           colp->OptScl->tind+1) ;
1365             if (SUMA_GetDsetColRange(colp->dset_link,
1366                                  colp->OptScl->tind, range, loc)) {
1367                SUMA_SetScaleRange(ado, range );
1368                SUMA_InitRangeTable(ado, -1) ;
1369                SUMA_UpdateNodeValField(ado);
1370             }else {
1371                SUMA_S_Err("Failed to get range");
1372             }
1373             if ((pp=SUMA_floatEnv("SUMA_pval_at_switch", -1.0)) >= 0) {
1374                pp = (float)SUMA_Pval2ThreshVal (ado, (double)pp);
1375                /* This function will cause undue redisplays, but
1376                keeps code clean */
1377                if ( pp != 0.0) {
1378                   SUMA_set_threshold_one(ado, colp, &pp);
1379                }
1380             }
1381          }
1382             }
1383          break;
1384       default:
1385          break;
1386    }
1387 
1388 
1389    SUMA_LH("Setting Range, Intensity change");
1390    SUMA_InitRangeTable(ado, 0) ;
1391    SUMA_UpdateCrossHairNodeLabelFieldForDO(ado);
1392 
1393    if (colp->ShowMode < 0) { SUMA_RETURN(1); } /* nothing else to do */
1394 
1395    SUMA_ADO_Flush_Pick_Buffer(ado, NULL);
1396 
1397    if (!SUMA_ColorizePlane (colp)) {
1398          SUMA_SLP_Err("Failed to colorize plane.\n");
1399          SUMA_RETURN(0);
1400    }
1401 
1402 
1403    SUMA_Remixedisplay(ado);
1404 
1405    #if SUMA_SEPARATE_SURF_CONTROLLERS
1406       SUMA_UpdateColPlaneShellAsNeeded(ado);
1407    #endif
1408 
1409    SUMA_UpdateNodeValField(ado);
1410    SUMA_UpdateNodeLblField(ado);
1411 
1412    SUMA_RETURN(1);
1413 }
1414 
SUMA_cb_SwitchIntensity(Widget w,XtPointer client_data,XtPointer call)1415 void SUMA_cb_SwitchIntensity(Widget w, XtPointer client_data, XtPointer call)
1416 {
1417    static char FuncName[]={"SUMA_cb_SwitchIntensity"};
1418    int imenu = 0;
1419    SUMA_MenuCallBackData *datap=NULL;
1420    SUMA_ALL_DO *ado=NULL;
1421    SUMA_OVERLAYS *curColPlane=NULL;
1422    SUMA_Boolean LocalHead = NOPE;
1423 
1424    SUMA_ENTRY;
1425 
1426    /* get the surface object that the setting belongs to */
1427    datap = (SUMA_MenuCallBackData *)client_data;
1428    ado = (SUMA_ALL_DO *)datap->ContID;
1429    curColPlane = SUMA_ADO_CurColPlane(ado);
1430    imenu = (INT_CAST)datap->callback_data;
1431 
1432    if (imenu-1 == curColPlane->OptScl->find) {
1433       SUMA_RETURNe; /* nothing to be done */
1434    }
1435 
1436    SUMA_SwitchColPlaneIntensity(ado, curColPlane, imenu -1, 0);
1437 
1438    SUMA_RETURNe;
1439 }
1440 
SUMA_SwitchColPlaneThreshold(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int ind,int setmen)1441 int SUMA_SwitchColPlaneThreshold(
1442          SUMA_ALL_DO *ado,
1443          SUMA_OVERLAYS *colp,
1444          int ind, int setmen)
1445 {
1446    static char FuncName[]={"SUMA_SwitchColPlaneThreshold"};
1447    char srange[500];
1448    double range[2];
1449    int loc[2];
1450    SUMA_DSET *dset=NULL;
1451    SUMA_SurfaceObject *SOC=NULL, *SO=NULL;
1452    SUMA_OVERLAYS *colpC=NULL;
1453    SUMA_Boolean LocalHead = NOPE;
1454 
1455    SUMA_ENTRY;
1456 
1457    if (!SUMA_SwitchColPlaneThreshold_one(ado, colp, ind, setmen)) {
1458       SUMA_S_Err("Failed in _one");
1459       SUMA_RETURN(0);
1460    }
1461 
1462    if (ado->do_type == SO_type) {
1463       SO = (SUMA_SurfaceObject *)ado;
1464       /* do we have a contralateral SO and overlay? */
1465       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
1466       if (colpC && SOC) {
1467          SUMA_LHv("Found contralateral equivalent to:\n"
1468                       " %s and %s in\n"
1469                       " %s and %s\n",
1470                       SO->Label, CHECK_NULL_STR(colp->Label),
1471                       SOC->Label, CHECK_NULL_STR(colpC->Label));
1472          if (!SUMA_SwitchColPlaneThreshold_one(ado, colpC, ind, 1)) {
1473             SUMA_S_Warn("Failed in contralateral");
1474          }
1475       }
1476    }
1477 
1478    SUMA_RETURN(1);
1479 }
1480 
SUMA_SwitchColPlaneThreshold_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int ind,int setmen)1481 int SUMA_SwitchColPlaneThreshold_one(
1482                                  SUMA_ALL_DO *ado, SUMA_OVERLAYS *colp,
1483                                  int ind, int setmen)
1484 {
1485    static char FuncName[]={"SUMA_SwitchColPlaneThreshold_one"};
1486    char srange[500];
1487    double range[2]; int loc[2];
1488    float pp=0.0;
1489    SUMA_X_SurfCont *SurfCont=NULL;
1490    SUMA_OVERLAYS *curColPlane=NULL;
1491    SUMA_Boolean LocalHead = NOPE;
1492 
1493    SUMA_ENTRY;
1494 
1495 
1496    SurfCont = SUMA_ADO_Cont(ado);
1497    curColPlane = SUMA_ADO_CurColPlane(ado);
1498    if (!ado || !SurfCont || !curColPlane ||
1499        !colp || ind < -1 || !colp->dset_link) { SUMA_RETURN(0); }
1500 
1501 
1502    if (LocalHead) {
1503       fprintf(SUMA_STDERR, "%s:\n request to switch threshold to col. %d\n",
1504                   FuncName, ind);
1505    }
1506    if (ind < 0) {
1507       /* turn threshold off */
1508       XmToggleButtonSetState (SurfCont->Thr_tb, NOPE, YUP);
1509       SUMA_RETURN(1);
1510    }
1511 
1512    if (ind >= SDSET_VECNUM(colp->dset_link)) {
1513       SUMA_S_Errv("Col. Index of %d exceeds maximum of %d for this dset.\n",
1514             ind, SDSET_VECNUM(colp->dset_link)-1);
1515       SUMA_RETURN(0);
1516    }
1517 
1518    if (ind != colp->OptScl->tind &&
1519           colp->OptScl->Clusterize) {
1520          /* Need a new clusterizing effort*/
1521          colp->OptScl->RecomputeClust = 1;
1522    }
1523    colp->OptScl->tind = ind;
1524 
1525 
1526    /* make sure threshold is on if command is not from the interface*/
1527    if (setmen && !colp->OptScl->UseThr && colp->OptScl->tind >= 0) {
1528       colp->OptScl->UseThr = YUP;
1529       XmToggleButtonSetState (SurfCont->Thr_tb, YUP, NOPE);
1530    }
1531 
1532    if (setmen && colp == curColPlane) {
1533       SUMA_Set_Menu_Widget(SurfCont->SwitchThrMenu,
1534                     colp->OptScl->tind+1) ;
1535    }
1536 
1537    if (SUMA_GetDsetColRange(colp->dset_link, colp->OptScl->tind, range, loc)) {
1538       SUMA_SetScaleRange(ado, range );
1539    }else {
1540       SUMA_SLP_Err("Failed to get range");
1541       SUMA_RETURN(0);
1542    }
1543 
1544    /* threshold sub-brick change */
1545    SUMA_InitRangeTable(ado, -1) ;
1546    SUMA_UpdateCrossHairNodeLabelFieldForDO(ado);
1547    SUMA_UpdateNodeValField(ado);
1548 
1549    if (!colp->OptScl->UseThr) { SUMA_RETURN(1); } /* nothing else to do */
1550 
1551    SUMA_ADO_Flush_Pick_Buffer(ado, NULL);
1552 
1553    if (!SUMA_ColorizePlane (colp)) {
1554          SUMA_SLP_Err("Failed to colorize plane.\n");
1555          SUMA_RETURN(0);
1556    }
1557 
1558    SUMA_Remixedisplay(ado);
1559 
1560    #if SUMA_SEPARATE_SURF_CONTROLLERS
1561       SUMA_UpdateColPlaneShellAsNeeded(ado);
1562    #endif
1563 
1564    SUMA_UpdateNodeLblField(ado);
1565 
1566    if ((pp=SUMA_floatEnv("SUMA_pval_at_switch", -1.0)) >= 0) {
1567       pp = (float)SUMA_Pval2ThreshVal (ado, (double)pp);
1568       /* This function will cause undue redisplays, but keeps code clean */
1569       if ( pp != 0.0) {
1570          SUMA_set_threshold_one(ado, colp, &pp);
1571       }
1572    }
1573 
1574    SUMA_RETURN(1);
1575 }
1576 
SUMA_cb_SwitchThreshold(Widget w,XtPointer client_data,XtPointer call)1577 void SUMA_cb_SwitchThreshold(Widget w, XtPointer client_data, XtPointer call)
1578 {
1579    static char FuncName[]={"SUMA_cb_SwitchThreshold"};
1580    int imenu = 0;
1581    SUMA_MenuCallBackData *datap=NULL;
1582    SUMA_ALL_DO *ado=NULL;
1583    SUMA_OVERLAYS *curColPlane=NULL;
1584    SUMA_Boolean LocalHead = NOPE;
1585 
1586    SUMA_ENTRY;
1587 
1588    /* get the surface object that the setting belongs to */
1589    datap = (SUMA_MenuCallBackData *)client_data;
1590    ado = (SUMA_ALL_DO *)datap->ContID;
1591    imenu = (INT_CAST)datap->callback_data;
1592 
1593    curColPlane = SUMA_ADO_CurColPlane(ado);
1594    if (imenu-1 == curColPlane->OptScl->tind) {
1595       SUMA_RETURNe; /* nothing to be done */
1596    }
1597 
1598    SUMA_SwitchColPlaneThreshold(ado, curColPlane, imenu -1, 0);
1599    SUMA_RETURNe;
1600 }
1601 
SUMA_SwitchColPlaneBrightness(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int ind,int setmen)1602 int SUMA_SwitchColPlaneBrightness(
1603          SUMA_ALL_DO *ado,
1604          SUMA_OVERLAYS *colp,
1605          int ind, int setmen)
1606 {
1607    static char FuncName[]={"SUMA_SwitchColPlaneBrightness"};
1608    char srange[500];
1609    double range[2];
1610    int loc[2];
1611    SUMA_DSET *dset=NULL;
1612    SUMA_OVERLAYS *colpC=NULL;
1613    SUMA_Boolean LocalHead = NOPE;
1614 
1615    SUMA_ENTRY;
1616 
1617    if (LocalHead) {
1618       fprintf(SUMA_STDERR,
1619          "%s:\n request to switch brightness to col. %d\n", FuncName, ind);
1620    }
1621 
1622    if (ind == colp->OptScl->bind) {
1623       SUMA_RETURN(0); /* nothing to be done */
1624    }
1625 
1626    if (!SUMA_SwitchColPlaneBrightness_one(ado, colp, ind, setmen)) {
1627       SUMA_S_Err("Failed in _one");
1628       SUMA_RETURN(0);
1629    }
1630 
1631    if (ado->do_type == SO_type) {
1632       SUMA_SurfaceObject *SOC=NULL;
1633       SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
1634       /* do we have a contralateral SO and overlay? */
1635       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
1636       if (colpC && SOC) {
1637          SUMA_LHv("Found contralateral equivalent to:\n"
1638                       " %s and %s in\n"
1639                       " %s and %s\n",
1640                       SO->Label, CHECK_NULL_STR(colp->Label),
1641                       SOC->Label, CHECK_NULL_STR(colpC->Label));
1642          if (!SUMA_SwitchColPlaneBrightness_one((SUMA_ALL_DO *)SOC,
1643                                                  colpC, ind, 1)) {
1644             SUMA_S_Warn("Failed in contralateral");
1645          }
1646       }
1647    }
1648    SUMA_RETURN(1);
1649 }
1650 
SUMA_SwitchColPlaneBrightness_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int ind,int setmen)1651 int SUMA_SwitchColPlaneBrightness_one(
1652          SUMA_ALL_DO *ado, SUMA_OVERLAYS *colp,
1653          int ind, int setmen)
1654 {
1655    static char FuncName[]={"SUMA_SwitchColPlaneBrightness_one"};
1656    char srange[500];
1657    double range[2]; int loc[2];
1658    SUMA_X_SurfCont *SurfCont=NULL;
1659    SUMA_OVERLAYS *curColPlane=NULL;
1660    SUMA_Boolean LocalHead = NOPE;
1661 
1662    SUMA_ENTRY;
1663 
1664    if (!ado) {
1665       SUMA_SL_Err("NULL ado");
1666       SUMA_RETURN(0);
1667    }
1668    SurfCont = SUMA_ADO_Cont(ado);
1669    curColPlane = SUMA_ADO_CurColPlane(ado);
1670 
1671    if (  !SurfCont || !curColPlane ||
1672          !colp || ind < -1 || !colp->dset_link) {
1673          SUMA_S_Err("NULLity");
1674          SUMA_RETURN(0);
1675    }
1676 
1677 
1678    if (LocalHead) {
1679       fprintf(SUMA_STDERR,
1680          "%s:\n request to switch brightness to col. %d, currently %d\n",
1681             FuncName, ind, colp->OptScl->bind);
1682    }
1683 
1684    if (ind < 0) {
1685       /* turn brightness off */
1686       XmToggleButtonSetState (SurfCont->Brt_tb, NOPE, YUP);
1687       SUMA_RETURN(1);
1688    }
1689 
1690    if (ind >= SDSET_VECNUM(colp->dset_link)) {
1691       SUMA_S_Errv("Col. Index of %d exceeds maximum of %d for this dset.\n",
1692                   ind, SDSET_VECNUM(colp->dset_link)-1);
1693       SUMA_RETURN(0);
1694    }
1695    colp->OptScl->bind = ind;
1696 
1697    /* make sure brightness is on if command is not from the interface*/
1698    if (setmen && !colp->OptScl->UseBrt && colp->OptScl->bind >= 0) {
1699       colp->OptScl->UseBrt = YUP;
1700       XmToggleButtonSetState (SurfCont->Brt_tb, YUP, NOPE);
1701    }
1702 
1703    if (setmen && colp == curColPlane) {
1704       SUMA_Set_Menu_Widget(SurfCont->SwitchBrtMenu,
1705                     colp->OptScl->bind+1);
1706    }
1707 
1708    if (SUMA_GetDsetColRange(colp->dset_link, colp->OptScl->bind, range, loc)) {
1709       SUMA_SetScaleRange(ado, range );
1710    }else {
1711       SUMA_SLP_Err("Failed to get range");
1712       SUMA_RETURN(0);
1713    }
1714 
1715    /* brightness change */
1716    SUMA_InitRangeTable(ado, -1) ;
1717    SUMA_UpdateCrossHairNodeLabelFieldForDO(ado);
1718    SUMA_UpdateNodeValField(ado);
1719 
1720    if (!colp->OptScl->UseBrt) { SUMA_RETURN(1); } /* nothing else to do */
1721 
1722    if (!SUMA_ColorizePlane (colp)) {
1723          SUMA_SLP_Err("Failed to colorize plane.\n");
1724          SUMA_RETURN(0);
1725    }
1726 
1727    SUMA_Remixedisplay(ado);
1728 
1729    #if SUMA_SEPARATE_SURF_CONTROLLERS
1730       SUMA_UpdateColPlaneShellAsNeeded(ado);
1731    #endif
1732 
1733    SUMA_UpdateNodeLblField(ado);
1734 
1735    SUMA_RETURN(1);
1736 }
1737 
1738 
SUMA_cb_SwitchBrightness(Widget w,XtPointer client_data,XtPointer call)1739 void SUMA_cb_SwitchBrightness(Widget w, XtPointer client_data, XtPointer call)
1740 {
1741    static char FuncName[]={"SUMA_cb_SwitchBrightness"};
1742    int imenu = 0;
1743    SUMA_MenuCallBackData *datap=NULL;
1744    SUMA_ALL_DO *ado = NULL;
1745    SUMA_OVERLAYS *curColPlane=NULL;
1746    SUMA_Boolean LocalHead = NOPE;
1747 
1748    SUMA_ENTRY;
1749 
1750    /* get the surface object that the setting belongs to */
1751    datap = (SUMA_MenuCallBackData *)client_data;
1752    ado = (SUMA_ALL_DO *)datap->ContID;
1753    curColPlane = SUMA_ADO_CurColPlane(ado);
1754    imenu = (INT_CAST)datap->callback_data;
1755 
1756    if (imenu-1 == curColPlane->OptScl->bind) {
1757       SUMA_RETURNe; /* nothing to be done */
1758    }
1759    SUMA_SwitchColPlaneBrightness(ado, curColPlane, imenu -1, 0);
1760 
1761    #if 0 /* Obsolete, now all handled in SUMA_SwitchColPlaneBrightness above*/
1762    if (LocalHead) {
1763       fprintf( SUMA_STDERR,
1764                "%s:\n request to switch brightness to col. %d\n",
1765                FuncName, imenu - 1);
1766    }
1767 
1768    curColPlane->OptScl->bind = imenu - 1;
1769 
1770    SUMA_InitRangeTable(ado, 1) ;
1771 
1772    SUMA_UpdateNodeValField(ado);
1773    if (!curColPlane->OptScl->UseBrt) {
1774       SUMA_RETURNe;
1775    } /* nothing else to do */
1776 
1777    if (!SUMA_ColorizePlane (curColPlane)) {
1778          SUMA_SLP_Err("Failed to colorize plane.\n");
1779          SUMA_RETURNe;
1780    }
1781 
1782 
1783    SUMA_Remixedisplay(ado);
1784 
1785    #if SUMA_SEPARATE_SURF_CONTROLLERS
1786       SUMA_UpdateColPlaneShellAsNeeded(ado);
1787    #endif
1788 
1789    SUMA_UpdateNodeLblField(ado);
1790    #endif
1791 
1792    SUMA_RETURNe;
1793 }
1794 
SUMA_SwitchCmap_one(SUMA_ALL_DO * ado,SUMA_COLOR_MAP * CM,int setmenu)1795 int SUMA_SwitchCmap_one(SUMA_ALL_DO *ado,
1796                          SUMA_COLOR_MAP *CM, int setmenu)
1797 {
1798    static char FuncName[]={"SUMA_SwitchCmap_one"};
1799    SUMA_Boolean LocalHead = NOPE;
1800 
1801    SUMA_ENTRY;
1802 
1803    if (!ado || !CM) SUMA_RETURN(0);
1804 
1805    if (LocalHead) {
1806       fprintf(SUMA_STDERR, "%s:\n request to switch colormap to  (%s)\n",
1807          FuncName, CM->Name);
1808    }
1809 
1810    if (setmenu) {
1811       if (!SUMA_SetCmapMenuChoice (ado, CM->Name)) {
1812              SUMA_SL_Err("Failed in SUMA_SetCmapMenuChoice");
1813       }
1814    }
1815 
1816    if (!SUMA_SwitchColPlaneCmap(ado, CM)) {
1817       SUMA_SL_Err("Failed in SUMA_SwitchColPlaneCmap");
1818    }
1819 
1820    /* Now you'll need to close the list widget if a choice has been made */
1821    if (SUMAg_CF->X->SwitchCmapLst) {
1822       if (!SUMAg_CF->X->SwitchCmapLst->isShaded)
1823          SUMA_cb_CloseSwitchCmap( NULL,  (XtPointer)SUMAg_CF->X->SwitchCmapLst,
1824                                   NULL);
1825    }
1826 
1827    #if SUMA_SEPARATE_SURF_CONTROLLERS
1828       SUMA_UpdateColPlaneShellAsNeeded(ado);
1829    #endif
1830 
1831    /* update Lbl fields */
1832    SUMA_UpdateNodeLblField(ado);
1833 
1834    if (SUMAg_CF->Fake_Cmap) {
1835       SUMA_LH("Attempting to keep up appearances");
1836       SUMA_PBAR_bigexpose_CB(NULL, (XtPointer)ado, NULL);
1837    }
1838 
1839    SUMA_RETURN(1);
1840 }
1841 
SUMA_SwitchCmap(SUMA_ALL_DO * ado,SUMA_COLOR_MAP * CM,int setmenu)1842 int SUMA_SwitchCmap(SUMA_ALL_DO *ado,
1843                     SUMA_COLOR_MAP *CM, int setmenu)
1844 {
1845    static char FuncName[]={"SUMA_SwitchCmap"};
1846    SUMA_Boolean LocalHead = NOPE;
1847 
1848    SUMA_ENTRY;
1849 
1850    SUMA_LH("Called");
1851    if (!ado || !CM) SUMA_RETURN(0);
1852 
1853    if (!SUMA_SwitchCmap_one(ado, CM, setmenu)) SUMA_RETURN(0);
1854 
1855    if (ado->do_type == SO_type) {
1856       SUMA_SurfaceObject *SOC=NULL, *SO=(SUMA_SurfaceObject *)ado;
1857       SUMA_OVERLAYS *colp=NULL, *colpC=NULL;
1858       /* do we have a contralateral SO and overlay? */
1859       colp = SO->SurfCont->curColPlane;
1860       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
1861       if (colpC && SOC) {
1862          SUMA_LHv("Found contralateral equivalent to:\n"
1863                       " %s and %s in\n"
1864                       " %s and %s\n",
1865                       SO->Label, CHECK_NULL_STR(colp->Label),
1866                       SOC->Label, CHECK_NULL_STR(colpC->Label));
1867          if (!SUMA_SwitchCmap_one((SUMA_ALL_DO *)SOC, CM, 1)) {
1868             SUMA_S_Warn("Failed in contralateralination");
1869          }
1870       }
1871    }
1872    SUMA_RETURN(1);
1873 }
1874 
1875 /*!
1876    \brief function that handlges switching colormap from the menu widget
1877    \sa SUMA_cb_SelectSwitchCmap
1878 */
SUMA_cb_SwitchCmap(Widget w,XtPointer client_data,XtPointer call)1879 void SUMA_cb_SwitchCmap(Widget w, XtPointer client_data, XtPointer call)
1880 {
1881    static char FuncName[]={"SUMA_cb_SwitchCmap"};
1882    SUMA_MenuCallBackData *datap=NULL;
1883    SUMA_ALL_DO *ado = NULL;
1884    SUMA_COLOR_MAP *CM = NULL;
1885    SUMA_Boolean LocalHead = NOPE;
1886 
1887    SUMA_ENTRY;
1888 
1889    /* get the surface object that the setting belongs to */
1890    datap = (SUMA_MenuCallBackData *)client_data;
1891    ado = (SUMA_ALL_DO *)datap->ContID;
1892    CM = (SUMA_COLOR_MAP *)datap->callback_data;
1893 
1894    SUMA_SwitchCmap(ado, CM, 0);
1895 
1896    SUMA_RETURNe;
1897 }
1898 
SUMA_cb_ShowZero_tb_toggled(Widget w,XtPointer data,XtPointer client_data)1899 void SUMA_cb_ShowZero_tb_toggled (Widget w, XtPointer data,
1900                                   XtPointer client_data)
1901 {
1902    static char FuncName[]={"SUMA_cb_ShowZero_tb_toggled"};
1903    SUMA_ALL_DO *ado = NULL;
1904    SUMA_TABLE_FIELD *TF=NULL;
1905    SUMA_X_SurfCont *SurfCont=NULL;
1906    SUMA_OVERLAYS *curColPlane=NULL;
1907    SUMA_Boolean LocalHead = NOPE;
1908 
1909    SUMA_ENTRY;
1910 
1911    SUMA_LH("Called");
1912 
1913    ado = (SUMA_ALL_DO *)data;
1914 
1915    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
1916       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
1917    curColPlane = SUMA_ADO_CurColPlane(ado);
1918    if (  !curColPlane ||
1919          !curColPlane->OptScl )  {
1920       SUMA_S_Warn("NULL input 2"); SUMA_RETURNe;
1921    }
1922 
1923    curColPlane->OptScl->MaskZero =
1924       !curColPlane->OptScl->MaskZero;
1925 
1926    /* seems the '!' were remnants -                                 */
1927    /* revert to original logic, but avoid warnings
1928     * (to later evaluate changes) todo: apply ShowMode
1929     *   original     : if (!curColPlane->ShowMode < 0)
1930     *   fix??        : if (curColPlane->ShowMode < 0)
1931     *   temp.as.orig : if ( 0 )
1932     *
1933     *   comments     : orig/temp would never show
1934     *                : we probably want to RETURN if not showing ( < 0 )
1935     *                : so '!' was just a remnant typo
1936     *                : might be unclear when == 0
1937     *                                           19 Feb 2021 [rickr] */
1938    if ( 0 ) {
1939       /* nothing else to do */
1940       SUMA_RETURNe;
1941    }
1942 
1943    SUMA_ADO_Flush_Pick_Buffer(ado, NULL);
1944 
1945    if (!SUMA_ColorizePlane (curColPlane)) {
1946          SUMA_SLP_Err("Failed to colorize plane.\n");
1947          SUMA_RETURNe;
1948    }
1949 
1950    SUMA_Remixedisplay(ado);
1951 
1952    SUMA_UpdateNodeLblField(ado);
1953 
1954    SUMA_RETURNe;
1955 }
1956 
1957 
SUMA_cb_SymIrange_tb_toggled(Widget w,XtPointer data,XtPointer client_data)1958 void SUMA_cb_SymIrange_tb_toggled (Widget w, XtPointer data,
1959                                    XtPointer client_data)
1960 {
1961    static char FuncName[]={"SUMA_cb_SymIrange_tb_toggled"};
1962    SUMA_ALL_DO *ado = NULL;
1963    SUMA_X_SurfCont *SurfCont=NULL;
1964    SUMA_OVERLAYS *curColPlane=NULL;
1965    SUMA_TABLE_FIELD *TF=NULL;
1966    SUMA_Boolean LocalHead = NOPE;
1967 
1968    SUMA_ENTRY;
1969 
1970    SUMA_LH("Called");
1971 
1972    ado = (SUMA_ALL_DO *)data;
1973 
1974    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
1975       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
1976    curColPlane = SUMA_ADO_CurColPlane(ado);
1977    if ( !curColPlane )  {
1978       SUMA_S_Warn("NULL input 2"); SUMA_RETURNe;
1979    }
1980 
1981    curColPlane->SymIrange = !curColPlane->SymIrange;
1982 
1983    if (curColPlane->SymIrange) {
1984       /* manual setting of range.
1985          DO NOT Call SUMA_InitRangeTable because it will
1986          automatically update the I range under certain conditions*/
1987       TF = SurfCont->SetRangeTable;
1988       curColPlane->OptScl->IntRange[1] =
1989          SUMA_LARG_ABS(curColPlane->OptScl->IntRange[0],
1990          curColPlane->OptScl->IntRange[1]);
1991       curColPlane->OptScl->IntRange[0] =
1992          -curColPlane->OptScl->IntRange[1];
1993       SUMA_INSERT_CELL_VALUE(TF, 1, 1,
1994                   curColPlane->OptScl->IntRange[0]);
1995       SUMA_INSERT_CELL_VALUE(TF, 1, 2,
1996                   curColPlane->OptScl->IntRange[1]);
1997    }
1998 
1999    /* seems the '!' were remnants -                                 */
2000    /* revert to original logic, but avoid warnings
2001     * (to later evaluate changes) todo: apply ShowMode
2002     *   original     : if (!curColPlane->ShowMode < 0)
2003     *   fix??        : if (curColPlane->ShowMode < 0)
2004     *   temp.as.orig : if ( 0 )
2005     *
2006     *   comments     : orig/temp would never RETURN
2007     *                : seems we should return if < 0
2008     *                                           19 Feb 2021 [rickr] */
2009    if ( 0 ) { SUMA_RETURNe; }
2010 
2011    if (!SUMA_ColorizePlane (curColPlane)) {
2012          SUMA_SLP_Err("Failed to colorize plane.\n");
2013          SUMA_RETURNe;
2014    }
2015 
2016    SUMA_Remixedisplay(ado);
2017 
2018    SUMA_UpdateNodeValField(ado);
2019    SUMA_UpdateNodeLblField(ado);
2020 
2021 
2022    SUMA_RETURNe;
2023 }
2024 
SUMA_cb_AbsThresh_tb_toggled(Widget w,XtPointer data,XtPointer client_data)2025 void SUMA_cb_AbsThresh_tb_toggled (Widget w, XtPointer data,
2026                                    XtPointer client_data)
2027 {
2028    static char FuncName[]={"SUMA_cb_AbsThresh_tb_toggled"};
2029    SUMA_ALL_DO *ado = NULL;
2030    SUMA_X_SurfCont *SurfCont=NULL;
2031    SUMA_OVERLAYS *curColPlane=NULL;
2032    char slabel[100];
2033    double range[2]; int loc[2];
2034    SUMA_Boolean LocalHead = NOPE;
2035 
2036    SUMA_ENTRY;
2037 
2038    SUMA_LH("Called");
2039 
2040    ado = (SUMA_ALL_DO *)data;
2041 
2042    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
2043       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
2044    curColPlane = SUMA_ADO_CurColPlane(ado);
2045    if ( !curColPlane )  {
2046       SUMA_S_Warn("NULL input 2"); SUMA_RETURNe;
2047    }
2048 
2049    if (curColPlane->OptScl->ThrMode == SUMA_LESS_THAN) {
2050       curColPlane->OptScl->ThrMode = SUMA_ABS_LESS_THAN;
2051    } else if (curColPlane->OptScl->ThrMode == SUMA_ABS_LESS_THAN){
2052       curColPlane->OptScl->ThrMode = SUMA_LESS_THAN;
2053    } else if (curColPlane->OptScl->ThrMode == SUMA_THRESH_OUTSIDE_RANGE){
2054       curColPlane->OptScl->ThrMode = SUMA_THRESH_INSIDE_RANGE;
2055    } else if (curColPlane->OptScl->ThrMode == SUMA_THRESH_INSIDE_RANGE){
2056       curColPlane->OptScl->ThrMode = SUMA_THRESH_OUTSIDE_RANGE;
2057    } else {
2058       SUMA_S_Err("Not ready for this situation %d...",
2059                  curColPlane->OptScl->ThrMode);
2060    }
2061    switch (curColPlane->OptScl->ThrMode) {
2062       case SUMA_LESS_THAN:
2063          sprintf(slabel, "%5s",
2064             MV_format_fval(curColPlane->OptScl->ThreshRange[0]));
2065          break;
2066       case SUMA_ABS_LESS_THAN:
2067          /* used to use this:
2068          sprintf(slabel, "|%5s|", ....
2069          but that does not work in the editable field ... */
2070          sprintf(slabel, "%5s",
2071                MV_format_fval(fabs(curColPlane->OptScl->ThreshRange[0])));
2072          break;
2073       case SUMA_THRESH_INSIDE_RANGE:
2074          /* This is just a place holder for now */
2075          sprintf(slabel, "<%5s..%5s>",
2076                        MV_format_fval(curColPlane->OptScl->ThreshRange[0]),
2077                        MV_format_fval(curColPlane->OptScl->ThreshRange[1]));
2078          break;
2079       case SUMA_THRESH_OUTSIDE_RANGE:
2080          /* This is just a place holder for now */
2081          sprintf(slabel, ">%5s..%5s<",
2082                        MV_format_fval(curColPlane->OptScl->ThreshRange[0]),
2083                        MV_format_fval(curColPlane->OptScl->ThreshRange[1]));
2084          break;
2085       case SUMA_NO_THRESH:
2086          break;
2087       default:
2088          /* This is just a place holder for now */
2089          sprintf(slabel, "?%5s??%5s?<",
2090                        MV_format_fval(curColPlane->OptScl->ThreshRange[0]),
2091                        MV_format_fval(curColPlane->OptScl->ThreshRange[1]));
2092          break;
2093    }
2094 
2095    /* SUMA_SET_LABEL(SurfCont->thr_lb,  slabel); */
2096    SUMA_INSERT_CELL_STRING(SurfCont->SetThrScaleTable, 0,0,slabel);
2097    if (SUMA_GetDsetColRange(curColPlane->dset_link,
2098                      curColPlane->OptScl->tind, range, loc)) {
2099       SUMA_SetScaleRange(ado, range );
2100    }else {
2101       SUMA_SLP_Err("Failed to get range");
2102       SUMA_RETURNe;
2103    }
2104 
2105    if (!curColPlane->OptScl->UseThr) { SUMA_RETURNe; }
2106                                                 /* nothing else to do */
2107 
2108    SUMA_ADO_Flush_Pick_Buffer(ado, NULL);
2109 
2110    if (!SUMA_ColorizePlane (curColPlane)) {
2111          SUMA_SLP_Err("Failed to colorize plane.\n");
2112          SUMA_RETURNe;
2113    }
2114 
2115    SUMA_Remixedisplay(ado);
2116 
2117    SUMA_UpdateNodeLblField(ado);
2118 
2119    SUMA_RETURNe;
2120 }
2121 
SUMA_cb_SwitchInt_toggled(Widget w,XtPointer data,XtPointer client_data)2122 void SUMA_cb_SwitchInt_toggled (Widget w, XtPointer data, XtPointer client_data)
2123 {
2124    static char FuncName[]={"SUMA_cb_SwitchInt_toggled"};
2125    SUMA_ALL_DO *ado = NULL;
2126    SUMA_X_SurfCont *SurfCont=NULL;
2127    SUMA_OVERLAYS *curColPlane=NULL;
2128    SUMA_Boolean LocalHead = NOPE;
2129 
2130    SUMA_ENTRY;
2131 
2132    SUMA_LH("Called");
2133 
2134    ado = (SUMA_ALL_DO *)data;
2135 
2136    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
2137       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
2138    curColPlane = SUMA_ADO_CurColPlane(ado);
2139    if ( !curColPlane )  {
2140       SUMA_S_Warn("NULL input 2"); SUMA_RETURNe;
2141    }
2142 
2143    /* make sure ok to turn on */
2144    if (curColPlane->OptScl->find < 0) {
2145       SUMA_BEEP;
2146       SUMA_SLP_Note("no intensity column set");
2147       XmToggleButtonSetState (SurfCont->Int_tb, NOPE, NOPE);
2148       SUMA_RETURNe;
2149    }
2150 
2151    /* this button's the same as the Show button */
2152    if (XmToggleButtonGetState (SurfCont->Int_tb)) {
2153       curColPlane->ShowMode =
2154          SUMA_ABS(curColPlane->ShowMode);
2155    } else {
2156       curColPlane->ShowMode =
2157          -SUMA_ABS(curColPlane->ShowMode);
2158    }
2159    if (SurfCont->DsetViewModeMenu) {
2160       SUMA_Set_Menu_Widget(SurfCont->DsetViewModeMenu,
2161                            SUMA_ShowMode2ShowModeMenuItem(
2162                                                 curColPlane->ShowMode));
2163    }
2164 
2165    SUMA_ColorizePlane(curColPlane);
2166    SUMA_Remixedisplay(ado);
2167    SUMA_UpdateNodeLblField(ado);
2168 
2169    #if SUMA_SEPARATE_SURF_CONTROLLERS
2170       SUMA_UpdateColPlaneShellAsNeeded(ado);
2171    #endif
2172    SUMA_RETURNe;
2173 }
2174 
SUMA_cb_SwitchThr_toggled(Widget w,XtPointer data,XtPointer client_data)2175 void SUMA_cb_SwitchThr_toggled (Widget w, XtPointer data, XtPointer client_data)
2176 {
2177    static char FuncName[]={"SUMA_cb_SwitchThr_toggled"};
2178    SUMA_ALL_DO *ado = NULL;
2179    SUMA_X_SurfCont *SurfCont=NULL;
2180    SUMA_OVERLAYS *curColPlane=NULL;
2181    SUMA_Boolean LocalHead = NOPE;
2182 
2183    SUMA_ENTRY;
2184 
2185    SUMA_LH("Called");
2186 
2187    ado = (SUMA_ALL_DO *)data;
2188 
2189    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
2190       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
2191    curColPlane = SUMA_ADO_CurColPlane(ado);
2192    if ( !curColPlane )  {
2193       SUMA_S_Warn("NULL input 2"); SUMA_RETURNe;
2194    }
2195 
2196 
2197    /* make sure ok to turn on */
2198    if (curColPlane->OptScl->tind < 0) {
2199       SUMA_BEEP;
2200       SUMA_SLP_Note("no threshold column set");
2201       XmToggleButtonSetState (SurfCont->Thr_tb, NOPE, NOPE);
2202       SUMA_RETURNe;
2203    }
2204 
2205    curColPlane->OptScl->UseThr =
2206          XmToggleButtonGetState (SurfCont->Thr_tb);
2207 
2208    SUMA_ColorizePlane(curColPlane);
2209    SUMA_Remixedisplay(ado);
2210 
2211    SUMA_UpdateNodeLblField(ado);
2212 
2213    #if SUMA_SEPARATE_SURF_CONTROLLERS
2214       SUMA_UpdateColPlaneShellAsNeeded(ado);
2215    #endif
2216    SUMA_RETURNe;
2217 }
2218 
SUMA_cb_SwitchBrt_toggled(Widget w,XtPointer data,XtPointer client_data)2219 void SUMA_cb_SwitchBrt_toggled (Widget w, XtPointer data, XtPointer client_data)
2220 {
2221    static char FuncName[]={"SUMA_cb_SwitchBrt_toggled"};
2222    SUMA_ALL_DO *ado = NULL;
2223    SUMA_X_SurfCont *SurfCont=NULL;
2224    SUMA_OVERLAYS *curColPlane=NULL;
2225    SUMA_Boolean LocalHead = NOPE;
2226 
2227    SUMA_ENTRY;
2228 
2229    SUMA_LH("Called");
2230 
2231    ado = (SUMA_ALL_DO *)data;
2232 
2233    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
2234       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
2235    curColPlane = SUMA_ADO_CurColPlane(ado);
2236    if ( !curColPlane )  {
2237       SUMA_S_Warn("NULL input 2"); SUMA_RETURNe;
2238    }
2239 
2240    /* make sure ok to turn on */
2241    if (curColPlane->OptScl->bind < 0) {
2242       SUMA_BEEP;
2243       SUMA_SLP_Note("no brightness column set");
2244       XmToggleButtonSetState (SurfCont->Brt_tb, NOPE, NOPE);
2245       SUMA_RETURNe;
2246    }
2247 
2248    curColPlane->OptScl->UseBrt =
2249                      XmToggleButtonGetState (SurfCont->Brt_tb);
2250 
2251    SUMA_ColorizePlane(curColPlane);
2252    SUMA_Remixedisplay(ado);
2253    SUMA_UpdateNodeLblField(ado);
2254 
2255    #if SUMA_SEPARATE_SURF_CONTROLLERS
2256       SUMA_UpdateColPlaneShellAsNeeded(ado);
2257    #endif
2258    SUMA_RETURNe;
2259 }
2260 
2261 SUMA_MenuItem CoordBias_Menu[] = {
2262    {  "-", &xmPushButtonWidgetClass,
2263       '\0', NULL, NULL,
2264       SUMA_cb_SetCoordBias, (XtPointer) SW_CoordBias_None, NULL},
2265 
2266    {  "x", &xmPushButtonWidgetClass,
2267       '\0', NULL, NULL,
2268       SUMA_cb_SetCoordBias, (XtPointer) SW_CoordBias_X, NULL},
2269 
2270    {  "y", &xmPushButtonWidgetClass,
2271       '\0', NULL, NULL,
2272       SUMA_cb_SetCoordBias, (XtPointer) SW_CoordBias_Y, NULL},
2273 
2274    {  "z", &xmPushButtonWidgetClass,
2275       '\0', NULL, NULL,
2276       SUMA_cb_SetCoordBias, (XtPointer) SW_CoordBias_Z, NULL},
2277 
2278    {  "n", &xmPushButtonWidgetClass,
2279       '\0', NULL, NULL,
2280       SUMA_cb_SetCoordBias, (XtPointer) SW_CoordBias_N, NULL},
2281 
2282    {NULL},
2283 };
2284 
2285 SUMA_MenuItem CmapMode_Menu[] = {
2286    {  "Dir", &xmPushButtonWidgetClass,
2287       '\0', NULL, NULL,
2288       SUMA_cb_SetCmapMode, (XtPointer) SW_Direct, NULL},
2289 
2290    {  "NN", &xmPushButtonWidgetClass,
2291       '\0', NULL, NULL,
2292       SUMA_cb_SetCmapMode, (XtPointer) SW_NN, NULL},
2293 
2294    {  "Int", &xmPushButtonWidgetClass,
2295       '\0', NULL, NULL,
2296       SUMA_cb_SetCmapMode, (XtPointer) SW_Interp, NULL},
2297 
2298    {NULL},
2299 };
2300 
2301 SUMA_MenuItem LinkMode_Menu[] = {
2302    {  "None", &xmPushButtonWidgetClass,
2303       '\0', NULL, NULL,
2304       SUMA_cb_SetLinkMode, (XtPointer) SW_LinkMode_None, NULL},
2305 
2306    {  "Pls1", &xmPushButtonWidgetClass,
2307       '\0', NULL, NULL,
2308       SUMA_cb_SetLinkMode, (XtPointer) SW_LinkMode_Pls1, NULL},
2309 
2310    {  "Same", &xmPushButtonWidgetClass,
2311       '\0', NULL, NULL,
2312       SUMA_cb_SetLinkMode, (XtPointer) SW_LinkMode_Same, NULL},
2313 
2314    {  "Stat", &xmPushButtonWidgetClass,
2315       '\0', NULL, NULL,
2316       SUMA_cb_SetLinkMode, (XtPointer) SW_LinkMode_Stat, NULL},
2317 
2318    {NULL},
2319 };
2320 
2321 
2322 /*!
2323    \brief sets the colormap interpolation mode
2324    - expects a SUMA_MenuCallBackData * in  client_data
2325    with SO as client_data->ContID and Menubutton in client_data->callback_data
2326 */
SUMA_cb_SetCmapMode(Widget widget,XtPointer client_data,XtPointer call_data)2327 void SUMA_cb_SetCmapMode(Widget widget, XtPointer client_data,
2328                          XtPointer call_data)
2329 {
2330    static char FuncName[]={"SUMA_cb_SetCmapMode"};
2331    SUMA_MenuCallBackData *datap=NULL;
2332    int imenu;
2333    SUMA_ALL_DO *ado=NULL;
2334    SUMA_Boolean LocalHead = NOPE;
2335 
2336    SUMA_ENTRY;
2337 
2338    /* get the surface object that the setting belongs to */
2339    datap = (SUMA_MenuCallBackData *)client_data;
2340    ado = (SUMA_ALL_DO *)datap->ContID;
2341    imenu = (INT_CAST)datap->callback_data;
2342 
2343    SUMA_SetCmapMode(ado, imenu);
2344 
2345    SUMA_RETURNe;
2346 }
2347 
SUMA_SetCmapMode(SUMA_ALL_DO * ado,int imenu)2348 SUMA_Boolean SUMA_SetCmapMode(SUMA_ALL_DO *ado, int imenu)
2349 {
2350    static char FuncName[]={"SUMA_SetCmapMode"};
2351    SUMA_Boolean NewDisp = NOPE;
2352    SUMA_X_SurfCont *SurfCont=NULL;
2353    SUMA_OVERLAYS *curColPlane=NULL;
2354    SUMA_Boolean LocalHead = NOPE;
2355 
2356    SUMA_ENTRY;
2357 
2358    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado)) ||
2359        !(curColPlane = SUMA_ADO_CurColPlane(ado)) ||
2360        imenu < 1) SUMA_RETURN(NOPE);
2361 
2362    /* get the surface object that the setting belongs to */
2363    NewDisp = NOPE;
2364    switch (imenu) {
2365       case SW_Interp:
2366          if (curColPlane->OptScl->interpmode != SUMA_INTERP) {
2367             curColPlane->OptScl->interpmode = SUMA_INTERP;
2368             NewDisp = YUP;
2369          }
2370          break;
2371       case SW_NN:
2372          if (curColPlane->OptScl->interpmode != SUMA_NO_INTERP) {
2373             curColPlane->OptScl->interpmode = SUMA_NO_INTERP;
2374             NewDisp = YUP;
2375          }
2376          break;
2377       case SW_Direct:
2378          if (curColPlane->OptScl->interpmode != SUMA_DIRECT) {
2379             curColPlane->OptScl->interpmode = SUMA_DIRECT;
2380             NewDisp = YUP;
2381          }
2382          break;
2383       default:
2384          fprintf (SUMA_STDERR,
2385                   "Error %s: Unexpected widget index.\n", FuncName);
2386          SUMA_RETURN(NOPE);
2387          break;
2388 
2389    }
2390 
2391    /* redisplay all viewers showing SO*/
2392    if (NewDisp) {
2393       SUMA_ColorizePlane(curColPlane);
2394       SUMA_Remixedisplay(ado);
2395    }
2396 
2397    SUMA_UpdateNodeNodeField(ado);
2398    SUMA_UpdateNodeLblField(ado);
2399 
2400    SUMA_RETURN(YUP);
2401 }
2402 
2403 /*!
2404    \brief sets the linking between I & T mode
2405    - expects a SUMA_MenuCallBackData * in  client_data
2406    with SO as client_data->ContID and Menubutton in client_data->callback_data
2407 */
SUMA_cb_SetLinkMode(Widget widget,XtPointer client_data,XtPointer call_data)2408 void SUMA_cb_SetLinkMode(Widget widget, XtPointer client_data,
2409                          XtPointer call_data)
2410 {
2411    static char FuncName[]={"SUMA_cb_SetLinkMode"};
2412    SUMA_MenuCallBackData *datap=NULL;
2413    int imenu;
2414    SUMA_ALL_DO *ado = NULL;
2415    SUMA_OVERLAYS *curColPlane=NULL;
2416    SUMA_Boolean NewDisp = NOPE;
2417    SUMA_Boolean LocalHead = NOPE;
2418 
2419    SUMA_ENTRY;
2420 
2421    /* get the surface object that the setting belongs to */
2422    datap = (SUMA_MenuCallBackData *)client_data;
2423    ado = (SUMA_ALL_DO *)datap->ContID;
2424    curColPlane = SUMA_ADO_CurColPlane(ado);
2425    imenu = (INT_CAST)datap->callback_data;
2426    NewDisp = NOPE;
2427    switch (imenu) { /* There is really no need for this
2428                         switching block... */
2429       case SW_LinkMode_None:
2430          if (curColPlane->LinkMode != imenu) {
2431              curColPlane->LinkMode = imenu;
2432             NewDisp = YUP;
2433          }
2434          break;
2435       case SW_LinkMode_Pls1:
2436          if (curColPlane->LinkMode != imenu) {
2437              curColPlane->LinkMode = imenu;
2438             NewDisp = YUP;
2439          }
2440          break;
2441       case SW_LinkMode_Same:
2442          if (curColPlane->LinkMode != imenu) {
2443              curColPlane->LinkMode = imenu;
2444             NewDisp = YUP;
2445          }
2446          break;
2447       case SW_LinkMode_Stat:
2448          if (curColPlane->LinkMode != imenu) {
2449              curColPlane->LinkMode = imenu;
2450             NewDisp = YUP;
2451          }
2452          break;
2453       default:
2454          fprintf (SUMA_STDERR, "Error %s: Unexpected widget index %d.\n",
2455                                  FuncName, imenu);
2456          break;
2457    }
2458    SUMA_LHv("LinkMode now %d\n", curColPlane->LinkMode);
2459    /* redisplay all viewers showing SO*/
2460    if (NewDisp) {
2461       SUMA_ColorizePlane(curColPlane);
2462       SUMA_Remixedisplay(ado);
2463    }
2464 
2465    SUMA_UpdateNodeNodeField(ado);
2466    SUMA_UpdateNodeLblField(ado);
2467 
2468    SUMA_RETURNe;
2469 }
2470 
2471 /*!
2472    \brief sets the coordinate bias mode
2473    - expects a SUMA_MenuCallBackData * in  client_data
2474    with SO as client_data->ContID and Menubutton in client_data->callback_data
2475 */
SUMA_cb_SetCoordBias(Widget widget,XtPointer client_data,XtPointer call_data)2476 void SUMA_cb_SetCoordBias(Widget widget, XtPointer client_data,
2477                            XtPointer call_data)
2478 {
2479    static char FuncName[]={"SUMA_cb_SetCoordBias"};
2480    SUMA_MenuCallBackData *datap=NULL;
2481    int imenu;
2482    SUMA_ALL_DO *ado = NULL;
2483    SUMA_OVERLAYS *curColPlane=NULL;
2484    SUMA_X_SurfCont *SurfCont=NULL;
2485    SUMA_Boolean NewDisp = NOPE;
2486    SUMA_VIS_XFORM_DATUM *x0=NULL;
2487    SUMA_Boolean LocalHead = NOPE;
2488 
2489    SUMA_ENTRY;
2490    /* get the surface object that the setting belongs to */
2491    datap = (SUMA_MenuCallBackData *)client_data;
2492    ado = (SUMA_ALL_DO *)datap->ContID;
2493    imenu = (INT_CAST)datap->callback_data;
2494    curColPlane = SUMA_ADO_CurColPlane(ado);
2495    SurfCont = SUMA_ADO_Cont(ado);
2496 
2497    /* if CoordBias is to be added, it should be before Prying */
2498    switch(ado->do_type) {
2499       case SO_type: {
2500          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
2501          x0 = SUMA_Fetch_VisX_Datum ("CoordBias", SO->VisX.Xchain,
2502                                               ADD_BEFORE, "Prying");
2503          break; }
2504       case GDSET_type: {
2505          SUMA_S_Warn("Not sure what to do here");
2506          break; }
2507       case CDOM_type: {
2508          SUMA_S_Warn("Not sure what to do here");
2509          break; }
2510       default:
2511          SUMA_S_Errv("Not ready for type %s\n",
2512             SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
2513          break;
2514    }
2515 
2516    NewDisp = NOPE;
2517    switch (imenu) {
2518       case SW_CoordBias_None:
2519          if (curColPlane->OptScl->DoBias != SW_CoordBias_None) {
2520             if (curColPlane->OptScl->BiasVect) {
2521                SUMA_RemoveCoordBias(curColPlane);
2522             }
2523             NewDisp = YUP;
2524          }
2525          break;
2526       case SW_CoordBias_X:
2527          if (curColPlane->OptScl->DoBias != SW_CoordBias_X) {
2528                /* something needs to be done */
2529                /* bias other than on other dimension exists, transfer it to
2530                   new dimension*/
2531                SUMA_TransferCoordBias(curColPlane, SW_CoordBias_X);
2532             NewDisp = YUP;
2533          }
2534          break;
2535       case SW_CoordBias_Y:
2536          if (curColPlane->OptScl->DoBias != SW_CoordBias_Y) {
2537                /* something needs to be done */
2538                /* bias other than on other dimension exists, transfer it to
2539                new dimension*/
2540                SUMA_TransferCoordBias(curColPlane, SW_CoordBias_Y);
2541             NewDisp = YUP;
2542          }
2543          break;
2544       case SW_CoordBias_Z:
2545          if (curColPlane->OptScl->DoBias != SW_CoordBias_Z) {
2546                /* something needs to be done */
2547                /* bias other than on other dimension exists, transfer it to
2548                   new dimension*/
2549                SUMA_TransferCoordBias(curColPlane, SW_CoordBias_Z);
2550             NewDisp = YUP;
2551          }
2552          break;
2553       case SW_CoordBias_N:
2554          if (curColPlane->OptScl->DoBias != SW_CoordBias_N) {
2555                /* something needs to be done */
2556                /* bias other than on other dimension exists, transfer it to
2557                   new dimension*/
2558                SUMA_TransferCoordBias(curColPlane, SW_CoordBias_N);
2559             NewDisp = YUP;
2560          }
2561          break;
2562       default:
2563          fprintf (SUMA_STDERR, "Error %s: Unexpected widget index.\n", FuncName);
2564          break;
2565    }
2566 
2567    /* redisplay all viewers showing DO*/
2568    if (NewDisp) {
2569       SUMA_ColorizePlane(curColPlane);
2570       SUMA_Remixedisplay(ado);
2571    }
2572 
2573    SUMA_UpdateNodeNodeField(ado);
2574 
2575    #if SUMA_SEPARATE_SURF_CONTROLLERS
2576       SUMA_UpdateColPlaneShellAsNeeded(ado);
2577    #endif
2578    SUMA_RETURNe;
2579 }
2580 
2581 /*!
2582    \brief Function to call a redisplay of all viewers showing SO
2583 */
SUMA_RedisplayAllShowing(char * SO_idcode_str,SUMA_SurfaceViewer * SVv,int N_SVv)2584 SUMA_Boolean SUMA_RedisplayAllShowing(char *SO_idcode_str,
2585                                       SUMA_SurfaceViewer *SVv, int N_SVv)
2586 {
2587    static char FuncName[]={"SUMA_RedisplayAllShowing"};
2588    SUMA_SurfaceViewer *sv;
2589    void *pp=NULL;
2590    SUMA_ALL_DO *ado=NULL;
2591    SUMA_DO_Types tp;
2592    SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
2593    SUMA_DSET *dset=NULL;
2594    int i, k;
2595    DList *list=NULL;
2596    SUMA_Boolean LocalHead = NOPE;
2597 
2598    SUMA_ENTRY;
2599 
2600    if (!SVv) {
2601       SVv = SUMAg_SVv;
2602       N_SVv = SUMAg_N_SVv;
2603    }
2604    if (!SO_idcode_str || !SVv) {
2605       SUMA_S_Err("NULL SVv or SO_idcode_str. BAD");
2606       SUMA_RETURN (NOPE);
2607    }
2608    if (!(pp = SUMA_find_any_object(SO_idcode_str, &tp))) {
2609       SUMA_S_Errv("Failed to find object with idcode %s.\n", SO_idcode_str);
2610       SUMA_RETURN(NOPE);
2611    }
2612    ado = (SUMA_ALL_DO*)pp;
2613    switch (tp) {
2614       case SO_type:
2615          SO1 = (SUMA_SurfaceObject *)pp;
2616          /* search all viewers */
2617          for (i=0; i < N_SVv; ++i) {
2618             SUMA_LHv("Searching viewer %d.\n", i);
2619             sv = &(SVv[i]);
2620             /* search for SO in RegisteredDO */
2621             for (k=0; k < sv->N_DO; ++k) {
2622                if (SUMA_isSO(SUMAg_DOv[sv->RegistDO[k].dov_ind])) {
2623                   SO2 = (SUMA_SurfaceObject *)
2624                                  SUMAg_DOv[sv->RegistDO[k].dov_ind].OP;
2625                   if (SUMA_WhatAreYouToMe(SO1, SO2) == SUMA_SO1_is_SO2) {
2626                      /* Get a redisplay for that puppy */
2627                      if (!list) list = SUMA_CreateList ();
2628                      SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay,
2629                                                   SES_SumaWidget, sv);
2630                   }
2631                }
2632             }
2633          }
2634          break;
2635       case MASK_type:
2636       case GDSET_type:
2637       case CDOM_type:
2638       case VO_type:
2639       case TRACT_type:
2640       case GRAPH_LINK_type:
2641          for (i=0; i < N_SVv; ++i) {
2642             sv = &(SVv[i]);
2643             if (SUMA_ADO_isRegistered(sv, ado)) {
2644                if (!list) list = SUMA_CreateList ();
2645                         SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay,
2646                                                      SES_SumaWidget, sv);
2647             }
2648          }
2649          break;
2650       default:
2651          SUMA_S_Errv("Type %d (%s) is not welcome here\n",
2652                      tp, SUMA_ObjectTypeCode2ObjectTypeName(tp));
2653          SUMA_RETURN(NOPE);
2654    }
2655 
2656    if (!SUMA_Engine(&list)) {
2657       SUMA_SLP_Err("Failed to redisplay.");
2658       SUMA_RETURN(NOPE);
2659    }
2660 
2661    SUMA_RETURN(YUP);
2662 }
2663 
SUMA_AllocTableField(char * wname)2664 SUMA_TABLE_FIELD * SUMA_AllocTableField(char *wname)
2665 {
2666    static char FuncName[]={"SUMA_AllocTableField"};
2667    SUMA_TABLE_FIELD *TF = NULL;
2668 
2669    SUMA_ENTRY;
2670    TF = (SUMA_TABLE_FIELD *)SUMA_calloc(1,sizeof(SUMA_TABLE_FIELD));
2671    if (!TF) {
2672       SUMA_SL_Crit("Failed to allocate");
2673       SUMA_RETURN(TF);
2674    }
2675    TF->Ni = -1;
2676    TF->Nj = -1;
2677    TF->rc = NULL;
2678    TF->cells = NULL;
2679    TF->cwidth = NULL;
2680    TF->editable = NOPE;
2681    TF->type = SUMA_string;
2682    TF->NewValueCallback = NULL;
2683    TF->NewValueCallbackData = NULL;
2684    TF->TitLabelEVHandler = NULL;
2685    TF->TitLabelEVHandlerData = NULL;
2686    TF->CellEVHandler = NULL;
2687    TF->CellEVHandlerData = NULL;
2688    TF->cell_modified = -1;
2689    TF->num_value = NULL;
2690    TF->str_value = NULL;
2691    TF->rowobject_id = NULL;
2692    if (wname) snprintf(TF->wname,63,"%s", wname);
2693    else snprintf(TF->wname,63,"UNNAMED");
2694    SUMA_RETURN(TF);
2695 }
2696 
SUMA_AllocSliceField(char * wname)2697 SUMA_SLICE_FIELD * SUMA_AllocSliceField(char *wname)
2698 {
2699    static char FuncName[]={"SUMA_AllocSliceField"};
2700    SUMA_SLICE_FIELD *SF = NULL;
2701 
2702    SUMA_ENTRY;
2703    SF = (SUMA_SLICE_FIELD *)SUMA_calloc(1,sizeof(SUMA_SLICE_FIELD));
2704    if (!SF) {
2705       SUMA_SL_Crit("Failed to allocate");
2706       SUMA_RETURN(SF);
2707    }
2708    SF->Nslc = -1;
2709    SF->sl = NULL;
2710    SF->tb = NULL;
2711    SF->text = NULL;
2712    SF->mont = NULL;
2713    SF->NewValueCallback = NULL;
2714    SF->NewValueCallbackData = NULL;
2715    SF->slice_num_str = NULL;
2716    SF->mont_str = NULL;
2717    SF->slice_units = SUMA_NO_NUM_UNITS;
2718    SF->mont_units = SUMA_NO_NUM_UNITS;
2719    SF->slice_num = 0;
2720    SF->mont_num = 1;
2721    SF->mont_inc = 10;
2722    SF->variant = NULL;
2723    if (wname) snprintf(SF->wname,63,"%s", wname);
2724    else snprintf(SF->wname,63,"UNNAMED");
2725    SUMA_RETURN(SF);
2726 }
2727 
SUMA_FreeSliceField(SUMA_SLICE_FIELD * SF)2728 SUMA_SLICE_FIELD * SUMA_FreeSliceField(SUMA_SLICE_FIELD *SF)
2729 {
2730    static char FuncName[]={"SUMA_FreeSliceField"};
2731    int i;
2732 
2733    SUMA_ENTRY;
2734 
2735    if (!SF) SUMA_RETURN(NULL);
2736 
2737    if (SF->slice_num_str) SUMA_free(SF->slice_num_str);
2738    if (SF->mont_str) SUMA_free(SF->mont_str);
2739    if (SF->variant) SUMA_free(SF->variant);
2740    SUMA_free(SF);
2741 
2742    SUMA_RETURN(NULL);
2743 
2744 }
2745 
SUMA_AllocVRField(char * wname)2746 SUMA_VR_FIELD * SUMA_AllocVRField(char *wname)
2747 {
2748    static char FuncName[]={"SUMA_AllocVRField"};
2749    SUMA_VR_FIELD *VrF = NULL;
2750 
2751    SUMA_ENTRY;
2752 
2753    VrF = (SUMA_VR_FIELD *)SUMA_calloc(1,sizeof(SUMA_VR_FIELD));
2754    if (!VrF) {
2755       SUMA_SL_Crit("Failed to allocate");
2756       SUMA_RETURN(VrF);
2757    }
2758    VrF->Nslc = -1;
2759    VrF->tb = NULL;
2760    VrF->text = NULL;
2761    VrF->NewValueCallback = NULL;
2762    VrF->NewValueCallbackData = NULL;
2763    VrF->N_slice_num_str = NULL;
2764    VrF->N_slice_units = SUMA_NO_NUM_UNITS;
2765    VrF->N_slice_num = -1;
2766    if (wname) snprintf(VrF->wname,63,"%s", wname);
2767    else snprintf(VrF->wname,63,"UNNAMED");
2768    SUMA_RETURN(VrF);
2769 }
2770 
SUMA_FreeVRField(SUMA_VR_FIELD * VrF)2771 SUMA_VR_FIELD * SUMA_FreeVRField(SUMA_VR_FIELD *VrF)
2772 {
2773    static char FuncName[]={"SUMA_FreeVRField"};
2774    int i;
2775 
2776    SUMA_ENTRY;
2777 
2778    if (!VrF) SUMA_RETURN(NULL);
2779 
2780    if (VrF->N_slice_num_str) SUMA_free(VrF->N_slice_num_str);
2781    SUMA_free(VrF);
2782 
2783    SUMA_RETURN(NULL);
2784 
2785 }
2786 
2787 /*!
2788    Called when user clicks on range table cell
2789    Expect SO in cd
2790 */
SUMA_RangeTableCell_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)2791 void SUMA_RangeTableCell_EV ( Widget w , XtPointer cd ,
2792                       XEvent *ev , Boolean *continue_to_dispatch )
2793 {
2794    static char FuncName[]={"SUMA_RangeTableCell_EV"};
2795    SUMA_ALL_DO *ado = (SUMA_ALL_DO *)cd, *curDO=NULL;
2796    SUMA_X_SurfCont *SurfCont=NULL;
2797    SUMA_OVERLAYS *curColPlane=NULL;
2798    XButtonEvent * bev = (XButtonEvent *) ev ;
2799    int  i, j, n, Found;
2800    void *cv=NULL;
2801    SUMA_TABLE_FIELD *TF = NULL;
2802    SUMA_Boolean LocalHead = NOPE;
2803 
2804    SUMA_ENTRY;
2805 
2806    SUMA_LH("Called");
2807 
2808 
2809    SurfCont = SUMA_ADO_Cont(ado);
2810    curColPlane = SUMA_ADO_CurColPlane(ado);
2811    curDO = SUMA_Cont_ADO(SurfCont);
2812    TF = SurfCont->RangeTable;
2813 
2814    /* see note in bbox.c optmenu_EV for the condition below*/
2815    if( bev->button == Button2 ) {
2816      XUngrabPointer( bev->display , CurrentTime ) ;
2817      SUMA_RETURNe ;
2818    }
2819 
2820    if( w == NULL || TF == NULL || ado == NULL ) { SUMA_RETURNe ; }
2821 
2822    switch (bev->button) {
2823       case Button1:
2824          SUMA_LH("Button 1");
2825          break;
2826       case Button2:
2827          SUMA_LH("Button 2");
2828          break;
2829       case Button3:
2830          SUMA_LH("Button 3");
2831          break;
2832       default:
2833          SUMA_RETURNe;
2834    }
2835 
2836    /* which cell is calling? */
2837    n = 0;
2838    Found = -1;
2839    while (n<TF->Nj*TF->Ni && Found == -1) {
2840       if (TF->cells[n] == w) {
2841          Found = n;
2842       } else ++n;
2843    }
2844 
2845    if (Found <0) {
2846       SUMA_SL_Err("Widget not found ????");
2847       SUMA_RETURNe;
2848    }
2849 
2850    /* find out widget's place in table*/
2851    i = Found % TF->Ni; j = Found / TF->Ni ;
2852    n = Found;
2853 
2854    switch (j) {
2855       case 0:
2856       case 1:
2857       case 3:
2858          break;
2859       case 2:
2860       case 4:
2861          SUMA_LH("Call to jump to a node");
2862          XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
2863          if (LocalHead) {
2864             fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s, node = %d\n",
2865                   FuncName, i, j, (char *)cv, atoi((char *)cv));
2866          }
2867 
2868          /* look for a viewer that is showing this surface
2869             and has this surface in focus*/
2870          for (i=0; i<SUMAg_N_SVv; ++i) {
2871             SUMA_LHv("Checking viewer %d.\n", i);
2872             if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
2873                /* is this viewer showing curDO ? */
2874                if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
2875                                     curDO)) {
2876                   if (SUMA_SV_Focus_ADO(&(SUMAg_SVv[i])) == curDO) {
2877                         SUMA_JumpIndex((char *)cv, (void *)(&(SUMAg_SVv[i])));
2878                   } else {
2879                      SUMA_LHv("Seeking DO, %p, %s\n",
2880                               curDO,
2881                               SUMA_CHECK_NULL_STR(SUMA_ADO_idcode(curDO)));
2882                      SUMAg_SVv[i].Focus_DO_ID =
2883                         SUMA_whichDO(SUMA_ADO_idcode(curDO),
2884                                      SUMAg_DOv, SUMAg_N_DOv );
2885                      if (SUMA_isADO_Cont_Realized(curDO)) {
2886                         SUMA_Init_SurfCont_SurfParam(curDO);
2887                      } else {
2888                         SUMA_S_Err("How did this happen?");
2889                      }
2890                      SUMA_JumpIndex((char *)cv, (void *)(&(SUMAg_SVv[i])));
2891                      SUMA_UpdateViewerTitle(SUMAg_SVv+i);
2892                   }
2893                }
2894             }
2895          }
2896 
2897          break;
2898       default:
2899          SUMA_SL_Err("Did not know you had so many");
2900          break;
2901    }
2902 
2903    SUMA_RETURNe;
2904 }
2905 
2906 /*!
2907    Called when user clicks on table title
2908    Expects SUMA_SRV_DATA in TF->NewValueCallbackData
2909 */
SUMA_SetRangeTableTit_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)2910 void SUMA_SetRangeTableTit_EV ( Widget w , XtPointer cd ,
2911                       XEvent *ev , Boolean *continue_to_dispatch )
2912 {
2913    static char FuncName[]={"SUMA_SetRangeTableTit_EV"};
2914    Dimension lw ;
2915    Widget * children , wl = NULL;
2916    XButtonEvent * bev = (XButtonEvent *) ev ;
2917    int  num_children , i, j, Found, AutoHist;
2918    SUMA_TABLE_FIELD *TF = (SUMA_TABLE_FIELD *)cd;
2919    SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)TF->NewValueCallbackData;
2920    SUMA_ALL_DO *ado = srvd->ado;
2921    SUMA_X_SurfCont *SurfCont=NULL;
2922    SUMA_OVERLAYS *curColPlane=NULL;
2923    SUMA_Boolean LocalHead = NOPE;
2924 
2925    SUMA_ENTRY;
2926 
2927    SUMA_LH("Called");
2928 
2929    /* see note in bbox.c optmenu_EV for the condition below*/
2930    if( bev->button == Button2 ){
2931      XUngrabPointer( bev->display , CurrentTime ) ;
2932      SUMA_RETURNe ;
2933    }
2934 
2935    if( w == NULL || TF == NULL ) SUMA_RETURNe ;
2936 
2937    switch (bev->button) {
2938       case Button1:
2939          SUMA_LH("Button 1");
2940          break;
2941       case Button2:
2942          SUMA_LH("Button 2");
2943          break;
2944       case Button3:
2945          SUMA_LH("Button 3");
2946          break;
2947       default:
2948          SUMA_RETURNe;
2949    }
2950 
2951    /* which column title (i == 0) widget is calling ? */
2952    /* check the first column */
2953    i = 0; j = 0;
2954    Found = 0;
2955    while (j<TF->Nj && !Found) {
2956       if (TF->cells[j*TF->Ni+i] == w) {
2957          Found = 1;
2958       } else ++j;
2959    }
2960 
2961    if (!Found) { /* maybe it is a row title */
2962       i = 0; j = 0;
2963       Found = 0;
2964       while (i<TF->Ni && !Found) {
2965          if (TF->cells[j*TF->Ni+i] == w) {
2966             Found = 1;
2967          } else ++i;
2968       }
2969    }
2970 
2971    if (Found >= 0) {
2972       SUMA_LHv("Click on cell [%d %d]\n", i, j);
2973    } else {
2974       SUMA_SL_Err("CEll not found!");
2975       SUMA_RETURNe;
2976    }
2977 
2978    SurfCont = SUMA_ADO_Cont(ado);
2979    curColPlane = SUMA_ADO_CurColPlane(ado);
2980 
2981    if (!ado || !SurfCont || !curColPlane) {
2982       SUMA_SL_Err("No curColPlane!");
2983       SUMA_RETURNe;
2984    }
2985 
2986    /* Now do something */
2987    if (j == 0) { /* clicked on one of the row's titles */
2988       switch (i) {
2989          case 1:
2990             if (bev->button == Button1) { /* toggle lock */
2991                curColPlane->OptScl->AutoIntRange =
2992                            !curColPlane->OptScl->AutoIntRange;
2993                SurfCont->IntRangeLocked = !SurfCont->IntRangeLocked;
2994                MCW_invert_widget(w);
2995             }else if (bev->button == Button3) { /* reset to autorange values */
2996                AutoHist = curColPlane->OptScl->AutoIntRange;
2997                curColPlane->OptScl->AutoIntRange = 1;
2998                SUMA_InitRangeTable(ado, 0); /* overkill but little overhead */
2999                SUMA_ColorizePlane(curColPlane);
3000                SUMA_Remixedisplay(ado);
3001                curColPlane->OptScl->AutoIntRange = AutoHist;
3002             }
3003             break;
3004          case 2:
3005             if (bev->button == Button1) { /* toggle lock */
3006                curColPlane->OptScl->AutoBrtRange =
3007                            !curColPlane->OptScl->AutoBrtRange;
3008                SurfCont->BrtRangeLocked = !SurfCont->BrtRangeLocked;
3009                MCW_invert_widget(w);
3010             }else if (bev->button == Button3) { /* reset to autorange values */
3011                AutoHist = curColPlane->OptScl->AutoBrtRange;
3012                curColPlane->OptScl->AutoBrtRange = 1;
3013                SUMA_InitRangeTable(ado, 1); /* overkill but little overhead */
3014                SUMA_ColorizePlane(curColPlane);
3015                SUMA_Remixedisplay(ado);
3016                curColPlane->OptScl->AutoBrtRange = AutoHist;
3017             }
3018             break;
3019          case 3:
3020             break;
3021          default:
3022             break;
3023       }
3024    }
3025    if (i == 0) { /* clicked on one of the column's titles */
3026       switch (j) {
3027          case 1:
3028             break;
3029          case 2:
3030             break;
3031          case 3:
3032             break;
3033          default:
3034             break;
3035       }
3036    }
3037 
3038    /* update the Xhair Info block */
3039    if (curColPlane->OptScl->DoBias != SW_CoordBias_None) {
3040       SUMA_UpdateNodeNodeField(ado);
3041    }
3042    SUMA_UpdateNodeLblField(ado);
3043 
3044    SUMA_RETURNe;
3045 
3046 }
3047 
SUMA_SetClustTableTit_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int i,int j,int Button)3048 SUMA_Boolean SUMA_SetClustTableTit_one (SUMA_ALL_DO *ado,
3049                         SUMA_OVERLAYS *colp, int i, int j, int Button)
3050 {
3051    static char FuncName[]={"SUMA_SetClustTableTit_one"};
3052    SUMA_TABLE_FIELD *TF = NULL;
3053    SUMA_X_SurfCont *SurfCont=NULL;
3054    SUMA_OVERLAYS *curColPlane=NULL;
3055    SUMA_Boolean LocalHead = NOPE;
3056 
3057    SUMA_ENTRY;
3058 
3059    SUMA_LH("Called");
3060 
3061    if (!ado) SUMA_RETURN(0);
3062 
3063    SurfCont = SUMA_ADO_Cont(ado);
3064    curColPlane = SUMA_ADO_CurColPlane(ado);
3065 
3066    if (colp && colp != curColPlane) SUMA_RETURN(0);
3067    colp = curColPlane;
3068    if (!colp) SUMA_RETURN(0);
3069    if (!(TF = SurfCont->SetClustTable)) SUMA_RETURN(0);
3070 
3071    /* Now do something */
3072    if (j == 0) { /* clicked on one of the row's titles */
3073       switch (i) {
3074          case 1:
3075             if (Button == Button1) { /* toggle lock */
3076                TF->but_flag[j*TF->Ni+i] = !TF->but_flag[j*TF->Ni+i];
3077                MCW_invert_widget(TF->cells[j*TF->Ni+i]);
3078                colp->OptScl->Clusterize = TF->but_flag[j*TF->Ni+i];
3079                colp->OptScl->RecomputeClust = YUP;
3080                SUMA_ColorizePlane(colp);
3081                SUMA_Remixedisplay((SUMA_ALL_DO*)ado);
3082             }else if (Button == Button3) { /* nothing to do */
3083 
3084             }
3085             break;
3086          default:
3087             break;
3088       }
3089    }
3090    if (i == 0) { /* clicked on one of the column's titles */
3091       switch (j) {
3092          case 1:
3093             break;
3094          case 2:
3095             break;
3096          case 3:
3097             break;
3098          default:
3099             break;
3100       }
3101    }
3102 
3103    /* update the Xhair Info block */
3104    SUMA_UpdateNodeLblField(ado);
3105 
3106    SUMA_RETURN(YUP);
3107 }
3108 
3109 /* Set the button flag for a table cell (usually for titles only),
3110 based on flag. Inverts widget if need be. */
SUMA_SetTableTitleButton1(SUMA_TABLE_FIELD * TF,int i,int j,byte flag)3111 SUMA_Boolean SUMA_SetTableTitleButton1(SUMA_TABLE_FIELD *TF, int i, int j,
3112                                        byte flag)
3113 {
3114    static char FuncName[]={"SUMA_SetTableTitleButton1"};
3115 
3116    SUMA_ENTRY;
3117 
3118    if (!TF) SUMA_RETURN(NOPE);
3119 
3120    if (flag == TF->but_flag[j*TF->Ni+i]) {
3121       /* Nothing to do, return*/
3122    } else {
3123       TF->but_flag[j*TF->Ni+i] = !TF->but_flag[j*TF->Ni+i];
3124                MCW_invert_widget(TF->cells[j*TF->Ni+i]);
3125    }
3126 
3127    SUMA_RETURN(YUP);
3128 }
3129 
SUMA_SetClustTableTit(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int i,int j,int Button)3130 SUMA_Boolean SUMA_SetClustTableTit (SUMA_ALL_DO *ado,
3131                         SUMA_OVERLAYS *colp, int i, int j, int Button)
3132 {
3133    static char FuncName[]={"SUMA_SetClustTableTit"};
3134    SUMA_X_SurfCont *SurfCont=NULL;
3135    SUMA_OVERLAYS *curColPlane=NULL;
3136 
3137    SUMA_Boolean LocalHead = NOPE;
3138 
3139    SUMA_ENTRY;
3140 
3141    SUMA_LH("Called");
3142 
3143    if (!ado) SUMA_RETURN(0);
3144    SurfCont = SUMA_ADO_Cont(ado);
3145    curColPlane = SUMA_ADO_CurColPlane(ado);
3146 
3147    if (colp && colp != curColPlane) SUMA_RETURN(0);
3148    colp = curColPlane;
3149    if (!colp) SUMA_RETURN(0);
3150 
3151    if (!SUMA_SetClustTableTit_one (ado, colp, i, j, Button)) SUMA_RETURN(0);
3152 
3153    if (ado->do_type == SO_type) {
3154       SUMA_SurfaceObject *SOC=NULL, *SO = (SUMA_SurfaceObject *)ado;
3155       SUMA_OVERLAYS *colpC=NULL;
3156       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
3157       if (colpC && SOC) {
3158          SUMA_LHv("Found contralateral equivalent to:\n"
3159                       " %s and %s in\n"
3160                       " %s and %s\n",
3161                       SO->Label, CHECK_NULL_STR(colp->Label),
3162                       SOC->Label, CHECK_NULL_STR(colpC->Label));
3163          if (!SUMA_SetClustTableTit_one ((SUMA_ALL_DO *)SOC,
3164                                           colpC, i, j, Button)) SUMA_RETURN(0);
3165       }
3166    }
3167 
3168    SUMA_RETURN(YUP);
3169 }
3170 
3171 /*!
3172    Called when user clicks on table title
3173    Expects SUMA_SRV_DATA in TF->NewValueCallbackData
3174 */
SUMA_SetClustTableTit_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)3175 void SUMA_SetClustTableTit_EV ( Widget w , XtPointer cd ,
3176                       XEvent *ev , Boolean *continue_to_dispatch )
3177 {
3178    static char FuncName[]={"SUMA_SetClustTableTit_EV"};
3179    Dimension lw ;
3180    Widget * children , wl = NULL;
3181    XButtonEvent * bev = (XButtonEvent *) ev ;
3182    int  num_children , i, j, Found;
3183    SUMA_TABLE_FIELD *TF = (SUMA_TABLE_FIELD *)cd;
3184    SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)TF->NewValueCallbackData;
3185    SUMA_ALL_DO *ado = srvd->ado;
3186    SUMA_X_SurfCont *SurfCont=NULL;
3187    SUMA_OVERLAYS *curColPlane=NULL;
3188    SUMA_Boolean LocalHead = NOPE;
3189 
3190    SUMA_ENTRY;
3191 
3192    SUMA_LH("Called");
3193 
3194    SurfCont = SUMA_ADO_Cont(ado);
3195    curColPlane = SUMA_ADO_CurColPlane(ado);
3196 
3197    /* see note in bbox.c optmenu_EV for the condition below*/
3198    if( bev->button == Button2 ){
3199      XUngrabPointer( bev->display , CurrentTime ) ;
3200      SUMA_RETURNe ;
3201    }
3202 
3203    if( w == NULL || TF == NULL ) SUMA_RETURNe ;
3204 
3205    switch (bev->button) {
3206       case Button1:
3207          SUMA_LH("Button 1");
3208          break;
3209       case Button2:
3210          SUMA_LH("Button 2");
3211          break;
3212       case Button3:
3213          SUMA_LH("Button 3");
3214          break;
3215       default:
3216          SUMA_RETURNe;
3217    }
3218 
3219    /* which column title (i == 0) widget is calling ? */
3220    /* check the first column */
3221    i = 0; j = 0;
3222    Found = 0;
3223    while (j<TF->Nj && !Found) {
3224       if (TF->cells[j*TF->Ni+i] == w) {
3225          Found = 1;
3226       } else ++j;
3227    }
3228 
3229    if (!Found) { /* maybe it is a row title */
3230       i = 0; j = 0;
3231       Found = 0;
3232       while (i<TF->Ni && !Found) {
3233          if (TF->cells[j*TF->Ni+i] == w) {
3234             Found = 1;
3235          } else ++i;
3236       }
3237    }
3238 
3239    if (Found >= 0) {
3240       SUMA_LHv("Click on cell [%d %d]\n", i, j);
3241    } else {
3242       SUMA_SL_Err("CEll not found!");
3243       SUMA_RETURNe;
3244    }
3245    if (!curColPlane) {
3246       SUMA_SL_Err("No curColPlane!");
3247       SUMA_RETURNe;
3248    }
3249 
3250 
3251    if (!SUMA_SetClustTableTit(ado, curColPlane, i, j, bev->button)){
3252       SUMA_S_Err("Failed, weird");
3253    }
3254 
3255    SUMA_RETURNe;
3256 
3257 }
3258 
SUMA_SetClustTableCell_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)3259 void SUMA_SetClustTableCell_EV ( Widget w , XtPointer cd ,
3260                       XEvent *ev , Boolean *continue_to_dispatch )
3261 {
3262    static char FuncName[]={"SUMA_SetClustTableCell_EV"};
3263    Dimension lw ;
3264    Widget * children , wl = NULL;
3265    XButtonEvent * bev = (XButtonEvent *) ev ;
3266    int  num_children , i, j, Found, incr=0, an, n;
3267    float reset, newv;
3268    SUMA_TABLE_FIELD *TF = (SUMA_TABLE_FIELD *)cd;
3269    SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)TF->NewValueCallbackData;
3270    SUMA_ALL_DO *ado = srvd->ado;
3271    SUMA_X_SurfCont *SurfCont=NULL;
3272    SUMA_OVERLAYS *curColPlane=NULL;
3273    DList *list = NULL;
3274    SUMA_Boolean LocalHead = NOPE;
3275 
3276    SUMA_ENTRY;
3277 
3278    SUMA_LH("Called Button %d", bev->button);
3279 
3280    SurfCont = SUMA_ADO_Cont(ado);
3281    curColPlane = SUMA_ADO_CurColPlane(ado);
3282 
3283    /* see note in bbox.c optmenu_EV for the condition below*/
3284    if( bev->button == Button2 ){
3285      XUngrabPointer( bev->display , CurrentTime ) ;
3286      SUMA_RETURNe ;
3287    }
3288 
3289    if( w == NULL || TF == NULL ) SUMA_RETURNe ;
3290 
3291    incr = 0;
3292    switch (bev->button) {
3293       case Button1:
3294          SUMA_LH("Button 1");
3295          break;
3296       case Button2:
3297          SUMA_LH("Button 2");
3298          break;
3299       case Button3:
3300          SUMA_LH("Button 3");
3301          break;
3302       case Button4:
3303       case 6:  /* This is shift and wheel on mac, Button6 is not in X.h ! */
3304          SUMA_LH("Button 4/6 %d", bev->button);
3305          incr = -1;
3306          break;
3307       case Button5:
3308       case 7:
3309          SUMA_LH("Button 5/7 %d", bev->button);
3310          incr = 1;
3311          break;
3312       default:
3313          SUMA_RETURNe;
3314    }
3315 
3316    /* which cell is calling? */
3317    n = 0;
3318    Found = -1;
3319    while (n<TF->Nj*TF->Ni && Found == -1) {
3320       if (TF->cells[n] == w) {
3321          Found = n;
3322       } else ++n;
3323    }
3324 
3325    if (Found <0) {
3326       SUMA_SL_Err("Widget not found ????");
3327       SUMA_RETURNe;
3328    }
3329 
3330    /* find out widget's place in table*/
3331    i = Found % TF->Ni; j = Found / TF->Ni ;
3332    n = Found;
3333 
3334    switch (j) {
3335       case 0:
3336          break;
3337       case 1:/* radius */
3338       case 2: /* area */
3339          if (incr) {
3340                  if (TF->num_value[n]>1000) incr = incr*100;
3341             else if (TF->num_value[n]>100) incr = incr*10;
3342             else if (TF->num_value[n]>50) incr = incr*5;
3343             newv = TF->num_value[n]+incr;
3344             SUMA_MODIFY_CELL_VALUE(TF, i, j, newv);
3345             an = SUMA_SetClustValue(ado, curColPlane, i, j,
3346                           TF->num_value[n], 0.0,
3347                           0, 1, &reset);
3348             if (an < 0) {
3349                SUMA_S_Warn("Error checking not handled yet.\n"
3350                            "This upcoming code chunk is from\n"
3351                            "sister function: SUMA_cb_SetRangeValueNew\n");
3352                if (an == -1 || an == -2) {
3353                   SUMA_BEEP;
3354                   TF->num_value[n] = reset;
3355                   SUMA_TableF_SetString(TF);
3356                   if (an == -1) { SUMA_SLP_Err("Doh"); }
3357                   else { SUMA_SLP_Err("Duh"); }
3358                   SUMA_RETURNe;
3359                } else {
3360                   SUMA_S_Err("Erriositation");
3361                   SUMA_RETURNe;
3362                }
3363             }
3364             /* redisplay */
3365             if (!list) list = SUMA_CreateList ();
3366             SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
3367                                                SES_Suma, NULL);
3368             if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
3369          }
3370          break;
3371       default:
3372          SUMA_SL_Err("Did not know you had so many");
3373          break;
3374    }
3375 
3376    SUMA_RETURNe;
3377 }
3378 
SUMA_FreeTableField(SUMA_TABLE_FIELD * TF)3379 SUMA_TABLE_FIELD * SUMA_FreeTableField(SUMA_TABLE_FIELD *TF)
3380 {
3381    static char FuncName[]={"SUMA_FreeTableField"};
3382    int i;
3383 
3384    SUMA_ENTRY;
3385 
3386    if (!TF) SUMA_RETURN(NULL);
3387 
3388    if (TF->cells) SUMA_free(TF->cells);
3389    if (TF->cwidth) SUMA_free(TF->cwidth);
3390    if (TF->num_value) SUMA_free(TF->num_value);
3391    if (TF->but_flag) SUMA_free(TF->but_flag);
3392    if (TF->str_value) {
3393       for (i=0; i<TF->Nj*TF->Ni; ++i)
3394          if (TF->str_value[i]) SUMA_free(TF->str_value[i]);
3395       SUMA_free(TF->str_value);
3396    }
3397    if (TF->rowobject_id) {
3398       for (i=0; i<TF->Ni; ++i)
3399          if (TF->rowobject_id[i]) SUMA_free(TF->rowobject_id[i]);
3400       SUMA_free(TF->rowobject_id);
3401    }
3402    SUMA_free(TF);
3403 
3404    SUMA_RETURN(NULL);
3405 
3406 }
3407 
3408 /*!
3409    \brief sets a cell entry widget to be in Edit or No Edit modes
3410    \param TF
3411    \param i (int) the row index
3412    \param j (int) the col index
3413    \param Mode (int) 0 no edit, 1 yes edit
3414 */
SUMA_SetCellEditMode(SUMA_TABLE_FIELD * TF,int i,int j,int Mode)3415 void  SUMA_SetCellEditMode(SUMA_TABLE_FIELD *TF, int i, int j, int Mode)
3416 {
3417    static char FuncName[]={"SUMA_SetCellEditMode"};
3418    int n;
3419    SUMA_Boolean LocalHead = NOPE;
3420 
3421    SUMA_ENTRY;
3422 
3423    if (!TF) { SUMA_SL_Err("NULL TF"); SUMA_RETURNe; }
3424    n = j * TF->Ni + i;
3425 
3426    /* remove calls anyway */
3427    XtRemoveCallback (TF->cells[n], XmNactivateCallback,
3428                      SUMA_TableF_cb_label_change, (XtPointer)TF);
3429    XtRemoveCallback (TF->cells[n], XmNmodifyVerifyCallback,
3430                      SUMA_TableF_cb_label_Modify, (XtPointer)TF);
3431    /* remove event handlers */
3432    XtRemoveEventHandler( TF->cells[n] ,
3433                          LeaveWindowMask ,
3434                          FALSE ,
3435                          SUMA_leave_TableField,
3436                          (XtPointer) TF);
3437    switch (Mode) {
3438       case 0:
3439          /* non edit */
3440          XtVaSetValues(TF->cells[n],
3441                        XmNeditable, False,
3442                        XmNshadowThickness , 1,          /* hide the border */
3443                        XmNcursorPositionVisible, False, /* hide the cursor */
3444                        NULL);
3445          break;
3446       case 1:
3447          /* si edit */
3448          XtVaSetValues(TF->cells[n],
3449                        XmNeditable, True,
3450                        XmNshadowThickness , 2,
3451                        XmNcursorPositionVisible, True,
3452                        NULL);
3453 
3454          XtAddCallback (TF->cells[n], XmNactivateCallback,
3455                         SUMA_TableF_cb_label_change, (XtPointer)TF);
3456          XtAddCallback (TF->cells[n], XmNmodifyVerifyCallback,
3457                         SUMA_TableF_cb_label_Modify, (XtPointer)TF);
3458          /* add event handler to notify when widget was left */
3459          XtInsertEventHandler( TF->cells[n] ,        /* notify when */
3460                                   LeaveWindowMask ,  /* pointer leaves */
3461                                   FALSE ,            /* this window */
3462                                   SUMA_leave_TableField,
3463                                   (XtPointer) TF ,
3464                                   XtListTail ) ;     /* last in queue */
3465          break;
3466       default:
3467          SUMA_SL_Err("What?");
3468          break;
3469    }
3470    SUMA_RETURNe;
3471 }
3472 
3473 /*
3474 Appends a font of a some name to a fontlist.
3475 You'll almost always want to call the function with the same 1st argument and
3476 the returned variable. The function will free the old one and return a new one.
3477 Read function for more detail.
3478 
3479    fontlist = SUMA_AppendToFontList(fontlist, w, "6x10", NULL);
3480 
3481 Font lesson from http://www-h.eng.cam.ac.uk/help/tpl/graphics/Motif/mt3 :
3482 -------------------------------------------------------------------------
3483 """Begin quote
3484 [How do you find out which font names are valid on your system? Generally,
3485 type the command:
3486 
3487     xlsfonts -fn "*" > out,
3488 
3489 and then look at "out". All the font names will be in the file. Some of
3490 them are short, like "6x10" used above, but some are monsters, as shown
3491 in the fragment of my "out" file copied below:
3492 
3493 -adobe-times-bold-i-normal--24-240-75-75-p-128-iso8859-1
3494 -adobe-times-bold-i-normal--25-180-100-100-p-128-iso8859-1
3495 -adobe-times-bold-i-normal--34-240-100-100-p-170-iso8859-1
3496 
3497 To use one of these fonts, I can say:
3498 
3499     namestring="*times*-25-*";
3500 
3501 in the above code. This will get a 25 point times font. If I want a specific
3502 times font I can be more specific, like "*times*bold*-25-*". The "*" is
3503 a wildcard like it is in a file name.]
3504 """End quote
3505 
3506 */
SUMA_AppendToFontList(XmFontList fontlisti,Widget w,char * fontname,char * tag)3507 XmFontList SUMA_AppendToFontList(XmFontList fontlisti, Widget w,
3508                                  char *fontname, char *tag)
3509 {
3510    static char FuncName[]={"SUMA_AppendToFontList"};
3511    XFontStruct *font = NULL;
3512    XmFontList fontlist = NULL;
3513    XmFontListEntry entry = NULL;
3514 
3515    SUMA_ENTRY;
3516 
3517    if (!tag) tag = XmFONTLIST_DEFAULT_TAG;
3518 
3519    if (!(font = XLoadQueryFont(XtDisplay(w), fontname))) {
3520       SUMA_S_Errv("Failed to get font named %s\n", fontname);
3521       SUMA_RETURN(fontlist);
3522    }
3523    #if 0
3524       /* OBSOLETE, do not use. If you use it, you'll also need to take care
3525       of clean up */
3526    fontlist = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
3527    #else
3528       entry = XmFontListEntryCreate(tag,
3529                                     XmFONT_IS_FONT, font);
3530       /* Do not free font after this call.
3531          Unless all other lists referencing it are feed */
3532       fontlist = XmFontListAppendEntry(fontlisti, entry);
3533          /* fontlisti is taken care of inside XmFontListAppendEntry */
3534       XmFontListEntryFree(&entry); entry = NULL;
3535    #endif
3536 
3537    SUMA_RETURN(fontlist);
3538 }
3539 
3540 /*!
3541    \brief create a table widget
3542    \param parent (Widget)
3543    \param Ni (int) number of entries in column (including title, if any)
3544    \param Nj (int) number of entries in row (including title, if any)
3545    \param col_tit (char **) if not NULL then this should be Nj strings
3546                             to appear as titles above each column
3547    \param row_tit (char **) if not NULL then this should be Ni strings
3548                             to appear as titles before each row
3549    \param cwidth (int *) number of characters to allow for each column. No auto sizing allowed
3550    \param editable (SUMA_Boolean) if YUP then fields are editable by user
3551    \param NewValueCallback(void * data) (void) function called when user changes value
3552    \param cb_data (void *) pointer to data sent back to call back
3553    \param TF (SUMA_TABLE_FIELD *) structure containing table info and the index
3554                                  for the newly modified field.
3555 */
SUMA_CreateTable(Widget parent,int Ni,int Nj,char * iwname,char ** row_tit,char ** col_tit,char ** row_hint,char ** col_hint,char ** row_help,char ** col_help,int * cwidth,SUMA_Boolean editable,SUMA_VARTYPE type,void (* NewValueCallback)(void * data),void * cb_data,void (* TitLabelEVHandler)(Widget w,XtPointer cd,XEvent * ev,Boolean * ctd),void * TitLabelEVHandlerData,void (* CellEVHandler)(Widget w,XtPointer cd,XEvent * ev,Boolean * ctd),void * CellEVHandlerData,SUMA_TABLE_FIELD * TF)3556 void SUMA_CreateTable(  Widget parent,
3557                         int Ni, int Nj,
3558                         char *iwname,
3559                         char **row_tit, char **col_tit,
3560                         char **row_hint, char **col_hint,
3561                         char **row_help, char **col_help,
3562                         int *cwidth, SUMA_Boolean editable, SUMA_VARTYPE type,
3563                         void (*NewValueCallback)(void * data), void *cb_data,
3564                         void (*TitLabelEVHandler)
3565                            (  Widget w , XtPointer cd , XEvent *ev ,
3566                               Boolean *ctd   ),
3567                         void *TitLabelEVHandlerData,
3568                         void (*CellEVHandler)
3569                            (  Widget w , XtPointer cd , XEvent *ev ,
3570                               Boolean *ctd),
3571                         void *CellEVHandlerData,
3572                         SUMA_TABLE_FIELD *TF)
3573 {
3574    static char FuncName[]={"SUMA_CreateTable"};
3575    int i, j, n, titw, xmw, shad;
3576    char *tmp, wname[64]={"NeedToSetMe"};
3577    Widget rcc;
3578    XtPointer cd;
3579    SUMA_Boolean LocalHead = NOPE;
3580 
3581    SUMA_ENTRY;
3582 
3583    if (!parent) { SUMA_SL_Err("NULL parent"); SUMA_RETURNe; }
3584 
3585    /* initialize font list if need be */
3586    if (!SUMAg_CF->X->TableTextFontList) {
3587       if (SUMA_isEnv("SUMA_SurfContFontSize", "BIG")) {
3588          SUMAg_CF->X->TableTextFontList =
3589                SUMA_AppendToFontList( SUMAg_CF->X->TableTextFontList,
3590                                        parent, "*9x15*", NULL);
3591       } else {
3592          SUMAg_CF->X->TableTextFontList =
3593                SUMA_AppendToFontList( SUMAg_CF->X->TableTextFontList,
3594                                        parent, "*8x13*", NULL);
3595       }
3596    }
3597 
3598    if (!TF) { SUMA_SL_Err("NULL TF"); SUMA_RETURNe; }
3599    /* looks like wname is the "useless default"    17 Feb 2021 [rickr] */
3600    if (iwname) { /* override useless default */
3601       snprintf(TF->wname,63,"%s", iwname);
3602    } else {
3603       snprintf(TF->wname,63,"%s", wname);
3604    }
3605    TF->Ni = Ni; TF->Nj = Nj; TF->editable = editable;
3606    TF->cwidth = (int *)SUMA_calloc(TF->Nj, sizeof(int));
3607    TF->rowobject_id = (char **)SUMA_calloc(TF->Ni, sizeof(char *));
3608    for (j=0; j<TF->Nj; ++j) TF->cwidth[j] = cwidth[j];
3609    if(col_tit) TF->HasColTit = YUP; else TF->HasColTit = NOPE;
3610    if(row_tit) TF->HasRowTit = YUP; else TF->HasRowTit = NOPE;
3611    TF->cells = (Widget *)SUMA_calloc(TF->Ni*TF->Nj,sizeof(Widget));
3612    TF->but_flag = (byte *)SUMA_calloc(TF->Ni*TF->Nj,sizeof(byte));
3613    if (!TF->cells) {  SUMA_SL_Crit("Failed to allocate"); SUMA_RETURNe; }
3614    TF->NewValueCallback = NewValueCallback;
3615    TF->NewValueCallbackData = cb_data;
3616    TF->TitLabelEVHandler = TitLabelEVHandler;
3617    TF->TitLabelEVHandlerData = TitLabelEVHandlerData;
3618    TF->CellEVHandler = CellEVHandler;
3619    TF->CellEVHandlerData = CellEVHandlerData;
3620    TF->type = type;
3621    TF->num_units = SUMA_NO_NUM_UNITS;
3622    switch (TF->type) {
3623       case SUMA_int:
3624       case SUMA_float:
3625          TF->num_value= (float *)SUMA_calloc(TF->Nj*TF->Ni, sizeof(float));
3626          break;
3627       case SUMA_string:
3628          TF->str_value= (char **)SUMA_malloc(TF->Nj*TF->Ni * sizeof(char *));
3629          for (i=0; i<TF->Nj*TF->Ni; ++i) TF->str_value[i] = NULL;
3630          break;
3631       default:
3632          SUMA_SL_Err("Comme tu es bete!");
3633          SUMA_RETURNe;
3634          break;
3635    }
3636    /* An outer row column to keep the inner one from resizing with parent
3637    YOU COULD HAVE SET XmNadjustLast to False, instead ....*/
3638    TF->rc = XtVaCreateManagedWidget ("rowcolumn",
3639       xmRowColumnWidgetClass, parent,
3640       XmNorientation , XmHORIZONTAL ,
3641       XmNpacking, XmPACK_TIGHT,
3642       XmNmarginHeight, 0,
3643       XmNmarginWidth, 0,
3644       NULL);
3645 
3646 
3647    /* Le row column to contain the table's columns*/
3648    TF->rco = XtVaCreateManagedWidget ("rowcolumn",
3649       xmRowColumnWidgetClass, TF->rc,
3650       XmNorientation , XmVERTICAL ,
3651       XmNpacking, XmPACK_TIGHT,
3652       XmNnumColumns, 1,
3653       XmNmarginHeight, 0,
3654       XmNmarginWidth, 0,
3655       NULL);
3656 
3657    /* must fill up row by row, each column is a separate bloody rc
3658       to allow for alignments */
3659    for (i=0; i<TF->Ni; ++i) {   /* for each row */
3660       rcc = XtVaCreateManagedWidget ("rowcolumn",
3661          xmRowColumnWidgetClass, TF->rco,
3662          XmNorientation , XmHORIZONTAL ,
3663          XmNmarginHeight, 0,
3664          XmNmarginHeight, 0,
3665          XmNmarginWidth, 0,
3666          NULL);
3667 
3668       if (i == 0 && TF->HasColTit) {
3669          /* This is left here to show that I
3670             tried using different packing methods
3671             to get the title to appear centered with the cell entries below.
3672             That did nothing. Setting packing to tight in all cases and padding
3673             the titles to fit the cell entry widths works fine */
3674          XtVaSetValues (rcc, XmNpacking, XmPACK_TIGHT, NULL);
3675       } else {
3676          XtVaSetValues (rcc, XmNpacking, XmPACK_TIGHT, NULL);
3677       }
3678 
3679       /* Create what would become a table URI in the html help */
3680       snprintf(wname, 63, "%s", TF->wname);
3681       SUMA_Register_Widget_Help(NULL, 2, wname, NULL, NULL);
3682 
3683       for (j=0; j<TF->Nj; ++j) { /* for each column */
3684          n = j * TF->Ni + i;
3685          switch (SUMA_cellvariety(TF, n)) {
3686             case SUMA_ROW_TIT_CELL: /* row's title */
3687                if (LocalHead)
3688                   fprintf( SUMA_STDERR,
3689                            "%s:\nAdding RT [%d %d] (%d) %s\n",
3690                            FuncName, i, j, n, row_tit[i] );
3691                #if 0
3692                   TF->cells[n] = XtVaCreateManagedWidget(row_tit[i],
3693                                                 xmLabelWidgetClass, rcc,
3694                                                 NULL);
3695                #else
3696                   TF->cells[n] =
3697                      XtVaCreateManagedWidget("table",
3698                            xmTextFieldWidgetClass, rcc,
3699                            XmNvalue, row_tit[i],
3700                            XmNmarginHeight, 0,
3701                            XmNmarginWidth, 0,
3702                            XmNmarginTop, 0,
3703                            XmNmarginBottom, 0,
3704                            XmNmarginLeft, 0,
3705                            XmNmarginRight, 0,
3706                            XmNeditable, False,
3707                            XmNshadowThickness , 0,          /* hide the border */
3708                            XmNcursorPositionVisible, False, /* hide the cursor */
3709                            XmNcolumns, strlen(row_tit[i]),
3710                            NULL);
3711                   XtVaSetValues( TF->cells[n],
3712                                  XmNfontList,
3713                                  SUMAg_CF->X->TableTextFontList, NULL);
3714 
3715                #endif
3716                if (!TF->TitLabelEVHandlerData)
3717                   cd = (XtPointer) TF;
3718                else cd = (XtPointer)TF->TitLabelEVHandlerData;
3719                if (TF->TitLabelEVHandler) {
3720                   /* insert handler to catch clicks on titles */
3721                   XtInsertEventHandler(
3722                      TF->cells[n] ,      /* handle events in title cell */
3723                      ButtonPressMask ,  /* button presses */
3724                      FALSE ,            /* nonmaskable events? */
3725                      TF->TitLabelEVHandler,  /* handler */
3726                      cd ,   /* client data */
3727                      XtListTail ) ;
3728                }
3729                if (0 && TF->HasRowTit &&  row_tit[i]) { /* Much better name, but
3730                     Cannot use it before updating
3731                     help generating functions which now call for help on .c00,
3732                     .c01, or .r00 .r01, etc. */
3733                   snprintf(wname, 63, "%s.%s", TF->wname, row_tit[i]);
3734                } else {
3735                   snprintf(wname, 63, "%s.r%02d", TF->wname, i);
3736                }
3737                SUMA_Register_Widget_Help(TF->cells[n], 1, wname,
3738                                          row_hint?row_hint[i]:NULL,
3739                                          row_help?row_help[i]:NULL ) ;
3740                break;
3741 
3742             case SUMA_COL_TIT_CELL: /* column's title */
3743                if (LocalHead)
3744                   fprintf( SUMA_STDERR,
3745                            "%s:\nAdding CT [%d %d] (%d) %s\n",
3746                            FuncName, i, j, n, col_tit[j]);
3747                /* padd to fit cell entry fields*/
3748                if (i == 0 && j != 0 && TF->HasColTit) {
3749                   titw = TF->cwidth[j];
3750                   /* set the margins to meet those of cell entries */
3751                   xmw = 6;
3752                   shad = 1;
3753                } else {
3754                   titw = TF->cwidth[j];
3755                   /* set the margins to meet those of Labels */
3756                   xmw = 0;
3757                   shad = 0;
3758                }
3759                #if 0
3760                   TF->cells[n] = XtVaCreateManagedWidget(tmp,
3761                                                 xmLabelWidgetClass, rcc,
3762                                                 NULL);
3763                #else
3764                   TF->cells[n] =
3765                      XtVaCreateManagedWidget("table",
3766                            xmTextFieldWidgetClass, rcc,
3767                            XmNvalue, col_tit[j],
3768                            XmNmarginHeight, 0,
3769                            XmNmarginWidth, xmw+shad,/*include shadow size
3770                                                      of text entry cells*/
3771                            XmNmarginTop, 0,
3772                            XmNmarginBottom, 0,
3773                            XmNmarginLeft, 0,
3774                            XmNmarginRight, 0,
3775                            XmNeditable, False,
3776                            XmNshadowThickness , 0,       /* hide the border */
3777                            XmNcursorPositionVisible, False, /* hide the cursor */
3778                               /* Keep these two out: See warning below ...
3779                               XmNfontList, SUMAg_CF->X->TableTextFontList,
3780                               XmNcolumns, titw,
3781                               */
3782                            NULL);
3783 
3784                   /* WARNING: At least with LESSTIF:
3785                      The order in which one sets XmNfontList
3786                      and XmNcolumns matters. For example, adding:
3787                         XmNfontList, SUMAg_CF->X->TableTextFontList,
3788                         XmNcolumns, titw,
3789                      to XtVaCreateManagedWidget above does not
3790                      work. You need to call XtVaSetValues for these
3791                      variables separately.
3792 
3793                      Also, simply adding the XtVaSetValues lines
3794                      below WITHOUT removing the two lines:
3795                         XmNfontList, SUMAg_CF->X->TableTextFontList,
3796                         XmNcolumns, titw,
3797                      from XtVaCreateManagedWidget does not work quite well.
3798 
3799                      Also, note that the shadow adds to the size of the
3800                      TextFieldWdiget, it does not eat 'into' it. So to
3801                      improve title alignment, I added the shadow thickness
3802                      into the margin width. */
3803 
3804                   XtVaSetValues( TF->cells[n],
3805                                  XmNfontList,
3806                                  SUMAg_CF->X->TableTextFontList, NULL);
3807                   XtVaSetValues( TF->cells[n], XmNcolumns, titw,
3808                            NULL);
3809 
3810                #endif
3811                if (i == 0 && j != 0) {
3812                   XtVaSetValues( TF->cells[n],
3813                                  XmNalignment, XmALIGNMENT_BEGINNING, NULL);
3814                }
3815 
3816                /* insert handler to catch clicks on titles */
3817                if (!TF->TitLabelEVHandlerData)
3818                   cd = (XtPointer) TF;
3819                else cd = (XtPointer)TF->TitLabelEVHandlerData;
3820                if (TF->TitLabelEVHandler) {
3821                   /* insert handler to catch clicks on titles */
3822                   XtInsertEventHandler(
3823                      TF->cells[n] ,      /* handle events in title cell */
3824                      ButtonPressMask ,  /* button presses */
3825                      FALSE ,            /* nonmaskable events? */
3826                      TF->TitLabelEVHandler,  /* handler */
3827                      cd ,   /* client data */
3828                      XtListTail ) ;
3829                }
3830                if (0 && TF->HasColTit &&  col_tit[j]) {/* Much better name, but
3831                     Cannot use it before updating
3832                     help generating functions which now call for help on .c00,
3833                     .c01, or .r00 .r01, etc. */
3834                   snprintf(wname, 63, "%s.%s", TF->wname, col_tit[j]);
3835                } else {
3836                   snprintf(wname, 63, "%s.c%02d", TF->wname, j);
3837                }
3838                SUMA_Register_Widget_Help(TF->cells[n], 1, wname,
3839                                          col_hint?col_hint[j]:NULL,
3840                                          col_help?col_help[j]:NULL ) ;
3841                break;
3842             case SUMA_ENTRY_CELL: /* entry cell */
3843                if (LocalHead)
3844                   fprintf( SUMA_STDERR,
3845                            "%s:\nAdding [%d %d] (%d) entry cell\n",
3846                            FuncName, i, j, n);
3847                TF->cells[n] = XtVaCreateManagedWidget(
3848                               "entry",
3849                               xmTextFieldWidgetClass, rcc,
3850                               XmNuserData, (XTP_CAST)n,
3851                               XmNvalue, "-",
3852                               XmNmarginHeight, 0,
3853                               XmNmarginTop, 0,
3854                               XmNmarginBottom, 0,
3855                               XmNmarginWidth, 5,
3856                               NULL);
3857                XtVaSetValues( TF->cells[n],
3858                               XmNfontList,
3859                               SUMAg_CF->X->TableTextFontList, NULL);
3860                if (col_help || col_hint || row_help || row_hint)  {
3861                   if (TF->Ni>1) {
3862                      snprintf(wname, 63, "%s[%d,%d]", TF->wname, i, j);
3863                   } else {
3864                      snprintf(wname, 63, "%s[%d]", TF->wname, n);
3865                   }
3866                   if (!row_tit && !col_tit && TF->Ni == 1 && TF->Nj == 1) {
3867                      char *shh=NULL, *sii=NULL;
3868                      if (col_help) shh =  col_help[0] ;
3869                      else if (row_help) shh =  row_help[0] ;
3870                      if (col_hint) sii = col_hint[0] ;
3871                      else if (row_hint) sii =  row_hint[0] ;
3872                      if (shh || sii) {
3873                         SUMA_Register_Widget_Help(TF->cells[n],1,wname,sii, shh);
3874                      }
3875                   } else {
3876                      SUMA_Register_Widget_Help(TF->cells[n], 1, wname,
3877                                                       NULL,
3878                                     "Use BHelp on table's column and row titles"
3879                                     "for usage information.") ;
3880                   }
3881                }
3882                if (TF->cwidth[j] > 0) {
3883                   XtVaSetValues(TF->cells[n], XmNcolumns, TF->cwidth[j], NULL);
3884                }
3885                if (!TF->editable) {
3886                   SUMA_SetCellEditMode(TF, i, j, 0);
3887                } else {
3888                   SUMA_SetCellEditMode(TF, i, j, 1);
3889                }
3890 
3891                /* insert handlers if any */
3892                if (!TF->CellEVHandlerData) cd = (XtPointer) TF;
3893                   else cd = (XtPointer)TF->CellEVHandlerData;
3894                if (TF->CellEVHandler) {
3895                   /* insert handler to catch clicks on cells */
3896                   XtInsertEventHandler(
3897                               TF->cells[n] ,      /* handle events in cell */
3898                               ButtonPressMask ,  /* button presses */
3899                               FALSE ,            /* nonmaskable events? */
3900                               TF->CellEVHandler,  /* handler */
3901                               cd ,   /* client data */
3902                               XtListTail ) ;
3903                }
3904                break;
3905             default:
3906                SUMA_SL_Err("Bad cell type");
3907                SUMA_RETURNe;
3908                break;
3909          }
3910       } /* for j */
3911    } /* for i */
3912 
3913    SUMA_RETURNe;
3914 }
3915 
SUMA_set_slice_label(SUMA_ALL_DO * ado,char * variant,float val)3916 int SUMA_set_slice_label(SUMA_ALL_DO *ado, char *variant, float val)
3917 {
3918    static char FuncName[]={"SUMA_set_slice_label"};
3919    char slabel[100];
3920    SUMA_X_SurfCont *SurfCont=NULL;
3921    SUMA_Boolean LocalHead = NOPE;
3922 
3923    SUMA_ENTRY;
3924 
3925    SUMA_LH("called");
3926 
3927    SurfCont = SUMA_ADO_Cont(ado);
3928    if (!ado || !variant || !SurfCont) {
3929       SUMA_SL_Err("NULL input"); SUMA_RETURN(0); }
3930 
3931    if (!SurfCont->Ax_slc || !SurfCont->Ax_slc->text ||
3932        !SurfCont->Sa_slc || !SurfCont->Sa_slc->text ||
3933        !SurfCont->Co_slc || !SurfCont->Co_slc->text) {
3934       SUMA_LH("No GUI yet"); SUMA_RETURN(1);
3935    }
3936 
3937    sprintf(slabel, "%3s", MV_format_fval(val));
3938           if (variant[0] == 'A') {
3939       SUMA_STRING_REPLACE(SurfCont->Ax_slc->slice_num_str, slabel);
3940       XtVaSetValues (SurfCont->Ax_slc->text, XmNvalue, slabel, NULL);
3941    } else if (variant[0] == 'S') {
3942       SUMA_STRING_REPLACE(SurfCont->Sa_slc->slice_num_str, slabel);
3943       XtVaSetValues (SurfCont->Sa_slc->text, XmNvalue, slabel, NULL);
3944    } else if (variant[0] == 'C') {
3945       SUMA_STRING_REPLACE(SurfCont->Co_slc->slice_num_str, slabel);
3946       XtVaSetValues (SurfCont->Co_slc->text, XmNvalue, slabel, NULL);
3947    }
3948 
3949    SUMA_RETURN(1);
3950 }
3951 
SUMA_set_slice_scale(SUMA_ALL_DO * ado,char * variant,float val)3952 int SUMA_set_slice_scale(SUMA_ALL_DO *ado, char *variant, float val)
3953 {
3954    static char FuncName[]={"SUMA_set_slice_scale"};
3955    char slabel[100];
3956    int cv;
3957    SUMA_X_SurfCont *SurfCont=NULL;
3958    SUMA_Boolean LocalHead = NOPE;
3959 
3960    SUMA_ENTRY;
3961 
3962    SUMA_LH("called");
3963 
3964    SurfCont = SUMA_ADO_Cont(ado);
3965    if (!ado || !variant || !SurfCont) {
3966       SUMA_SL_Err("NULL input"); SUMA_RETURN(0); }
3967 
3968    if (!SurfCont->Ax_slc || !SurfCont->Ax_slc->sl ||
3969        !SurfCont->Sa_slc || !SurfCont->Sa_slc->sl ||
3970        !SurfCont->Co_slc || !SurfCont->Co_slc->sl) {
3971       SUMA_LH("No GUI yet"); SUMA_RETURN(1);
3972    }
3973 
3974    cv = SUMA_SliceVal2ScalePos (ado, variant, &val );
3975 
3976           if (variant[0] == 'A') {
3977       XtVaSetValues(SurfCont->Ax_slc->sl,  XmNvalue, cv, NULL);
3978    } else if (variant[0] == 'S') {
3979       XtVaSetValues(SurfCont->Sa_slc->sl,  XmNvalue, cv, NULL);
3980    } else if (variant[0] == 'C') {
3981       XtVaSetValues(SurfCont->Co_slc->sl,  XmNvalue, cv, NULL);
3982    }
3983 
3984    SUMA_RETURN(1);
3985 }
3986 
SUMA_cb_set_Ax_slice_label(Widget w,XtPointer clientData,XtPointer call)3987 void SUMA_cb_set_Ax_slice_label(Widget w, XtPointer clientData, XtPointer call)
3988 {
3989    static char FuncName[]={"SUMA_cb_set_Ax_slice_label"};
3990    SUMA_ALL_DO *ado=NULL;
3991    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
3992    float fff ;
3993    int dec=0;
3994    char slabel[100];
3995    SUMA_Boolean LocalHead = NOPE;
3996 
3997    SUMA_ENTRY;
3998 
3999    SUMA_LH("called");
4000    ado = (SUMA_ALL_DO *)clientData;
4001    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
4002 
4003    XtVaGetValues(w, XmNuserData, &dec, NULL);
4004    fff = (float)cbs->value / pow(10.0, dec);
4005 
4006    SUMA_set_slice(ado, "Ax", &fff, "text_field", 1);
4007 
4008    SUMA_RETURNe;
4009 }
4010 
SUMA_cb_set_Sa_slice_label(Widget w,XtPointer clientData,XtPointer call)4011 void SUMA_cb_set_Sa_slice_label(Widget w, XtPointer clientData, XtPointer call)
4012 {
4013    static char FuncName[]={"SUMA_cb_set_Sa_slice_label"};
4014    SUMA_ALL_DO *ado=NULL;
4015    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
4016    float fff ;
4017    int dec=0;
4018    char slabel[100];
4019    SUMA_Boolean LocalHead = NOPE;
4020 
4021    SUMA_ENTRY;
4022 
4023    SUMA_LH("called");
4024    ado = (SUMA_ALL_DO *)clientData;
4025    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
4026 
4027    XtVaGetValues(w, XmNuserData, &dec, NULL);
4028    fff = (float)cbs->value / pow(10.0, dec);
4029 
4030    SUMA_set_slice(ado, "Sa", &fff, "text_field", 1);
4031 
4032    SUMA_RETURNe;
4033 }
4034 
SUMA_cb_set_Co_slice_label(Widget w,XtPointer clientData,XtPointer call)4035 void SUMA_cb_set_Co_slice_label(Widget w, XtPointer clientData, XtPointer call)
4036 {
4037    static char FuncName[]={"SUMA_cb_set_Co_slice_label"};
4038    SUMA_ALL_DO *ado=NULL;
4039    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
4040    float fff ;
4041    int dec=0;
4042    char slabel[100];
4043    SUMA_Boolean LocalHead = NOPE;
4044 
4045    SUMA_ENTRY;
4046 
4047    SUMA_LH("called");
4048    ado = (SUMA_ALL_DO *)clientData;
4049    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
4050 
4051    XtVaGetValues(w, XmNuserData, &dec, NULL);
4052    fff = (float)cbs->value / pow(10.0, dec);
4053 
4054    SUMA_set_slice(ado, "Co", &fff, "text_field", 1);
4055 
4056    SUMA_RETURNe;
4057 }
4058 
SUMA_cb_set_Ax_slice(Widget w,XtPointer clientData,XtPointer call)4059 void SUMA_cb_set_Ax_slice(Widget w, XtPointer clientData, XtPointer call)
4060 {
4061    static char FuncName[]={"SUMA_cb_set_Ax_slice"};
4062    SUMA_ALL_DO *ado=NULL;
4063    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
4064    float fff=0.0;
4065    int dec=-1;
4066    SUMA_Boolean LocalHead = NOPE;
4067 
4068    SUMA_ENTRY;
4069    ado = (SUMA_ALL_DO *)clientData;
4070    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
4071    XtVaGetValues(w, XmNuserData, &dec, NULL);
4072    fff = (float)cbs->value / pow(10.0, dec);
4073    SUMA_LHv("Have %f\n", fff);
4074    SUMA_set_slice(ado, "Ax", &fff, "scale", 1);
4075 
4076    SUMA_RETURNe;
4077 }
4078 
SUMA_cb_set_Sa_slice(Widget w,XtPointer clientData,XtPointer call)4079 void SUMA_cb_set_Sa_slice(Widget w, XtPointer clientData, XtPointer call)
4080 {
4081    static char FuncName[]={"SUMA_cb_set_Sa_slice"};
4082    SUMA_ALL_DO *ado=NULL;
4083    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
4084    float fff=0.0;
4085    int dec=-1;
4086    SUMA_Boolean LocalHead = NOPE;
4087 
4088    SUMA_ENTRY;
4089    ado = (SUMA_ALL_DO *)clientData;
4090    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
4091    XtVaGetValues(w, XmNuserData, &dec, NULL);
4092    fff = (float)cbs->value / pow(10.0, dec);
4093    SUMA_LHv("Have %f\n", fff);
4094    SUMA_set_slice(ado, "Sa", &fff, "scale", 1);
4095 
4096    SUMA_RETURNe;
4097 }
4098 
SUMA_cb_set_Co_slice(Widget w,XtPointer clientData,XtPointer call)4099 void SUMA_cb_set_Co_slice(Widget w, XtPointer clientData, XtPointer call)
4100 {
4101    static char FuncName[]={"SUMA_cb_set_Co_slice"};
4102    SUMA_ALL_DO *ado=NULL;
4103    XmScaleCallbackStruct * cbs = (XmScaleCallbackStruct *) call ;
4104    float fff=0.0;
4105    int dec=-1;
4106    SUMA_Boolean LocalHead = NOPE;
4107 
4108    SUMA_ENTRY;
4109    ado = (SUMA_ALL_DO *)clientData;
4110    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURNe; }
4111    XtVaGetValues(w, XmNuserData, &dec, NULL);
4112    fff = (float)cbs->value / pow(10.0, dec);
4113    SUMA_LHv("Have %f\n", fff);
4114    SUMA_set_slice(ado, "Co", &fff, "scale", 1);
4115 
4116    SUMA_RETURNe;
4117 }
4118 
SUMA_set_slice(SUMA_ALL_DO * ado,char * variant,float * valp,char * caller,int redisp)4119 int SUMA_set_slice(SUMA_ALL_DO *ado, char *variant, float *valp,
4120                    char *caller, int redisp)
4121 {
4122    static char FuncName[]={"SUMA_set_slice"};
4123    float oval, val;
4124    SUMA_X_SurfCont *SurfCont=NULL;
4125    SUMA_VolumeObject *VO=(SUMA_VolumeObject *)ado;
4126    SUMA_Boolean LocalHead = NOPE;
4127 
4128    SUMA_ENTRY;
4129 
4130    if (!ado || !variant) SUMA_RETURN(0);
4131    if (!caller) caller = "XXX"; /* Don't update other input sources */
4132 
4133    SurfCont = SUMA_ADO_Cont(ado);
4134 
4135    if (!valp) {
4136       val = SUMA_VO_N_Slices(VO, variant);/* dirty trick to force scale height */
4137    } else val = *valp;
4138 
4139    SUMA_LH("Slice %s set to %f", variant, val);
4140 
4141    if (caller[0] == 'i') { /* incrementor */
4142       /* calculate val to reflect increment */
4143              if (variant[0] == 'A') {
4144             val += SurfCont->Ax_slc->slice_num;
4145       } else if (variant[0] == 'S') {
4146             val += SurfCont->Sa_slc->slice_num;
4147       } else if (variant[0] == 'C') {
4148             val += SurfCont->Co_slc->slice_num;
4149       } else if (variant[0] == 'V') {
4150             val += SurfCont->VR_fld->N_slice_num;
4151       }
4152    }
4153 
4154    if (val < 0) val = 0;
4155    else if (val >= SUMA_VO_N_Slices(VO, variant) &&
4156                    variant[0] != 'V')
4157                      val = SUMA_VO_N_Slices(VO, variant)-1;
4158 
4159    /* call this one since it is not being called as the slider is dragged. */
4160    if (caller[0] != 'X' && variant[0] != 'V') { /* Update equivalent */
4161       if (caller[0] != 't') { /* Caller not from text field so set that*/
4162          SUMA_set_slice_label(ado, variant, val);
4163       }
4164       if (caller[0] != 's') { /* Caller not from slider, so update that too */
4165          SUMA_set_slice_scale(ado, variant, val);
4166       }
4167    }
4168 
4169           if (variant[0] == 'A') {
4170          SurfCont->Ax_slc->slice_num = val;
4171    } else if (variant[0] == 'S') {
4172          SurfCont->Sa_slc->slice_num = val;
4173    } else if (variant[0] == 'C') {
4174          SurfCont->Co_slc->slice_num = val;
4175    } else if (variant[0] == 'V') {
4176          SurfCont->VR_fld->N_slice_num = val;
4177    }
4178 
4179    if (redisp) SUMA_Remixedisplay(ado);
4180 
4181    /* sad as it is */
4182    if (variant[0] != 'V') SUMA_FORCE_SLICE_SCALE_WIDTH(SUMA_ADO_Cont(ado));
4183 
4184    #if 0 /* I don't think this will be necessary */
4185    SUMA_ADO_Flush_Pick_Buffer(ado, NULL);
4186    #endif
4187 
4188    /* And this?
4189    #if SUMA_SEPARATE_SURF_CONTROLLERS
4190       SUMA_UpdateColPlaneShellAsNeeded(ado);
4191    #endif
4192    */
4193 
4194    if (0) {
4195       static int ncnt=0;
4196       /* Do nothing about selection. Not sure what would be of use
4197       One could supposedly move the selection - if the selection
4198       was on the slice being moved. Something to ponder for the
4199       future
4200          Remember selection could be on any of the slices in the
4201          montage, or even elsewhere in space....
4202       */
4203       if (!ncnt) {
4204          SUMA_S_Warn("What to do about selected voxels here? Move them along?");
4205          ++ncnt;
4206       }
4207       SUMA_UpdateNodeValField(ado);
4208       SUMA_UpdateNodeLblField(ado);
4209    }
4210 
4211    SUMA_RETURN(1);
4212 }
4213 
SUMA_set_mont(SUMA_ALL_DO * ado,char * variant,float * val1p,float * val2p,char * caller,int redisp)4214 int SUMA_set_mont(SUMA_ALL_DO *ado, char *variant,
4215                   float *val1p, float *val2p,
4216                   char *caller, int redisp)
4217 {
4218    static char FuncName[]={"SUMA_set_mont"};
4219    float oval, val1, val2;
4220    SUMA_X_SurfCont *SurfCont=NULL;
4221    SUMA_VolumeObject *VO=(SUMA_VolumeObject *)ado;
4222    SUMA_Boolean LocalHead = NOPE;
4223 
4224    SUMA_ENTRY;
4225 
4226    if (!ado || !variant) SUMA_RETURN(0);
4227    if (!caller) caller = "XXX"; /* Don't update other input sources */
4228 
4229    SurfCont = SUMA_ADO_Cont(ado);
4230 
4231    if (!val1p) {
4232       val1 = 1;
4233    } else val1 = *val1p;
4234    if (!val2p) {
4235       val2 = 1;
4236    } else val2 = *val2p;
4237 
4238       if (val1 < 1) val1 = 1;
4239    else if (val1 > SUMA_VO_N_Slices(VO, variant))
4240                      val1 = SUMA_VO_N_Slices(VO, variant);
4241       if (val2 < 1) val2 = 1;
4242    else if (val2 > SUMA_VO_N_Slices(VO, variant))
4243                      val2 = SUMA_VO_N_Slices(VO, variant);
4244 
4245    val1 = (int)val1; val2 = (int)val2;
4246    SUMA_LH("Slice %s mont set to %d %d", variant, (int)val1, (int)val2);
4247 
4248 
4249           if (variant[0] == 'A') {
4250          SurfCont->Ax_slc->mont_num = val1;
4251          SurfCont->Ax_slc->mont_inc = val2;
4252    } else if (variant[0] == 'S') {
4253          SurfCont->Sa_slc->mont_num = val1;
4254          SurfCont->Sa_slc->mont_inc = val2;
4255    } else if (variant[0] == 'C') {
4256          SurfCont->Co_slc->mont_num = val1;
4257          SurfCont->Co_slc->mont_inc = val2;
4258    }
4259 
4260    if (redisp) SUMA_Remixedisplay(ado);
4261 
4262    SUMA_RETURN(1);
4263 }
4264 
4265 /*!
4266    \brief create slice selection widgets
4267 */
SUMA_CreateSliceFields(Widget parent,char * tit,char * hint,char * help,int Nslc,char * var,SUMA_ALL_DO * ado,void (* NewValueCallback)(void * data),void * cb_data,SUMA_SLICE_FIELD * SF)4268 void SUMA_CreateSliceFields(  Widget parent,
4269                         char *tit, char *hint, char *help,
4270                         int Nslc, char *var, SUMA_ALL_DO *ado,
4271                         void (*NewValueCallback)(void * data), void *cb_data,
4272                         SUMA_SLICE_FIELD *SF)
4273 {
4274    static char FuncName[]={"SUMA_CreateSliceFields"};
4275    int i, j, n, titw, xmw, shad, mult;
4276    char *tmp, sbuf[12], wname[64]={"SetMePlease"};
4277    XtPointer cd;
4278    XtVarArgsList arglist=NULL;
4279    XtCallbackProc slcb, sllbcb, slcactcb, shwslccb;
4280    int shw_init = 0;
4281    SUMA_VOL_SAUX *VSaux=NULL;
4282    SUMA_Boolean LocalHead = NOPE;
4283 
4284    SUMA_ENTRY;
4285 
4286    if (!parent) { SUMA_SL_Err("NULL parent"); SUMA_RETURNe; }
4287    if (!ado) { SUMA_S_Err("NULL ado"); SUMA_RETURNe; }
4288    if (!(VSaux = SUMA_ADO_VSaux(ado))) { SUMA_S_Err("No VSaux"); SUMA_RETURNe; }
4289    if (!tit) tit = var;
4290 
4291    if (LocalHead) {
4292       SUMA_S_Warn("Are NewValueCallback and its data needed at all?");
4293    }
4294    /* initialize font list if need be */
4295    if (!SUMAg_CF->X->TableTextFontList) {
4296       if (SUMA_isEnv("SUMA_SurfContFontSize", "BIG")) {
4297          SUMAg_CF->X->TableTextFontList =
4298                SUMA_AppendToFontList( SUMAg_CF->X->TableTextFontList,
4299                                        parent, "*9x15*", NULL);
4300       } else {
4301          SUMAg_CF->X->TableTextFontList =
4302                SUMA_AppendToFontList( SUMAg_CF->X->TableTextFontList,
4303                                        parent, "*8x13*", NULL);
4304       }
4305    }
4306 
4307    if (!SF) { SUMA_SL_Err("NULL SF"); SUMA_RETURNe; }
4308    if (!var){ SUMA_S_Err("Bad var format"); SUMA_RETURNe; }
4309    SUMA_LH("Init");
4310    if (!strcmp(var,"Ax")) {
4311       slcb = SUMA_cb_set_Ax_slice;
4312       sllbcb = SUMA_cb_set_Ax_slice_label;
4313       slcactcb = SUMA_SliceF_cb_label_change;
4314       shwslccb = SUMA_cb_ShowAxSlice_toggled;
4315       shw_init = VSaux->ShowAxSlc;
4316    } else if (!strcmp(var,"Sa")) {
4317       slcb = SUMA_cb_set_Sa_slice;
4318       sllbcb = SUMA_cb_set_Sa_slice_label;
4319       slcactcb = SUMA_SliceF_cb_label_change;
4320       shwslccb = SUMA_cb_ShowSaSlice_toggled;
4321       shw_init = VSaux->ShowSaSlc;
4322    } else if (!strcmp(var,"Co")) {
4323       slcb = SUMA_cb_set_Co_slice;
4324       sllbcb = SUMA_cb_set_Co_slice_label;
4325       slcactcb = SUMA_SliceF_cb_label_change;
4326       shwslccb = SUMA_cb_ShowCoSlice_toggled;
4327       shw_init = VSaux->ShowCoSlc;
4328    } else {
4329       SUMA_S_Err("Bad var %s", var);
4330       SUMA_RETURNe;
4331    }
4332    SF->variant = SUMA_copy_string(var);
4333    SF->Nslc = Nslc;
4334    SF->NewValueCallback = NewValueCallback;
4335    SF->NewValueCallbackData = cb_data;
4336    /* An outer row column to keep the inner one from resizing with parent
4337    YOU COULD HAVE SET XmNadjustLast to False, instead ....*/
4338    SF->rc = XtVaCreateManagedWidget ("rowcolumn",
4339       xmRowColumnWidgetClass, parent,
4340       XmNorientation , XmHORIZONTAL ,
4341       XmNpacking, XmPACK_TIGHT,
4342       XmNmarginHeight, 0,
4343       XmNmarginWidth, 0,
4344       NULL);
4345 
4346    SUMA_LH("Widgets, var %s, tit %s, slice num = %d, Nslc = %d, wname = %s",
4347             var, tit, (int)SF->slice_num, SF->Nslc, SF->wname);
4348    SF->lab = XtVaCreateManagedWidget(tit, xmLabelWidgetClass, SF->rc,
4349                            XmNfontList, SUMAg_CF->X->TableTextFontList,
4350                                      NULL);
4351    if (hint || help) {
4352       snprintf(wname,63, "%s->%s", SF->wname, tit);
4353       SUMA_Register_Widget_Help( SF->lab, 1, wname, hint, help);
4354    }
4355    mult = ((int)(SF->Nslc/20.0)/5)*5; if (mult < 1) mult = 1;
4356    arglist = XtVaCreateArgsList( NULL,
4357                            XmNshowValue, False,
4358                            XmNmaximum, SF->Nslc,
4359                            XmNvalue, (int)SF->slice_num,
4360                            XmNscaleMultiple, mult,
4361                            XmNheight,  SUMA_SCALE_HEIGHT,
4362                            XmNorientation, XmHORIZONTAL,
4363                            XmNuserData, (XtPointer)0,
4364                            NULL);
4365 
4366    SF->sl =  XtVaCreateManagedWidget(var,
4367                                  xmScaleWidgetClass, SF->rc,
4368                                  XtVaNestedList, arglist,
4369                                  NULL);
4370    XtAddCallback (SF->sl,
4371                   XmNvalueChangedCallback,
4372                   slcb,
4373                   (XtPointer) ado);
4374 
4375    XtAddCallback (SF->sl,
4376                   XmNdragCallback,
4377                   sllbcb,
4378                   (XtPointer) ado);
4379 
4380    if (arglist) XtFree(arglist); arglist = NULL;
4381 
4382    sprintf(sbuf,"%-3d", (int)SF->slice_num);
4383    SF->text = XtVaCreateManagedWidget(
4384                      "slice",
4385                      xmTextFieldWidgetClass, SF->rc,
4386                      XmNuserData, (XTP_CAST)ado,
4387                      XmNvalue, sbuf,
4388                      XmNmarginHeight, 0,
4389                      XmNmarginTop, 0,
4390                      XmNmarginBottom, 0,
4391                      XmNmarginWidth, 5,
4392                      NULL);
4393    XtVaSetValues( SF->text, XmNfontList,
4394                   SUMAg_CF->X->TableTextFontList, NULL);
4395 
4396    if (hint || help) {
4397       snprintf(wname, 63, "%s->%s_text", SF->wname, tit);
4398       SUMA_Register_Widget_Help( SF->text, 1, wname, hint, help);
4399    }
4400    XtVaSetValues(SF->text, XmNcolumns, 3, NULL);
4401    XtVaSetValues(SF->text, XmNeditable, True,
4402                  XmNshadowThickness , 2,
4403                  XmNcursorPositionVisible, True,
4404                  NULL);
4405 
4406    XtAddCallback (SF->text, XmNactivateCallback,
4407                SUMA_SliceF_cb_label_change, (XtPointer)SF);
4408    /* add event handler to notify when widget was left */
4409    XtInsertEventHandler( SF->text ,        /* notify when */
4410                          LeaveWindowMask ,  /* pointer leaves */
4411                          FALSE ,            /* this window */
4412                          SUMA_leave_SliceField,
4413                          (XtPointer) SF ,
4414                          XtListTail ) ;     /* last in queue */
4415 
4416    sprintf(sbuf,"%d:%d", (int)SF->mont_num, (int)SF->mont_inc);
4417    SF->mont = XtVaCreateManagedWidget(
4418                      "mont",
4419                      xmTextFieldWidgetClass, SF->rc,
4420                      XmNuserData, (XTP_CAST)ado,
4421                      XmNvalue, sbuf,
4422                      XmNmarginHeight, 0,
4423                      XmNmarginTop, 0,
4424                      XmNmarginBottom, 0,
4425                      XmNmarginWidth, 5,
4426                      NULL);
4427    XtVaSetValues( SF->mont, XmNfontList,
4428                   SUMAg_CF->X->TableTextFontList, NULL);
4429 
4430    if (hint || help) {
4431       snprintf(wname, 63, "%s->mont", SF->wname);
4432       SUMA_Register_Widget_Help( SF->mont, 1, wname, hint, help);
4433    }
4434    XtVaSetValues(SF->mont, XmNcolumns, 5, NULL);
4435    XtVaSetValues(SF->mont, XmNeditable, True,
4436                  XmNshadowThickness , 2,
4437                  XmNcursorPositionVisible, True,
4438                  NULL);
4439 
4440    XtAddCallback (SF->mont, XmNactivateCallback,
4441                SUMA_SliceF_cb_mont_change, (XtPointer)SF);
4442    /* add event handler to notify when widget was left */
4443    XtInsertEventHandler( SF->mont ,        /* notify when */
4444                          LeaveWindowMask ,  /* pointer leaves */
4445                          FALSE ,            /* this window */
4446                          SUMA_leave_MontField,
4447                          (XtPointer) SF ,
4448                          XtListTail ) ;     /* last in queue */
4449 
4450 
4451    /* Now for the toggle button */
4452    SF->tb = XtVaCreateManagedWidget("v",
4453       xmToggleButtonWidgetClass, SF->rc, NULL);
4454    XtAddCallback (SF->tb,
4455          XmNvalueChangedCallback, shwslccb, ado);
4456    snprintf(wname, 63, "%s->tb", SF->wname);
4457    SUMA_Register_Widget_Help(SF->tb, 1, wname,
4458                      "View (ON)/Hide Slice(s)",
4459                      SUMA_SurfContHelp_ShowSliceTgl);
4460 
4461    SUMA_SET_SELECT_COLOR(SF->tb);
4462    XmToggleButtonSetState (SF->tb, shw_init , NOPE);
4463 
4464    SUMA_RETURNe;
4465 }
4466 
SUMA_cb_ShowAxSlice_toggled(Widget w,XtPointer data,XtPointer client_data)4467 void SUMA_cb_ShowAxSlice_toggled(Widget w, XtPointer data, XtPointer client_data)
4468 {
4469    static char FuncName[]={"SUMA_cb_ShowAxSlice_toggled"};
4470    SUMA_ALL_DO *ado = NULL;
4471    SUMA_X_SurfCont *SurfCont=NULL;
4472    SUMA_Boolean LocalHead = NOPE;
4473 
4474    SUMA_ENTRY;
4475 
4476    SUMA_LH("Called");
4477 
4478    ado = (SUMA_ALL_DO *)data;
4479    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
4480       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
4481 
4482    SUMA_SetShowSlice((SUMA_VolumeObject *)ado, "Ax",
4483                       XmToggleButtonGetState (SurfCont->Ax_slc->tb));
4484    SUMA_RETURNe;
4485 }
4486 
4487 
SUMA_cb_ShowSaSlice_toggled(Widget w,XtPointer data,XtPointer client_data)4488 void SUMA_cb_ShowSaSlice_toggled(Widget w, XtPointer data, XtPointer client_data)
4489 {
4490    static char FuncName[]={"SUMA_cb_ShowSaSlice_toggled"};
4491    SUMA_ALL_DO *ado = NULL;
4492    SUMA_X_SurfCont *SurfCont=NULL;
4493    SUMA_Boolean LocalHead = NOPE;
4494 
4495    SUMA_ENTRY;
4496 
4497    SUMA_LH("Called");
4498 
4499    ado = (SUMA_ALL_DO *)data;
4500    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
4501       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
4502 
4503    SUMA_SetShowSlice((SUMA_VolumeObject *)ado, "Sa",
4504                       XmToggleButtonGetState (SurfCont->Sa_slc->tb));
4505    SUMA_RETURNe;
4506 }
4507 
SUMA_cb_ShowCoSlice_toggled(Widget w,XtPointer data,XtPointer client_data)4508 void SUMA_cb_ShowCoSlice_toggled(Widget w, XtPointer data, XtPointer client_data)
4509 {
4510    static char FuncName[]={"SUMA_cb_ShowCoSlice_toggled"};
4511    SUMA_ALL_DO *ado = NULL;
4512    SUMA_X_SurfCont *SurfCont=NULL;
4513    SUMA_Boolean LocalHead = NOPE;
4514 
4515    SUMA_ENTRY;
4516 
4517    SUMA_LH("Called");
4518 
4519    ado = (SUMA_ALL_DO *)data;
4520    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
4521       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
4522 
4523    SUMA_SetShowSlice((SUMA_VolumeObject *)ado, "Co",
4524                       XmToggleButtonGetState (SurfCont->Co_slc->tb));
4525    SUMA_RETURNe;
4526 }
4527 
SUMA_SetShowSlice(SUMA_VolumeObject * vdo,char * variant,int val)4528 int SUMA_SetShowSlice(SUMA_VolumeObject *vdo, char *variant, int val)
4529 {
4530    static char FuncName[]={"SUMA_SetShowSlice"};
4531    SUMA_ALL_DO *ado = NULL;
4532    SUMA_X_SurfCont *SurfCont=NULL;
4533    SUMA_VOL_SAUX *VSaux = NULL;
4534    SUMA_Boolean LocalHead = NOPE;
4535 
4536    SUMA_ENTRY;
4537 
4538    SUMA_LH("Called variant %s, val %d", variant?variant:"NULL", val);
4539 
4540    ado = (SUMA_ALL_DO *)vdo;
4541    VSaux = SUMA_ADO_VSaux(ado);
4542    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado)) || !VSaux || !variant) {
4543       SUMA_S_Warn("NULL input"); SUMA_RETURN(0); }
4544 
4545    if (!strcmp(variant, "Ax")) {
4546       if (VSaux->ShowAxSlc != val) {
4547          VSaux->ShowAxSlc = val;
4548          SUMA_Remixedisplay(ado);
4549          #if SUMA_SEPARATE_SURF_CONTROLLERS
4550             SUMA_UpdateColPlaneShellAsNeeded(ado);
4551          #endif
4552       }
4553    } else if (!strcmp(variant, "Sa")) {
4554       if (VSaux->ShowSaSlc != val) {
4555          VSaux->ShowSaSlc = val;
4556          SUMA_Remixedisplay(ado);
4557          #if SUMA_SEPARATE_SURF_CONTROLLERS
4558             SUMA_UpdateColPlaneShellAsNeeded(ado);
4559          #endif
4560       }
4561    } else if (!strcmp(variant, "Co")) {
4562       if (VSaux->ShowCoSlc != val) {
4563          VSaux->ShowCoSlc = val;
4564          SUMA_Remixedisplay(ado);
4565          #if SUMA_SEPARATE_SURF_CONTROLLERS
4566             SUMA_UpdateColPlaneShellAsNeeded(ado);
4567          #endif
4568       }
4569    } else if (!strcmp(variant, "Vr")) {
4570       if (VSaux->ShowVrSlc != val) {
4571          VSaux->ShowVrSlc = val;
4572          SUMA_Remixedisplay(ado);
4573          #if SUMA_SEPARATE_SURF_CONTROLLERS
4574             SUMA_UpdateColPlaneShellAsNeeded(ado);
4575          #endif
4576       }
4577       SUMA_LH("ShowVrSlc now %d", VSaux->ShowVrSlc);
4578    } else if (!strcmp(variant, "AtXYZ")) {
4579       SUMA_SurfaceViewer *sv=NULL;
4580       if (VSaux->SlicesAtCrosshair != val) {
4581          VSaux->SlicesAtCrosshair = val;
4582          if (VSaux->SlicesAtCrosshair && (sv=SUMA_OneViewerWithADOVisible(ado))
4583              && sv->Ch){
4584             SUMA_VO_set_slices_XYZ(vdo, sv->Ch->c_noVisX);
4585          }
4586          SUMA_Remixedisplay(ado);
4587          #if SUMA_SEPARATE_SURF_CONTROLLERS
4588             SUMA_UpdateColPlaneShellAsNeeded(ado);
4589          #endif
4590       }
4591       SUMA_LH("SlicesAtCrosshair now %d", VSaux->SlicesAtCrosshair);
4592    } else if (!strcmp(variant, "Sel")) {
4593       if (VSaux->VrSelect != val) {
4594          VSaux->VrSelect = val;
4595       }
4596       SUMA_LH("VrSelect now %d", VSaux->VrSelect);
4597    } else {
4598       SUMA_S_Err("And what is variant %s for?", variant);
4599       SUMA_RETURN(NOPE);
4600    }
4601    SUMA_RETURN(1);
4602 }
4603 
4604 
4605 
SUMA_cellvariety(SUMA_TABLE_FIELD * TF,int n)4606 SUMA_CELL_VARIETY SUMA_cellvariety (SUMA_TABLE_FIELD *TF, int n)
4607 {
4608    static char FuncName[]={"SUMA_cellvariety"};
4609    int i, j;
4610    SUMA_Boolean LocalHead = NOPE;
4611 
4612    SUMA_ENTRY;
4613 
4614    if (!TF) SUMA_RETURN(SUMA_ERROR_CELL);
4615    i = n % TF->Ni;
4616    j = n / TF->Ni;
4617    if (TF->HasColTit && i == 0) SUMA_RETURN(SUMA_COL_TIT_CELL);
4618    if (TF->HasRowTit && j == 0) SUMA_RETURN(SUMA_ROW_TIT_CELL);
4619    SUMA_RETURN(SUMA_ENTRY_CELL);
4620 }
4621 
SUMA_RowTitCell(SUMA_TABLE_FIELD * TF,int r)4622 int SUMA_RowTitCell(SUMA_TABLE_FIELD *TF, int r)
4623 {
4624    static char FuncName[]={"SUMA_RowTitCell"};
4625    SUMA_Boolean LocalHead = NOPE;
4626 
4627    SUMA_ENTRY;
4628 
4629    if (!TF || !TF->HasRowTit || r < 0 || r >= TF->Ni) SUMA_RETURN(-1);
4630 
4631    SUMA_RETURN(r);
4632 }
4633 
SUMA_ColTitCell(SUMA_TABLE_FIELD * TF,int c)4634 int SUMA_ColTitCell(SUMA_TABLE_FIELD *TF, int c)
4635 {
4636    static char FuncName[]={"SUMA_ColTitCell"};
4637    SUMA_Boolean LocalHead = NOPE;
4638 
4639    SUMA_ENTRY;
4640 
4641    if (!TF || !TF->HasColTit || c < 0 || c >= TF->Nj) SUMA_RETURN(-1);
4642 
4643    SUMA_RETURN(c*TF->Ni);
4644 }
4645 
SUMA_ObjectID_Row(SUMA_TABLE_FIELD * TF,char * id)4646 int SUMA_ObjectID_Row(SUMA_TABLE_FIELD *TF, char *id)
4647 {
4648    static char FuncName[]={"SUMA_ObjectID_Row"};
4649    int found = -1, ii=-1;
4650    SUMA_Boolean LocalHead = NOPE;
4651 
4652    SUMA_ENTRY;
4653 
4654    if (!TF || !TF->rowobject_id || !id) SUMA_RETURN(-1);
4655 
4656    if (LocalHead) {
4657       fprintf(SUMA_STDERR, "Seeking %s\n"
4658                            "in      ", id);
4659       for (ii=0; ii<TF->Ni; ++ii) {
4660          fprintf(SUMA_STDERR,"%s\n        ",
4661                  TF->rowobject_id[ii]?TF->rowobject_id[ii]:"NULL");
4662       }
4663       fprintf(SUMA_STDERR, "\n");
4664    }
4665    found = -1; ii=0;
4666    while (found < 0 && ii < TF->Ni) {
4667       if (TF->rowobject_id[ii] &&
4668           !strcmp(id, TF->rowobject_id[ii])) {
4669          found = ii;
4670       }
4671       ++ii;
4672    }
4673 
4674    SUMA_RETURN(found);
4675 }
4676 
4677 
4678 /*!
4679    \brief This function is called when mouse pointer leaves label field
4680    It only acts if  TF->modified
4681 */
SUMA_leave_TableField(Widget w,XtPointer client_data,XEvent * ev,Boolean * continue_to_dispatch)4682 void SUMA_leave_TableField( Widget w , XtPointer client_data ,
4683                            XEvent * ev , Boolean * continue_to_dispatch )
4684 {
4685    static char FuncName[]={"SUMA_leave_TableField"};
4686    SUMA_TABLE_FIELD *TF=NULL;
4687    XLeaveWindowEvent * lev = (XLeaveWindowEvent *) ev ;
4688    XmAnyCallbackStruct cbs ;
4689    SUMA_Boolean LocalHead = NOPE;
4690 
4691    SUMA_ENTRY;
4692 
4693    SUMA_LH("Called");
4694    TF = (SUMA_TABLE_FIELD *)client_data ;
4695    if( lev->type != LeaveNotify || TF->cell_modified < 0) SUMA_RETURNe;
4696 
4697    if (LocalHead) fprintf (SUMA_STDERR, "%s: Leave notification.\n", FuncName);
4698 
4699    SUMA_TableF_cb_label_change( w , (XtPointer)TF , NULL ) ;
4700 
4701    SUMA_RETURNe;
4702 }
4703 
4704 /*!
4705    \brief This function is called when mouse pointer leaves montage field
4706 */
SUMA_leave_MontField(Widget w,XtPointer client_data,XEvent * ev,Boolean * continue_to_dispatch)4707 void SUMA_leave_MontField( Widget w , XtPointer client_data ,
4708                             XEvent * ev , Boolean * continue_to_dispatch )
4709 {
4710    static char FuncName[]={"SUMA_leave_MontField"};
4711    SUMA_SLICE_FIELD *SF=NULL;
4712    XLeaveWindowEvent * lev = (XLeaveWindowEvent *) ev ;
4713    XmAnyCallbackStruct cbs ;
4714    SUMA_Boolean LocalHead = NOPE;
4715 
4716    SUMA_ENTRY;
4717 
4718    SUMA_LH("Called");
4719    SF = (SUMA_SLICE_FIELD *)client_data ;
4720    if( lev->type != LeaveNotify) SUMA_RETURNe;
4721 
4722    if (LocalHead) fprintf (SUMA_STDERR, "%s: Leave notification.\n", FuncName);
4723 
4724    SUMA_SliceF_cb_mont_change( w , (XtPointer)SF , NULL ) ;
4725 
4726    SUMA_RETURNe;
4727 }
4728 
4729 /*!
4730    \brief This function is called when mouse pointer leaves slice field
4731 */
SUMA_leave_SliceField(Widget w,XtPointer client_data,XEvent * ev,Boolean * continue_to_dispatch)4732 void SUMA_leave_SliceField( Widget w , XtPointer client_data ,
4733                             XEvent * ev , Boolean * continue_to_dispatch )
4734 {
4735    static char FuncName[]={"SUMA_leave_SliceField"};
4736    SUMA_SLICE_FIELD *SF=NULL;
4737    XLeaveWindowEvent * lev = (XLeaveWindowEvent *) ev ;
4738    XmAnyCallbackStruct cbs ;
4739    SUMA_Boolean LocalHead = NOPE;
4740 
4741    SUMA_ENTRY;
4742 
4743    SUMA_LH("Called");
4744    SF = (SUMA_SLICE_FIELD *)client_data ;
4745    if( lev->type != LeaveNotify) SUMA_RETURNe;
4746 
4747    if (LocalHead) fprintf (SUMA_STDERR, "%s: Leave notification.\n", FuncName);
4748 
4749    SUMA_SliceF_cb_label_change( w , (XtPointer)SF , NULL ) ;
4750 
4751    SUMA_RETURNe;
4752 }
4753 
4754 /*!
4755    \brief User entered new slice value
4756 */
SUMA_SliceF_cb_label_change(Widget w,XtPointer client_data,XtPointer call_data)4757 void SUMA_SliceF_cb_label_change (  Widget w, XtPointer client_data,
4758                                     XtPointer call_data)
4759 {
4760    static char FuncName[]={"SUMA_SliceF_cb_label_change"};
4761    SUMA_SLICE_FIELD *SF=NULL;
4762    float val;
4763    int N_words = 0;
4764    XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
4765    void *n=NULL;
4766    char *cs=NULL;
4767    int unt = SUMA_NO_NUM_UNITS;
4768    SUMA_Boolean DoCallBacks;
4769    SUMA_Boolean LocalHead = NOPE;
4770 
4771    SUMA_ENTRY;
4772 
4773    SUMA_LH("Called");
4774    /* make call to NewValue callback */
4775    SF = (SUMA_SLICE_FIELD *)client_data;
4776 
4777    DoCallBacks = NOPE;
4778    if (call_data) {
4779       /* do the call backs if carriage return even if nothing is modified */
4780       if (LocalHead)
4781          fprintf (SUMA_STDERR,"%s: cbs->reason = %d (CR=%d)\n",
4782                               FuncName, cbs->reason, XmCR_ACTIVATE);
4783       if (cbs->reason == XmCR_ACTIVATE) {
4784          DoCallBacks = YUP;
4785       }
4786    }
4787 
4788    DoCallBacks = YUP;   /* do the callbacks even if no carriage return ... */
4789    /* Check if the string is numerical, and get unit */
4790    XtVaGetValues (w, XmNvalue, &n, NULL);
4791    cs = (char *)n;
4792    if (!cs || !strlen(cs)) {/* empty cell, leave it alone */
4793       SUMA_LHv("empty %s", cs);
4794       SUMA_RETURNe;
4795    } else  {
4796       SUMA_COUNT_WORDS(cs, NULL, N_words);
4797       if (!N_words) { /* no harm, go back */
4798          SUMA_LHv("spacy %s", cs);
4799          SUMA_RETURNe;
4800       }
4801    }
4802    unt = SUMA_NumStringUnits(cs, 0);
4803    if (SUMA_StringToNum(cs, (void *)&val, 1, 1) != 1) {
4804       SUMA_BEEP;
4805       /* bad syntax, reset value*/
4806       if (LocalHead) fprintf (SUMA_STDERR, "%s: Bad syntax.\n", FuncName);
4807       SUMA_RegisterMessage (SUMAg_CF->MessageList,
4808                             "Bad value in text field", FuncName,
4809                             SMT_Error, SMA_Log);
4810       SUMA_SliceF_SetString (SF);
4811    }else {
4812       if (SF->slice_num == val &&
4813           SF->slice_units == unt) {
4814             SUMA_LH("Same value");
4815             SUMA_RETURNe;
4816       }
4817       SUMA_LH("A new beast? %f, %f, %d %d",
4818               SF->slice_num, val, SF->slice_units, unt);
4819       SF->slice_num = val;
4820       SF->slice_units = unt;
4821       SUMA_SliceF_SetString (SF);
4822    }
4823 
4824    if (DoCallBacks) {
4825       SUMA_set_slice((SUMA_ALL_DO *)SF->NewValueCallbackData, SF->variant, &val,
4826                      "text_field", 1);
4827    }
4828 
4829    SUMA_RETURNe;
4830 }
4831 
4832 /*!
4833    \brief User entered new montage string
4834 */
SUMA_SliceF_cb_mont_change(Widget w,XtPointer client_data,XtPointer call_data)4835 void SUMA_SliceF_cb_mont_change (  Widget w, XtPointer client_data,
4836                                     XtPointer call_data)
4837 {
4838    static char FuncName[]={"SUMA_SliceF_cb_mont_change"};
4839    SUMA_SLICE_FIELD *SF=NULL;
4840    float val1, val2;
4841    int N_words = 0;
4842    XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
4843    void *n=NULL;
4844    char *cs=NULL, *ss=NULL;
4845    int unt = SUMA_NO_NUM_UNITS;
4846    SUMA_Boolean DoCallBacks;
4847    SUMA_Boolean LocalHead = NOPE;
4848 
4849    SUMA_ENTRY;
4850 
4851    SUMA_LH("Nothing done yet, build based on SUMA_SliceF_cb_label_change");
4852    /* make call to NewValue callback */
4853    SF = (SUMA_SLICE_FIELD *)client_data;
4854 
4855    DoCallBacks = NOPE;
4856    if (call_data) {
4857       /* do the call backs if carriage return even if nothing is modified */
4858       if (LocalHead)
4859          fprintf (SUMA_STDERR,"%s: cbs->reason = %d (CR=%d)\n",
4860                               FuncName, cbs->reason, XmCR_ACTIVATE);
4861       if (cbs->reason == XmCR_ACTIVATE) {
4862          DoCallBacks = YUP;
4863       }
4864    }
4865 
4866    DoCallBacks = YUP;   /* do the callbacks even if no carriage return ... */
4867    /* Check if the string is numerical, and get unit */
4868    XtVaGetValues (w, XmNvalue, &n, NULL);
4869    cs = (char *)n;
4870    if (!cs || !strlen(cs)) {/* empty cell, leave it alone */
4871       SUMA_LHv("empty %s", cs);
4872       SUMA_RETURNe;
4873    } else  {
4874       SUMA_COUNT_WORDS(cs, NULL, N_words);
4875       if (!N_words) { /* no harm, go back */
4876          SUMA_LHv("spacy %s", cs);
4877          SUMA_RETURNe;
4878       }
4879    }
4880    val1 = -1;
4881    val2 = -1;
4882    unt = SUMA_NumStringUnits(cs, 0);
4883    /* Split based on the presence of ':' */
4884    if (!(ss = SUMA_NI_get_ith_string(cs, ":", 0))) {
4885       SUMA_LH("Nothing in cs?");
4886       SUMA_RETURNe;
4887    }
4888    if (SUMA_StringToNum(ss, (void *)&val1, 1, 1) != 1) {
4889       SUMA_BEEP;
4890       /* bad syntax, reset value*/
4891       if (LocalHead) fprintf (SUMA_STDERR, "%s: Bad syntax.\n", FuncName);
4892       SUMA_RegisterMessage (SUMAg_CF->MessageList,
4893                             "Bad value in text field", FuncName,
4894                             SMT_Error, SMA_Log);
4895       SUMA_SliceF_SetString (SF);
4896       val1 = SF->mont_num;
4897    } else {
4898       SUMA_ifree(ss);
4899       if (!(ss = SUMA_NI_get_ith_string(cs, ":", 1))) {
4900          SUMA_LH("No second number, assume 1");
4901          val2 = 1;
4902       } else if (SUMA_StringToNum(ss, (void *)&val2, 1, 1) != 1) {
4903          SUMA_BEEP;
4904          /* bad syntax, reset value*/
4905          if (LocalHead) fprintf (SUMA_STDERR, "%s: Bad syntax.\n", FuncName);
4906          SUMA_RegisterMessage (SUMAg_CF->MessageList,
4907                                "Bad value in text field", FuncName,
4908                                SMT_Error, SMA_Log);
4909          SUMA_SliceF_SetString (SF);
4910          val2 = SF->mont_inc;
4911       }
4912    }
4913    SUMA_ifree(ss);
4914 
4915    if (val1 >= 0.0 && val2 >= 0.0) {
4916       if (SF->mont_num == val1 &&
4917           SF->mont_inc == val2) {
4918             SUMA_LH("Same value");
4919             SUMA_RETURNe;
4920       }
4921       SF->mont_num = val1;
4922       SF->mont_inc = val2;
4923       SUMA_SliceF_SetString (SF);
4924    }
4925 
4926    if (DoCallBacks) {
4927       SUMA_set_mont((SUMA_ALL_DO *)SF->NewValueCallbackData, SF->variant,
4928                      &val1, &val2, "text_field", 1);
4929    }
4930 
4931    SUMA_RETURNe;
4932 }
4933 
SUMA_SliceF_SetString(SUMA_SLICE_FIELD * SF)4934 void SUMA_SliceF_SetString (SUMA_SLICE_FIELD * SF)
4935 {
4936    static char FuncName[]={"SUMA_SliceF_SetString"};
4937    char buf[36];
4938 
4939    SUMA_ENTRY;
4940 
4941    if (SF->slice_units == SUMA_NO_NUM_UNITS) {
4942       sprintf (buf, "%-4d", (int)SF->slice_num);
4943    }else if (SF->slice_units == SUMA_MM_UNITS) {
4944       sprintf (buf, "%s",
4945                MV_format_fval2(  SF->slice_num, 3));
4946    }else {
4947       /* fair enough, must be stringy */
4948    }
4949 
4950    XtVaSetValues (SF->text, XmNvalue, buf, NULL);
4951    SUMA_RETURNe;
4952 }
4953 
4954 
4955 /*!
4956    \brief This function is called when the label field is activated by the user
4957 \*/
SUMA_TableF_cb_label_change(Widget w,XtPointer client_data,XtPointer call_data)4958 void SUMA_TableF_cb_label_change (  Widget w, XtPointer client_data,
4959                                     XtPointer call_data)
4960 {
4961    static char FuncName[]={"SUMA_TableF_cb_label_change"};
4962    SUMA_TABLE_FIELD *TF=NULL;
4963    float val;
4964    int N_words = 0;
4965    XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
4966    void *n=NULL;
4967    char *cs=NULL;
4968    int unt = SUMA_NO_NUM_UNITS;
4969    SUMA_Boolean DoCallBacks;
4970    SUMA_Boolean LocalHead = NOPE;
4971 
4972    SUMA_ENTRY;
4973 
4974    SUMA_LH("Called");
4975    /* make call to NewValue callback */
4976    TF = (SUMA_TABLE_FIELD *)client_data;
4977 
4978    DoCallBacks = NOPE;
4979    if (call_data) {
4980       /* do the call backs if carriage return even if nothing is modified */
4981       if (LocalHead)
4982          fprintf (SUMA_STDERR,"%s: cbs->reason = %d (CR=%d)\n",
4983                               FuncName, cbs->reason, XmCR_ACTIVATE);
4984       if (cbs->reason == XmCR_ACTIVATE) {
4985          DoCallBacks = YUP;
4986       }
4987    }
4988 
4989    if (TF->cell_modified >= 0) {
4990       DoCallBacks = YUP;   /* do the callbacks even if no carriage return ... */
4991       if (TF->type == SUMA_int || TF->type == SUMA_float) {
4992          /* Check if the string is numerical, and get unit */
4993          XtVaGetValues (w, XmNvalue, &n, NULL);
4994          cs = (char *)n;
4995          if (!cs || !strlen(cs)) {/* empty cell, leave it alone */
4996             TF->cell_modified = -1;
4997             SUMA_LHv("empty %s", cs);
4998             SUMA_RETURNe;
4999          } else  {
5000             SUMA_COUNT_WORDS(cs, NULL, N_words);
5001             if (!N_words) { /* no harm, go back */
5002                TF->cell_modified = -1;
5003                SUMA_LHv("spacy %s", cs);
5004                SUMA_RETURNe;
5005             }
5006          }
5007          unt = SUMA_NumStringUnits(cs, 0);
5008          if (SUMA_StringToNum(cs, (void *)&val, 1, 1) != 1) {
5009             SUMA_BEEP;
5010             /* bad syntax, reset value*/
5011             if (LocalHead) fprintf (SUMA_STDERR, "%s: Bad syntax.\n", FuncName);
5012             SUMA_RegisterMessage (SUMAg_CF->MessageList,
5013                                   "Bad value in text field", FuncName,
5014                                   SMT_Error, SMA_Log);
5015             SUMA_TableF_SetString (TF);
5016          }else {
5017             if (TF->type == SUMA_int) {
5018                if (TF->num_value[TF->cell_modified] == (int)val &&
5019                    TF->num_units == unt ) {
5020                   SUMA_LH("Same value");
5021                   TF->cell_modified = -1;
5022                   SUMA_RETURNe;
5023                }
5024                TF->num_value[TF->cell_modified] = (int)val;
5025             } else if (TF->type == SUMA_float) {
5026                if (TF->num_value[TF->cell_modified] == val &&
5027                    TF->num_units == unt) {
5028                   SUMA_LH("Same value");
5029                   TF->cell_modified = -1;
5030                   SUMA_RETURNe;
5031                }
5032                TF->num_value[TF->cell_modified] = val;
5033             }
5034             SUMA_LH("Going to set string");
5035             TF->num_units = unt;
5036             SUMA_TableF_SetString (TF);
5037          }
5038       } else if (TF->type == SUMA_string) {
5039          XtVaGetValues (w, XmNvalue, &n, NULL);
5040          cs = (char *)n;
5041          if ( TF->str_value && TF->str_value[TF->cell_modified] &&
5042              !strcmp(TF->str_value[TF->cell_modified],cs)) {
5043                SUMA_LH("Same string");
5044                TF->cell_modified = -1;
5045                SUMA_RETURNe;
5046          }
5047          SUMA_LH("Here now, modified %d \n", TF->cell_modified);
5048       }
5049    } else {
5050       SUMA_LH("no cells modified");
5051    }
5052 
5053    if (DoCallBacks) {
5054       SUMA_LH("CallBacks ...");
5055       if (TF->cell_modified < 0) {
5056          /* figure out which one, user insists on value */
5057          SUMA_WHICH_CELL(TF, w, TF->cell_modified);
5058       }
5059       if (!TF->NewValueCallbackData) {
5060          SUMA_LH("No Callback data.");
5061          if (TF->NewValueCallback) TF->NewValueCallback((void*)TF);
5062       } else {
5063          SUMA_LH("Callback data.");
5064          if (TF->NewValueCallback)
5065             TF->NewValueCallback(TF->NewValueCallbackData);
5066       }
5067    }
5068 
5069    TF->cell_modified = -1;
5070    SUMA_RETURNe;
5071 }
5072 
SUMA_SliceVal2ScalePos(SUMA_ALL_DO * ado,char * variant,float * val)5073 int  SUMA_SliceVal2ScalePos (SUMA_ALL_DO *ado, char *variant, float *val)
5074 {
5075    static char FuncName[]={"SUMA_SliceVal2ScalePos"};
5076    int min_v=0, max_v=0, cv=0, scl=0, dec=0;
5077    float ftmp;
5078    Widget w = NULL;
5079    SUMA_X_SurfCont *SurfCont=NULL;
5080    SUMA_VOL_SAUX *VSaux=NULL;
5081    SUMA_Boolean LocalHead = NOPE;
5082 
5083    SUMA_ENTRY;
5084 
5085    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))
5086        || !(VSaux = SUMA_ADO_VSaux(ado)) || !variant) {
5087       SUMA_SL_Err("Null ado or no SurfCont"); SUMA_RETURN(0);
5088    }
5089    if (variant[0] == 'A') {
5090       w = SurfCont->Ax_slc->sl;
5091    } else if (variant[0] == 'S') {
5092       w = SurfCont->Sa_slc->sl;
5093    } else if (variant[0] == 'C') {
5094       w = SurfCont->Co_slc->sl;
5095    }
5096    if (!w) { SUMA_SL_Err("Null widget"); SUMA_RETURN(0); }
5097 
5098    if (XtIsRealized(w)) {
5099       XtVaGetValues(w, XmNuserData, &dec, NULL);
5100       XtVaGetValues( w,
5101                      XmNmaximum, &max_v,
5102                      XmNminimum, &min_v,
5103                      XmNvalue, &cv,
5104                      XmNscaleMultiple, &scl,
5105                      NULL);
5106    } else {
5107       SUMA_S_Note("Slider widget not realized"); SUMA_RETURN(0);
5108    }
5109 
5110    if (*val < 0) { /* ignore sign */
5111       *val = -*val;
5112    }
5113    SUMA_LHv("min %d max %d scalemult %d decimals %d\nCurrent scale value %d\n",
5114             min_v, max_v, scl, dec, cv);
5115 
5116    /* what is the new slider value to be ?*/
5117    ftmp = *val * pow(10.0, dec);
5118    if (ftmp > 0) cv = (int) (ftmp+0.5);
5119    else cv = (int) (ftmp-0.5);
5120 
5121    /* Now check on the new cv */
5122    if (cv < min_v) {
5123       cv = min_v;
5124       /* must update threshold value in options structure*/
5125       *val = (float)cv / pow(10.0, dec);
5126    } else if (cv > max_v) {
5127       cv = max_v;
5128       *val = (float)cv / pow(10.0, dec);
5129    }
5130 
5131    SUMA_RETURN(cv);
5132 }
5133 
5134 
5135 /*!
5136    threshold value to scale value (position)
5137    NOTE val's value might change if it is outside the slider range
5138    or if it is negative when the slider is in |T| mode
5139 */
SUMA_ThreshVal2ScalePos(SUMA_ALL_DO * ado,float * val)5140 int SUMA_ThreshVal2ScalePos(SUMA_ALL_DO *ado, float *val)
5141 {
5142    static char FuncName[]={"SUMA_ThreshVal2ScalePos"};
5143    int min_v=0, max_v=0, cv=0, scl=0, dec=0;
5144    float ftmp;
5145    Widget w = NULL;
5146    SUMA_X_SurfCont *SurfCont=NULL;
5147    SUMA_OVERLAYS *curColPlane=NULL;
5148    SUMA_Boolean LocalHead = NOPE;
5149 
5150    SUMA_ENTRY;
5151 
5152    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) {
5153       SUMA_SL_Err("Null ado or no SurfCont"); SUMA_RETURN(0);
5154    }
5155    curColPlane = SUMA_ADO_CurColPlane(ado);
5156    w = SurfCont->thr_sc;
5157    if (!w) { SUMA_SL_Err("Null widget"); SUMA_RETURN(0); }
5158 
5159    if (XtIsRealized(w)) {
5160       XtVaGetValues(w, XmNuserData, &dec, NULL);
5161       XtVaGetValues( w,
5162                      XmNmaximum, &max_v,
5163                      XmNminimum, &min_v,
5164                      XmNvalue, &cv,
5165                      XmNscaleMultiple, &scl,
5166                      NULL);
5167    } else {
5168       SUMA_S_Note("Slider widget not realized"); SUMA_RETURN(0);
5169    }
5170    if (*val < 0 &&
5171        curColPlane->OptScl->ThrMode == SUMA_ABS_LESS_THAN) {
5172       *val = -*val;
5173    }
5174    SUMA_LHv("min %d max %d scalemult %d decimals %d\nCurrent scale value %d\n",
5175             min_v, max_v, scl, dec, cv);
5176 
5177    /* what is the new slider value to be ?*/
5178    ftmp = *val * pow(10.0, dec);
5179    if (ftmp > 0) cv = (int) (ftmp+0.5);
5180    else cv = (int) (ftmp-0.5);
5181 
5182    /* Now check on the new cv */
5183    if (cv < min_v) {
5184       cv = min_v;
5185       /* must update threshold value in options structure*/
5186       *val = (float)cv / pow(10.0, dec);
5187    } else if (cv > max_v) {
5188       cv = max_v;
5189       *val = (float)cv / pow(10.0, dec);
5190    }
5191 
5192    SUMA_RETURN(cv);
5193 }
5194 
SUMA_Pval2ThreshVal(SUMA_ALL_DO * ado,double pval)5195 double SUMA_Pval2ThreshVal (SUMA_ALL_DO *ado, double pval)
5196 {
5197    static char FuncName[]={"SUMA_Pval2ThreshVal"};
5198    float p[3], zval = -1.0;
5199    int statcode;
5200    double val = 0.0;
5201    SUMA_X_SurfCont *SurfCont=NULL;
5202    SUMA_OVERLAYS *curColPlane=NULL;
5203    SUMA_Boolean LocalHead = NOPE;
5204 
5205    SUMA_ENTRY;
5206 
5207    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) {
5208       SUMA_SL_Err("Null ado or no SurfCont"); SUMA_RETURN(val);
5209    }
5210    curColPlane = SUMA_ADO_CurColPlane(ado);
5211 
5212    if (!SurfCont ||
5213        !SurfCont->thr_sc ||
5214        !curColPlane ||
5215        !curColPlane->dset_link) {
5216       SUMA_SL_Err("NULL SurfCont or other things");
5217       SUMA_RETURN(val);
5218    }
5219 
5220    /* see if you can get the stat codes */
5221    if (!SUMA_GetDsetColStatAttr(
5222             curColPlane->dset_link,
5223             curColPlane->OptScl->tind,
5224             &statcode,
5225             p, (p+1), (p+2))) {
5226       SUMA_LH("Error");
5227    }else if (statcode) {
5228       SUMA_LHv("Have stats at sb %d\n"
5229                "statcode %d: %f %f %f\n",
5230                curColPlane->OptScl->tind,
5231                statcode, p[0], p[1], p[2]);
5232       curColPlane->OptScl->ThreshStats[0] = pval;
5233       val = THD_pval_to_stat( pval , statcode , p  ) ;
5234       SUMA_LHv("Have pval of %f\n"
5235                "      val of %f\n",
5236                curColPlane->OptScl->ThreshStats[0],val);
5237    } else {
5238       /* no stats */
5239       curColPlane->OptScl->ThreshStats[0] = -1.0;
5240       curColPlane->OptScl->ThreshStats[1] = -1.0;
5241    }
5242 
5243    SUMA_RETURN(val);
5244 }
5245 
5246 
5247 /*!
5248    set the threshold bar when a new value is entered
5249 
5250    Crash note for suma in macosx_10.7_Intel_64 binaries.
5251 
5252 With gcc 4.7.0 and 4.7.1, SUMA crashed when two hemispheres are loaded
5253 and the threshold level is changed for one hemisphere. Because of LR yoking
5254 the contralateral hemisphere is subject to the threshold change too.
5255 This works fine on all other binaries but with binaries from SARUMAN which use
5256 gcc 4.7.1, rather than the older gcc 4.2.1. The stack at the crash reliably pointed
5257 to SUMA_SetScaleThr_one(), right after the call to SUMA_ThreshVal2ScalePos().
5258 Debugging messages show that SUMA_ThreshVal2ScalePos() returns OK, but not even
5259 a simple statement can get printed right afterwards. Valgrind showed no relevant
5260 errors.
5261    To reproduce the problem, use the toy surfaces under std10_toy. Something like
5262  suma -spec std.10both.mini.spec , followed by ctrl+s and a few threshold adjustments
5263  is enough to cause the crash.
5264 
5265 */
SUMA_SetScaleThr_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,float * val,int setmen,int redisplay)5266 int SUMA_SetScaleThr_one(SUMA_ALL_DO *ado, SUMA_OVERLAYS *colp,
5267                           float *val, int setmen, int redisplay)
5268 {
5269    static char FuncName[]={"SUMA_SetScaleThr_one"};
5270    SUMA_ALL_DO *curDO = NULL;
5271    SUMA_TABLE_FIELD *TF=NULL;
5272    int cv=0;
5273    SUMA_X_SurfCont *SurfCont=NULL;
5274    SUMA_OVERLAYS *curColPlane=NULL;
5275    SUMA_Boolean LocalHead = NOPE;
5276 
5277    SUMA_ENTRY;
5278 
5279    SUMA_LH("Called");
5280 
5281    if (!(SurfCont=SUMA_ADO_Cont(ado)) ||
5282        !SurfCont->SetThrScaleTable) SUMA_RETURN(0);
5283    curColPlane = SUMA_ADO_CurColPlane(ado);
5284    if (colp && colp != curColPlane) SUMA_RETURN(0);
5285 
5286    if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
5287       SUMA_S_Err("Failed to get curDOp");
5288       SUMA_RETURN(0);
5289    }
5290    TF = SurfCont->SetThrScaleTable;
5291 
5292    switch (TF->num_units) {
5293       case SUMA_P_VALUE_UNITS:
5294          if (LocalHead)
5295                fprintf( SUMA_STDERR,
5296                         "%s:\nUnits in p value, transforming %f\n",
5297                         FuncName, *val);
5298          /* transform value from P to threshold value */
5299          *val = (float)SUMA_Pval2ThreshVal (ado, (double)*val);
5300          if (LocalHead)
5301                fprintf( SUMA_STDERR,
5302                         "   to %f\n",
5303                         *val);
5304          /* reset the units of the table to reflect new value,
5305             string containing new val is reset later on*/
5306          TF->num_units = SUMA_NO_NUM_UNITS;
5307          break;
5308       case SUMA_PERC_VALUE_UNITS:
5309          SUMA_LH("Units in percentile value, transforming %f\n", *val);
5310          *val = SUMA_OverlayPercentile(colp, 'T', *val);
5311          TF->num_units = SUMA_NO_NUM_UNITS;
5312          break;
5313       default:
5314          break;
5315    }
5316 
5317    cv = SUMA_ThreshVal2ScalePos (ado, val );
5318 
5319    if (LocalHead)
5320       fprintf(SUMA_STDERR,
5321               "%s:\nChecksums, new value is %f, cv to be set to %d\n"
5322               "val now %f\n",
5323               FuncName, TF->num_value[0], cv, *val);
5324 
5325    /* TF->cell_modifed is not good when the call is made
5326    as a result of LR controller yoking. So don't bother using it.
5327    We only have one cell to be modified anyway. ZSS Sept 11 2012 */
5328 
5329    /* check on value */
5330    if (TF->num_value[0] != *val) {
5331       /* a change in value (plateau effect) */
5332       TF->num_value[0] = *val;
5333       if (!setmen) setmen = 1;
5334    }
5335 
5336    if (setmen) {
5337       SUMA_INSERT_CELL_VALUE(TF, 0, 0, *val);
5338    }
5339 
5340    if (LocalHead)
5341       fprintf( SUMA_STDERR,
5342                "%s:\nSet thresholdiation, new value is %f\n",
5343                FuncName, *val);
5344    /* if value OK, set threshold bar*/
5345    curColPlane->OptScl->ThreshRange[0] = *val;
5346    XtVaSetValues(SurfCont->thr_sc,
5347             XmNvalue, cv,
5348             NULL);
5349 
5350    SUMA_LHv("Colorize if necessary, redisplay=%d\n", redisplay);
5351    /* colorize if necessary */
5352    if ( redisplay == 0 ||
5353         (redisplay == 1 && !curColPlane->OptScl->UseThr) ) {
5354       SUMA_RETURN(0);
5355    } /* nothing else to do */
5356 
5357 
5358    SUMA_ADO_Flush_Pick_Buffer(ado, NULL);
5359 
5360    SUMA_LH("Colorize");
5361    if (!SUMA_ColorizePlane (curColPlane)) {
5362       SUMA_SLP_Err("Failed to colorize plane.\n");
5363       SUMA_RETURN(0);
5364    }
5365 
5366    SUMA_LH("Remix redisplay");
5367    SUMA_Remixedisplay(ado);
5368 
5369    SUMA_UpdateNodeLblField(ado);
5370    SUMA_UpdatePvalueField( ado,
5371                            curColPlane->OptScl->ThreshRange[0]);
5372    SUMA_RETURN(1);
5373 }
5374 
SUMA_SetScaleThr(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,float * val,int setmen,int redisplay)5375 int SUMA_SetScaleThr(SUMA_ALL_DO *ado, SUMA_OVERLAYS *colp,
5376                           float *val, int setmen, int redisplay)
5377 {
5378    static char FuncName[]={"SUMA_SetScaleThr"};
5379    SUMA_X_SurfCont *SurfCont=NULL;
5380    SUMA_OVERLAYS *curColPlane=NULL;
5381 
5382    SUMA_Boolean LocalHead = NOPE;
5383 
5384    SUMA_ENTRY;
5385 
5386    SUMA_LH("Called");
5387 
5388    SurfCont = SUMA_ADO_Cont(ado);
5389    curColPlane = SUMA_ADO_CurColPlane(ado);
5390    if (!ado || !SurfCont || !curColPlane) SUMA_RETURN(0);
5391 
5392    if (colp && colp != curColPlane) SUMA_RETURN(0);
5393    colp = curColPlane;
5394 
5395    if (!SUMA_SetScaleThr_one(ado, colp, val, setmen, redisplay)) SUMA_RETURN(0);
5396 
5397    if (ado->do_type == SO_type) {
5398       SUMA_SurfaceObject *SOC=NULL, *SO = (SUMA_SurfaceObject *)ado;
5399       SUMA_OVERLAYS *colpC=NULL;
5400       /* do we have a contralateral SO and overlay? */
5401       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
5402       if (colpC && SOC) {
5403          SUMA_LHv("Found contralateral equivalent to:\n"
5404                       " %s and %s in\n"
5405                       " %s and %s\n",
5406                       SO->Label, CHECK_NULL_STR(colp->Label),
5407                       SOC->Label, CHECK_NULL_STR(colpC->Label));
5408          if (!SUMA_SetScaleThr_one((SUMA_ALL_DO *)SOC,
5409                                     colpC, val, 1, redisplay)) SUMA_RETURN(0);
5410       }
5411    }
5412    SUMA_RETURN(1);
5413 }
5414 
SUMA_cb_SetScaleThr(void * data)5415 void SUMA_cb_SetScaleThr(void *data)
5416 {
5417    static char FuncName[]={"SUMA_cb_SetScaleThr"};
5418    SUMA_ALL_DO *ado=(SUMA_ALL_DO *)data, *curDO = NULL;
5419    SUMA_TABLE_FIELD *TF=NULL;
5420    int cv, max_v, min_v, cell_mod = -1;
5421    float val;
5422    SUMA_X_SurfCont *SurfCont=NULL;
5423    SUMA_OVERLAYS *curColPlane=NULL;
5424    SUMA_Boolean LocalHead = NOPE;
5425 
5426    SUMA_ENTRY;
5427 
5428    SUMA_LH("Called");
5429    if (!ado) SUMA_RETURNe;
5430    SurfCont = SUMA_ADO_Cont(ado);
5431    curColPlane = SUMA_ADO_CurColPlane(ado);
5432    if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
5433       SUMA_S_Err("Failed to get curDOp");
5434       SUMA_RETURNe;
5435    }
5436    TF = SurfCont->SetThrScaleTable;
5437    if (TF->cell_modified<0) SUMA_RETURNe;
5438    val = TF->num_value[TF->cell_modified];
5439 
5440    SUMA_SetScaleThr(ado, NULL, &val, 0, 1);
5441 
5442    SUMA_RETURNe;
5443 }
5444 
5445 /*!
5446    \brief Sends the Focus triangle  when new value is entered
5447 */
SUMA_TriInput(void * data)5448 void SUMA_TriInput (void *data)
5449 {
5450    static char FuncName[]={"SUMA_TriInput"};
5451    SUMA_ALL_DO *ado=(SUMA_ALL_DO *)data, *curDO=NULL;
5452    SUMA_SurfaceObject *SO=NULL, *curSO = NULL;
5453    SUMA_TABLE_FIELD *TF=NULL;
5454    int i, n, j;
5455    void *cv=NULL;
5456    float fv3[3];
5457    char str[100];
5458    SUMA_X_SurfCont *SurfCont=NULL;
5459    SUMA_Boolean LocalHead = NOPE;
5460 
5461    SUMA_ENTRY;
5462 
5463    SUMA_LH("Called");
5464    SurfCont = SUMA_ADO_Cont(ado);
5465    if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
5466       SUMA_S_Err("Failed to get curDOp");
5467       SUMA_RETURNe;
5468    }
5469 
5470    if (ado->do_type != SO_type || curDO->do_type != SO_type) {
5471       SUMA_S_Err("Should not call this");
5472       SUMA_RETURNe;
5473    }
5474    SO = (SUMA_SurfaceObject *)ado;
5475    curSO = (SUMA_SurfaceObject *)curDO;
5476 
5477    TF = SO->SurfCont->FaceTable;
5478    if (TF->cell_modified<0) SUMA_RETURNe;
5479    n = TF->cell_modified;
5480    i = n % TF->Ni;
5481    j = n / TF->Ni;
5482 
5483    if ((int)TF->num_value[n] < 0 || (int)TF->num_value[n] >= curSO->N_FaceSet) {
5484       SUMA_SLP_Err("Triangle index n must be positive\n"
5485                    "and less than the number of nodes \n"
5486                    "forming the surface.\n");
5487       TF->num_value[n] = SO->SelectedFaceSet;
5488       SUMA_TableF_SetString (TF);
5489       TF->cell_modified = -1;
5490       SUMA_RETURNe;
5491    }
5492 
5493    switch (j) {
5494       case 1:
5495          XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
5496          if (LocalHead) {
5497             fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s, Tri = %d\n",
5498                   FuncName, i, j, (char *)cv, (int)TF->num_value[n]);
5499          }
5500 
5501          /* look for a viewer that is showing this surface and
5502             has this surface in focus*/
5503          for (i=0; i<SUMAg_N_SVv; ++i) {
5504             SUMA_LHv("Checking viewer %d.\n", i);
5505             if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
5506                /* is this viewer showing curSO ? */
5507                if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
5508                                     (SUMA_ALL_DO *)curSO)) {
5509                   if (SUMA_SV_Focus_SO(&(SUMAg_SVv[i])) == curSO) {
5510                      SUMA_JumpFocusFace((char *)cv, (void *)(&(SUMAg_SVv[i])));
5511                   }
5512                }
5513             }
5514          }
5515          break;
5516       default:
5517          SUMA_SL_Err("Should not get this input");
5518          break;
5519    }
5520    SUMA_RETURNe;
5521 }
5522 /*!
5523    \brief Sends the node/datum flying when new value is entered
5524 */
SUMA_NodeInput(void * data)5525 void SUMA_NodeInput (void *data)
5526 {
5527    static char FuncName[]={"SUMA_NodeInput"};
5528    SUMA_ALL_DO *ado=(SUMA_ALL_DO *)data, *curDO = NULL;
5529    SUMA_TABLE_FIELD *TF=NULL;
5530    int i, n, j;
5531    void *cv=NULL;
5532    float fv3[3];
5533    char str[100];
5534    SUMA_X_SurfCont *SurfCont=NULL;
5535    SUMA_Boolean LocalHead = NOPE;
5536 
5537    SUMA_ENTRY;
5538 
5539    SUMA_LH("Called");
5540 
5541    SurfCont = SUMA_ADO_Cont(ado);
5542 
5543    if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
5544       SUMA_S_Err("Failed to get curDOp");
5545       SUMA_RETURNe;
5546    }
5547    TF = SurfCont->NodeTable;
5548    if (TF->cell_modified<0) SUMA_RETURNe;
5549    n = TF->cell_modified;
5550    i = n % TF->Ni;
5551    j = n / TF->Ni;
5552 
5553    if ((int)TF->num_value[n] < 0 ||
5554        (int)TF->num_value[n] > SUMA_ADO_Max_Datum_Index(ado)) {
5555       SUMA_SLP_Err("Node/Voxel/etc index must be positive and \n"
5556                    "less than the number of nodes \n"
5557                    "forming the surface.\n");
5558       TF->num_value[n] = SUMA_ADO_SelectedDatum(ado, NULL, NULL);
5559       SUMA_TableF_SetString (TF);
5560       TF->cell_modified = -1;
5561       SUMA_RETURNe;
5562    }
5563    if (ado->do_type == MASK_type) {
5564       SUMA_S_Warn("Have not dealt with masks yet");
5565       SUMA_RETURNe;
5566    }
5567    switch (j) {
5568       case 1:
5569          XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
5570          if (LocalHead) {
5571             fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s, node = %d\n",
5572                   FuncName, i, j, (char *)cv, (int)TF->num_value[n]);
5573          }
5574 
5575          /* look for a viewer that is showing this surface and
5576             has this surface in focus*/
5577          for (i=0; i<SUMAg_N_SVv; ++i) {
5578             SUMA_LHv("Checking viewer %d.\n", i);
5579             if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
5580                /* is this viewer showing curSO ? */
5581                if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
5582                                     curDO)) {
5583                   if (SUMA_SV_Focus_ADO(&(SUMAg_SVv[i])) == curDO) {
5584                         SUMA_JumpIndex((char *)cv, (void *)(&(SUMAg_SVv[i])));
5585                   }
5586                }
5587             }
5588          }
5589          break;
5590       case 2:
5591          XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
5592          if (LocalHead) {
5593             fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s, node = %d\n",
5594                   FuncName, i, j, (char *)cv, (int)TF->num_value[n]);
5595          }
5596          switch (ado->do_type) {
5597             case TRACT_type:
5598                for (i=0; i<SUMAg_N_SVv; ++i) {
5599                   SUMA_LHv("Checking viewer %d.\n", i);
5600                   if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
5601                      /* is this viewer showing curDO ? */
5602                      if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
5603                                           curDO)) {
5604                         if (SUMA_SV_Focus_ADO(&(SUMAg_SVv[i])) == curDO) {
5605                                  SUMA_JumpIndex((char *)cv,
5606                                                 (void *)(&(SUMAg_SVv[i])));
5607                         }
5608                      }
5609                   }
5610                }
5611                break;
5612             default:
5613                SUMA_LH("Nothing to do here");
5614                break;
5615          }
5616          break;
5617       default:
5618          SUMA_SL_Err("Should not get this input");
5619          break;
5620    }
5621    SUMA_RETURNe;
5622 }
5623 
5624 
SUMA_IJKInput(void * data)5625 void SUMA_IJKInput(void *data) {
5626    SUMA_TpointInput (data);
5627    return;
5628 }
5629 /*!
5630    \brief Sends the node/datum flying when new value is entered
5631 */
SUMA_TpointInput(void * data)5632 void SUMA_TpointInput (void *data)
5633 {
5634    static char FuncName[]={"SUMA_TpointInput"};
5635    SUMA_ALL_DO *ado=(SUMA_ALL_DO *)data, *curDO = NULL;
5636    SUMA_TABLE_FIELD *TF=NULL;
5637    int i, n, j;
5638    void *cv=NULL;
5639    float fv3[3];
5640    char str[100];
5641    SUMA_X_SurfCont *SurfCont=NULL;
5642    SUMA_Boolean LocalHead = NOPE;
5643 
5644    SUMA_ENTRY;
5645 
5646    SUMA_LH("Called");
5647 
5648    SurfCont = SUMA_ADO_Cont(ado);
5649 
5650    if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
5651       SUMA_S_Err("Failed to get curDOp");
5652       SUMA_RETURNe;
5653    }
5654    TF = SurfCont->FaceTable;
5655    if (TF->cell_modified<0) SUMA_RETURNe;
5656    n = TF->cell_modified;
5657    i = n % TF->Ni;
5658    j = n / TF->Ni;
5659 
5660    switch (j) {
5661       case 1:
5662          XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
5663          if (LocalHead) {
5664             fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s\n",
5665                   FuncName, i, j, (char *)cv);
5666          }
5667 
5668          /* look for a viewer that is showing this surface and
5669             has this surface in focus*/
5670          for (i=0; i<SUMAg_N_SVv; ++i) {
5671             SUMA_LHv("Checking viewer %d.\n", i);
5672             if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
5673                /* is this viewer showing curSO ? */
5674                if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
5675                                     curDO)) {
5676                   if (SUMA_SV_Focus_ADO(&(SUMAg_SVv[i])) == curDO) {
5677                         SUMA_JumpIndex((char *)cv, (void *)(&(SUMAg_SVv[i])));
5678                   }
5679                }
5680             }
5681          }
5682          break;
5683       default:
5684          SUMA_SL_Err("Should not get this input");
5685          break;
5686    }
5687    SUMA_RETURNe;
5688 }
5689 
5690 /* What happens when you select a graph's node?
5691 THis is parallel to SUMA_TriInput */
SUMA_GNodeInput(void * data)5692 void SUMA_GNodeInput (void *data)
5693 {
5694    static char FuncName[]={"SUMA_GNodeInput"};
5695    SUMA_ALL_DO *ado=(SUMA_ALL_DO *)data, *curDO = NULL;
5696    SUMA_TABLE_FIELD *TF=NULL;
5697    int i, n, j;
5698    void *cv=NULL;
5699    float fv3[3];
5700    char str[100];
5701    SUMA_X_SurfCont *SurfCont=NULL;
5702    SUMA_GRAPH_SAUX *GSaux=NULL;
5703    SUMA_DSET *dset = NULL;
5704 
5705    SUMA_Boolean LocalHead = NOPE;
5706 
5707    SUMA_ENTRY;
5708 
5709    SUMA_LH("Called");
5710 
5711    if (!ado || ado->do_type != GRAPH_LINK_type) {
5712       SUMA_S_Err("NULL/bad input");
5713       SUMA_RETURNe;
5714    }
5715    dset = SUMA_find_GLDO_Dset((SUMA_GraphLinkDO*)ado);
5716    GSaux = SDSET_GSAUX(dset);
5717 
5718    SurfCont = SUMA_ADO_Cont(ado);
5719 
5720    if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
5721       SUMA_S_Err("Failed to get curDOp");
5722       SUMA_RETURNe;
5723    }
5724    TF = SurfCont->FaceTable;
5725    if (TF->cell_modified<0) SUMA_RETURNe;
5726    n = TF->cell_modified;
5727    i = n % TF->Ni;
5728    j = n / TF->Ni;
5729 
5730    if ((int)TF->num_value[n] < 0 ||
5731        (int)TF->num_value[n] < dset->Aux->range_node_index[0] ||
5732        (int)TF->num_value[n] > dset->Aux->range_node_index[1]) {
5733       SUMA_SLP_Err("Node index must be positive and \n"
5734                    "less than the number of nodes \n"
5735                    "forming the surface.\n");
5736       TF->num_value[n] = GSaux->PR->iAltSel[SUMA_ENODE_0];
5737       SUMA_TableF_SetString (TF);
5738       TF->cell_modified = -1;
5739       SUMA_RETURNe;
5740    }
5741 
5742    switch (j) {
5743       case 1:
5744          XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
5745          if (LocalHead) {
5746             fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s, node = %d\n",
5747                   FuncName, i, j, (char *)cv, (int)TF->num_value[n]);
5748          }
5749 
5750          for (i=0; i<SUMAg_N_SVv; ++i) {
5751             SUMA_LHv("Checking viewer %d.\n", i);
5752             if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
5753                /* is this viewer showing curSO ? */
5754                if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv,
5755                                     curDO)) {
5756                   if (SUMA_SV_Focus_ADO(&(SUMAg_SVv[i])) == curDO) {
5757                         /* FocusFace works for this one too */
5758                         SUMA_JumpFocusFace((char *)cv,
5759                                             (void *)(&(SUMAg_SVv[i])));
5760                   }
5761                }
5762             }
5763          }
5764          break;
5765       default:
5766          SUMA_SL_Err("Should not get this input");
5767          break;
5768    }
5769    SUMA_RETURNe;
5770 }
5771 /*!
5772    \brief Sends the cross hair flying when new value is entered
5773 */
SUMA_XhairInput(void * data)5774 void SUMA_XhairInput (void* data)
5775 {
5776    static char FuncName[]={"SUMA_XhairInput"};
5777    SUMA_ALL_DO *ado=(SUMA_ALL_DO *)data, *curDO = NULL;
5778    SUMA_X_SurfCont *SurfCont=NULL;
5779    SUMA_SurfaceViewer *sv=NULL;
5780    SUMA_TABLE_FIELD *TF=NULL;
5781    int i, n, j;
5782    void *cv=NULL;
5783    float fv3[3];
5784    char str[100];
5785    SUMA_Boolean LocalHead = NOPE;
5786 
5787    SUMA_ENTRY;
5788 
5789    SUMA_LH("Called");
5790    SurfCont = SUMA_ADO_Cont(ado);
5791 
5792    if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
5793       SUMA_S_Err("Failed to get curDOp");
5794       SUMA_RETURNe;
5795    }
5796    TF = SurfCont->XhairTable;
5797    if (TF->cell_modified<0) SUMA_RETURNe;
5798    SUMA_LH("Cell modified, modifying ...");
5799    n = TF->cell_modified;
5800    i = n % TF->Ni;
5801    j = n / TF->Ni;
5802    XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
5803    if (LocalHead) {
5804       fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s\n",
5805                FuncName, i, j, (char *)cv);
5806    }
5807    /* Now parse that string into 3 numbers */
5808    if (SUMA_StringToNum ((char *)cv, (void *)fv3, 3,1) != 3) {
5809       SUMA_BEEP;
5810       str[0]='\0';
5811    } else {
5812       SUMA_XHAIR_STRING(fv3, str);
5813    }
5814    XtVaSetValues(TF->cells[n], XmNvalue, str, NULL);
5815 
5816    /* look for a viewer that is showing this surface */
5817    for (i=0; i<SUMAg_N_SVv; ++i) {
5818       if (LocalHead)
5819          fprintf (SUMA_STDERR,"%s: Checking viewer %d.\n", FuncName, i);
5820       if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
5821          /* is this viewer showing curDO ? */
5822          sv = &(SUMAg_SVv[i]);
5823          if (SUMA_isVisibleDO(sv, SUMAg_DOv, curDO)) {
5824             /* is this a new coordinate?
5825                Avoid calls due to cosmetic text changes */
5826             if (sv->Ch->c[0] != fv3[0] ||
5827                 sv->Ch->c[1] != fv3[1] || sv->Ch->c[2] != fv3[2]) {
5828                if (LocalHead) fprintf(SUMA_STDERR,
5829                                       "%s: Calling for jump to %s\n",
5830                                       FuncName, str);
5831                SUMA_JumpXYZ(str, (void *)(&(SUMAg_SVv[i])));
5832             }
5833          }
5834       }
5835    }
5836    SUMA_RETURNe;
5837 }
5838 
5839 
5840 #define SETMEN (setmen > 1 || (setmen && isCur))
5841 #define REDISP (redisplay > 1 || (redisplay && NewDisp))
5842 
SUMA_SetRangeValueNew_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int row,int col,float v1,float v2,int setmen,int redisplay,float * reset,SUMA_NUMERICAL_UNITS num_units)5843 int SUMA_SetRangeValueNew_one(SUMA_ALL_DO *ado,
5844                           SUMA_OVERLAYS *colp,
5845                           int row, int col,
5846                           float v1, float v2,
5847                           int setmen,
5848                           int redisplay, float *reset,
5849                           SUMA_NUMERICAL_UNITS num_units)
5850 {
5851    static char FuncName[]={"SUMA_SetRangeValueNew_one"};
5852    int NewDisp=0, isCur=0;
5853    SUMA_X_SurfCont *SurfCont=NULL;
5854    SUMA_OVERLAYS *curColPlane=NULL;
5855    SUMA_TABLE_FIELD *TF=NULL;
5856    SUMA_Boolean LocalHead = NOPE;
5857 
5858    SUMA_ENTRY;
5859 
5860    if (LocalHead) {
5861       SUMA_DUMP_TRACE("Who called SUMA_SetRangeValueNew_one?");
5862    }
5863 
5864    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado)) ||
5865        !SurfCont->SetRangeTable || !reset) {
5866       SUMA_RETURN(0);
5867    }
5868    curColPlane = SUMA_ADO_CurColPlane(ado);
5869    if (!colp) colp = curColPlane;
5870 
5871    if (colp && colp == curColPlane) {
5872       isCur=YUP;
5873    } else {
5874       isCur=NOPE;
5875    }
5876 
5877    if (!colp) {
5878       SUMA_RETURN(0); /* not much to do */
5879    }
5880 
5881    if (colp->SymIrange) { /* must set table fields in this case */
5882       if (!setmen) setmen = 1;
5883    }
5884 
5885    TF = SurfCont->SetRangeTable;
5886    if (!TF) setmen = 0; /* can't set nothing */
5887 
5888    if (num_units == SUMA_PERC_VALUE_UNITS) {
5889       float pr[2], prv[2], *Vsort=NULL;
5890 
5891       /* Update, because for colorization (I) column, both colp->V
5892          and colp->Vperc get clamped by range */
5893       if (!SUMA_SetOverlay_Vecs(colp, 'V', colp->OptScl->find,
5894                                 "reset", 1)) {
5895          SUMA_S_Err("Failed to set overlay vecs");
5896          SUMA_RETURN(0);
5897       }
5898 
5899       if (v2 < v1) v2 = v1;
5900       pr[0] = v1; pr[1] = v2;
5901          /* some safety checks */
5902       if (pr[1]<pr[0]) pr[1] = pr[0]+1;
5903       if (pr[1] > 100.0) pr[1] = 100.0;
5904       if (pr[0] < 0.0) pr[0] = 0.0;
5905 
5906       #if 0 /* old but works */
5907       if (!colp->V) {
5908          SUMA_S_Err("Cannot do percentiles without colp->V");
5909          SUMA_RETURN(0);
5910       }
5911       if (!(Vsort = SUMA_PercRangeVol(colp->V, NULL, colp->N_V, pr, 2, prv,
5912                                       NULL, colp->OptScl->MaskZero, NULL))) {
5913          SUMA_S_Err("Failed to get perc. range");
5914          SUMA_RETURN(0);
5915       }
5916       SUMA_ifree(Vsort);
5917       #else
5918       prv[0] = SUMA_OverlayPercentile (colp, 'V', pr[0]);
5919       prv[1] = SUMA_OverlayPercentile (colp, 'V', pr[1]);
5920       #endif
5921 
5922       SUMA_LH("Computed percentiles %f %f-->%f %f",
5923                pr[0], pr[1], prv[0], prv[1]);
5924       v1 = prv[0]; v2 = prv[1];
5925 
5926       /* Need to update the value in the table struct */
5927       if (TF) ++setmen;
5928 
5929       /* Remove percentile units */
5930       if (TF) TF->num_units = SUMA_NO_NUM_UNITS;
5931    }
5932 
5933    NewDisp = NOPE;
5934    /* What are we dealing with ? */
5935    switch (row) {
5936       case 1:  /* That's the Int. range */
5937          SUMA_LHv("Setting Int. Range, isCur=%d [%d %d] sym %d\n",
5938                    isCur, row, col, colp->SymIrange);
5939          if (col == 1) { /* the min value */
5940             if (colp->SymIrange) {
5941                colp->OptScl->IntRange[0] = -fabs((double)v1);
5942                colp->OptScl->IntRange[1] = -colp->OptScl->IntRange[0];
5943                if (SETMEN) {
5944                   SUMA_LHv("Inserting cell values %f and %f\n",
5945                            colp->OptScl->IntRange[0], colp->OptScl->IntRange[1]);
5946                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
5947                                          colp->OptScl->IntRange[0]);
5948                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
5949                                          colp->OptScl->IntRange[1]);
5950                }
5951             } else {
5952                if (v1 > colp->OptScl->IntRange[1]) {
5953                   *reset = colp->OptScl->IntRange[0];
5954                   SUMA_RETURN(-1);
5955                } else {
5956                   if (LocalHead)
5957                      fprintf (SUMA_STDERR,"%s: IntRange[0] was %f, will be %f\n",
5958                               FuncName, colp->OptScl->IntRange[0],
5959                               v1);
5960                   colp->OptScl->IntRange[0] = v1;
5961                   if (SETMEN) {
5962                      SUMA_INSERT_CELL_VALUE(TF, row, 1,
5963                                          colp->OptScl->IntRange[0]);
5964                   }
5965                }
5966             }
5967          } else if (col==2) {
5968              if (colp->SymIrange) {
5969                colp->OptScl->IntRange[1] = fabs((double)v1);
5970                colp->OptScl->IntRange[0] = -colp->OptScl->IntRange[1];
5971                if (SETMEN) {
5972                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
5973                                          colp->OptScl->IntRange[0]);
5974                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
5975                                          colp->OptScl->IntRange[1]);
5976                }
5977              } else {
5978                if (v1 < colp->OptScl->IntRange[0]) {
5979                   *reset = colp->OptScl->IntRange[1];
5980                   SUMA_RETURN(-2);
5981                } else {
5982                   colp->OptScl->IntRange[1] = v1;
5983                   if (SETMEN) {
5984                      SUMA_INSERT_CELL_VALUE(TF, row, 2,
5985                                          colp->OptScl->IntRange[1]);
5986                   }
5987                }
5988             }
5989          } else if (col==-1) {
5990             if (v1 > v2) {
5991                SUMA_S_Errv("Bad range %f %f\n", v1, v2);
5992                SUMA_RETURN(-3);
5993             } else {
5994                colp->OptScl->IntRange[0] = v1;
5995                colp->OptScl->IntRange[1] = v2;
5996                if (SETMEN) {
5997                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
5998                                          colp->OptScl->IntRange[0]);
5999                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
6000                                          colp->OptScl->IntRange[1]);
6001                }
6002             }
6003          } else { SUMA_SL_Err("What's going on John ?"); }
6004          if (isCur && colp->ShowMode > 0) NewDisp = YUP;
6005          break;
6006       case 2:  /* That's the Brt.. range */
6007          SUMA_LH("Setting Brt. Range");
6008          if (col == 1) {
6009             if (v1 > colp->OptScl->BrightRange[1]) {
6010                *reset = colp->OptScl->BrightRange[0];
6011                SUMA_RETURN(-1);
6012             } else {
6013                colp->OptScl->BrightRange[0] = v1;
6014                if (SETMEN) {
6015                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
6016                                       colp->OptScl->BrightRange[0]);
6017                }
6018             }
6019          } else if (col==2) {
6020             if (v1 < colp->OptScl->BrightRange[0]) {
6021                *reset = colp->OptScl->BrightRange[1];
6022                SUMA_RETURN(-2);
6023             } else {
6024                colp->OptScl->BrightRange[1] = v1;
6025                if (SETMEN) {
6026                      SUMA_INSERT_CELL_VALUE(TF, row, 2,
6027                                          colp->OptScl->BrightRange[1]);
6028                }
6029             }
6030          } else if (col == -1) {
6031             if (v1 > v2) {
6032                SUMA_S_Errv("Bad range %f %f\n", v1, v2);
6033                SUMA_RETURN(-3);
6034             } else {
6035                colp->OptScl->BrightRange[0] = v1;
6036                colp->OptScl->BrightRange[1] = v2;
6037                if (SETMEN) {
6038                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
6039                                          colp->OptScl->BrightRange[0]);
6040                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
6041                                          colp->OptScl->BrightRange[1]);
6042                }
6043             }
6044          } else { SUMA_SL_Err("What's going on Ron ?"); }
6045          if (isCur && colp->OptScl->UseBrt) NewDisp = YUP;
6046          break;
6047       case 3:  /* That's the Brt. Map Range */
6048          SUMA_LH("Setting BrtMap. Range");
6049          if (col == 1) {
6050             if (v1 > colp->OptScl->BrightMap[1]) {
6051                *reset = colp->OptScl->BrightMap[0];
6052                SUMA_RETURN(-1);
6053             } else if (v1 < 0) {
6054                *reset = colp->OptScl->BrightMap[0];
6055                SUMA_RETURN(-1);
6056             } else {
6057                colp->OptScl->BrightMap[0] = v1;
6058                if (SETMEN) {
6059                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
6060                                       colp->OptScl->BrightMap[0]);
6061                }
6062             }
6063          } else if (col==2) {
6064             if (v1 < colp->OptScl->BrightMap[0]) {
6065                *reset = colp->OptScl->BrightMap[1];
6066                SUMA_RETURN(-2);
6067             } else {
6068                colp->OptScl->BrightMap[1] = v1;
6069                if (SETMEN) {
6070                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
6071                                       colp->OptScl->BrightMap[1]);
6072                }
6073             }
6074          } else if (col == -1) {
6075             if (v1 > v2 || v1 < 0) {
6076                SUMA_S_Errv("Bad range %f %f\n", v1, v2);
6077                SUMA_RETURN(-3);
6078             } else {
6079                colp->OptScl->BrightMap[0] = v1;
6080                colp->OptScl->BrightMap[1] = v2;
6081                if (SETMEN) {
6082                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
6083                                          colp->OptScl->BrightMap[0]);
6084                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
6085                                          colp->OptScl->BrightMap[1]);
6086                }
6087             }
6088          } else { SUMA_SL_Err("What's going on Mon ?"); }
6089          if (isCur && colp->OptScl->UseBrt) NewDisp = YUP;
6090          break;
6091       case 4:  /* That's the coordinate bias Range */
6092          SUMA_LH("Setting CoordBias. Range");
6093          if (col == 1) {
6094             if (v1 > colp->OptScl->CoordBiasRange[1]) {
6095                *reset = colp->OptScl->CoordBiasRange[0];
6096                SUMA_RETURN(-1);
6097             } else { /* OK */
6098                colp->OptScl->CoordBiasRange[0] = v1;
6099                if (SETMEN) {
6100                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
6101                                       colp->OptScl->CoordBiasRange[0]);
6102                }
6103             }
6104          } else if (col==2) {
6105             if (v1 < colp->OptScl->CoordBiasRange[0]) {
6106                 *reset = colp->OptScl->CoordBiasRange[1];
6107                SUMA_RETURN(-2);
6108             } else { /* OK */
6109                colp->OptScl->CoordBiasRange[1] = v1;
6110                if (SETMEN) {
6111                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
6112                                       colp->OptScl->CoordBiasRange[1]);
6113                }
6114             }
6115          } else if (col == -1) {
6116             if (v1 > v2) {
6117                SUMA_S_Errv("Bad range %f %f\n", v1, v2);
6118                SUMA_RETURN(-3);
6119             } else {
6120                colp->OptScl->CoordBiasRange[0] = v1;
6121                colp->OptScl->CoordBiasRange[1] = v2;
6122                if (SETMEN) {
6123                   SUMA_INSERT_CELL_VALUE(TF, row, 1,
6124                                          colp->OptScl->CoordBiasRange[0]);
6125                   SUMA_INSERT_CELL_VALUE(TF, row, 2,
6126                                          colp->OptScl->CoordBiasRange[1]);
6127                }
6128             }
6129          } else { SUMA_SL_Err("What's going on Hon ?"); }
6130          if (isCur) NewDisp = YUP;
6131                /* You might want to disable this feature if the colp
6132                   is not shown */
6133          break;
6134       default:
6135          SUMA_SL_Err("You make me sick");
6136          break;
6137    }
6138 
6139    /* Now, you need to redraw the deal */
6140    if (REDISP) {
6141       SUMA_ColorizePlane(curColPlane);
6142       SUMA_Remixedisplay(ado);
6143    }
6144 
6145    /* update the Xhair Info block */
6146    if (curColPlane->OptScl->DoBias != SW_CoordBias_None) {
6147       SUMA_UpdateNodeNodeField(ado);
6148    }
6149    SUMA_UpdateNodeLblField(ado);
6150 
6151    SUMA_RETURN(1);
6152 }
6153 
SUMA_SetRangeValueNew(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int row,int col,float v1,float v2,int setmen,int redisplay,float * reset,SUMA_NUMERICAL_UNITS num_units)6154 int SUMA_SetRangeValueNew (SUMA_ALL_DO *ado,
6155                           SUMA_OVERLAYS *colp,
6156                           int row, int col,
6157                           float v1, float v2,
6158                           int setmen,
6159                           int redisplay, float *reset,
6160                           SUMA_NUMERICAL_UNITS num_units)
6161 {
6162    static char FuncName[]={"SUMA_SetRangeValueNew"};
6163    int NewDisp=0, an=0;
6164    SUMA_Boolean LocalHead = NOPE;
6165 
6166    SUMA_ENTRY;
6167 
6168    if (LocalHead) {
6169       fprintf(SUMA_STDERR,
6170          "%s:\n request to switch range \n", FuncName);
6171    }
6172 
6173    an = SUMA_SetRangeValueNew_one(ado, colp, row, col,
6174                                   v1, v2, setmen,
6175                                   redisplay, reset, num_units);
6176    if (an <= 0) SUMA_RETURN(an);
6177 
6178    if (ado->do_type == SO_type) {
6179       SUMA_SurfaceObject *SOC=NULL, *SO = (SUMA_SurfaceObject *)ado;
6180       SUMA_OVERLAYS *colpC=NULL;
6181       /* do we have a contralateral SO and overlay? */
6182       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
6183       if (colpC && SOC) {
6184          SUMA_LHv("Found contralateral equivalent to:\n"
6185                       " %s and %s in\n"
6186                       " %s and %s\n",
6187                       SO->Label, CHECK_NULL_STR(colp->Label),
6188                       SOC->Label, CHECK_NULL_STR(colpC->Label));
6189          an = SUMA_SetRangeValueNew_one((SUMA_ALL_DO *)SOC, colpC, row, col,
6190                                         v1, v2, 1,
6191                                         redisplay, reset, num_units);
6192       }
6193    }
6194 
6195    SUMA_RETURN(an);
6196 }
6197 
6198 
SUMA_cb_SetRangeValue(void * data)6199 void SUMA_cb_SetRangeValue (void *data)
6200 {
6201    static char FuncName[]={"SUMA_cb_SetRangeValue"};
6202    SUMA_SRV_DATA srvdC, *srvd=NULL;
6203    SUMA_ALL_DO *ado=NULL;
6204    SUMA_OVERLAYS *colp=NULL;
6205    int n=-1,row=-1,col=-1, an=0;
6206    float reset = 0.0;
6207    void *cv=NULL;
6208    SUMA_TABLE_FIELD *TF=NULL;
6209    SUMA_X_SurfCont *SurfCont=NULL;
6210    SUMA_OVERLAYS *curColPlane=NULL;
6211    SUMA_Boolean LocalHead = NOPE;
6212 
6213    SUMA_ENTRY;
6214 
6215    if (LocalHead) {
6216       fprintf(SUMA_STDERR,
6217          "%s:\n request to switch range \n", FuncName);
6218    }
6219    if (!(srvd = (SUMA_SRV_DATA *)data)) SUMA_RETURNe;
6220    ado = srvd->ado; colp = srvd->colp;
6221    if (!ado) SUMA_RETURNe;
6222    SurfCont = SUMA_ADO_Cont(ado);
6223    curColPlane = SUMA_ADO_CurColPlane(ado);
6224 
6225    if (!colp) colp = curColPlane;
6226 
6227    TF = SurfCont->SetRangeTable;
6228    if (TF->cell_modified<0) SUMA_RETURNe;
6229    n = TF->cell_modified;
6230    row = n % TF->Ni;
6231    col = n / TF->Ni;
6232    XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
6233    if (LocalHead) {
6234       fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s\n",
6235                            FuncName, row, col, (char *)cv);
6236    }
6237 
6238    an = SUMA_SetRangeValueNew(ado, colp, row, col,
6239                           TF->num_value[n], 0.0,
6240                           0, 1, &reset, TF->num_units);
6241    if (an < 0) {
6242       if (an == -1 || an == -2) {
6243          SUMA_BEEP;
6244          TF->num_value[n] = reset;
6245          SUMA_TableF_SetString(TF);
6246          if (an == -1) { SUMA_SLP_Err("Lower bound > Upper bound!"); }
6247          else { SUMA_SLP_Err("Upper bound < Lower bound!"); }
6248       } else {
6249          SUMA_S_Err("Erriosity");
6250       }
6251    }
6252 
6253    SUMA_RETURNe;
6254 }
6255 
SUMA_SetClustValue_one(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int row,int col,float v1,float v2,int setmen,int redisplay,float * reset)6256 int SUMA_SetClustValue_one(SUMA_ALL_DO *ado,
6257                           SUMA_OVERLAYS *colp,
6258                           int row, int col,
6259                           float v1, float v2,
6260                           int setmen,
6261                           int redisplay, float *reset)
6262 {
6263    static char FuncName[]={"SUMA_SetClustValue_one"};
6264    int NewDisp=0, isCur=0;
6265    SUMA_X_SurfCont *SurfCont=NULL;
6266    SUMA_OVERLAYS *curColPlane=NULL;
6267    SUMA_Boolean LocalHead = NOPE;
6268    SUMA_TABLE_FIELD *TF=NULL;
6269 
6270    SUMA_ENTRY;
6271 
6272    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado)) ||
6273        !SurfCont->SetClustTable || !reset) {
6274       SUMA_RETURN(0);
6275    }
6276    curColPlane = SUMA_ADO_CurColPlane(ado);
6277    if (!colp) colp = curColPlane;
6278 
6279    if (colp && colp == curColPlane) {
6280       isCur=YUP;
6281    } else {
6282       isCur=NOPE;
6283    }
6284 
6285    if (!colp) {
6286       SUMA_RETURN(0); /* not much to do */
6287    }
6288 
6289 
6290    TF = SurfCont->SetClustTable;
6291    if (!TF) setmen = 0; /* can't set nothing */
6292 
6293    NewDisp = NOPE;
6294    /* What are we dealing with ? */
6295    switch (row) {
6296       case 1:  /* That's the Int. range */
6297          SUMA_LHv("Setting Clust params isCur=%d [%d %d]\n",
6298                    isCur, row, col);
6299          if (col == 1) { /* the DistLim value */
6300             if (colp->OptScl->Clusterize &&
6301                 colp->OptScl->ClustOpt->DistLim != v1) {
6302                colp->OptScl->RecomputeClust = 1;
6303             }
6304             colp->OptScl->ClustOpt->DistLim = v1;
6305             if (SETMEN) {
6306                SUMA_LHv("Inserting cell value %f \n",
6307                         colp->OptScl->ClustOpt->DistLim);
6308                SUMA_INSERT_CELL_VALUE(TF, row, 1,
6309                                       colp->OptScl->ClustOpt->DistLim);
6310             }
6311          } else if (col==2) {
6312             if (colp->OptScl->Clusterize &&
6313                 colp->OptScl->ClustOpt->AreaLim != v1) {
6314                colp->OptScl->RecomputeClust = 1;
6315             }
6316             colp->OptScl->ClustOpt->AreaLim = v1;
6317             if (SETMEN) {
6318                SUMA_LHv("Inserting cell value %f \n",
6319                         colp->OptScl->ClustOpt->AreaLim);
6320                SUMA_INSERT_CELL_VALUE(TF, row, 2,
6321                                       colp->OptScl->ClustOpt->AreaLim);
6322             }
6323          } else if (col==-1) {
6324             if (colp->OptScl->Clusterize &&
6325                 (colp->OptScl->ClustOpt->DistLim != v1 ||
6326                  colp->OptScl->ClustOpt->AreaLim != v2)) {
6327                colp->OptScl->RecomputeClust = 1;
6328             }
6329             colp->OptScl->ClustOpt->DistLim = v1;
6330             colp->OptScl->ClustOpt->AreaLim = v2;
6331             if (SETMEN) {
6332                SUMA_LHv("Inserting cell values %f %f\n",
6333                         colp->OptScl->ClustOpt->DistLim,
6334                         colp->OptScl->ClustOpt->AreaLim);
6335                SUMA_INSERT_CELL_VALUE(TF, row, 1,
6336                                       colp->OptScl->ClustOpt->DistLim);
6337                SUMA_INSERT_CELL_VALUE(TF, row, 2,
6338                                       colp->OptScl->ClustOpt->AreaLim);
6339             }
6340          } else { SUMA_SL_Err("What's going on Jane ?"); }
6341          if (isCur &&
6342               colp->ShowMode > 0 && colp->ShowMode < SW_SurfCont_DsetViewXXX &&
6343               colp->OptScl->Clusterize)
6344                                                             NewDisp = YUP;
6345          break;
6346       default:
6347          SUMA_SL_Err("You make me sick. What's that you're eating?");
6348          break;
6349    }
6350 
6351    /* Now, you need to redraw the deal */
6352    if (REDISP) {
6353       SUMA_ColorizePlane(curColPlane);
6354       SUMA_Remixedisplay(ado);
6355    }
6356 
6357    /* update the Xhair Info block */
6358    if (curColPlane->OptScl->DoBias != SW_CoordBias_None) {
6359       SUMA_UpdateNodeNodeField(ado);
6360    }
6361    SUMA_UpdateNodeLblField(ado);
6362 
6363    SUMA_RETURN(1);
6364 }
6365 
SUMA_SetClustValue(SUMA_ALL_DO * ado,SUMA_OVERLAYS * colp,int row,int col,float v1,float v2,int setmen,int redisplay,float * reset)6366 int SUMA_SetClustValue (SUMA_ALL_DO *ado,
6367                           SUMA_OVERLAYS *colp,
6368                           int row, int col,
6369                           float v1, float v2,
6370                           int setmen,
6371                           int redisplay, float *reset)
6372 {
6373    static char FuncName[]={"SUMA_SetClustValue"};
6374    int NewDisp=0, an=0;
6375    SUMA_Boolean LocalHead = NOPE;
6376 
6377    SUMA_ENTRY;
6378 
6379    if (LocalHead) {
6380       fprintf(SUMA_STDERR,
6381          "%s:\n request to switch clust params \n", FuncName);
6382    }
6383 
6384    an = SUMA_SetClustValue_one(ado, colp, row, col,
6385                                   v1, v2, setmen,
6386                                   redisplay, reset);
6387    if (an <= 0) SUMA_RETURN(an);
6388 
6389    if (ado->do_type == SO_type) {
6390       SUMA_SurfaceObject *SOC=NULL, *SO = (SUMA_SurfaceObject *)ado;
6391       SUMA_OVERLAYS *colpC=NULL;
6392       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
6393       if (colpC && SOC) {
6394          SUMA_LHv("Found contralateral equivalent to:\n"
6395                       " %s and %s in\n"
6396                       " %s and %s\n",
6397                       SO->Label, CHECK_NULL_STR(colp->Label),
6398                       SOC->Label, CHECK_NULL_STR(colpC->Label));
6399          an = SUMA_SetClustValue_one((SUMA_ALL_DO *)SOC, colpC, row, col,
6400                                         v1, v2, 1,
6401                                         redisplay, reset);
6402       }
6403    }
6404    SUMA_RETURN(an);
6405 }
6406 
6407 
SUMA_cb_SetClustValue(void * data)6408 void SUMA_cb_SetClustValue (void *data)
6409 {
6410    static char FuncName[]={"SUMA_cb_SetClustValue"};
6411    SUMA_SRV_DATA srvdC, *srvd=NULL;
6412    SUMA_OVERLAYS *colp=NULL;
6413    SUMA_ALL_DO *ado=NULL;
6414    SUMA_X_SurfCont *SurfCont=NULL;
6415    SUMA_OVERLAYS *curColPlane=NULL;
6416    int n=-1,row=-1,col=-1, an=0;
6417    float reset = 0.0;
6418    void *cv=NULL;
6419    SUMA_TABLE_FIELD *TF=NULL;
6420    SUMA_Boolean LocalHead = NOPE;
6421 
6422    SUMA_ENTRY;
6423 
6424    if (LocalHead) {
6425       fprintf(SUMA_STDERR,
6426          "%s:\n request to switch range \n", FuncName);
6427    }
6428    if (!(srvd = (SUMA_SRV_DATA *)data)) SUMA_RETURNe;
6429    ado = srvd->ado; colp = srvd->colp;
6430    if (!ado) SUMA_RETURNe;
6431    SurfCont = SUMA_ADO_Cont(ado);
6432    curColPlane = SUMA_ADO_CurColPlane(ado);
6433    if (!colp) colp = curColPlane;
6434 
6435    TF = SurfCont->SetClustTable;
6436    if (TF->cell_modified<0) SUMA_RETURNe;
6437    n = TF->cell_modified;
6438    row = n % TF->Ni;
6439    col = n / TF->Ni;
6440    XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
6441    if (LocalHead) {
6442       fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s\n",
6443                            FuncName, row, col, (char *)cv);
6444    }
6445 
6446    an = SUMA_SetClustValue(ado, colp, row, col,
6447                           TF->num_value[n], 0.0,
6448                           0, 1, &reset);
6449    if (an < 0) {
6450       SUMA_S_Warn("Error checking not handled yet.\n"
6451                   "This upcoming code chunk is from\n"
6452                   "sister function: SUMA_cb_SetRangeValueNew\n");
6453       if (an == -1 || an == -2) {
6454          SUMA_BEEP;
6455          TF->num_value[n] = reset;
6456          SUMA_TableF_SetString(TF);
6457          if (an == -1) { SUMA_SLP_Err("Doh"); }
6458          else { SUMA_SLP_Err("Duh"); }
6459       } else {
6460          SUMA_S_Err("Erriositation");
6461       }
6462    }
6463 
6464    SUMA_RETURNe;
6465 }
6466 
6467 /*!
6468    \brief updates string based on value entered in table field.
6469    Nothing is done unless field is numeric
6470 */
SUMA_TableF_SetString(SUMA_TABLE_FIELD * TF)6471 void SUMA_TableF_SetString (SUMA_TABLE_FIELD * TF)
6472 {
6473    static char FuncName[]={"SUMA_TableF_SetString"};
6474    char buf[36];
6475 
6476    SUMA_ENTRY;
6477 
6478    if (TF->cell_modified < 0) {
6479       /* nothing to do, user hit enter in field without modification */
6480       SUMA_RETURNe;
6481    }
6482    if (TF->type == SUMA_int) {
6483       sprintf (buf, "%-4d", (int)TF->num_value[TF->cell_modified]);
6484    }else if (TF->type == SUMA_float) {
6485       sprintf (buf, "%s",
6486                MV_format_fval2(  TF->num_value[TF->cell_modified],
6487                                  TF->cwidth[TF->cell_modified / TF->Ni]));
6488    }else {
6489       /* fair enough, must be stringy */
6490    }
6491 
6492    XtVaSetValues (TF->cells[TF->cell_modified], XmNvalue, buf, NULL);
6493    SUMA_RETURNe;
6494 }
6495 
6496 /*!
6497    \brief This function is called when label field has been modified by user keyboard input.
6498    All it does is set TF->cell_modified to the 1D index of that cell
6499 
6500 */
SUMA_TableF_cb_label_Modify(Widget w,XtPointer client_data,XtPointer call_data)6501 void SUMA_TableF_cb_label_Modify (Widget w, XtPointer client_data,
6502                                   XtPointer call_data)
6503 {
6504    static char FuncName[]={"SUMA_TableF_cb_label_Modify"};
6505    SUMA_TABLE_FIELD *TF=NULL;
6506    int ud=0;
6507    static int CurrentCell = -1;
6508    SUMA_Boolean LocalHead = NOPE;
6509 
6510    SUMA_ENTRY;
6511 
6512    SUMA_LH("Called");
6513 
6514    TF = (SUMA_TABLE_FIELD *)client_data ;
6515 
6516    if (!TF->editable) { /* this does not apply */
6517       SUMA_RETURNe;
6518    }
6519    if (TF->cell_modified != -1) {
6520       /* make sure it is the last one you'd been working on
6521       This check fails when I am dealing with mutliple tables
6522       If you need it, store a value for each cell and
6523       check them individually*/
6524       if (0 && CurrentCell >= 0  && TF->cell_modified != CurrentCell) {
6525          SUMA_SL_Err("cell_modified not reset.");
6526          SUMA_RETURNe;
6527       }
6528    }
6529    XtVaGetValues(w, XmNuserData, &ud, NULL);
6530    SUMA_LH("ud %d, cell modified %d", ud, TF->cell_modified);
6531    if (TF->cell_modified == -1) {
6532       /* fresh start, keep track */
6533       CurrentCell = ud;
6534    }
6535    TF->cell_modified = ud;
6536 
6537    SUMA_RETURNe;
6538 }
6539 
6540 
6541 /*!
6542    \brief This function sets the color mapping options including the switch datasets and what have you
6543    It is called each time one loads a new data set and is meant to be called if the user adds a new
6544    colormap (not supported at the moment).
6545    \param NewMap --> New ColorMap was added.
6546    \param NewDset --> New Dataset was added.
6547    DO NOT CALL THIS FUNCTION if:
6548    You are switching color maps, you are switching Intensity/threshold and so on
6549    DO call this function if you load or switch between dsets
6550    Do call this function if you load a new color map
6551 
6552 */
6553 
SUMA_set_cmap_options(SUMA_ALL_DO * ado,SUMA_Boolean NewDset,SUMA_Boolean NewMap)6554 void SUMA_set_cmap_options(SUMA_ALL_DO *ado, SUMA_Boolean NewDset,
6555                            SUMA_Boolean NewMap)
6556 {
6557    static char FuncName[]={"SUMA_set_cmap_options"};
6558    SUMA_Boolean LocalHead = NOPE;
6559 
6560    SUMA_ENTRY;
6561 
6562    if (!ado) SUMA_RETURNe;
6563    switch (ado->do_type) {
6564       case SO_type:
6565          SUMA_set_cmap_options_SO(ado, NewDset,  NewMap);
6566          SUMA_RETURNe;
6567          break;
6568       case GDSET_type:
6569          SUMA_S_Err("No init for a DO that cannot be dispalyed\n"
6570                     "without variant");
6571          SUMA_RETURNe;
6572       case CDOM_type:
6573          SUMA_set_cmap_options_CO(ado, NewDset,  NewMap);
6574          SUMA_RETURNe;
6575       case GRAPH_LINK_type:
6576          SUMA_set_cmap_options_GLDO(ado, NewDset, NewMap);
6577          SUMA_RETURNe;
6578          break;
6579       case VO_type:
6580          SUMA_set_cmap_options_VO(ado, NewDset,  NewMap);
6581          SUMA_RETURNe;
6582          break;
6583       default:
6584          SUMA_S_Errv("Nothing for type %s\n",
6585             SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
6586          SUMA_RETURNe;
6587          break;
6588    }
6589 
6590    SUMA_RETURNe;
6591 }
6592 
SUMA_set_cmap_options_SO(SUMA_ALL_DO * ado,SUMA_Boolean NewDset,SUMA_Boolean NewMap)6593 void SUMA_set_cmap_options_SO(SUMA_ALL_DO *ado, SUMA_Boolean NewDset,
6594                            SUMA_Boolean NewMap)
6595 {
6596    static char FuncName[]={"SUMA_set_cmap_options_SO"};
6597    SUMA_MenuItem  *SwitchInt_Menu = NULL, *SwitchThr_Menu = NULL,
6598                   *SwitchBrt_Menu = NULL;
6599    int N_items, FirstTime;
6600    SUMA_X_SurfCont *SurfCont=NULL;
6601    SUMA_OVERLAYS *curColPlane=NULL;
6602    SUMA_Boolean LocalHead = NOPE;
6603 
6604    SUMA_ENTRY;
6605 
6606    if (!ado) SUMA_RETURNe;
6607    if (ado->do_type != SO_type) {
6608       SUMA_S_Err("Should not be here");
6609       SUMA_RETURNe;
6610    }
6611    SurfCont = SUMA_ADO_Cont(ado);
6612    curColPlane = SUMA_ADO_CurColPlane(ado);
6613 
6614    if (!SurfCont) SUMA_RETURNe;
6615    if (!SurfCont->opts_form || !SurfCont->opts_rc) SUMA_RETURNe;
6616    if (!curColPlane) SUMA_RETURNe;
6617    if (!NewDset && !NewMap && SurfCont->rcvo && SurfCont->rccm) {
6618       SUMA_SL_Err("Nothing to do");
6619       SUMA_RETURNe;
6620    }
6621    /* row column to contain all switching stuffs */
6622    if (!SurfCont->rcvo){
6623       SurfCont->rcvo = XtVaCreateWidget ("rowcolumn",
6624          xmRowColumnWidgetClass, SurfCont->opts_rc,
6625          XmNpacking, XmPACK_TIGHT,
6626          XmNorientation , XmVERTICAL ,
6627          XmNmarginHeight, 0 ,
6628          XmNmarginWidth , 0 ,
6629          NULL);
6630       NewDset = YUP; /* The first time around */
6631    } else {
6632       /* (no need ..) */
6633       /* XtUnmanageChild(SurfCont->rcvo);  */
6634    }
6635 
6636    if (NewDset) { /* The intensity / threshold / Brightness block*/
6637       /* link mode */
6638       if (!SurfCont->LinkModeMenu->mw[SW_LinkMode]) {
6639                Widget rc = NULL; /* one pass through this block ONLY */
6640                rc = XtVaCreateWidget ("rowcolumn",
6641                   xmRowColumnWidgetClass, SurfCont->rcvo,
6642                   XmNpacking, XmPACK_TIGHT,
6643                   XmNorientation , XmHORIZONTAL ,
6644                   XmNmarginHeight, 0 ,
6645                   XmNmarginWidth , 0 ,
6646                   NULL);
6647 
6648                SUMA_LH("Forming map mode menu");
6649                SUMA_BuildMenuReset(0);
6650                SUMA_BuildMenu ( rc, XmMENU_OPTION,
6651                                "IxT", '\0', YUP, LinkMode_Menu,
6652                                (void *)ado,
6653                                "SurfCont->Dset_Mapping->IxT",
6654                                "Set I, T selection linking modes.",
6655                                SUMA_SurfContHelp_Link,
6656                                SurfCont->LinkModeMenu);
6657                XtManageChild (SurfCont->LinkModeMenu->mw[SW_LinkMode]);
6658 
6659                XtManageChild(rc);
6660          }
6661 
6662       if (!SurfCont->rcsw) {
6663          SurfCont->rcsw = XtVaCreateWidget ("rowcolumn",
6664             xmRowColumnWidgetClass, SurfCont->rcvo,
6665             XmNpacking, XmPACK_TIGHT,
6666             XmNorientation , XmHORIZONTAL ,
6667             XmNheight, 105,         /* don't let that change dynamically,  */
6668             XmNresizeHeight, False, /* it messes up the frame size, when you
6669                                        switch dsets*/
6670             XmNmarginHeight, 0 ,
6671             XmNmarginWidth , 0 ,
6672             NULL);
6673        } else {
6674          /* (no need ..) */
6675          /*XtUnmanageChild(SurfCont->rcsw); */
6676        }
6677       if (!SurfCont->rcsw_v1) {
6678          SurfCont->rcsw_v1 = XtVaCreateWidget ("rowcolumn",
6679             xmRowColumnWidgetClass, SurfCont->rcsw,
6680             XmNpacking, XmPACK_COLUMN,
6681             XmNorientation , XmVERTICAL ,
6682             XmNnumColumns, 1,
6683             XmNmarginHeight, 0 ,
6684             XmNmarginWidth , 0 ,
6685             NULL);
6686       }
6687       if (!SurfCont->rcsw_v2) {
6688          SurfCont->rcsw_v2 = XtVaCreateWidget ("rowcolumn",
6689             xmRowColumnWidgetClass, SurfCont->rcsw,
6690             XmNpacking, XmPACK_COLUMN,
6691             XmNorientation , XmVERTICAL ,
6692             XmNnumColumns, 1,
6693             XmNmarginHeight, 0 ,
6694             XmNmarginWidth , 0 ,
6695             NULL);
6696       }
6697 
6698       /* Switching triplets */
6699       SwitchInt_Menu = SUMA_FormSwitchColMenuVector(ado, 0, &N_items);
6700       if (LocalHead) fprintf (SUMA_STDERR,"%s: %d items.\n", FuncName, N_items);
6701       if (SwitchInt_Menu || !N_items) {
6702          SurfCont->SwitchIntMenu =
6703                SUMA_Free_Menu_Widget(SurfCont->SwitchIntMenu);
6704          SurfCont->SwitchIntMenu =
6705                SUMA_Alloc_Menu_Widget(N_items+1);
6706          SUMA_BuildMenuReset(13);
6707          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
6708                            "I", '\0', YUP, SwitchInt_Menu,
6709                            (void *)ado,
6710                            "SurfCont->Dset_Mapping->I",
6711                   "Select Intensity (I) column, aka sub-brick. (BHelp for more)",
6712                            SUMA_SurfContHelp_SelInt,
6713                            SurfCont->SwitchIntMenu );
6714          XtInsertEventHandler( SurfCont->SwitchIntMenu->mw[0] ,
6715                                              /* handle events in optmenu */
6716                         ButtonPressMask ,  /* button presses */
6717                         FALSE ,            /* nonmaskable events? */
6718                         SUMA_optmenu_EV ,  /* handler */
6719                         (XtPointer) ado ,   /* client data */
6720                         XtListTail ) ;
6721          if (LocalHead)
6722             SUMA_ShowMeTheChildren(SurfCont->SwitchIntMenu->mw[0]);
6723          XtManageChild (SurfCont->SwitchIntMenu->mw[0]);
6724          /* Now destroy the SwitchInt_Menu */
6725          SwitchInt_Menu = SUMA_FreeMenuVector(SwitchInt_Menu, N_items);
6726          /* setup the history to the proper widget */
6727          SUMA_Set_Menu_Widget(SurfCont->SwitchIntMenu,
6728                        curColPlane->OptScl->find+1) ;
6729       } else {
6730          SUMA_SL_Err("NULL SwitchInt_Menu");
6731       }
6732 
6733       SwitchThr_Menu = SUMA_FormSwitchColMenuVector(ado, 1, &N_items);
6734       if (SwitchThr_Menu || !N_items) {
6735          SurfCont->SwitchThrMenu =
6736                SUMA_Free_Menu_Widget(SurfCont->SwitchThrMenu);
6737          SurfCont->SwitchThrMenu =
6738                SUMA_Alloc_Menu_Widget(N_items+1);
6739          SUMA_BuildMenuReset(13);
6740          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
6741                            "T", '\0', YUP, SwitchThr_Menu,
6742                            (void *)ado,
6743                            "SurfCont->Dset_Mapping->T",
6744                   "Select Threshold (T) column, aka sub-brick. (BHelp for more)",
6745                            SUMA_SurfContHelp_SelThr ,
6746                            SurfCont->SwitchThrMenu );
6747          XtInsertEventHandler( SurfCont->SwitchThrMenu->mw[0] ,
6748                                        /* handle events in optmenu */
6749                         ButtonPressMask ,  /* button presses */
6750                         FALSE ,            /* nonmaskable events? */
6751                         SUMA_optmenu_EV ,  /* handler */
6752                         (XtPointer) ado ,   /* client data */
6753                         XtListTail ) ;
6754          XtManageChild (SurfCont->SwitchThrMenu->mw[0]);
6755          /* Now destroy the SwitchThr_Menu */
6756          SwitchThr_Menu = SUMA_FreeMenuVector(SwitchThr_Menu, N_items);
6757          /* setup the history to the proper widget */
6758          SUMA_Set_Menu_Widget(SurfCont->SwitchThrMenu,
6759                        curColPlane->OptScl->tind+1);
6760       } else {
6761          SUMA_SL_Err("NULL SwitchThr_Menu");
6762       }
6763 
6764       SwitchBrt_Menu = SUMA_FormSwitchColMenuVector(ado, 2, &N_items);
6765       if (SwitchBrt_Menu || !N_items) {
6766          SurfCont->SwitchBrtMenu =
6767                SUMA_Free_Menu_Widget(SurfCont->SwitchBrtMenu);
6768          SurfCont->SwitchBrtMenu =
6769                SUMA_Alloc_Menu_Widget(N_items+1);
6770          SUMA_BuildMenuReset(13);
6771          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
6772                            "B", '\0', YUP, SwitchBrt_Menu,
6773                            (void *)ado,
6774                            "SurfCont->Dset_Mapping->B",
6775                "Select Brightness (B) column, aka sub-brick. (BHelp for more)",
6776                            SUMA_SurfContHelp_SelBrt,
6777                            SurfCont->SwitchBrtMenu );
6778          XtInsertEventHandler( SurfCont->SwitchBrtMenu->mw[0] ,
6779                                                 /* handle events in optmenu */
6780                         ButtonPressMask ,  /* button presses */
6781                         FALSE ,            /* nonmaskable events? */
6782                         SUMA_optmenu_EV ,  /* handler */
6783                         (XtPointer) ado ,   /* client data */
6784                         XtListTail ) ;
6785 
6786          XtManageChild (SurfCont->SwitchBrtMenu->mw[0]);
6787          /* Now destroy the SwitchBrt_Menu */
6788          SwitchBrt_Menu = SUMA_FreeMenuVector(SwitchBrt_Menu, N_items);
6789          /* setup the history to the proper widget */
6790          SUMA_Set_Menu_Widget(SurfCont->SwitchBrtMenu,
6791                        curColPlane->OptScl->bind+1);
6792       } else {
6793          SUMA_SL_Err("NULL SwitchBrt_Menu");
6794       }
6795 
6796      if (1) {
6797      /* put the toggle buttons */
6798          if (!SurfCont->Int_tb) {
6799             SurfCont->Int_tb = XtVaCreateManagedWidget("v",
6800                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
6801             XtAddCallback (SurfCont->Int_tb,
6802                   XmNvalueChangedCallback, SUMA_cb_SwitchInt_toggled, ado);
6803             SUMA_Register_Widget_Help(SurfCont->Int_tb, 1,
6804                                    "SurfCont->Dset_Mapping->I->v",
6805                                    "View (ON)/Hide Dset node colors",
6806                                    SUMA_SurfContHelp_SelIntTgl);
6807             SUMA_SET_SELECT_COLOR(SurfCont->Int_tb);
6808          }
6809          XmToggleButtonSetState (SurfCont->Int_tb,
6810                     curColPlane->ShowMode > 0 ? 1:0 , NOPE);
6811 
6812          if (!SurfCont->Thr_tb) {
6813             SurfCont->Thr_tb = XtVaCreateManagedWidget("v",
6814                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
6815             XtAddCallback (SurfCont->Thr_tb,
6816                   XmNvalueChangedCallback, SUMA_cb_SwitchThr_toggled, ado);
6817             SUMA_SET_SELECT_COLOR(SurfCont->Thr_tb);
6818             SUMA_Register_Widget_Help(SurfCont->Thr_tb, 1,
6819                                    "SurfCont->Dset_Mapping->T->v",
6820                                    "Apply (ON)/Ignore thresholding",
6821                                    SUMA_SurfContHelp_SelThrTgl);
6822          }
6823          if (curColPlane->OptScl->tind >=0) {
6824             XmToggleButtonSetState (SurfCont->Thr_tb,
6825                               curColPlane->OptScl->UseThr, NOPE);
6826          }else {
6827             XmToggleButtonSetState (SurfCont->Thr_tb, NOPE, NOPE);
6828          }
6829 
6830          if (!SurfCont->Brt_tb) {
6831             SurfCont->Brt_tb = XtVaCreateManagedWidget("v",
6832                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
6833             XtAddCallback (SurfCont->Brt_tb,
6834                      XmNvalueChangedCallback, SUMA_cb_SwitchBrt_toggled, ado);
6835             SUMA_SET_SELECT_COLOR(SurfCont->Brt_tb);
6836             SUMA_Register_Widget_Help(SurfCont->Brt_tb, 1,
6837                                       "SurfCont->Dset_Mapping->B->v",
6838                                       "View (ON)/Ignore brightness modulation",
6839                                       SUMA_SurfContHelp_SelBrtTgl);
6840          }
6841          if (curColPlane->OptScl->bind >=0) {
6842             XmToggleButtonSetState (SurfCont->Brt_tb,
6843                      curColPlane->OptScl->UseBrt, NOPE);
6844          } else {
6845             XmToggleButtonSetState (SurfCont->Brt_tb, NOPE, NOPE);
6846          }
6847       }
6848       if (!XtIsManaged(SurfCont->rcsw_v1))
6849          XtManageChild (SurfCont->rcsw_v1);
6850       if (!XtIsManaged(SurfCont->rcsw_v2))
6851          XtManageChild (SurfCont->rcsw_v2);
6852       if (!XtIsManaged(SurfCont->rcsw)) XtManageChild (SurfCont->rcsw);
6853    } /* The intensity / threshold / Brightness block */
6854 
6855 
6856    {/*  The Color map range and selector block */
6857       char *col_tit[]=  {  " ", "Min", "Max", NULL};
6858       char *col_hint[]= {  "Clipping ranges",
6859                            "Minimum clip value",
6860                            "Maximum clip value" , NULL};
6861       char *col_help[]= {  SUMA_SurfContHelp_SetRngTbl_r0,
6862                            SUMA_SurfContHelp_SetRngTbl_c1,
6863                            SUMA_SurfContHelp_SetRngTbl_c2 , NULL};
6864       char *row_tit[]=  {  " ", "I", "B", " " , "C", NULL};
6865       char *row_hint[]= {
6866          "Clipping ranges ",
6867          "Intensity clipping range (append '%' for percentiles, see BHelp)",
6868          "Brightness modulation clipping range (much more with BHelp)",
6869          "Brightness modulation factor range (much more with BHelp)" ,
6870          "Coordinate bias range (much more with BHelp)", NULL};
6871       char *row_help[]= {  SUMA_SurfContHelp_SetRngTbl_r0,
6872                            SUMA_SurfContHelp_SetRngTbl_r1,
6873                            SUMA_SurfContHelp_SetRngTbl_r2,
6874                            SUMA_SurfContHelp_SetRngTbl_r3,
6875                            SUMA_SurfContHelp_SetRngTbl_r4, NULL};
6876       if (!SurfCont->rccm) {
6877          SurfCont->rccm = XtVaCreateWidget ("rowcolumn",
6878             xmRowColumnWidgetClass, SurfCont->rcvo,
6879             XmNpacking, XmPACK_TIGHT,
6880             XmNorientation , XmVERTICAL ,
6881             XmNmarginHeight, 0,
6882             XmNmarginWidth, 0,
6883             NULL);
6884          NewMap = YUP; /* the first time around */
6885       }
6886 
6887       if (NewMap) {/* new colormaps */
6888          SUMA_Register_Widget_Help(SurfCont->rccm, 0,
6889                         "SurfContCont->Dset_Mapping->SetRangeTable",
6890                         "Node colorization parameters",
6891                         "Set parameters for mapping node data onto color scale");
6892          SUMA_LH("NewMap set");
6893          if (!SurfCont->SetRangeTable->cells) {
6894             int colw[3] = { 1, 8, 8 };
6895             SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)calloc(1,sizeof(SUMA_SRV_DATA));
6896             srvd->ado = ado; srvd->colp = NULL;
6897             /* create the widgets for the range table */
6898             SUMA_LH("Creating table");
6899             SUMA_CreateTable( SurfCont->rccm,
6900                            5, 3,
6901                            "SurfCont->Dset_Mapping->SetRangeTable",
6902                            row_tit, col_tit,
6903                            row_hint, col_hint,
6904                            row_help, col_help,
6905                            colw, YUP, SUMA_float,
6906                            SUMA_cb_SetRangeValue, (void *)srvd,
6907                            SUMA_SetRangeTableTit_EV, NULL,
6908                            NULL, NULL,
6909                            SurfCont->SetRangeTable);
6910          }
6911          if (!SurfCont->CoordBiasMenu->mw[SW_CoordBias]) {
6912                Widget rc = NULL; /* one pass through this block ONLY */
6913                rc = XtVaCreateWidget ("rowcolumn",
6914                   xmRowColumnWidgetClass, SurfCont->rccm,
6915                   XmNpacking, XmPACK_TIGHT,
6916                   XmNorientation , XmHORIZONTAL ,
6917                   XmNmarginHeight, 0 ,
6918                   XmNmarginWidth , 0 ,
6919                   NULL);
6920 
6921                SUMA_LH("Forming map mode menu");
6922                SUMA_BuildMenuReset(0);
6923                SUMA_BuildMenu ( rc, XmMENU_OPTION,
6924                                "Col", '\0', YUP, CmapMode_Menu,
6925                                (void *)ado,
6926                                "SurfCont->Dset_Mapping->Col",
6927                                "Switch between color mapping modes.",
6928                                SUMA_SurfContHelp_Col,
6929                                SurfCont->CmapModeMenu);
6930                XtManageChild (SurfCont->CmapModeMenu->mw[SW_CmapMode]);
6931 
6932                SUMA_LH("Forming new bias menu");
6933                SUMA_BuildMenuReset(0);
6934                SUMA_BuildMenu ( rc, XmMENU_OPTION,
6935                                "Bias", '\0', YUP, CoordBias_Menu,
6936                                (void *)ado,
6937                                "SurfCont->Dset_Mapping->Bias",
6938                                "Coordinate bias direction",
6939                                SUMA_SurfContHelp_Bias,
6940                                SurfCont->CoordBiasMenu);
6941                XtManageChild (SurfCont->CoordBiasMenu->mw[SW_CoordBias]);
6942 
6943                XtManageChild(rc);
6944          }
6945 
6946          if (!SurfCont->rccm_swcmap) {
6947             SUMA_LH("Creating rccm_swcmap");
6948             SurfCont->rccm_swcmap =  XtVaCreateWidget ("rowcolumn",
6949                xmRowColumnWidgetClass, SurfCont->rccm,
6950                XmNpacking, XmPACK_TIGHT,
6951                XmNorientation , XmHORIZONTAL ,
6952                XmNmarginHeight, 0 ,
6953                XmNmarginWidth , 0 ,
6954                NULL);
6955          }
6956 
6957          {
6958             SUMA_CreateUpdatableCmapMenu(ado);
6959 
6960             #if 0
6961                /* Not any more, menu is now stuck in its own rc */
6962                /* the loader, needs to be recreated with colormap menu  */
6963                if (SurfCont->CmapLoad_pb) {
6964                   XtDestroyWidget(SurfCont->CmapLoad_pb);
6965                   SurfCont->CmapLoad_pb = NULL;
6966                }
6967             #endif
6968             if (!SurfCont->CmapLoad_pb) {
6969                SUMA_LH("Forming CmapLoad button");
6970                SurfCont->CmapLoad_pb = XtVaCreateManagedWidget ("New",
6971                                  xmPushButtonWidgetClass,
6972                                  SurfCont->rccm_swcmap,
6973                                  NULL);
6974                XtAddCallback (SurfCont->CmapLoad_pb, XmNactivateCallback,
6975                               SUMA_cb_Cmap_Load, (XtPointer) ado);
6976                SUMA_Register_Widget_Help(SurfCont->CmapLoad_pb , 1,
6977                                          "SurfCont->Dset_Mapping->Cmp->New",
6978                                          "Load new colormap",
6979                                          SUMA_SurfContHelp_CmpNew);
6980             }
6981          } /* new colormaps */
6982          if (!XtIsManaged(SurfCont->rccm_swcmap))
6983                      XtManageChild (SurfCont->rccm_swcmap);
6984       }
6985 
6986       /* Set the CoordBias's menu history to reflect current setting */
6987       SUMA_LH("Updating Link Mode History");
6988       SUMA_Set_Menu_Widget( SurfCont->LinkModeMenu,
6989                      curColPlane->LinkMode);
6990 
6991       SUMA_LH("Working the lock stuff ...");
6992       /* You'll need to fix the table's locking widget colors */
6993       if ( SurfCont->IntRangeLocked ==
6994                curColPlane->OptScl->AutoIntRange) {
6995          SUMA_LH("   Do the Int");
6996          /* need to put things in sync */
6997          SurfCont->IntRangeLocked = !SurfCont->IntRangeLocked;
6998          MCW_invert_widget_sync(SurfCont->SetRangeTable->cells[1],0);
6999       }
7000       if ( SurfCont->BrtRangeLocked ==
7001                curColPlane->OptScl->AutoBrtRange) {
7002          SUMA_LH("   Do the Brt");
7003          /* need to put things in sync */
7004          SurfCont->BrtRangeLocked = !SurfCont->BrtRangeLocked;
7005          MCW_invert_widget_sync(SurfCont->SetRangeTable->cells[2],0);
7006       }
7007 
7008       /* Set the CoordBias's menu history to reflect current setting */
7009       SUMA_LH("Updating CoorBias chooser History");
7010       SUMA_Set_Menu_Widget( SurfCont->CoordBiasMenu,
7011                      curColPlane->OptScl->DoBias);
7012 
7013       /* Set the Col's menu history to reflect current setting */
7014       SUMA_LH("Updating Col chooser History");
7015       SUMA_Set_Menu_Widget( SurfCont->CmapModeMenu,
7016                      curColPlane->OptScl->interpmode);
7017 
7018       /* add the selectors for symmetric range and absolute threshold */
7019       if (!SurfCont->AbsThresh_tb) {
7020          Widget rc;
7021          rc = XtVaCreateWidget ("rowcolumn",
7022                xmRowColumnWidgetClass, SurfCont->rccm,
7023                XmNpacking, XmPACK_TIGHT,
7024                XmNorientation , XmHORIZONTAL ,
7025                XmNmarginHeight, 0 ,
7026                XmNmarginWidth , 0 ,
7027                NULL);
7028          /* create the absolute threshold toggle button */
7029          SurfCont->AbsThresh_tb = XtVaCreateManagedWidget("|T|",
7030                xmToggleButtonWidgetClass, rc,
7031                NULL);
7032          XtAddCallback (SurfCont->AbsThresh_tb,
7033                XmNvalueChangedCallback, SUMA_cb_AbsThresh_tb_toggled, ado);
7034          SUMA_Register_Widget_Help(SurfCont->AbsThresh_tb , 1,
7035                                    "SurfCont->Dset_Mapping->abs_T",
7036                                    "Absolute threshold ON/OFF",
7037                                    SUMA_SurfContHelp_AbsThr );
7038 
7039          SUMA_SET_SELECT_COLOR(SurfCont->AbsThresh_tb);
7040 
7041          /* create the symmetric range toggle button */
7042          SurfCont->SymIrange_tb = XtVaCreateManagedWidget("sym I",
7043                xmToggleButtonWidgetClass, rc, NULL);
7044          XtAddCallback (SurfCont->SymIrange_tb,
7045                XmNvalueChangedCallback, SUMA_cb_SymIrange_tb_toggled, ado);
7046          SUMA_Register_Widget_Help(SurfCont->SymIrange_tb, 1,
7047                                    "SurfCont->Dset_Mapping->sym_I",
7048                                    "Intensity range symmetry about 0 ",
7049                                    SUMA_SurfContHelp_Isym);
7050          SUMA_SET_SELECT_COLOR(SurfCont->SymIrange_tb);
7051 
7052          /* add a button for zero masking */
7053          SurfCont->ShowZero_tb = XtVaCreateManagedWidget("shw 0",
7054                xmToggleButtonWidgetClass, rc, NULL);
7055          XtAddCallback (SurfCont->ShowZero_tb,
7056                XmNvalueChangedCallback, SUMA_cb_ShowZero_tb_toggled, ado);
7057          SUMA_Register_Widget_Help(SurfCont->ShowZero_tb, 1,
7058                                    "SurfCont->Dset_Mapping->shw_0",
7059                                    "Color masking of nodes with intensity = 0 ",
7060                                    SUMA_SurfContHelp_Shw0);
7061          SUMA_SET_SELECT_COLOR(SurfCont->ShowZero_tb);
7062          XtManageChild (rc);
7063       }
7064 
7065       {/* The clustering options */
7066          char *col_tit[]= { " ", "Conn", "Area", NULL };
7067          char *col_hint[]={ "Clusterizing options",
7068                             "Connectedness criterion",
7069                             "Cluster Area Threshold", NULL };
7070          char *col_help[]={   SUMA_SurfContHelp_SetClustTbl_r0,
7071                               SUMA_SurfContHelp_SetClustTbl_c1,
7072                               SUMA_SurfContHelp_SetClustTbl_c2, NULL
7073                            };
7074          char *row_tit[]={ " ", "Clst", NULL};
7075          char *row_hint[]={ "Clusterizing options", "Clust on/off", NULL};
7076          char *row_help[]={ SUMA_SurfContHelp_SetClustTbl_r0,
7077                             SUMA_SurfContHelp_SetClustTbl_r1, NULL
7078                            };
7079 
7080          SUMA_LH("Receptacle");
7081          if (!SurfCont->rcclust) {
7082             SurfCont->rcclust = XtVaCreateWidget ("rowcolumn",
7083                xmRowColumnWidgetClass, SurfCont->opts_form,
7084                XmNpacking, XmPACK_TIGHT,
7085                XmNorientation , XmHORIZONTAL ,
7086                XmNmarginHeight, 0,
7087                XmNmarginWidth, 0,
7088                XmNrightAttachment, XmATTACH_FORM ,
7089                XmNleftAttachment,  XmATTACH_NONE,
7090                XmNtopAttachment, XmATTACH_WIDGET ,
7091                XmNtopWidget, SurfCont->opts_rc,
7092                NULL);
7093             FirstTime = YUP; /* the first time around */
7094          } else {
7095             FirstTime = NOPE;
7096          }
7097 
7098          if (FirstTime) {/* new clust */
7099             SUMA_LH("FirstTime set");
7100             if (!SurfCont->SetClustTable->cells) {
7101                int colw[3] = { 4, 6, 6 };
7102                SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)
7103                                  calloc(1,sizeof(SUMA_SRV_DATA));
7104                srvd->ado = ado; srvd->colp = NULL;
7105                /* create the widgets for the range table */
7106                SUMA_LH("Creating table");
7107                SUMA_CreateTable( SurfCont->rcclust,
7108                               2, 3,
7109                               "SurfCont->Dset_Mapping->Clst",
7110                               row_tit, col_tit,
7111                               row_hint, col_hint,
7112                               row_help, col_help,
7113                               colw, YUP, SUMA_float,
7114                               SUMA_cb_SetClustValue, (void *)srvd,
7115                               SUMA_SetClustTableTit_EV, NULL,
7116                               SUMA_SetClustTableCell_EV, NULL,
7117                               SurfCont->SetClustTable);
7118             }
7119 
7120             if (curColPlane->OptScl) {
7121                 SUMA_SetTableTitleButton1(SurfCont->SetClustTable, 1,0,                                       curColPlane->OptScl->Clusterize);
7122             }
7123          }
7124          SUMA_LH("Managerial");
7125 
7126          if (!XtIsManaged(SurfCont->rcclust))
7127                   XtManageChild (SurfCont->rcclust);
7128 
7129       }/* The clustering options */
7130 
7131       /* do the initialization */
7132       SUMA_InitClustTable(ado); /* init the clust table values*/
7133 
7134       /* This button is NOT appropriate for anything other than
7135          SUMA_ABS_LESS_THAN and SUMA_LESS_THAN
7136          Probably need separate button ormenu system for other
7137          thresholding modes */
7138       if (curColPlane->OptScl->ThrMode == SUMA_ABS_LESS_THAN) {
7139          XmToggleButtonSetState( SurfCont->AbsThresh_tb, True, NOPE);
7140       } else if (curColPlane->OptScl->ThrMode == SUMA_LESS_THAN) {
7141          XmToggleButtonSetState( SurfCont->AbsThresh_tb, False, NOPE);
7142       } else {
7143          SUMA_S_Err("Not ready to handle ThrModeR of %d yet",
7144                      curColPlane->OptScl->ThrMode);
7145       }
7146       if (!curColPlane->SymIrange) {
7147          XmToggleButtonSetState( SurfCont->SymIrange_tb, False, NOPE);
7148       } else {
7149          XmToggleButtonSetState( SurfCont->SymIrange_tb, True, NOPE);
7150       }
7151       if (!curColPlane->OptScl->MaskZero) {
7152          XmToggleButtonSetState( SurfCont->ShowZero_tb, True, NOPE);
7153       } else {
7154          XmToggleButtonSetState( SurfCont->ShowZero_tb, False, NOPE);
7155       }
7156 
7157       if (!XtIsManaged(SurfCont->rccm)) XtManageChild (SurfCont->rccm);
7158 
7159    }/*  The Color map range and selector block */
7160 
7161    if (1){ /* The Range values block*/
7162       char *col_tit[]=  {  " ", "Min", "Node", "Max", "Node", NULL};
7163       char *col_hint[]= {  "Full range of values in Dset",
7164                            "Minimum value in Dset column",
7165                            "Node index at minimum",
7166                            "Maximum value in Dset column",
7167                            "Node index at maximum", NULL};
7168       char *col_help[]= {  SUMA_SurfContHelp_RangeTbl_c0,
7169                            SUMA_SurfContHelp_RangeTbl_c1,
7170                            SUMA_SurfContHelp_RangeTbl_c2,
7171                            SUMA_SurfContHelp_RangeTbl_c3,
7172                            SUMA_SurfContHelp_RangeTbl_c4, NULL};
7173       char *row_tit[]=  {  " ", "I", "T", "B", NULL};
7174       char *row_hint[]= {  "Full range of values in Dset",
7175                            "Range of values in intensity (I) column",
7176                            "Range of values in threshold (T) column",
7177                            "Range of values in brightness (B) column", NULL};
7178       char *row_help[]= {  SUMA_SurfContHelp_RangeTbl_c0,
7179                            SUMA_SurfContHelp_RangeTbl_r1,
7180                            SUMA_SurfContHelp_RangeTbl_r2,
7181                            SUMA_SurfContHelp_RangeTbl_r3, NULL};
7182       if (!SurfCont->rcswr) {
7183          SurfCont->rcswr = XtVaCreateWidget ("rowcolumn",
7184             xmRowColumnWidgetClass, SurfCont->opts_form,
7185             XmNpacking, XmPACK_TIGHT,
7186             XmNorientation , XmVERTICAL ,
7187             XmNrightAttachment, XmATTACH_FORM ,
7188             XmNleftAttachment,  XmATTACH_NONE,
7189             XmNtopAttachment, XmATTACH_WIDGET ,
7190             XmNtopWidget, SurfCont->rcclust,
7191             NULL);
7192       }
7193 
7194       if (!SurfCont->RangeTable->cells) {
7195          int colw[5] = { 1, 6, 6, 6, 6 };
7196          /* create the widgets for the range table */
7197          SUMA_CreateTable( SurfCont->rcswr,
7198                            4, 5,
7199                            "SurfCont->Dset_Mapping->RangeTable",
7200                            row_tit, col_tit,
7201                            row_hint, col_hint,
7202                            row_help, col_help,
7203                            colw, NOPE, SUMA_string,
7204                            NULL, NULL,
7205                            NULL, NULL,
7206                            SUMA_RangeTableCell_EV, (void *)ado,
7207                            SurfCont->RangeTable);
7208       }
7209 
7210       if (!XtIsManaged(SurfCont->rcswr)) XtManageChild (SurfCont->rcswr);
7211    } /* The Range values block */
7212 
7213    if (NewDset) {
7214       /* initialize tables of range values */
7215       SUMA_InitRangeTable(ado, 2);
7216    }
7217 
7218    if (!XtIsManaged(SurfCont->rcvo)) XtManageChild (SurfCont->rcvo);
7219    SUMA_FORCE_SCALE_HEIGHT(SUMA_ADO_Cont(ado));
7220 
7221    SUMA_RETURNe;
7222 }
7223 
SUMA_set_cmap_options_CO(SUMA_ALL_DO * ado,SUMA_Boolean NewDset,SUMA_Boolean NewMap)7224 void SUMA_set_cmap_options_CO(SUMA_ALL_DO *ado, SUMA_Boolean NewDset,
7225                            SUMA_Boolean NewMap)
7226 {
7227    static char FuncName[]={"SUMA_set_cmap_options_CO"};
7228    SUMA_MenuItem  *SwitchInt_Menu = NULL, *SwitchThr_Menu = NULL,
7229                   *SwitchBrt_Menu = NULL;
7230    int N_items, FirstTime;
7231    SUMA_X_SurfCont *SurfCont=NULL;
7232    SUMA_OVERLAYS *curColPlane=NULL;
7233    SUMA_Boolean LocalHead = NOPE;
7234 
7235    SUMA_ENTRY;
7236 
7237    if (!ado) SUMA_RETURNe;
7238    if (ado->do_type != CDOM_type) {
7239       SUMA_S_Err("Should not be here");
7240       SUMA_RETURNe;
7241    }
7242    SurfCont = SUMA_ADO_Cont(ado);
7243    curColPlane = SUMA_ADO_CurColPlane(ado);
7244 
7245    if (!SurfCont) SUMA_RETURNe;
7246 
7247    SUMA_S_Err("Nothing here still");
7248 
7249    SUMA_RETURNe;
7250 }
7251 
SUMA_set_cmap_options_VO(SUMA_ALL_DO * ado,SUMA_Boolean NewDset,SUMA_Boolean NewMap)7252 void SUMA_set_cmap_options_VO(SUMA_ALL_DO *ado, SUMA_Boolean NewDset,
7253                            SUMA_Boolean NewMap)
7254 {
7255    static char FuncName[]={"SUMA_set_cmap_options_VO"};
7256    SUMA_MenuItem  *SwitchInt_Menu = NULL, *SwitchThr_Menu = NULL,
7257                   *SwitchBrt_Menu = NULL;
7258    int N_items, FirstTime;
7259    SUMA_X_SurfCont *SurfCont=NULL;
7260    SUMA_OVERLAYS *curColPlane=NULL;
7261    SUMA_Boolean LocalHead = NOPE;
7262 
7263    SUMA_ENTRY;
7264 
7265    if (!ado) SUMA_RETURNe;
7266    if (ado->do_type != VO_type) {
7267       SUMA_S_Err("Should not be here");
7268       SUMA_RETURNe;
7269    }
7270    SurfCont = SUMA_ADO_Cont(ado);
7271    curColPlane = SUMA_ADO_CurColPlane(ado);
7272 
7273    if (!SurfCont) SUMA_RETURNe;
7274    if (!SurfCont->opts_form || !SurfCont->opts_rc) SUMA_RETURNe;
7275    if (!curColPlane) SUMA_RETURNe;
7276    if (!NewDset && !NewMap && SurfCont->rcvo && SurfCont->rccm) {
7277       SUMA_SL_Err("Nothing to do");
7278       SUMA_RETURNe;
7279    }
7280    /* row column to contain all switching stuffs */
7281    if (!SurfCont->rcvo){
7282       SurfCont->rcvo = XtVaCreateWidget ("rowcolumn",
7283          xmRowColumnWidgetClass, SurfCont->opts_rc,
7284          XmNpacking, XmPACK_TIGHT,
7285          XmNorientation , XmVERTICAL ,
7286          XmNmarginHeight, 0 ,
7287          XmNmarginWidth , 0 ,
7288          NULL);
7289       NewDset = YUP; /* The first time around */
7290    } else {
7291       /* (no need ..) */
7292       /* XtUnmanageChild(SurfCont->rcvo);  */
7293    }
7294 
7295    if (NewDset) { /* The intensity / threshold / Brightness block*/
7296       /* link mode */
7297       if (!SurfCont->LinkModeMenu->mw[SW_LinkMode]) {
7298                Widget rc = NULL; /* one pass through this block ONLY */
7299                rc = XtVaCreateWidget ("rowcolumn",
7300                   xmRowColumnWidgetClass, SurfCont->rcvo,
7301                   XmNpacking, XmPACK_TIGHT,
7302                   XmNorientation , XmHORIZONTAL ,
7303                   XmNmarginHeight, 0 ,
7304                   XmNmarginWidth , 0 ,
7305                   NULL);
7306 
7307                SUMA_LH("Forming map mode menu");
7308                SUMA_BuildMenuReset(0);
7309                SUMA_BuildMenu ( rc, XmMENU_OPTION,
7310                                "IxT", '\0', YUP, LinkMode_Menu,
7311                                (void *)ado,
7312                                "VolCont->Dset_Mapping->IxT",
7313                                "Set I, T selection linking modes.",
7314                                SUMA_SurfContHelp_Link,
7315                                SurfCont->LinkModeMenu);
7316                XtManageChild (SurfCont->LinkModeMenu->mw[SW_LinkMode]);
7317 
7318                XtManageChild(rc);
7319          }
7320 
7321       if (!SurfCont->rcsw) {
7322          SurfCont->rcsw = XtVaCreateWidget ("rowcolumn",
7323             xmRowColumnWidgetClass, SurfCont->rcvo,
7324             XmNpacking, XmPACK_TIGHT,
7325             XmNorientation , XmHORIZONTAL ,
7326             XmNheight, 105,         /* don't let that change dynamically,  */
7327             XmNresizeHeight, False, /* it messes up the frame size, when you
7328                                        switch dsets*/
7329             XmNmarginHeight, 0 ,
7330             XmNmarginWidth , 0 ,
7331             NULL);
7332        } else {
7333          /* (no need ..) */
7334          /*XtUnmanageChild(SurfCont->rcsw); */
7335        }
7336       if (!SurfCont->rcsw_v1) {
7337          SurfCont->rcsw_v1 = XtVaCreateWidget ("rowcolumn",
7338             xmRowColumnWidgetClass, SurfCont->rcsw,
7339             XmNpacking, XmPACK_COLUMN,
7340             XmNorientation , XmVERTICAL ,
7341             XmNnumColumns, 1,
7342             XmNmarginHeight, 0 ,
7343             XmNmarginWidth , 0 ,
7344             NULL);
7345       }
7346       if (!SurfCont->rcsw_v2) {
7347          SurfCont->rcsw_v2 = XtVaCreateWidget ("rowcolumn",
7348             xmRowColumnWidgetClass, SurfCont->rcsw,
7349             XmNpacking, XmPACK_COLUMN,
7350             XmNorientation , XmVERTICAL ,
7351             XmNnumColumns, 1,
7352             XmNmarginHeight, 0 ,
7353             XmNmarginWidth , 0 ,
7354             NULL);
7355       }
7356 
7357       /* Switching triplets */
7358       SwitchInt_Menu = SUMA_FormSwitchColMenuVector(ado, 0, &N_items);
7359       if (LocalHead) fprintf (SUMA_STDERR,"%s: %d items.\n", FuncName, N_items);
7360       if (SwitchInt_Menu || !N_items) {
7361          SurfCont->SwitchIntMenu =
7362                SUMA_Free_Menu_Widget(SurfCont->SwitchIntMenu);
7363          SurfCont->SwitchIntMenu =
7364                SUMA_Alloc_Menu_Widget(N_items+1);
7365          SUMA_BuildMenuReset(13);
7366          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
7367                            "I", '\0', YUP, SwitchInt_Menu,
7368                            (void *)ado,
7369                            "VolCont->Dset_Mapping->I",
7370                   "Select Intensity (I) column, aka sub-brick. (BHelp for more)",
7371                            SUMA_SurfContHelp_SelInt,
7372                            SurfCont->SwitchIntMenu );
7373          XtInsertEventHandler( SurfCont->SwitchIntMenu->mw[0] ,
7374                                              /* handle events in optmenu */
7375                         ButtonPressMask ,  /* button presses */
7376                         FALSE ,            /* nonmaskable events? */
7377                         SUMA_optmenu_EV ,  /* handler */
7378                         (XtPointer) ado ,   /* client data */
7379                         XtListTail ) ;
7380          if (LocalHead)
7381             SUMA_ShowMeTheChildren(SurfCont->SwitchIntMenu->mw[0]);
7382          XtManageChild (SurfCont->SwitchIntMenu->mw[0]);
7383          /* Now destroy the SwitchInt_Menu */
7384          SwitchInt_Menu = SUMA_FreeMenuVector(SwitchInt_Menu, N_items);
7385          /* setup the history to the proper widget */
7386          SUMA_Set_Menu_Widget(SurfCont->SwitchIntMenu,
7387                        curColPlane->OptScl->find+1) ;
7388       } else {
7389          SUMA_SL_Err("NULL SwitchInt_Menu");
7390       }
7391 
7392       SwitchThr_Menu = SUMA_FormSwitchColMenuVector(ado, 1, &N_items);
7393       if (SwitchThr_Menu || !N_items) {
7394          SurfCont->SwitchThrMenu =
7395                SUMA_Free_Menu_Widget(SurfCont->SwitchThrMenu);
7396          SurfCont->SwitchThrMenu =
7397                SUMA_Alloc_Menu_Widget(N_items+1);
7398          SUMA_BuildMenuReset(13);
7399          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
7400                            "T", '\0', YUP, SwitchThr_Menu,
7401                            (void *)ado,
7402                            "VolCont->Dset_Mapping->T",
7403                "Select Threshold (T) column, aka sub-brick.  (BHelp for more)",
7404                            SUMA_SurfContHelp_SelThr ,
7405                            SurfCont->SwitchThrMenu );
7406          XtInsertEventHandler( SurfCont->SwitchThrMenu->mw[0] ,
7407                                        /* handle events in optmenu */
7408                         ButtonPressMask ,  /* button presses */
7409                         FALSE ,            /* nonmaskable events? */
7410                         SUMA_optmenu_EV ,  /* handler */
7411                         (XtPointer) ado ,   /* client data */
7412                         XtListTail ) ;
7413          XtManageChild (SurfCont->SwitchThrMenu->mw[0]);
7414          /* Now destroy the SwitchThr_Menu */
7415          SwitchThr_Menu = SUMA_FreeMenuVector(SwitchThr_Menu, N_items);
7416          /* setup the history to the proper widget */
7417          SUMA_Set_Menu_Widget(SurfCont->SwitchThrMenu,
7418                        curColPlane->OptScl->tind+1);
7419       } else {
7420          SUMA_SL_Err("NULL SwitchThr_Menu");
7421       }
7422 
7423       SwitchBrt_Menu = SUMA_FormSwitchColMenuVector(ado, 2, &N_items);
7424       if (SwitchBrt_Menu || !N_items) {
7425          SurfCont->SwitchBrtMenu =
7426                SUMA_Free_Menu_Widget(SurfCont->SwitchBrtMenu);
7427          SurfCont->SwitchBrtMenu =
7428                SUMA_Alloc_Menu_Widget(N_items+1);
7429          SUMA_BuildMenuReset(13);
7430          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
7431                            "B", '\0', YUP, SwitchBrt_Menu,
7432                            (void *)ado,
7433                            "VolCont->Dset_Mapping->B",
7434                "Select Brightness (B) column, aka sub-brick. (BHelp for more)",
7435                            SUMA_SurfContHelp_SelBrt,
7436                            SurfCont->SwitchBrtMenu );
7437          XtInsertEventHandler( SurfCont->SwitchBrtMenu->mw[0] ,
7438                                                 /* handle events in optmenu */
7439                         ButtonPressMask ,  /* button presses */
7440                         FALSE ,            /* nonmaskable events? */
7441                         SUMA_optmenu_EV ,  /* handler */
7442                         (XtPointer) ado ,   /* client data */
7443                         XtListTail ) ;
7444 
7445          XtManageChild (SurfCont->SwitchBrtMenu->mw[0]);
7446          /* Now destroy the SwitchBrt_Menu */
7447          SwitchBrt_Menu = SUMA_FreeMenuVector(SwitchBrt_Menu, N_items);
7448          /* setup the history to the proper widget */
7449          SUMA_Set_Menu_Widget(SurfCont->SwitchBrtMenu,
7450                        curColPlane->OptScl->bind+1);
7451       } else {
7452          SUMA_SL_Err("NULL SwitchBrt_Menu");
7453       }
7454 
7455      if (1) {
7456      /* put the toggle buttons */
7457          if (!SurfCont->Int_tb) {
7458             SurfCont->Int_tb = XtVaCreateManagedWidget("v",
7459                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
7460             XtAddCallback (SurfCont->Int_tb,
7461                   XmNvalueChangedCallback, SUMA_cb_SwitchInt_toggled, ado);
7462             SUMA_Register_Widget_Help(SurfCont->Int_tb, 1,
7463                               "VolCont->Dset_Mapping->I->v",
7464                               "View (ON)/Hide volume voxel colors",
7465                               SUMA_VolContHelp_SelIntTgl);
7466 
7467             SUMA_SET_SELECT_COLOR(SurfCont->Int_tb);
7468          }
7469          XmToggleButtonSetState (SurfCont->Int_tb,
7470                     curColPlane->ShowMode > 0 ? 1:0 , NOPE);
7471 
7472          if (!SurfCont->Thr_tb) {
7473             SurfCont->Thr_tb = XtVaCreateManagedWidget("v",
7474                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
7475             XtAddCallback (SurfCont->Thr_tb,
7476                   XmNvalueChangedCallback, SUMA_cb_SwitchThr_toggled, ado);
7477             SUMA_SET_SELECT_COLOR(SurfCont->Thr_tb);
7478             SUMA_Register_Widget_Help(SurfCont->Thr_tb, 1,
7479                               "VolCont->Dset_Mapping->T->v",
7480                               "Apply (ON)/Ignore thresholding",
7481                               SUMA_SurfContHelp_SelThrTgl);
7482          }
7483          if (curColPlane->OptScl->tind >=0) {
7484             XmToggleButtonSetState (SurfCont->Thr_tb,
7485                               curColPlane->OptScl->UseThr, NOPE);
7486          }else {
7487             XmToggleButtonSetState (SurfCont->Thr_tb, NOPE, NOPE);
7488          }
7489 
7490          if (!SurfCont->Brt_tb) {
7491             SurfCont->Brt_tb = XtVaCreateManagedWidget("v",
7492                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
7493             XtAddCallback (SurfCont->Brt_tb,
7494                      XmNvalueChangedCallback, SUMA_cb_SwitchBrt_toggled, ado);
7495             SUMA_SET_SELECT_COLOR(SurfCont->Brt_tb);
7496             SUMA_Register_Widget_Help(SurfCont->Brt_tb, 1,
7497                      "VolCont->Dset_Mapping->B->v",
7498                      "View (ON)/Ignore brightness modulation",
7499                      SUMA_SurfContHelp_SelBrtTgl);
7500          }
7501          if (curColPlane->OptScl->bind >=0) {
7502             XmToggleButtonSetState (SurfCont->Brt_tb,
7503                      curColPlane->OptScl->UseBrt, NOPE);
7504          } else {
7505             XmToggleButtonSetState (SurfCont->Brt_tb, NOPE, NOPE);
7506          }
7507       }
7508       if (!XtIsManaged(SurfCont->rcsw_v1))
7509          XtManageChild (SurfCont->rcsw_v1);
7510       if (!XtIsManaged(SurfCont->rcsw_v2))
7511          XtManageChild (SurfCont->rcsw_v2);
7512       if (!XtIsManaged(SurfCont->rcsw)) XtManageChild (SurfCont->rcsw);
7513    } /* The intensity / threshold / Brightness block */
7514 
7515 
7516    {/*  The Color map range and selector block */
7517       char *col_tit[]=  {  " ", "Min", "Max", NULL};
7518       char *col_hint[]= {  "Clipping ranges",
7519                            "Minimum clip value",
7520                            "Maximum clip value" , NULL};
7521       char *col_help[]= {  SUMA_SurfContHelp_SetRngTbl_r0,
7522                            SUMA_SurfContHelp_SetRngTbl_c1,
7523                            SUMA_SurfContHelp_SetRngTbl_c2 , NULL};
7524       char *row_tit[]=  {  " ", "I", "B", " " , "C", NULL};
7525       char *row_hint[]= {
7526          "Clipping ranges ",
7527          "Intensity clipping range (append '%' for percentiles, see BHelp)",
7528          "Brightness modulation clipping range (much more with BHelp)",
7529          "Brightness modulation factor range (much more with BHelp)" ,
7530          "Coordinate bias range (much more with BHelp)", NULL};
7531       char *row_help[]= {  SUMA_SurfContHelp_SetRngTbl_r0,
7532                            SUMA_SurfContHelp_SetRngTbl_r1,
7533                            SUMA_SurfContHelp_SetRngTbl_r2,
7534                            SUMA_SurfContHelp_SetRngTbl_r3,
7535                            SUMA_SurfContHelp_SetRngTbl_r4, NULL};
7536       if (!SurfCont->rccm) {
7537          SurfCont->rccm = XtVaCreateWidget ("rowcolumn",
7538             xmRowColumnWidgetClass, SurfCont->rcvo,
7539             XmNpacking, XmPACK_TIGHT,
7540             XmNorientation , XmVERTICAL ,
7541             XmNmarginHeight, 0,
7542             XmNmarginWidth, 0,
7543             NULL);
7544          NewMap = YUP; /* the first time around */
7545       }
7546 
7547       if (NewMap) {/* new colormaps */
7548          SUMA_LH("NewMap set");
7549          SUMA_Register_Widget_Help(SurfCont->rccm, 1,
7550                            "VolCont->Dset_Mapping->SetRangeTable",
7551                            "Voxel colorization parameters",
7552                            "Set parameters for mapping data onto color scale");
7553          if (!SurfCont->SetRangeTable->cells) {
7554             int colw[3] = { 1, 8, 8 };
7555             SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)calloc(1,sizeof(SUMA_SRV_DATA));
7556             srvd->ado = ado; srvd->colp = NULL;
7557             /* create the widgets for the range table */
7558             SUMA_LH("Creating table");
7559             SUMA_CreateTable( SurfCont->rccm,
7560                            5, 3,
7561                            "VolCont->Dset_Mapping->SetRangeTable",
7562                            row_tit, col_tit,
7563                            row_hint, col_hint,
7564                            row_help, col_help,
7565                            colw, YUP, SUMA_float,
7566                            SUMA_cb_SetRangeValue, (void *)srvd,
7567                            SUMA_SetRangeTableTit_EV, NULL,
7568                            NULL, NULL,
7569                            SurfCont->SetRangeTable);
7570          }
7571          if (!SurfCont->CoordBiasMenu->mw[SW_CoordBias]) {
7572                Widget rc = NULL; /* one pass through this block ONLY */
7573                rc = XtVaCreateWidget ("rowcolumn",
7574                   xmRowColumnWidgetClass, SurfCont->rccm,
7575                   XmNpacking, XmPACK_TIGHT,
7576                   XmNorientation , XmHORIZONTAL ,
7577                   XmNmarginHeight, 0 ,
7578                   XmNmarginWidth , 0 ,
7579                   NULL);
7580 
7581                SUMA_LH("Forming map mode menu");
7582                SUMA_BuildMenuReset(0);
7583                SUMA_BuildMenu ( rc, XmMENU_OPTION,
7584                                "Col", '\0', YUP, CmapMode_Menu,
7585                                (void *)ado,
7586                                "VolCont->Dset_Mapping->Col",
7587                                "Switch between color mapping modes.",
7588                                SUMA_SurfContHelp_Col,
7589                                SurfCont->CmapModeMenu);
7590                XtManageChild (SurfCont->CmapModeMenu->mw[SW_CmapMode]);
7591 
7592                #if 0
7593                SUMA_LH("Forming new bias menu");
7594                SUMA_BuildMenuReset(0);
7595                SUMA_BuildMenu ( rc, XmMENU_OPTION,
7596                                "Bias", '\0', YUP, CoordBias_Menu,
7597                                (void *)ado,
7598                                "VolCont->Dset_Mapping->Bias",
7599                                "Coordinate bias direction",
7600                                SUMA_SurfContHelp_Bias,
7601                                SurfCont->CoordBiasMenu);
7602                XtManageChild (SurfCont->CoordBiasMenu->mw[SW_CoordBias]);
7603                #endif
7604                XtManageChild(rc);
7605          }
7606 
7607          if (!SurfCont->rccm_swcmap) {
7608             SUMA_LH("Creating rccm_swcmap");
7609             SurfCont->rccm_swcmap =  XtVaCreateWidget ("rowcolumn",
7610                xmRowColumnWidgetClass, SurfCont->rccm,
7611                XmNpacking, XmPACK_TIGHT,
7612                XmNorientation , XmHORIZONTAL ,
7613                XmNmarginHeight, 0 ,
7614                XmNmarginWidth , 0 ,
7615                NULL);
7616          }
7617 
7618          {
7619             SUMA_CreateUpdatableCmapMenu(ado);
7620 
7621             #if 0
7622                /* Not any more, menu is now stuck in its own rc */
7623                /* the loader, needs to be recreated with colormap menu  */
7624                if (SurfCont->CmapLoad_pb) {
7625                   XtDestroyWidget(SurfCont->CmapLoad_pb);
7626                   SurfCont->CmapLoad_pb = NULL;
7627                }
7628             #endif
7629             if (!SurfCont->CmapLoad_pb) {
7630                SUMA_LH("Forming CmapLoad button");
7631                SurfCont->CmapLoad_pb = XtVaCreateManagedWidget ("New",
7632                                  xmPushButtonWidgetClass,
7633                                  SurfCont->rccm_swcmap,
7634                                  NULL);
7635                XtAddCallback (SurfCont->CmapLoad_pb, XmNactivateCallback,
7636                               SUMA_cb_Cmap_Load, (XtPointer) ado);
7637                SUMA_Register_Widget_Help(SurfCont->CmapLoad_pb , 1,
7638                                  "VolCont->Dset_Mapping->Cmp->New",
7639                                  "Load new colormap",
7640                                  SUMA_SurfContHelp_CmpNew);
7641             }
7642          } /* new colormaps */
7643          if (!XtIsManaged(SurfCont->rccm_swcmap))
7644                      XtManageChild (SurfCont->rccm_swcmap);
7645       }
7646 
7647       /* Set the CoordBias's menu history to reflect current setting */
7648       SUMA_LH("Updating Link Mode History");
7649       SUMA_Set_Menu_Widget( SurfCont->LinkModeMenu,
7650                      curColPlane->LinkMode);
7651 
7652       SUMA_LH("Working the lock stuff ...");
7653       /* You'll need to fix the table's locking widget colors */
7654       if ( SurfCont->IntRangeLocked ==
7655                curColPlane->OptScl->AutoIntRange) {
7656          SUMA_LH("   Do the Int");
7657          /* need to put things in sync */
7658          SurfCont->IntRangeLocked = !SurfCont->IntRangeLocked;
7659          MCW_invert_widget_sync(SurfCont->SetRangeTable->cells[1], 0);
7660       }
7661       if ( SurfCont->BrtRangeLocked ==
7662                curColPlane->OptScl->AutoBrtRange) {
7663          SUMA_LH("   Do the Brt");
7664          /* need to put things in sync */
7665          SurfCont->BrtRangeLocked = !SurfCont->BrtRangeLocked;
7666          MCW_invert_widget_sync(SurfCont->SetRangeTable->cells[2], 0);
7667       }
7668 
7669       /* Set the CoordBias's menu history to reflect current setting */
7670       SUMA_LH("Updating CoorBias chooser History");
7671       SUMA_Set_Menu_Widget( SurfCont->CoordBiasMenu,
7672                      curColPlane->OptScl->DoBias);
7673 
7674       /* Set the Col's menu history to reflect current setting */
7675       SUMA_LH("Updating Col chooser History");
7676       SUMA_Set_Menu_Widget( SurfCont->CmapModeMenu,
7677                      curColPlane->OptScl->interpmode);
7678 
7679       /* add the selectors for symmetric range and absolute threshold */
7680       if (!SurfCont->AbsThresh_tb) {
7681          Widget rc;
7682          rc = XtVaCreateWidget ("rowcolumn",
7683                xmRowColumnWidgetClass, SurfCont->rccm,
7684                XmNpacking, XmPACK_TIGHT,
7685                XmNorientation , XmHORIZONTAL ,
7686                XmNmarginHeight, 0 ,
7687                XmNmarginWidth , 0 ,
7688                NULL);
7689          /* create the absolute threshold toggle button */
7690          SurfCont->AbsThresh_tb = XtVaCreateManagedWidget("|T|",
7691                xmToggleButtonWidgetClass, rc,
7692                NULL);
7693          XtAddCallback (SurfCont->AbsThresh_tb,
7694                XmNvalueChangedCallback, SUMA_cb_AbsThresh_tb_toggled, ado);
7695          SUMA_Register_Widget_Help(SurfCont->AbsThresh_tb , 1,
7696                            "VolCont->Dset_Mapping->abs_T",
7697                            "Absolute threshold ON/OFF",
7698                            SUMA_SurfContHelp_AbsThr );
7699 
7700          SUMA_SET_SELECT_COLOR(SurfCont->AbsThresh_tb);
7701 
7702          /* create the symmetric range toggle button */
7703          SurfCont->SymIrange_tb = XtVaCreateManagedWidget("sym I",
7704                xmToggleButtonWidgetClass, rc, NULL);
7705          XtAddCallback (SurfCont->SymIrange_tb,
7706                XmNvalueChangedCallback, SUMA_cb_SymIrange_tb_toggled, ado);
7707          SUMA_Register_Widget_Help(SurfCont->SymIrange_tb, 1,
7708                            "VolCont->Dset_Mapping->sym_I",
7709                            "Intensity range symmetry about 0 ",
7710                            SUMA_SurfContHelp_Isym);
7711          SUMA_SET_SELECT_COLOR(SurfCont->SymIrange_tb);
7712 
7713          /* add a button for zero masking */
7714          SurfCont->ShowZero_tb = XtVaCreateManagedWidget("shw 0",
7715                xmToggleButtonWidgetClass, rc, NULL);
7716          XtAddCallback (SurfCont->ShowZero_tb,
7717                XmNvalueChangedCallback, SUMA_cb_ShowZero_tb_toggled, ado);
7718          SUMA_Register_Widget_Help(SurfCont->ShowZero_tb, 1,
7719                "VolCont->Dset_Mapping->shw_0",
7720                "Color masking of nodes with intensity = 0 ",
7721                SUMA_SurfContHelp_Shw0);
7722          SUMA_SET_SELECT_COLOR(SurfCont->ShowZero_tb);
7723          XtManageChild (rc);
7724       }
7725 
7726       if (0) {/* The clustering options - NOT YET IMPLEMENTED FOR VOLUMES -
7727                  Interface OK, but callbacks do not handle volumes yet */
7728          char *col_tit[]= { " ", "Conn", "Area", NULL };
7729          char *col_hint[]={ "Clusterizing options",
7730                             "Connectedness criterion",
7731                             "Cluster Area Threshold", NULL };
7732          char *col_help[]={   SUMA_SurfContHelp_SetClustTbl_r0,
7733                               SUMA_SurfContHelp_SetClustTbl_c1,
7734                               SUMA_SurfContHelp_SetClustTbl_c2, NULL
7735                            };
7736          char *row_tit[]={ " ", "Clst", NULL};
7737          char *row_hint[]={ "Clusterizing options", "Clust on/off", NULL};
7738          char *row_help[]={ SUMA_SurfContHelp_SetClustTbl_r0,
7739                             SUMA_SurfContHelp_SetClustTbl_r1, NULL
7740                            };
7741 
7742          SUMA_LH("Receptacle");
7743          if (!SurfCont->rcclust) {
7744             SurfCont->rcclust = XtVaCreateWidget ("rowcolumn",
7745                xmRowColumnWidgetClass, SurfCont->opts_form,
7746                XmNpacking, XmPACK_TIGHT,
7747                XmNorientation , XmHORIZONTAL ,
7748                XmNmarginHeight, 0,
7749                XmNmarginWidth, 0,
7750                XmNrightAttachment, XmATTACH_FORM ,
7751                XmNleftAttachment,  XmATTACH_NONE,
7752                XmNtopAttachment, XmATTACH_WIDGET ,
7753                XmNtopWidget, SurfCont->opts_rc,
7754                NULL);
7755             FirstTime = YUP; /* the first time around */
7756          } else {
7757             FirstTime = NOPE;
7758          }
7759 
7760          if (FirstTime) {/* new clust */
7761             SUMA_LH("FirstTime set");
7762             if (!SurfCont->SetClustTable->cells) {
7763                int colw[3] = { 4, 6, 6 };
7764                SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)
7765                                  calloc(1,sizeof(SUMA_SRV_DATA));
7766                srvd->ado = ado; srvd->colp = NULL;
7767                /* create the widgets for the range table */
7768                SUMA_LH("Creating table");
7769                SUMA_CreateTable( SurfCont->rcclust,
7770                               2, 3,
7771                               "VolCont->Dset_Mapping->Clst",
7772                               row_tit, col_tit,
7773                               row_hint, col_hint,
7774                               row_help, col_help,
7775                               colw, YUP, SUMA_float,
7776                               SUMA_cb_SetClustValue, (void *)srvd,
7777                               SUMA_SetClustTableTit_EV, NULL,
7778                               SUMA_SetClustTableCell_EV, NULL,
7779                               SurfCont->SetClustTable);
7780             }
7781 
7782             if (curColPlane->OptScl) {
7783                 SUMA_SetTableTitleButton1(SurfCont->SetClustTable, 1,0,                                       curColPlane->OptScl->Clusterize);
7784             }
7785          }
7786          SUMA_LH("Managerial");
7787 
7788          if (!XtIsManaged(SurfCont->rcclust))
7789                   XtManageChild (SurfCont->rcclust);
7790 
7791          /* do the initialization */
7792          SUMA_InitClustTable(ado); /* init the clust table values*/
7793       }/* The clustering options */
7794 
7795 
7796       if (curColPlane->OptScl->ThrMode == SUMA_ABS_LESS_THAN) {
7797          XmToggleButtonSetState( SurfCont->AbsThresh_tb, True, NOPE);
7798       } else if (curColPlane->OptScl->ThrMode == SUMA_LESS_THAN){
7799          XmToggleButtonSetState( SurfCont->AbsThresh_tb, False, NOPE);
7800       } else {
7801          SUMA_S_Err("Not ready to handle ThrModeR of %d yet",
7802                      curColPlane->OptScl->ThrMode);
7803       }
7804       if (!curColPlane->SymIrange) {
7805          XmToggleButtonSetState( SurfCont->SymIrange_tb, False, NOPE);
7806       } else {
7807          XmToggleButtonSetState( SurfCont->SymIrange_tb, True, NOPE);
7808       }
7809       if (!curColPlane->OptScl->MaskZero) {
7810          XmToggleButtonSetState( SurfCont->ShowZero_tb, True, NOPE);
7811       } else {
7812          XmToggleButtonSetState( SurfCont->ShowZero_tb, False, NOPE);
7813       }
7814 
7815       if (!XtIsManaged(SurfCont->rccm)) XtManageChild (SurfCont->rccm);
7816 
7817    }/*  The Color map range and selector block */
7818 
7819    { /* The Range values block*/
7820       char *col_tit[]=  {  " ", "Min", "Vox", "Max", "Vox", NULL};
7821       char *col_hint[]= {  "Full range of values in Dset",
7822                            "Minimum value in Dset column",
7823                            "Node index at minimum",
7824                            "Maximum value in Dset column",
7825                            "Node index at maximum", NULL};
7826       char *col_help[]= {  SUMA_SurfContHelp_RangeTbl_c0,
7827                            SUMA_SurfContHelp_RangeTbl_c1,
7828                            SUMA_SurfContHelp_RangeTbl_c2,
7829                            SUMA_SurfContHelp_RangeTbl_c3,
7830                            SUMA_SurfContHelp_RangeTbl_c4, NULL};
7831       char *row_tit[]=  {  " ", "I", "T", "B", NULL};
7832       char *row_hint[]= {  "Full range of values in Dset",
7833                            "Range of values in intensity (I) column",
7834                            "Range of values in threshold (T) column",
7835                            "Range of values in brightness (B) column", NULL};
7836       char *row_help[]= {  SUMA_SurfContHelp_RangeTbl_c0,
7837                            SUMA_SurfContHelp_RangeTbl_r1,
7838                            SUMA_SurfContHelp_RangeTbl_r2,
7839                            SUMA_SurfContHelp_RangeTbl_r3, NULL};
7840       if (!SurfCont->rcswr) {
7841          SurfCont->rcswr = XtVaCreateWidget ("rowcolumn",
7842             xmRowColumnWidgetClass, SurfCont->opts_form,
7843             XmNpacking, XmPACK_TIGHT,
7844             XmNorientation , XmVERTICAL ,
7845             XmNrightAttachment, XmATTACH_FORM ,
7846             XmNleftAttachment,  XmATTACH_NONE,
7847             XmNtopAttachment, XmATTACH_WIDGET ,
7848             XmNtopWidget, SurfCont->rcclust?SurfCont->rcclust:SurfCont->opts_rc,
7849             NULL);
7850       }
7851 
7852       if (!SurfCont->RangeTable->cells) {
7853          int colw[5] = { 1, 6, 6, 6, 6 };
7854          /* create the widgets for the range table */
7855          SUMA_CreateTable( SurfCont->rcswr,
7856                            4, 5,
7857                            "VolCont->Dset_Mapping->RangeTable",
7858                            row_tit, col_tit,
7859                            row_hint, col_hint,
7860                            row_help, col_help,
7861                            colw, NOPE, SUMA_string,
7862                            NULL, NULL,
7863                            NULL, NULL,
7864                            SUMA_RangeTableCell_EV, (void *)ado,
7865                            SurfCont->RangeTable);
7866       }
7867 
7868       if (!XtIsManaged(SurfCont->rcswr)) XtManageChild (SurfCont->rcswr);
7869    } /* The Range values block */
7870 
7871    if (NewDset) {
7872       /* initialize tables of range values */
7873       SUMA_InitRangeTable(ado, 2);
7874    }
7875 
7876    if (!XtIsManaged(SurfCont->rcvo)) XtManageChild (SurfCont->rcvo);
7877    SUMA_FORCE_SCALE_HEIGHT(SUMA_ADO_Cont(ado));
7878 
7879    SUMA_RETURNe;
7880 }
7881 
SUMA_set_cmap_options_GLDO(SUMA_ALL_DO * ado,SUMA_Boolean NewDset,SUMA_Boolean NewMap)7882 void SUMA_set_cmap_options_GLDO(SUMA_ALL_DO *ado, SUMA_Boolean NewDset,
7883                            SUMA_Boolean NewMap)
7884 {
7885    static char FuncName[]={"SUMA_set_cmap_options_GLDO"};
7886    SUMA_MenuItem  *SwitchInt_Menu = NULL, *SwitchThr_Menu = NULL,
7887                   *SwitchBrt_Menu = NULL;
7888    int N_items, FirstTime;
7889    SUMA_X_SurfCont *SurfCont=NULL;
7890    SUMA_OVERLAYS *curColPlane=NULL;
7891 
7892    SUMA_Boolean LocalHead = NOPE;
7893 
7894    SUMA_ENTRY;
7895 
7896    if (!ado) SUMA_RETURNe;
7897 
7898    SurfCont = SUMA_ADO_Cont(ado);
7899    curColPlane = SUMA_ADO_CurColPlane(ado);
7900 
7901    if (!SurfCont) SUMA_RETURNe;
7902    if (!SurfCont->opts_form || !SurfCont->opts_rc) SUMA_RETURNe;
7903    if (!curColPlane) SUMA_RETURNe;
7904    if (!NewDset && !NewMap && SurfCont->rcvo && SurfCont->rccm) {
7905       SUMA_SL_Err("Nothing to do");
7906       SUMA_RETURNe;
7907    }
7908    /* row column to contain all switching stuffs */
7909    if (!SurfCont->rcvo){
7910       SurfCont->rcvo = XtVaCreateWidget ("rowcolumn",
7911          xmRowColumnWidgetClass, SurfCont->opts_rc,
7912          XmNpacking, XmPACK_TIGHT,
7913          XmNorientation , XmVERTICAL ,
7914          XmNmarginHeight, 0 ,
7915          XmNmarginWidth , 0 ,
7916          NULL);
7917       NewDset = YUP; /* The first time around */
7918    } else {
7919       /* (no need ..) */
7920       /* XtUnmanageChild(SurfCont->rcvo);  */
7921    }
7922 
7923    if (NewDset) { /* The intensity / threshold / Brightness block*/
7924       /* link mode */
7925       if (!SurfCont->LinkModeMenu->mw[SW_LinkMode]) {
7926                Widget rc = NULL; /* one pass through this block ONLY */
7927                rc = XtVaCreateWidget ("rowcolumn",
7928                   xmRowColumnWidgetClass, SurfCont->rcvo,
7929                   XmNpacking, XmPACK_TIGHT,
7930                   XmNorientation , XmHORIZONTAL ,
7931                   XmNmarginHeight, 0 ,
7932                   XmNmarginWidth , 0 ,
7933                   NULL);
7934 
7935                SUMA_LH("Forming map mode menu");
7936                SUMA_BuildMenuReset(0);
7937                SUMA_BuildMenu ( rc, XmMENU_OPTION,
7938                                "IxT", '\0', YUP, LinkMode_Menu,
7939                                (void *)ado,
7940                                "GraphCont->GDset_Mapping->IxT",
7941                                "Set I, T selection linking modes.",
7942                                SUMA_SurfContHelp_Link,
7943                                SurfCont->LinkModeMenu);
7944                XtManageChild (SurfCont->LinkModeMenu->mw[SW_LinkMode]);
7945 
7946                XtManageChild(rc);
7947          }
7948 
7949       if (!SurfCont->rcsw) {
7950          SurfCont->rcsw = XtVaCreateWidget ("rowcolumn",
7951             xmRowColumnWidgetClass, SurfCont->rcvo,
7952             XmNpacking, XmPACK_TIGHT,
7953             XmNorientation , XmHORIZONTAL ,
7954             XmNheight, 105,         /* don't let that change dynamically,  */
7955             XmNresizeHeight, False, /* it messes up the frame size, when you
7956                                        switch dsets*/
7957             XmNmarginHeight, 0 ,
7958             XmNmarginWidth , 0 ,
7959             NULL);
7960        } else {
7961          /* (no need ..) */
7962          /*XtUnmanageChild(SurfCont->rcsw); */
7963        }
7964       if (!SurfCont->rcsw_v1) {
7965          SurfCont->rcsw_v1 = XtVaCreateWidget ("rowcolumn",
7966             xmRowColumnWidgetClass, SurfCont->rcsw,
7967             XmNpacking, XmPACK_COLUMN,
7968             XmNorientation , XmVERTICAL ,
7969             XmNnumColumns, 1,
7970             XmNmarginHeight, 0 ,
7971             XmNmarginWidth , 0 ,
7972             NULL);
7973       }
7974       if (!SurfCont->rcsw_v2) {
7975          SurfCont->rcsw_v2 = XtVaCreateWidget ("rowcolumn",
7976             xmRowColumnWidgetClass, SurfCont->rcsw,
7977             XmNpacking, XmPACK_COLUMN,
7978             XmNorientation , XmVERTICAL ,
7979             XmNnumColumns, 1,
7980             XmNmarginHeight, 0 ,
7981             XmNmarginWidth , 0 ,
7982             NULL);
7983       }
7984 
7985       /* Switching triplets */
7986       SwitchInt_Menu =
7987          SUMA_FormSwitchColMenuVector(ado, 0, &N_items);
7988       if (LocalHead) fprintf (SUMA_STDERR,"%s: %d items.\n", FuncName, N_items);
7989       if (SwitchInt_Menu || !N_items) {
7990          SurfCont->SwitchIntMenu =
7991                SUMA_Free_Menu_Widget(SurfCont->SwitchIntMenu);
7992          SurfCont->SwitchIntMenu =
7993                SUMA_Alloc_Menu_Widget(N_items+1);
7994          SUMA_BuildMenuReset(13);
7995          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
7996                            "I", '\0', YUP, SwitchInt_Menu,
7997                            (void *)ado,
7998                            "GraphCont->GDset_Mapping->I",
7999                   "Select Intensity (I) column, aka sub-brick. (BHelp for more)",
8000                            SUMA_SurfContHelp_SelInt,
8001                            SurfCont->SwitchIntMenu );
8002          XtInsertEventHandler( SurfCont->SwitchIntMenu->mw[0] ,
8003                                              /* handle events in optmenu */
8004                         ButtonPressMask ,  /* button presses */
8005                         FALSE ,            /* nonmaskable events? */
8006                         SUMA_optmenu_EV ,  /* handler */
8007                         (XtPointer) ado ,   /* client data */
8008                         XtListTail ) ;
8009          if (LocalHead)
8010             SUMA_ShowMeTheChildren(SurfCont->SwitchIntMenu->mw[0]);
8011          XtManageChild (SurfCont->SwitchIntMenu->mw[0]);
8012          /* Now destroy the SwitchInt_Menu */
8013          SwitchInt_Menu = SUMA_FreeMenuVector(SwitchInt_Menu, N_items);
8014          /* setup the history to the proper widget */
8015          SUMA_Set_Menu_Widget(SurfCont->SwitchIntMenu,
8016                        curColPlane->OptScl->find+1) ;
8017       } else {
8018          SUMA_SL_Err("NULL SwitchInt_Menu");
8019       }
8020 
8021       SwitchThr_Menu =
8022          SUMA_FormSwitchColMenuVector(ado, 1, &N_items);
8023       if (SwitchThr_Menu || !N_items) {
8024          SurfCont->SwitchThrMenu =
8025                SUMA_Free_Menu_Widget(SurfCont->SwitchThrMenu);
8026          SurfCont->SwitchThrMenu =
8027                SUMA_Alloc_Menu_Widget(N_items+1);
8028          SUMA_BuildMenuReset(13);
8029          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
8030                            "T", '\0', YUP, SwitchThr_Menu,
8031                            (void *)ado,
8032                            "GraphCont->GDset_Mapping->T",
8033                "Select Threshold (T) column, aka sub-brick. (BHelp for more)",
8034                            SUMA_SurfContHelp_SelThr ,
8035                            SurfCont->SwitchThrMenu );
8036          XtInsertEventHandler( SurfCont->SwitchThrMenu->mw[0] ,
8037                                        /* handle events in optmenu */
8038                         ButtonPressMask ,  /* button presses */
8039                         FALSE ,            /* nonmaskable events? */
8040                         SUMA_optmenu_EV ,  /* handler */
8041                         (XtPointer) ado ,   /* client data */
8042                         XtListTail ) ;
8043          XtManageChild (SurfCont->SwitchThrMenu->mw[0]);
8044          /* Now destroy the SwitchThr_Menu */
8045          SwitchThr_Menu = SUMA_FreeMenuVector(SwitchThr_Menu, N_items);
8046          /* setup the history to the proper widget */
8047          SUMA_Set_Menu_Widget(SurfCont->SwitchThrMenu,
8048                        curColPlane->OptScl->tind+1);
8049       } else {
8050          SUMA_SL_Err("NULL SwitchThr_Menu");
8051       }
8052 
8053       SwitchBrt_Menu =
8054          SUMA_FormSwitchColMenuVector(ado, 2, &N_items);
8055       if (SwitchBrt_Menu || !N_items) {
8056          SurfCont->SwitchBrtMenu =
8057                SUMA_Free_Menu_Widget(SurfCont->SwitchBrtMenu);
8058          SurfCont->SwitchBrtMenu =
8059                SUMA_Alloc_Menu_Widget(N_items+1);
8060          SUMA_BuildMenuReset(13);
8061          SUMA_BuildMenu (SurfCont->rcsw_v1, XmMENU_OPTION, /* populate it */
8062                            "B", '\0', YUP, SwitchBrt_Menu,
8063                            (void *)ado,
8064                            "GraphCont->GDset_Mapping->B",
8065                "Select Brightness (B) column, aka sub-brick. (BHelp for more)",
8066                            SUMA_SurfContHelp_SelBrt,
8067                            SurfCont->SwitchBrtMenu );
8068          XtInsertEventHandler( SurfCont->SwitchBrtMenu->mw[0] ,
8069                                                 /* handle events in optmenu */
8070                         ButtonPressMask ,  /* button presses */
8071                         FALSE ,            /* nonmaskable events? */
8072                         SUMA_optmenu_EV ,  /* handler */
8073                         (XtPointer) ado ,   /* client data */
8074                         XtListTail ) ;
8075 
8076          XtManageChild (SurfCont->SwitchBrtMenu->mw[0]);
8077          /* Now destroy the SwitchBrt_Menu */
8078          SwitchBrt_Menu = SUMA_FreeMenuVector(SwitchBrt_Menu, N_items);
8079          /* setup the history to the proper widget */
8080          SUMA_Set_Menu_Widget(SurfCont->SwitchBrtMenu,
8081                        curColPlane->OptScl->bind+1);
8082       } else {
8083          SUMA_SL_Err("NULL SwitchBrt_Menu");
8084       }
8085 
8086      if (1) {
8087      /* put the toggle buttons */
8088          if (!SurfCont->Int_tb) {
8089             SurfCont->Int_tb = XtVaCreateManagedWidget("v",
8090                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
8091             XtAddCallback (SurfCont->Int_tb,
8092                   XmNvalueChangedCallback, SUMA_cb_SwitchInt_toggled, ado);
8093             SUMA_Register_Widget_Help(SurfCont->Int_tb, 1,
8094                               "GraphCont->GDset_Mapping->I->v",
8095                               "View (ON)/Hide graph edge colors",
8096                               SUMA_GraphContHelp_SelIntTgl);
8097             SUMA_SET_SELECT_COLOR(SurfCont->Int_tb);
8098          }
8099          XmToggleButtonSetState (SurfCont->Int_tb,
8100                     curColPlane->ShowMode > 0 ? 1:0 , NOPE);
8101 
8102          if (!SurfCont->Thr_tb) {
8103             SurfCont->Thr_tb = XtVaCreateManagedWidget("v",
8104                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
8105             XtAddCallback (SurfCont->Thr_tb,
8106                   XmNvalueChangedCallback, SUMA_cb_SwitchThr_toggled, ado);
8107             SUMA_SET_SELECT_COLOR(SurfCont->Thr_tb);
8108             SUMA_Register_Widget_Help(SurfCont->Thr_tb, 1,
8109                               "GraphCont->GDset_Mapping->T->v",
8110                               "Apply (ON)/Ignore thresholding",
8111                               SUMA_SurfContHelp_SelThrTgl);
8112          }
8113          if (curColPlane->OptScl->tind >=0) {
8114             XmToggleButtonSetState (SurfCont->Thr_tb,
8115                               curColPlane->OptScl->UseThr, NOPE);
8116          }else {
8117             XmToggleButtonSetState (SurfCont->Thr_tb, NOPE, NOPE);
8118          }
8119 
8120          if (!SurfCont->Brt_tb) {
8121             SurfCont->Brt_tb = XtVaCreateManagedWidget("v",
8122                xmToggleButtonWidgetClass, SurfCont->rcsw_v2, NULL);
8123             XtAddCallback (SurfCont->Brt_tb,
8124                      XmNvalueChangedCallback, SUMA_cb_SwitchBrt_toggled, ado);
8125             SUMA_SET_SELECT_COLOR(SurfCont->Brt_tb);
8126             SUMA_Register_Widget_Help(SurfCont->Brt_tb, 1,
8127                      "GraphCont->GDset_Mapping->B->v",
8128                      "View (ON)/Ignore brightness modulation",
8129                      SUMA_SurfContHelp_SelBrtTgl);
8130          }
8131          if (curColPlane->OptScl->bind >=0) {
8132             XmToggleButtonSetState (SurfCont->Brt_tb,
8133                      curColPlane->OptScl->UseBrt, NOPE);
8134          } else {
8135             XmToggleButtonSetState (SurfCont->Brt_tb, NOPE, NOPE);
8136          }
8137       }
8138       if (!XtIsManaged(SurfCont->rcsw_v1))
8139          XtManageChild (SurfCont->rcsw_v1);
8140       if (!XtIsManaged(SurfCont->rcsw_v2))
8141          XtManageChild (SurfCont->rcsw_v2);
8142       if (!XtIsManaged(SurfCont->rcsw)) XtManageChild (SurfCont->rcsw);
8143    } /* The intensity / threshold / Brightness block */
8144 
8145 
8146    {/*  The Color map range and selector block */
8147       char *col_tit[]=  {  " ", "Min", "Max", NULL};
8148       char *col_hint[]= {  "Clipping ranges",
8149                            "Minimum clip value",
8150                            "Maximum clip value" , NULL};
8151       char *col_help[]= {  SUMA_SurfContHelp_SetRngTbl_r0,
8152                            SUMA_SurfContHelp_SetRngTbl_c1,
8153                            SUMA_SurfContHelp_SetRngTbl_c2 , NULL};
8154       char *row_tit[]=  {  " ", "I", "B", " " , "C", NULL};
8155       char *row_hint[]= {
8156          "Clipping ranges ",
8157          "Intensity clipping range (append '%' for percentiles, see BHelp)",
8158          "Brightness modulation clipping range (much more with BHelp)",
8159          "Brightness modulation factor range (much more with BHelp)" ,
8160          "Coordinate bias range (much more with BHelp)", NULL};
8161       char *row_help[]= {  SUMA_SurfContHelp_SetRngTbl_r0,
8162                            SUMA_SurfContHelp_SetRngTbl_r1,
8163                            SUMA_SurfContHelp_SetRngTbl_r2,
8164                            SUMA_SurfContHelp_SetRngTbl_r3,
8165                            SUMA_SurfContHelp_SetRngTbl_r4, NULL};
8166       if (!SurfCont->rccm) {
8167          SurfCont->rccm = XtVaCreateWidget ("rowcolumn",
8168             xmRowColumnWidgetClass, SurfCont->rcvo,
8169             XmNpacking, XmPACK_TIGHT,
8170             XmNorientation , XmVERTICAL ,
8171             XmNmarginHeight, 0,
8172             XmNmarginWidth, 0,
8173             NULL);
8174          NewMap = YUP; /* the first time around */
8175       }
8176 
8177       if (NewMap) {/* new colormaps */
8178          SUMA_LH("NewMap set");
8179          SUMA_Register_Widget_Help(SurfCont->rccm, 0,
8180                         "GraphCont->GDset_Mapping->SetRangeTable",
8181                         "Edge colorization parameters",
8182                         "Set parameters for mapping edge data onto color scale");
8183          if (!SurfCont->SetRangeTable->cells) {
8184             int colw[3] = { 1, 8, 8 };
8185             SUMA_SRV_DATA *srvd=(SUMA_SRV_DATA *)calloc(1,sizeof(SUMA_SRV_DATA));
8186             srvd->ado = ado; srvd->colp = NULL;
8187             /* create the widgets for the range table */
8188             SUMA_LH("Creating table");
8189             SUMA_CreateTable( SurfCont->rccm,
8190                            5, 3,
8191                            "GraphCont->GDset_Mapping->SetRangeTable",
8192                            row_tit, col_tit,
8193                            row_hint, col_hint,
8194                            row_help, col_help,
8195                            colw, YUP, SUMA_float,
8196                            SUMA_cb_SetRangeValue, (void *)srvd,
8197                            SUMA_SetRangeTableTit_EV, NULL,
8198                            NULL, NULL,
8199                            SurfCont->SetRangeTable);
8200          }
8201          if (!SurfCont->CoordBiasMenu->mw[SW_CoordBias]) {
8202                Widget rc = NULL; /* one pass through this block ONLY */
8203                rc = XtVaCreateWidget ("rowcolumn",
8204                   xmRowColumnWidgetClass, SurfCont->rccm,
8205                   XmNpacking, XmPACK_TIGHT,
8206                   XmNorientation , XmHORIZONTAL ,
8207                   XmNmarginHeight, 0 ,
8208                   XmNmarginWidth , 0 ,
8209                   NULL);
8210 
8211                SUMA_LH("Forming map mode menu");
8212                SUMA_BuildMenuReset(0);
8213                SUMA_BuildMenu ( rc, XmMENU_OPTION,
8214                                "Col", '\0', YUP, CmapMode_Menu,
8215                                (void *)ado,
8216                                "GraphCont->GDset_Mapping->Col",
8217                                "Switch between color mapping modes.",
8218                                SUMA_SurfContHelp_Col,
8219                                SurfCont->CmapModeMenu);
8220                XtManageChild (SurfCont->CmapModeMenu->mw[SW_CmapMode]);
8221 
8222                #if 0
8223                SUMA_LH("Forming new bias menu");
8224                SUMA_BuildMenuReset(0);
8225                SUMA_BuildMenu ( rc, XmMENU_OPTION,
8226                                "Bias", '\0', YUP, CoordBias_Menu,
8227                                (void *)ado,
8228                                "GraphCont->GDset_Mapping->Bias",
8229                                "Coordinate bias direction",
8230                                SUMA_SurfContHelp_Bias,
8231                                SurfCont->CoordBiasMenu);
8232                XtManageChild (SurfCont->CoordBiasMenu->mw[SW_CoordBias]);
8233                #endif
8234 
8235                XtManageChild(rc);
8236          }
8237 
8238          if (!SurfCont->rccm_swcmap) {
8239             SUMA_LH("Creating rccm_swcmap");
8240             SurfCont->rccm_swcmap =  XtVaCreateWidget ("rowcolumn",
8241                xmRowColumnWidgetClass, SurfCont->rccm,
8242                XmNpacking, XmPACK_TIGHT,
8243                XmNorientation , XmHORIZONTAL ,
8244                XmNmarginHeight, 0 ,
8245                XmNmarginWidth , 0 ,
8246                NULL);
8247          }
8248 
8249          {
8250             SUMA_CreateUpdatableCmapMenu((SUMA_ALL_DO *)ado);
8251 
8252             #if 0
8253                /* Not any more, menu is now stuck in its own rc */
8254                /* the loader, needs to be recreated with colormap menu  */
8255                if (SurfCont->CmapLoad_pb) {
8256                   XtDestroyWidget(SurfCont->CmapLoad_pb);
8257                   SurfCont->CmapLoad_pb = NULL;
8258                }
8259             #endif
8260             if (!SurfCont->CmapLoad_pb) {
8261                SUMA_LH("Forming CmapLoad button");
8262                SurfCont->CmapLoad_pb = XtVaCreateManagedWidget ("New",
8263                                  xmPushButtonWidgetClass,
8264                                  SurfCont->rccm_swcmap,
8265                                  NULL);
8266                XtAddCallback (SurfCont->CmapLoad_pb, XmNactivateCallback,
8267                               SUMA_cb_Cmap_Load, (XtPointer) ado);
8268                SUMA_Register_Widget_Help(SurfCont->CmapLoad_pb , 1,
8269                               "GraphCont->GDset_Mapping->Cmp->New",
8270                               "Load new colormap",
8271                               SUMA_SurfContHelp_CmpNew);
8272             }
8273          } /* new colormaps */
8274          if (!XtIsManaged(SurfCont->rccm_swcmap))
8275                      XtManageChild (SurfCont->rccm_swcmap);
8276       }
8277 
8278       /* Set the CoordBias's menu history to reflect current setting */
8279       SUMA_LH("Updating Link Mode History");
8280       SUMA_Set_Menu_Widget( SurfCont->LinkModeMenu,
8281                      curColPlane->LinkMode);
8282 
8283       SUMA_LH("Working the lock stuff ...");
8284       /* You'll need to fix the table's locking widget colors */
8285       if ( SurfCont->IntRangeLocked ==
8286                curColPlane->OptScl->AutoIntRange) {
8287          SUMA_LH("   Do the Int");
8288          /* need to put things in sync */
8289          SurfCont->IntRangeLocked = !SurfCont->IntRangeLocked;
8290          MCW_invert_widget_sync(SurfCont->SetRangeTable->cells[1], 0);
8291       }
8292       if ( SurfCont->BrtRangeLocked ==
8293                curColPlane->OptScl->AutoBrtRange) {
8294          SUMA_LH("   Do the Brt");
8295          /* need to put things in sync */
8296          SurfCont->BrtRangeLocked = !SurfCont->BrtRangeLocked;
8297          MCW_invert_widget_sync(SurfCont->SetRangeTable->cells[2], 0);
8298       }
8299 
8300       /* Set the CoordBias's menu history to reflect current setting */
8301       SUMA_LH("Updating CoorBias chooser History");
8302       SUMA_Set_Menu_Widget( SurfCont->CoordBiasMenu,
8303                      curColPlane->OptScl->DoBias);
8304 
8305       /* Set the Col's menu history to reflect current setting */
8306       SUMA_LH("Updating Col chooser History");
8307       SUMA_Set_Menu_Widget( SurfCont->CmapModeMenu,
8308                      curColPlane->OptScl->interpmode);
8309 
8310       /* add the selectors for symmetric range and absolute threshold */
8311       if (!SurfCont->AbsThresh_tb) {
8312          Widget rc;
8313          rc = XtVaCreateWidget ("rowcolumn",
8314                xmRowColumnWidgetClass, SurfCont->rccm,
8315                XmNpacking, XmPACK_TIGHT,
8316                XmNorientation , XmHORIZONTAL ,
8317                XmNmarginHeight, 0 ,
8318                XmNmarginWidth , 0 ,
8319                NULL);
8320          /* create the absolute threshold toggle button */
8321          SurfCont->AbsThresh_tb = XtVaCreateManagedWidget("|T|",
8322                xmToggleButtonWidgetClass, rc,
8323                NULL);
8324          XtAddCallback (SurfCont->AbsThresh_tb,
8325                XmNvalueChangedCallback, SUMA_cb_AbsThresh_tb_toggled, ado);
8326          SUMA_Register_Widget_Help(SurfCont->AbsThresh_tb , 1,
8327                            "GraphCont->GDset_Mapping->abs_T",
8328                            "Absolute threshold ON/OFF",
8329                            SUMA_SurfContHelp_AbsThr );
8330 
8331          SUMA_SET_SELECT_COLOR(SurfCont->AbsThresh_tb);
8332 
8333          /* create the symmetric range toggle button */
8334          SurfCont->SymIrange_tb = XtVaCreateManagedWidget("sym I",
8335                xmToggleButtonWidgetClass, rc, NULL);
8336          XtAddCallback (SurfCont->SymIrange_tb,
8337                XmNvalueChangedCallback, SUMA_cb_SymIrange_tb_toggled, ado);
8338          SUMA_Register_Widget_Help(SurfCont->SymIrange_tb, 1,
8339                            "GraphCont->GDset_Mapping->sym_I",
8340                            "Intensity range symmetry about 0 ",
8341                            SUMA_SurfContHelp_Isym );
8342          SUMA_SET_SELECT_COLOR(SurfCont->SymIrange_tb);
8343 
8344          /* add a button for zero masking */
8345          SurfCont->ShowZero_tb = XtVaCreateManagedWidget("shw 0",
8346                xmToggleButtonWidgetClass, rc, NULL);
8347          XtAddCallback (SurfCont->ShowZero_tb,
8348                XmNvalueChangedCallback, SUMA_cb_ShowZero_tb_toggled, ado);
8349          SUMA_Register_Widget_Help(SurfCont->ShowZero_tb,  1,
8350                      "GraphCont->GDset_Mapping->shw_0",
8351                      "Color masking of nodes with intensity = 0 ",
8352                      SUMA_SurfContHelp_Shw0);
8353          SUMA_SET_SELECT_COLOR(SurfCont->ShowZero_tb);
8354          XtManageChild (rc);
8355       }
8356 
8357       if (curColPlane->OptScl->ThrMode == SUMA_ABS_LESS_THAN) {
8358          XmToggleButtonSetState( SurfCont->AbsThresh_tb, True, NOPE);
8359       } else if (curColPlane->OptScl->ThrMode == SUMA_LESS_THAN) {
8360          XmToggleButtonSetState( SurfCont->AbsThresh_tb, False, NOPE);
8361       } else {
8362          SUMA_S_Err("Not ready to handle ThrModeR of %d yet",
8363                      curColPlane->OptScl->ThrMode);
8364       }
8365       if (!curColPlane->SymIrange) {
8366          XmToggleButtonSetState( SurfCont->SymIrange_tb, False, NOPE);
8367       } else {
8368          XmToggleButtonSetState( SurfCont->SymIrange_tb, True, NOPE);
8369       }
8370       if (!curColPlane->OptScl->MaskZero) {
8371          XmToggleButtonSetState( SurfCont->ShowZero_tb, True, NOPE);
8372       } else {
8373          XmToggleButtonSetState( SurfCont->ShowZero_tb, False, NOPE);
8374       }
8375 
8376       if (!XtIsManaged(SurfCont->rccm)) XtManageChild (SurfCont->rccm);
8377 
8378    }/*  The Color map range and selector block */
8379 
8380    if (1){ /* The Range values block*/
8381       char *col_tit[]=  {  " ", "Min", "Edge", "Max", "Edge", NULL};
8382       char *col_hint[]= {  "Full range of values in Dset",
8383                            "Minimum value in Dset column",
8384                            "Edge index at minimum",
8385                            "Maximum value in Dset column",
8386                            "Edge index at maximum", NULL};
8387       char *col_help[]= {  SUMA_SurfContHelp_RangeTbl_c0,
8388                            SUMA_SurfContHelp_RangeTbl_c1,
8389                            SUMA_GraphContHelp_RangeTbl_c2,
8390                            SUMA_SurfContHelp_RangeTbl_c3,
8391                            SUMA_GraphContHelp_RangeTbl_c4, NULL};
8392       char *row_tit[]=  {  " ", "I", "T", "B", NULL};
8393       char *row_hint[]= {  "Full range of values in Dset",
8394                            "Range of values in intensity (I) column",
8395                            "Range of values in threshold (T) column",
8396                            "Range of values in brightness (B) column", NULL};
8397       char *row_help[]= {  SUMA_SurfContHelp_RangeTbl_c0,
8398                            SUMA_SurfContHelp_RangeTbl_r1,
8399                            SUMA_SurfContHelp_RangeTbl_r2,
8400                            SUMA_SurfContHelp_RangeTbl_r3, NULL};
8401       if (!SurfCont->rcswr) {
8402          SurfCont->rcswr = XtVaCreateWidget ("rowcolumn",
8403             xmRowColumnWidgetClass, SurfCont->opts_form,
8404             XmNpacking, XmPACK_TIGHT,
8405             XmNorientation , XmVERTICAL ,
8406             XmNrightAttachment, XmATTACH_FORM ,
8407             XmNleftAttachment,  XmATTACH_NONE,
8408             XmNtopAttachment, XmATTACH_WIDGET ,
8409             XmNtopWidget, SurfCont->opts_rc,
8410             NULL);
8411       }
8412 
8413       if (!SurfCont->RangeTable->cells) {
8414          int colw[5] = { 1, 6, 6, 6, 6 };
8415          /* create the widgets for the range table */
8416          SUMA_CreateTable( SurfCont->rcswr,
8417                            4, 5,
8418                            "GraphCont->GDset_Mapping->RangeTable",
8419                            row_tit, col_tit,
8420                            row_hint, col_hint,
8421                            row_help, col_help,
8422                            colw, NOPE, SUMA_string,
8423                            NULL, NULL,
8424                            NULL, NULL,
8425                            SUMA_RangeTableCell_EV, (void *)ado,
8426                            SurfCont->RangeTable);
8427       }
8428 
8429       if (!XtIsManaged(SurfCont->rcswr)) XtManageChild (SurfCont->rcswr);
8430    } /* The Range values block */
8431 
8432    if (NewDset) {
8433       /* initialize tables of range values */
8434       SUMA_InitRangeTable(ado, 2);
8435    }
8436 
8437    if (!XtIsManaged(SurfCont->rcvo)) XtManageChild (SurfCont->rcvo);
8438    SUMA_FORCE_SCALE_HEIGHT(SUMA_ADO_Cont(ado));
8439 
8440    SUMA_RETURNe;
8441 }
8442 
8443 /*!
8444    A function to create the cmap selection menu
8445    in a manner that can be recreated if the menu
8446    contents change. You can call this function
8447    repeatedly whenever menu contents change
8448 */
SUMA_CreateUpdatableCmapMenu(SUMA_ALL_DO * ado)8449 void SUMA_CreateUpdatableCmapMenu(SUMA_ALL_DO *ado)
8450 {
8451    static char FuncName[]={"SUMA_CreateUpdatableCmapMenu"};
8452    SUMA_MenuItem *SwitchCmap_Menu = NULL;
8453    SUMA_X_SurfCont *SurfCont=NULL;
8454    char *wname;
8455    SUMA_Boolean LocalHead = NOPE;
8456 
8457    SUMA_ENTRY;
8458 
8459    if (!SUMAg_CF->scm) {
8460       SUMAg_CF->scm = SUMA_Build_Color_maps();
8461       if (!SUMAg_CF->scm) {
8462          SUMA_SL_Err("Failed to build color maps.\n");
8463          SUMA_RETURNe;
8464       }
8465    }
8466 
8467    SurfCont = SUMA_ADO_Cont(ado);
8468    if (!SurfCont->rc_CmapCont) { /* first pass, create placement container */
8469       SurfCont->rc_CmapCont = XtVaCreateWidget ("rowcolumn",
8470       xmRowColumnWidgetClass, SurfCont->rccm_swcmap,
8471       XmNpacking, XmPACK_TIGHT,
8472       XmNorientation , XmHORIZONTAL ,
8473       XmNmarginHeight, 0 ,
8474       XmNmarginWidth , 0 ,
8475       NULL);
8476    }
8477 
8478    SUMA_LH("Forming CmapMenu");
8479    SwitchCmap_Menu = SUMA_FormSwitchCmapMenuVector(SUMAg_CF->scm->CMv,
8480                                                    SUMAg_CF->scm->N_maps);
8481    switch(ado->do_type) {
8482       case SO_type:
8483          wname = "SurfCont->Dset_Mapping->Cmp";
8484          break;
8485       case VO_type:
8486          wname = "VolCont->Dset_Mapping->Cmp";
8487          break;
8488       case GRAPH_LINK_type:
8489          wname = "GraphCont->GDset_Mapping->Cmp";
8490          break;
8491       default:
8492          wname = "WhatIsThisFor->Cmp";
8493          break;
8494    }
8495 
8496    if (SwitchCmap_Menu) {
8497       SurfCont->SwitchCmapMenu =
8498          SUMA_Free_Menu_Widget(SurfCont->SwitchCmapMenu);
8499       SurfCont->SwitchCmapMenu =
8500                SUMA_Alloc_Menu_Widget(SUMAg_CF->scm->N_maps+1);
8501       SUMA_BuildMenuReset(10);
8502       SUMA_BuildMenu (  SurfCont->rc_CmapCont,
8503                            XmMENU_OPTION, /* populate it */
8504                            "Cmp", '\0', YUP, SwitchCmap_Menu,
8505                            (void *)ado,
8506                            wname,
8507                            "Switch between available color maps."
8508                            " (BHelp for more)",
8509                            SUMA_SurfContHelp_Cmp,
8510                            SurfCont->SwitchCmapMenu );
8511       XtInsertEventHandler( SurfCont->SwitchCmapMenu->mw[0] ,
8512                                                /* handle events in optmenu */
8513                             ButtonPressMask ,  /* button presses */
8514                             FALSE ,            /* nonmaskable events? */
8515                             SUMA_optmenu_EV ,  /* handler */
8516                             (XtPointer)ado ,   /* client data */
8517                             XtListTail ) ;
8518       XtManageChild (SurfCont->SwitchCmapMenu->mw[0]);
8519       /* Now destroy the SwitchCmap_Menu */
8520       SwitchCmap_Menu = SUMA_FreeMenuVector(SwitchCmap_Menu,
8521                                           SUMAg_CF->scm->N_maps);
8522    }
8523 
8524    XtManageChild(SurfCont->rc_CmapCont);
8525 
8526    SUMA_RETURNe;
8527 }
8528 
SUMA_InitClustTable(SUMA_ALL_DO * ado)8529 SUMA_Boolean SUMA_InitClustTable(SUMA_ALL_DO *ado)
8530 {
8531    static char FuncName[]={"SUMA_InitClustTable"};
8532    SUMA_TABLE_FIELD *TFs;
8533    SUMA_Boolean ColorizeBaby;
8534    SUMA_X_SurfCont *SurfCont=NULL;
8535    SUMA_OVERLAYS *curColPlane=NULL;
8536    SUMA_SCALE_TO_MAP_OPT *OptScl;
8537    SUMA_Boolean LocalHead = NOPE;
8538 
8539    SUMA_ENTRY;
8540 
8541    SurfCont = SUMA_ADO_Cont(ado);
8542    curColPlane = SUMA_ADO_CurColPlane(ado);
8543 
8544    if (!SurfCont) SUMA_RETURN(NOPE);
8545    if (ado->do_type == VO_type) {
8546       /* At the moment GUI is for interactive clustering is turned off, but
8547       to be safe, return without complaints */
8548       SUMA_LH("Nothing to do here until you implement clustering for volumes");
8549       SUMA_RETURN(YUP);
8550    }
8551    TFs = SurfCont->SetClustTable;
8552    if (!TFs) SUMA_RETURN(NOPE);
8553    OptScl = curColPlane->OptScl;
8554 
8555    ColorizeBaby = NOPE; /* Not sure if I'll need this one here */
8556 
8557    SUMA_INSERT_CELL_VALUE(TFs, 1, 1, OptScl->ClustOpt->DistLim);
8558    SUMA_INSERT_CELL_VALUE(TFs, 1, 2, OptScl->ClustOpt->AreaLim);
8559    SUMA_SetTableTitleButton1(TFs, 1,0, OptScl->Clusterize);
8560 
8561    if (ColorizeBaby) {
8562       if (!SUMA_ColorizePlane (curColPlane)) {
8563          SUMA_SLP_Err("Failed to colorize plane.\n");
8564          SUMA_RETURN(NOPE);
8565       }
8566    }
8567 
8568    SUMA_RETURN(YUP);
8569 }
8570 /*!
8571    \brief updates table with data value range
8572             and the table where user sets mapping
8573             range (that last one depends on what)
8574    SO: You know what
8575    what: (int)   -1: Do NOTHING with user accessible mapping ranges
8576                   0: intensity only
8577                   1: brightness modulation only
8578                   2: Set all user accessible mapping ranges
8579 */
SUMA_InitRangeTable(SUMA_ALL_DO * ado,int what)8580 SUMA_Boolean SUMA_InitRangeTable(SUMA_ALL_DO *ado, int what)
8581 {
8582    static char FuncName[]={"SUMA_InitRangeTable"};
8583    char srange_min[50], srange_max[50], srange_minloc[50], srange_maxloc[50];
8584    SUMA_TABLE_FIELD *TF, *TFs;
8585    int i, j, i1D, fi, bi, ti;
8586    double range[2];
8587    NI_element *nel;
8588    SUMA_SCALE_TO_MAP_OPT *OptScl;
8589    SUMA_Boolean DoIs = NOPE, DoBs = NOPE, ColorizeBaby;
8590    SUMA_X_SurfCont *SurfCont=NULL;
8591    SUMA_OVERLAYS *curColPlane=NULL;
8592    SUMA_Boolean LocalHead = NOPE;
8593 
8594    SUMA_ENTRY;
8595 
8596    if (LocalHead) {
8597       SUMA_DUMP_TRACE("Who just called SUMA_InitRangeTable?");
8598    }
8599    if (!ado) {
8600       SUMA_SL_Err("NULL ado");
8601       SUMA_RETURN(NOPE);
8602    }
8603    SurfCont = SUMA_ADO_Cont(ado);
8604    curColPlane = SUMA_ADO_CurColPlane(ado);
8605 
8606    if (!SurfCont || !curColPlane) SUMA_RETURN(NOPE);
8607    TF = SurfCont->RangeTable;
8608    TFs = SurfCont->SetRangeTable;
8609    if (!TF || !TFs || !TF->cells || !TFs->cells) SUMA_RETURN(NOPE);
8610    OptScl = curColPlane->OptScl;
8611    fi = OptScl->find;
8612    ti = OptScl->tind;
8613    bi = OptScl->bind;
8614    ColorizeBaby = NOPE;
8615 
8616    switch (what) {
8617       case -1:
8618          DoIs = NOPE;
8619          DoBs = NOPE;
8620          break;
8621       case 2:
8622          DoIs = YUP;
8623          DoBs = YUP;
8624          break;
8625       case 0:
8626          DoIs = YUP;
8627          break;
8628       case 1:
8629          DoBs = YUP;
8630          break;
8631       default:
8632          SUMA_SL_Err("That's stupid Joe!");
8633          SUMA_RETURN(NOPE);
8634          break;
8635    }
8636 
8637    /* TF Range table Int*/
8638    SUMA_LHv("Setting Int. fi=%d\n", fi);
8639    SUMA_RANGE_STRING(curColPlane->dset_link,
8640                      fi, srange_min, srange_max,
8641                      srange_minloc, srange_maxloc, range);
8642    SUMA_INSERT_CELL_STRING(TF, 1, 1, srange_min);/* min */
8643    SUMA_INSERT_CELL_STRING(TF, 1, 2, srange_minloc);/* minloc */
8644    SUMA_INSERT_CELL_STRING(TF, 1, 3, srange_max);/* max */
8645    SUMA_INSERT_CELL_STRING(TF, 1, 4, srange_maxloc);/* maxloc */
8646 
8647    /* TFs Range table Int*/
8648    if (DoIs) {
8649       if (curColPlane->OptScl->AutoIntRange) {
8650          if (!curColPlane->ForceIntRange[0] &&
8651              !curColPlane->ForceIntRange[1]) {
8652             if (  OptScl->IntRange[0] != range[0] ||
8653                   OptScl->IntRange[1] != range[1] ) {
8654                ColorizeBaby = YUP;
8655                OptScl->IntRange[0] = range[0]; OptScl->IntRange[1] = range[1];
8656             }
8657          } else {
8658             SUMA_LH("Using ForceIntRange");
8659             if (  OptScl->IntRange[0] !=
8660                      curColPlane->ForceIntRange[0] ||
8661                   OptScl->IntRange[1] !=
8662                      curColPlane->ForceIntRange[1] ) {
8663                ColorizeBaby = YUP;
8664                OptScl->IntRange[0] = curColPlane->ForceIntRange[0];
8665                OptScl->IntRange[1] = curColPlane->ForceIntRange[1];
8666             }
8667          }
8668 
8669          /* enforce the SymIrange option */
8670          if (curColPlane->SymIrange) {
8671             if (  OptScl->IntRange[1] !=
8672                      SUMA_LARG_ABS(OptScl->IntRange[0], OptScl->IntRange[1]) ||
8673                   OptScl->IntRange[0] != -OptScl->IntRange[1]) {
8674                ColorizeBaby = YUP;
8675                OptScl->IntRange[1] =
8676                      SUMA_LARG_ABS(OptScl->IntRange[0], OptScl->IntRange[1]);
8677                OptScl->IntRange[0] = -OptScl->IntRange[1];
8678             }
8679          }
8680 
8681          SUMA_INSERT_CELL_VALUE(TFs, 1, 1, OptScl->IntRange[0]);/* min */
8682          SUMA_INSERT_CELL_VALUE(TFs, 1, 2, OptScl->IntRange[1]);/* max */
8683          if (curColPlane->OptScl->AutoIntRange < 0) {
8684             /* snap out of the initialization and go to user's default */
8685             curColPlane->OptScl->AutoIntRange =
8686                      SUMA_isEnv("SUMA_Auto_I_Range","YES") ? 1:0;
8687             SUMA_LHv("AutoIntRange now %d\n",
8688                      curColPlane->OptScl->AutoIntRange);
8689          }
8690       }else {
8691          /* Make sure viewer is showing same values as in OptScl */
8692          /* enforce the SymIrange option */
8693          if (curColPlane->SymIrange) {
8694             if (  OptScl->IntRange[1] !=
8695                      SUMA_LARG_ABS(OptScl->IntRange[0], OptScl->IntRange[1]) ||
8696                   OptScl->IntRange[0] != -OptScl->IntRange[1]) {
8697                ColorizeBaby = YUP;
8698                OptScl->IntRange[1] =
8699                      SUMA_LARG_ABS(OptScl->IntRange[0], OptScl->IntRange[1]);
8700                OptScl->IntRange[0] = -OptScl->IntRange[1];
8701             }
8702          }
8703          SUMA_LH("Imposing...");
8704          if (  OptScl->IntRange[0] != TFs->num_value[1*TFs->Ni+1] ||
8705                OptScl->IntRange[1] != TFs->num_value[2*TFs->Ni+1] ) {
8706             SUMA_INSERT_CELL_VALUE(TFs, 1, 1, OptScl->IntRange[0]);/* min */
8707             SUMA_INSERT_CELL_VALUE(TFs, 1, 2, OptScl->IntRange[1]);/* max */
8708          }
8709       }
8710    }
8711    /* TF Range table Thr*/
8712    SUMA_LH("Setting Thr.");
8713    SUMA_RANGE_STRING(curColPlane->dset_link, ti,
8714                      srange_min, srange_max,
8715                      srange_minloc, srange_maxloc, range);
8716    SUMA_INSERT_CELL_STRING(TF, 2, 1, srange_min);/* min */
8717    SUMA_INSERT_CELL_STRING(TF, 2, 2, srange_minloc);/* minloc */
8718    SUMA_INSERT_CELL_STRING(TF, 2, 3, srange_max);/* max */
8719    SUMA_INSERT_CELL_STRING(TF, 2, 4, srange_maxloc);/* maxloc */
8720 
8721    /* TF Range table Brt*/
8722    SUMA_LH("Setting Brt.");
8723    SUMA_RANGE_STRING(curColPlane->dset_link, bi,
8724                      srange_min, srange_max,
8725                      srange_minloc, srange_maxloc, range);
8726    SUMA_INSERT_CELL_STRING(TF, 3, 1, srange_min);/* min */
8727    SUMA_INSERT_CELL_STRING(TF, 3, 2, srange_minloc);/* minloc */
8728    SUMA_INSERT_CELL_STRING(TF, 3, 3, srange_max);/* max */
8729    SUMA_INSERT_CELL_STRING(TF, 3, 4, srange_maxloc);/* maxloc */
8730    /* TFs Range table Brt*/
8731    if (DoBs) {
8732       if (curColPlane->OptScl->AutoBrtRange) {
8733          if (  OptScl->BrightRange[0] != range[0] ||
8734                OptScl->BrightRange[1] != range[1] ) {
8735             ColorizeBaby = YUP;
8736             OptScl->BrightRange[0] = range[0]; OptScl->BrightRange[1] = range[1];
8737          }
8738          SUMA_INSERT_CELL_VALUE(TFs, 2, 1, OptScl->BrightRange[0]);/* min */
8739          SUMA_INSERT_CELL_VALUE(TFs, 2, 2, OptScl->BrightRange[1]);/* max */
8740          /* TFs Range table BrtMap*/
8741          SUMA_INSERT_CELL_VALUE(TFs, 3, 1, OptScl->BrightMap[0]);/* min */
8742          SUMA_INSERT_CELL_VALUE(TFs, 3, 2, OptScl->BrightMap[1]);/* max */
8743          if (curColPlane->OptScl->AutoBrtRange < 0) {
8744             /* snap out of the initialization and go to user's default */
8745             curColPlane->OptScl->AutoBrtRange =
8746                      SUMA_isEnv("SUMA_Auto_B_Range","YES") ? 1:0;
8747             SUMA_LHv("AutoBrtRange now %d\n",
8748                      curColPlane->OptScl->AutoBrtRange);
8749          }
8750       } else {
8751          /* Make sure viewer is showing same values as in OptScl */
8752          if (  OptScl->BrightRange[0] != TFs->num_value[1*TFs->Ni+2] ||
8753                OptScl->BrightRange[1] != TFs->num_value[2*TFs->Ni+2] ||
8754                OptScl->BrightMap[0]   != TFs->num_value[1*TFs->Ni+3] ||
8755                OptScl->BrightMap[1]   != TFs->num_value[2*TFs->Ni+3]   ) {
8756             SUMA_INSERT_CELL_VALUE(TFs, 2, 1, OptScl->BrightRange[0]);/* min */
8757             SUMA_INSERT_CELL_VALUE(TFs, 2, 2, OptScl->BrightRange[1]);/* max */
8758             /* TFs Range table BrtMap*/
8759             SUMA_INSERT_CELL_VALUE(TFs, 3, 1, OptScl->BrightMap[0]);/* min */
8760             SUMA_INSERT_CELL_VALUE(TFs, 3, 2, OptScl->BrightMap[1]);/* max */
8761          }
8762       }
8763    }
8764 
8765    /* TFs Range table CoordBias*/
8766    SUMA_INSERT_CELL_VALUE(TFs, 4, 1, OptScl->CoordBiasRange[0]);/* min */
8767    SUMA_INSERT_CELL_VALUE(TFs, 4, 2, OptScl->CoordBiasRange[1]);/* max */
8768 
8769    if (ColorizeBaby) {
8770       if (!SUMA_ColorizePlane (curColPlane)) {
8771          SUMA_SLP_Err("Failed to colorize plane.\n");
8772          SUMA_RETURN(NOPE);
8773       }
8774    }
8775    SUMA_RETURN(YUP);
8776 }
8777 
SUMA_AssembleCmapList(SUMA_COLOR_MAP ** CMv,int N_maps)8778 SUMA_ASSEMBLE_LIST_STRUCT * SUMA_AssembleCmapList(SUMA_COLOR_MAP **CMv,
8779                                                   int N_maps)
8780 {
8781    static char FuncName[]={"SUMA_AssembleCmapList"};
8782    SUMA_ASSEMBLE_LIST_STRUCT *clist_str = NULL;
8783    int i;
8784    SUMA_Boolean LocalHead = NOPE;
8785 
8786    SUMA_ENTRY;
8787 
8788    clist_str = SUMA_CreateAssembleListStruct();
8789    clist_str->clist = (char **)SUMA_calloc(N_maps, sizeof(char *));
8790    clist_str->oplist = (void **)SUMA_calloc(N_maps, sizeof(void *));
8791    clist_str->N_clist = N_maps;
8792 
8793    for (i=0; i<N_maps; ++i) {
8794       clist_str->clist[i] = SUMA_copy_string(CMv[i]->Name);
8795       clist_str->oplist[i] = (void*)CMv[i];
8796    }
8797 
8798    SUMA_RETURN(clist_str);
8799 }
8800 
SUMA_AssembleDsetColList(SUMA_DSET * dset)8801 SUMA_ASSEMBLE_LIST_STRUCT * SUMA_AssembleDsetColList(SUMA_DSET *dset)
8802 {
8803    static char FuncName[]={"SUMA_AssembleDsetColList"};
8804    SUMA_ASSEMBLE_LIST_STRUCT *clist_str = NULL;
8805    int i;
8806    SUMA_Boolean LocalHead = NOPE;
8807 
8808    SUMA_ENTRY;
8809 
8810    if (SDSET_VECNUM(dset) < 1) SUMA_RETURN(clist_str);
8811 
8812    clist_str = SUMA_CreateAssembleListStruct();
8813    clist_str->clist = (char **)SUMA_calloc(SDSET_VECNUM(dset), sizeof(char *));
8814    clist_str->oplist = (void **)SUMA_calloc(SDSET_VECNUM(dset), sizeof(void *));
8815    clist_str->N_clist = SDSET_VECNUM(dset);
8816    clist_str->content_id = SUMA_copy_string(SDSET_ID(dset));
8817 
8818    for (i=0; i<SDSET_VECNUM(dset); ++i) {
8819       clist_str->clist[SDSET_VECNUM(dset)-1-i] =
8820                   SUMA_DsetColLabelCopy(dset,i, 1);
8821       clist_str->oplist[SDSET_VECNUM(dset)-1-i] = (XTP_CAST)i;
8822    }
8823 
8824    SUMA_RETURN(clist_str);
8825 }
8826 
8827 /*!
8828    \brief opens a list selection for choosing a Dset column
8829 */
SUMA_DsetColSelectList(SUMA_ALL_DO * ado,int type,int refresh,int bringup)8830 SUMA_Boolean SUMA_DsetColSelectList(
8831          SUMA_ALL_DO *ado, int type,
8832          int refresh, int bringup)
8833 {
8834    static char FuncName[]={"SUMA_DsetColSelectList"};
8835    SUMA_LIST_WIDGET *LW = NULL;
8836    SUMA_X_SurfCont *SurfCont=NULL;
8837    SUMA_OVERLAYS *curColPlane=NULL;
8838    SUMA_Boolean LocalHead = NOPE;
8839 
8840    SUMA_ENTRY;
8841 
8842    SUMA_LH("Called");
8843 
8844    SurfCont = SUMA_ADO_Cont(ado);
8845    curColPlane = SUMA_ADO_CurColPlane(ado);
8846    if (!ado || !SurfCont) SUMA_RETURN(NOPE);
8847 
8848    /* Widget is common to a surface controller. */
8849    switch (type) {
8850       case 0:
8851          LW = SurfCont->SwitchIntMenu->lw;
8852          if (!LW) {
8853             SUMA_LH("Allocating widget");
8854             /* need to create widget */
8855             LW = SUMA_AllocateScrolledList   (
8856                   "Switch Intensity", SUMA_LSP_BROWSE,
8857                   NOPE,          NOPE,
8858                   SurfCont->TLS, SWP_POINTER_OFF,
8859                   150,
8860                   SUMA_cb_SelectSwitchInt, (void *)ado,
8861                   SUMA_cb_SelectSwitchInt, (void *)ado,
8862                   SUMA_cb_CloseSwitchLst, NULL);
8863 
8864             SurfCont->SwitchIntMenu->lw = LW;
8865             refresh = 1; /* no doubt aboot it */
8866          } else {
8867             if (  (void *)ado != LW->Default_Data ||
8868                   (void *)ado != LW->Select_Data) {
8869                /* just update the callback data info in LW */
8870                SUMA_UpdateScrolledListData(LW, (void *)ado, (void *)ado, NULL);
8871             }
8872 
8873          }
8874          break;
8875       case 1:
8876          LW = SurfCont->SwitchThrMenu->lw;
8877          if (!LW) {
8878             SUMA_LH("Allocating widget");
8879             /* need to create widget */
8880             LW = SUMA_AllocateScrolledList   (
8881                   "Switch Threshold", SUMA_LSP_BROWSE,
8882                   NOPE,          NOPE,
8883                   SurfCont->TLS, SWP_POINTER_OFF,
8884                   150,
8885                   SUMA_cb_SelectSwitchThr, (void *)ado,
8886                   SUMA_cb_SelectSwitchThr, (void *)ado,
8887                   SUMA_cb_CloseSwitchLst, NULL);
8888 
8889             SurfCont->SwitchThrMenu->lw = LW;
8890             refresh = 1; /* no doubt aboot it */
8891          } else {
8892             if (  (void *)ado != LW->Default_Data ||
8893                   (void *)ado != LW->Select_Data) {
8894                /* just update the callback data info in LW */
8895                SUMA_UpdateScrolledListData(LW, (void *)ado, (void *)ado, NULL);
8896             }
8897 
8898          }
8899          break;
8900       case 2:
8901          LW = SurfCont->SwitchBrtMenu->lw;
8902          if (!LW) {
8903             SUMA_LH("Allocating widget");
8904             /* need to create widget */
8905             LW = SUMA_AllocateScrolledList   (
8906                   "Switch Brightness", SUMA_LSP_BROWSE,
8907                   NOPE,          NOPE,
8908                   SurfCont->TLS, SWP_POINTER_OFF,
8909                   150,
8910                   SUMA_cb_SelectSwitchBrt, (void *)ado,
8911                   SUMA_cb_SelectSwitchBrt, (void *)ado,
8912                   SUMA_cb_CloseSwitchLst, NULL);
8913 
8914             SurfCont->SwitchBrtMenu->lw = LW;
8915             refresh = 1; /* no doubt aboot it */
8916          } else {
8917             if (  (void *)ado != LW->Default_Data ||
8918                   (void *)ado != LW->Select_Data) {
8919                /* just update the callback data info in LW */
8920                SUMA_UpdateScrolledListData(LW, (void *)ado, (void *)ado, NULL);
8921             }
8922 
8923          }
8924          break;
8925       default:
8926          SUMA_SL_Err("Unexpected type");
8927          SUMA_RETURN(NOPE);
8928    }
8929 
8930    /* Refresh if LW exists, but request is for a new data set */
8931    if (!refresh &&
8932         strcmp(LW->ALS->content_id,
8933                SDSET_ID(curColPlane->dset_link))) {
8934       refresh=1;
8935    }
8936 
8937   if (refresh) {
8938       /* Now creating list*/
8939       if (LW->ALS) {
8940          if (LocalHead) SUMA_S_Err("Freeing the hag.");
8941          LW->ALS = SUMA_FreeAssembleListStruct(LW->ALS);
8942       }
8943       SUMA_LH("Assembling");
8944       LW->ALS = SUMA_AssembleDsetColList(curColPlane->dset_link);
8945       if (!LW->ALS) {
8946          SUMA_SL_Err("Failed to assemble list");
8947          SUMA_RETURN(NOPE);
8948       }
8949       if (LW->ALS->N_clist < 0) {
8950          SUMA_SL_Err("Failed in SUMA_AssembleDsetColList");
8951          SUMA_RETURN(NOPE);
8952       }
8953       if (!LW->ALS->N_clist) {
8954          SUMA_SLP_Note ("No Dset Cols to choose from.");
8955          SUMA_RETURN(NOPE);
8956       }
8957    }
8958 
8959    if (bringup)
8960       SUMA_CreateScrolledList ( LW->ALS->clist, LW->ALS->N_clist, NOPE, LW);
8961 
8962    SUMA_RETURN(YUP);
8963 }
8964 
8965 
SUMA_GetListIchoice(XmListCallbackStruct * cbs,SUMA_LIST_WIDGET * LW,SUMA_Boolean * CloseShop)8966 int SUMA_GetListIchoice(XmListCallbackStruct *cbs,
8967                         SUMA_LIST_WIDGET *LW,
8968                         SUMA_Boolean *CloseShop)
8969 {
8970    static char FuncName[]={"SUMA_GetListIchoice"};
8971    int ichoice;
8972    char *choice=NULL;
8973    SUMA_Boolean Found = NOPE;
8974    SUMA_Boolean LocalHead = NOPE;
8975 
8976    SUMA_ENTRY;
8977 
8978    *CloseShop = NOPE;
8979    ichoice = -1;
8980    if (!LW) {
8981       SUMA_S_Err("NULL LW!");
8982       SUMA_RETURN(ichoice);
8983    }
8984 
8985 
8986    if (  cbs->reason == XmCR_SINGLE_SELECT ||
8987          cbs->reason == XmCR_BROWSE_SELECT) {
8988       if (LocalHead)
8989          fprintf (SUMA_STDERR,
8990                   "%s: Single selection (reason %d, (%d, %d)),\n"
8991                   "list widget %s... \n",
8992                FuncName, cbs->reason,
8993                XmCR_SINGLE_SELECT, XmCR_BROWSE_SELECT , LW->Label);
8994    } else {
8995       if (LocalHead)
8996          fprintf (SUMA_STDERR,
8997                   "%s: Default selection (reason %d, (%d, %d)),\n"
8998                   "list widget %s... \n",
8999                   FuncName, cbs->reason,
9000                   XmCR_SINGLE_SELECT, XmCR_BROWSE_SELECT, LW->Label);
9001       /*double click or enter on that one, close shop after selection */
9002       *CloseShop = YUP;
9003    }
9004 
9005    XmStringGetLtoR (cbs->item, XmFONTLIST_DEFAULT_TAG, &choice);
9006 
9007    if (LocalHead)
9008       fprintf (SUMA_STDERR,
9009                "%s: Selected item: %s {%s} (%d)\n",
9010                FuncName, choice, choice, cbs->item_position);
9011    LW->lastitempos = cbs->item_position;   /* store for next opening */
9012    /* because of sorting, choice cannot be used
9013       as an index into clist and oplist in ALS */
9014    Found = NOPE;
9015    ichoice = 0;
9016    do {
9017       if (LocalHead)
9018          fprintf (SUMA_STDERR,"%s: Comparing:\t>%s<\t>%s<\n",
9019                   FuncName, LW->ALS->clist[ichoice], choice);
9020       if (strcmp(LW->ALS->clist[ichoice],
9021                   choice) == 0) Found = YUP;
9022       else ++ichoice;
9023    } while (ichoice < LW->ALS->N_clist && !Found);
9024 
9025    if (!Found) { /* do older search, with strncmp dunno why it
9026                      was like that
9027                      but I worry about backward compatibility */
9028       ichoice = 0;
9029       do {
9030          if (LocalHead)
9031             fprintf (SUMA_STDERR,"%s: Comparing:\t>%s<\t>%s<\n",
9032                      FuncName, LW->ALS->clist[ichoice], choice);
9033          if (strncmp(LW->ALS->clist[ichoice],
9034                      choice, strlen(choice)) == 0) Found = YUP;
9035          else ++ichoice;
9036       } while (ichoice < LW->ALS->N_clist && !Found);
9037    }
9038 
9039    if (!Found) {
9040       SUMA_SLP_Err("Choice not found.");
9041       SUMA_RETURN(-1);
9042    }
9043 
9044    XtFree (choice);
9045    SUMA_RETURN(ichoice);
9046 }
9047 /*!
9048    \brief function that handles switching intensity from the list widget
9049    \sa SUMA_cb_SwitchIntensity
9050 */
SUMA_cb_SelectSwitchInt(Widget w,XtPointer client_data,XtPointer call_data)9051 void SUMA_cb_SelectSwitchInt (
9052          Widget w, XtPointer client_data,
9053          XtPointer call_data)
9054 {
9055    static char FuncName[]={"SUMA_cb_SelectSwitchInt"};
9056    SUMA_ALL_DO *ado = NULL;
9057    SUMA_LIST_WIDGET *LW = NULL;
9058    XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
9059    int ichoice;
9060    SUMA_X_SurfCont *SurfCont=NULL;
9061    SUMA_Boolean CloseShop = NOPE;
9062    SUMA_Boolean LocalHead = NOPE;
9063 
9064    SUMA_ENTRY;
9065 
9066    SUMA_LH("Called");
9067    ado = (SUMA_ALL_DO *)client_data;
9068    SurfCont = SUMA_ADO_Cont(ado);
9069    LW = SurfCont->SwitchIntMenu->lw;
9070 
9071    if ((ichoice = SUMA_GetListIchoice(cbs, LW, &CloseShop))==-1) {
9072       SUMA_RETURNe;
9073    }
9074 
9075 
9076    if (!SUMA_SelectSwitchDsetCol(ado, LW, 0, ichoice)) {
9077       SUMA_S_Err("Failed to SelectSwitchDsetCol");
9078       SUMA_RETURNe;
9079    }
9080 
9081    if (CloseShop) {
9082       SUMA_cb_CloseSwitchLst( w,  (XtPointer)LW,  call_data);
9083    }
9084 
9085    /* update Lbl fields */
9086    SUMA_UpdateNodeLblField(ado);
9087 
9088    SUMA_RETURNe;
9089 }
9090 
SUMA_cb_SelectSwitchThr(Widget w,XtPointer client_data,XtPointer call_data)9091 void SUMA_cb_SelectSwitchThr (
9092          Widget w, XtPointer client_data,
9093          XtPointer call_data)
9094 {
9095    static char FuncName[]={"SUMA_cb_SelectSwitchThr"};
9096    SUMA_ALL_DO *ado = NULL;
9097    XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
9098    SUMA_Boolean CloseShop = NOPE;
9099    SUMA_LIST_WIDGET *LW = NULL;
9100    int ichoice;
9101    SUMA_X_SurfCont *SurfCont=NULL;
9102    SUMA_Boolean LocalHead = NOPE;
9103 
9104    SUMA_ENTRY;
9105 
9106    SUMA_LH("Called");
9107    ado = (SUMA_ALL_DO *)client_data;
9108    SurfCont = SUMA_ADO_Cont(ado);
9109    LW = SurfCont->SwitchThrMenu->lw;
9110 
9111    if ((ichoice = SUMA_GetListIchoice(cbs, LW, &CloseShop))==-1) {
9112       SUMA_RETURNe;
9113    }
9114 
9115    if (!SUMA_SelectSwitchDsetCol(ado, LW, 1, ichoice)) {
9116       SUMA_S_Err("Failed to SelectSwitchDsetCol");
9117       SUMA_RETURNe;
9118    }
9119 
9120    if (CloseShop) {
9121       SUMA_cb_CloseSwitchLst( w,  (XtPointer)LW,  call_data);
9122    }
9123 
9124    /* update Lbl fields */
9125    SUMA_UpdateNodeLblField(ado);
9126 
9127    SUMA_RETURNe;
9128 }
9129 
SUMA_cb_SelectSwitchBrt(Widget w,XtPointer client_data,XtPointer call_data)9130 void SUMA_cb_SelectSwitchBrt (
9131          Widget w, XtPointer client_data,
9132          XtPointer call_data)
9133 {
9134    static char FuncName[]={"SUMA_cb_SelectSwitchBrt"};
9135    SUMA_ALL_DO *ado = NULL;
9136    XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
9137    SUMA_Boolean CloseShop = NOPE;
9138    SUMA_LIST_WIDGET *LW = NULL;
9139    int ichoice;
9140    SUMA_X_SurfCont *SurfCont=NULL;
9141    SUMA_Boolean LocalHead = NOPE;
9142 
9143    SUMA_ENTRY;
9144 
9145    SUMA_LH("Called");
9146    ado = (SUMA_ALL_DO *)client_data;
9147    SurfCont = SUMA_ADO_Cont(ado);
9148    LW = SurfCont->SwitchBrtMenu->lw;
9149 
9150    if ((ichoice = SUMA_GetListIchoice(cbs, LW, &CloseShop))==-1) {
9151       SUMA_RETURNe;
9152    }
9153 
9154    if (!SUMA_SelectSwitchDsetCol(ado, LW, 2, ichoice)) {
9155       SUMA_S_Err("Failed to SelectSwitchDsetCol");
9156       SUMA_RETURNe;
9157    }
9158 
9159    if (CloseShop) {
9160       SUMA_cb_CloseSwitchLst( w,  (XtPointer)LW,  call_data);
9161    }
9162 
9163    /* update Lbl fields */
9164    SUMA_UpdateNodeLblField(ado);
9165 
9166    SUMA_RETURNe;
9167 }
9168 
9169 
SUMA_SelectSwitchDsetCol(SUMA_ALL_DO * ado,SUMA_LIST_WIDGET * LW,int block,int ichoice)9170 int SUMA_SelectSwitchDsetCol(
9171          SUMA_ALL_DO *ado,
9172          SUMA_LIST_WIDGET *LW,
9173          int block,
9174          int ichoice)
9175 {
9176    static char FuncName[]={"SUMA_SelectSwitchDsetCol"};
9177    SUMA_MenuCallBackData data;
9178    SUMA_X_SurfCont *SurfCont=NULL;
9179    SUMA_OVERLAYS *curColPlane=NULL;
9180    SUMA_Boolean LocalHead = NOPE;
9181 
9182    SUMA_ENTRY;
9183 
9184    SUMA_LH("Called");
9185    if (!ado || !LW || block < 0 || block > 2 || ichoice < 0) SUMA_RETURN(0);
9186    SurfCont = SUMA_ADO_Cont(ado);
9187    curColPlane = SUMA_ADO_CurColPlane(ado);
9188 
9189 
9190    /* now retrieve that choice from the
9191       SUMA_ASSEMBLE_LIST_STRUCT structure and initialize  */
9192    if (LW->ALS) {
9193       if (LocalHead)
9194          fprintf (SUMA_STDERR,
9195                   "%s: N_clist = %d\n",
9196                   FuncName, LW->ALS->N_clist);
9197       if (LW->ALS->N_clist > ichoice) {
9198          if (LocalHead)
9199             fprintf (SUMA_STDERR,
9200                      "%s: Retrieved Column indexed %d\n",
9201                      FuncName, (INT_CAST)LW->ALS->oplist[ichoice]);
9202 
9203          switch (block){
9204             case 0:
9205                if (!SUMA_SwitchColPlaneIntensity
9206                      (ado, curColPlane,
9207                       (INT_CAST)LW->ALS->oplist[ichoice], 1)) {
9208                   SUMA_SL_Err("Failed in SUMA_SwitchColPlaneIntensity");
9209                }
9210                break;
9211             case 1:
9212                if (!SUMA_SwitchColPlaneThreshold
9213                      (ado, curColPlane,
9214                       (INT_CAST)LW->ALS->oplist[ichoice], 1)) {
9215                   SUMA_SL_Err("Failed in SUMA_SwitchColPlaneThreshold");
9216                }
9217                break;
9218             case 2:
9219                if (!SUMA_SwitchColPlaneBrightness
9220                      (ado, curColPlane,
9221                       (INT_CAST)LW->ALS->oplist[ichoice], 1)) {
9222                   SUMA_SL_Err("Failed in SUMA_SwitchColPlaneBrightness");
9223                }
9224                break;
9225             default:
9226                SUMA_S_Err("Ah NON!");
9227                SUMA_RETURN(0);
9228                break;
9229          }
9230       }
9231    } else {
9232       if (LocalHead) fprintf (SUMA_STDERR,"%s: NULL ALS\n", FuncName);
9233    }
9234 
9235    SUMA_RETURN(1);
9236 }
9237 
9238 /*!
9239    \brief function that handles closing switch * list widget
9240    expects LW in client_data
9241 */
SUMA_cb_CloseSwitchLst(Widget w,XtPointer client_data,XtPointer call)9242 void SUMA_cb_CloseSwitchLst (Widget w, XtPointer client_data, XtPointer call)
9243 {
9244    static char FuncName[]={"SUMA_cb_CloseSwitchLst"};
9245    SUMA_LIST_WIDGET *LW = NULL;
9246    SUMA_Boolean LocalHead = NOPE;
9247 
9248    SUMA_ENTRY;
9249 
9250    SUMA_LH("Called");
9251 
9252    LW = (SUMA_LIST_WIDGET *)client_data;
9253 
9254    switch (SUMA_CLOSE_MODE)   {/* No open GL drawables in this widget*/
9255       case SUMA_WITHDRAW:
9256          if (LocalHead)
9257             fprintf (SUMA_STDERR,
9258                      "%s: Withdrawing list widget %s...\n",
9259                      FuncName, LW->Label);
9260 
9261          XWithdrawWindow(SUMAg_CF->X->DPY_controller1,
9262             XtWindow(LW->toplevel),
9263             XScreenNumberOfScreen(XtScreen(LW->toplevel)));
9264          break;
9265       case SUMA_DESTROY:
9266          if (LocalHead)
9267             fprintf (SUMA_STDERR,
9268                      "%s: Destroying list widget %s...\n",
9269                      FuncName, LW->Label);
9270          XtDestroyWidget(LW->toplevel);
9271          LW->toplevel = NULL;
9272          break;
9273       default:
9274          SUMA_S_Err("Not ready for this type of closing");
9275          SUMA_RETURNe;
9276          break;
9277    }
9278 
9279    LW->isShaded = YUP;
9280 
9281 
9282 
9283    SUMA_RETURNe;
9284 }
9285 
9286 
9287 /*!
9288    \brief opens a list selection for choosing a color map
9289 */
SUMA_CmapSelectList(SUMA_ALL_DO * ado,int refresh,int bringup)9290 SUMA_Boolean SUMA_CmapSelectList(SUMA_ALL_DO *ado, int refresh,
9291                                  int bringup)
9292 {
9293    static char FuncName[]={"SUMA_CmapSelectList"};
9294    SUMA_LIST_WIDGET *LW = NULL;
9295    SUMA_X_SurfCont *SurfCont=NULL;
9296    SUMA_Boolean LocalHead = NOPE;
9297 
9298    SUMA_ENTRY;
9299 
9300    if (!SUMAg_CF->scm) {
9301       SUMAg_CF->scm = SUMA_Build_Color_maps();
9302       if (!SUMAg_CF->scm) {
9303          SUMA_SL_Err("Failed to build color maps.\n");
9304          SUMA_RETURN(NOPE);
9305       }
9306    }
9307 
9308    /* Widget is common to all SUMA */
9309    LW = SUMAg_CF->X->SwitchCmapLst;
9310    SurfCont = SUMA_ADO_Cont(ado);
9311 
9312    if (!LW) {
9313       SUMA_LH("Allocating widget");
9314       /* need to create widget */
9315       LW = SUMA_AllocateScrolledList   (
9316             "Switch Cmap", SUMA_LSP_BROWSE,
9317             NOPE,          NOPE,
9318             SurfCont->TLS, SWP_POINTER_OFF,
9319             125,
9320             SUMA_cb_SelectSwitchCmap, (void *)ado,
9321             SUMA_cb_SelectSwitchCmap, (void *)ado,
9322             SUMA_cb_CloseSwitchCmap, NULL);
9323 
9324       SUMAg_CF->X->SwitchCmapLst = LW;
9325       refresh = 1; /* no doubt aboot it */
9326    } else {
9327       if ((void *)ado != LW->Default_Data || (void *)ado != LW->Select_Data) {
9328          /* just update the callback data info in LW */
9329          SUMA_UpdateScrolledListData(LW, (void *)ado, (void *)ado, NULL);
9330       }
9331    }
9332 
9333    if (refresh) {
9334       /* Now creating list*/
9335       if (LW->ALS) {
9336          if (LocalHead) SUMA_S_Err("Freeing the hag.");
9337          LW->ALS = SUMA_FreeAssembleListStruct(LW->ALS);
9338       }
9339       SUMA_LH("Assembling");
9340       LW->ALS = SUMA_AssembleCmapList(SUMAg_CF->scm->CMv, SUMAg_CF->scm->N_maps);
9341       if (!LW->ALS) {
9342          SUMA_SL_Err("Failed to assemble list");
9343          SUMA_RETURN(NOPE);
9344       }
9345       if (LW->ALS->N_clist < 0) {
9346          SUMA_SL_Err("Failed in SUMA_AssembleCmapList");
9347          SUMA_RETURN(NOPE);
9348       }
9349       if (!LW->ALS->N_clist) {
9350          SUMA_SLP_Note ("No cmaps to choose from.");
9351          SUMA_RETURN(NOPE);
9352       }
9353    }
9354 
9355    if (bringup)
9356       SUMA_CreateScrolledList ( LW->ALS->clist, LW->ALS->N_clist, NOPE, LW);
9357 
9358    SUMA_RETURN(YUP);
9359 }
9360 
SUMA_SetCmodeMenuChoice(SUMA_ALL_DO * ado,char * str)9361 SUMA_Boolean SUMA_SetCmodeMenuChoice(SUMA_ALL_DO *ado, char *str)
9362 {
9363    static char FuncName[]={"SUMA_SetCmodeMenuChoice"};
9364    int i, Nbutt = 0, nstr=0, nf=0;
9365    Widget whist = NULL, *w = NULL;
9366    SUMA_X_SurfCont *SurfCont=NULL;
9367    SUMA_Boolean LocalHead = NOPE;
9368 
9369    SUMA_ENTRY;
9370 
9371    SurfCont = SUMA_ADO_Cont(ado);
9372    SUMA_LHv("So(%p), SurfCont(%p), CmapModeMenu(%p)\n",
9373             ado, SurfCont, SurfCont->CmapModeMenu);
9374    w = SurfCont->CmapModeMenu->mw;
9375    if (!w) {
9376       SUMA_LH("NULL w");
9377       SUMA_RETURN(NOPE);
9378    }
9379    if (!str) {
9380       SUMA_S_Err("NULL str");
9381       SUMA_RETURN(NOPE);
9382    }
9383    /* what's your history joe ? */
9384    XtVaGetValues(  w[0], XmNmenuHistory , &whist , NULL ) ;
9385    if (!whist) {
9386       SUMA_SL_Err("NULL whist!");
9387       SUMA_RETURN(NOPE);
9388    }
9389 
9390    if (LocalHead) {
9391       fprintf (SUMA_STDERR,"%s: The history is NAMED: %s (%d buttons total)\n",
9392                FuncName, XtName(whist), Nbutt);
9393    }
9394    if (!strcasecmp(XtName(whist), str)) {
9395       SUMA_LHv("Current setting of %s same as %s, nothing to do.\n",
9396                XtName(whist),str);
9397       SUMA_RETURN(YUP);
9398    }
9399    nstr = strlen(str);
9400 
9401    /* Now search the widgets in w for a widget labeled str */
9402    for (i=0; i< SW_N_CmapMode; ++i) {
9403       if (LocalHead)
9404          fprintf (SUMA_STDERR,"I have %s, want %s\n", XtName(w[i]), str);
9405       nf = strcasecmp(str, XtName(w[i]));
9406       if (nf == 0) {
9407          SUMA_LH("Match!");
9408          XtVaSetValues(  w[0], XmNmenuHistory , w[i] , NULL ) ;
9409          SUMA_SetCmapMode(ado, i);
9410          SUMA_RETURN(YUP);
9411      }
9412    }
9413 
9414    SUMA_RETURN(NOPE);
9415 }
9416 
9417 /*!
9418    This function will fail if the strings have been trunctated
9419    Consider writing SetMenuChoiceUserData
9420 */
SUMA_SetCmapMenuChoice(SUMA_ALL_DO * ado,char * str)9421 SUMA_Boolean SUMA_SetCmapMenuChoice(SUMA_ALL_DO *ado, char *str)
9422 {
9423    static char FuncName[]={"SUMA_SetCmapMenuChoice"};
9424    int i, Nbutt = 0, nstr=0, nf=0;
9425    Widget whist = NULL, *w = NULL;
9426    SUMA_X_SurfCont *SurfCont=NULL;
9427    SUMA_OVERLAYS *curColPlane=NULL;
9428    SUMA_Boolean LocalHead = NOPE;
9429 
9430    SUMA_ENTRY;
9431 
9432    SurfCont = SUMA_ADO_Cont(ado);
9433    curColPlane = SUMA_ADO_CurColPlane(ado);
9434    SUMA_LHv("DO(%p), SurfCont(%p), SwitchCmapMenu(%p)\n",
9435             ado, SurfCont, SurfCont?SurfCont->SwitchCmapMenu:NULL);
9436 
9437    if (!ado || !SurfCont || !SurfCont->SwitchCmapMenu) {
9438       SUMA_S_Err("NULL input");
9439       SUMA_RETURN(NOPE);
9440    }
9441 
9442    w = SurfCont->SwitchCmapMenu->mw;
9443    if (!w) {
9444       SUMA_LH("NULL w");
9445       SUMA_RETURN(NOPE);
9446    }
9447    if (!str) {
9448       SUMA_S_Err("NULL str");
9449       SUMA_RETURN(NOPE);
9450    }
9451    /* what's your history joe ? */
9452    XtVaGetValues(  w[0], XmNmenuHistory , &whist , NULL ) ;
9453    if (!whist) {
9454       SUMA_SL_Err("NULL whist!");
9455       SUMA_S_Notev("ado(%p), SurfCont(%p), SwitchCmapMenu(%p), %s\n",
9456             ado, SurfCont, SurfCont->SwitchCmapMenu, str);
9457       SUMA_RETURN(NOPE);
9458    }
9459 
9460    if (LocalHead) {
9461       fprintf (SUMA_STDERR,"%s: The history is NAMED: %s (%d buttons total)\n",
9462                FuncName, XtName(whist), Nbutt);
9463    }
9464 
9465    nstr = strlen(str);
9466    /* Now search the widgets in w for a widget labeled str */
9467    for (i=0; i< SurfCont->SwitchCmapMenu->N_mw; ++i) {
9468       if (LocalHead)
9469          fprintf (SUMA_STDERR,"I have %s, want %s\n", XtName(w[i]), str);
9470       if (nstr > strlen(XtName(w[i]))) { /* name in list got trunctated ...*/
9471          nf = strncmp(str, XtName(w[i]), strlen(XtName(w[i])));
9472       } else {
9473          nf = strcmp(str, XtName(w[i]));
9474       }
9475       if (nf == 0) {
9476          SUMA_LH("Match!");
9477          XtVaSetValues(  w[0], XmNmenuHistory , w[i] , NULL ) ;
9478          SUMA_RETURN(YUP);
9479      }
9480    }
9481 
9482    SUMA_RETURN(NOPE);
9483 }
9484 
SUMA_SelectSwitchCmap_one(SUMA_ALL_DO * ado,SUMA_LIST_WIDGET * LW,int ichoice,SUMA_Boolean CloseShop,int setmen)9485 int SUMA_SelectSwitchCmap_one( SUMA_ALL_DO *ado, SUMA_LIST_WIDGET *LW,
9486                                int ichoice, SUMA_Boolean CloseShop, int setmen)
9487 {
9488    static char FuncName[]={"SUMA_SelectSwitchCmap_one"};
9489    SUMA_COLOR_MAP *CM = NULL;
9490    char *choice=NULL;
9491 
9492    SUMA_Boolean LocalHead = NOPE;
9493 
9494    SUMA_ENTRY;
9495 
9496    if (!ado || !LW) SUMA_RETURN(0);
9497 
9498    /*  retrieve that choice from the SUMA_ASSEMBLE_LIST_STRUCT structure
9499    and initialize the drawing window */
9500    if (LW->ALS) {
9501       if (LocalHead)
9502          fprintf (SUMA_STDERR,"%s: N_clist = %d\n",
9503                      FuncName, LW->ALS->N_clist);
9504       if (LW->ALS->N_clist > ichoice) {
9505          CM = (SUMA_COLOR_MAP *)LW->ALS->oplist[ichoice];
9506          if (LocalHead)
9507             fprintf (SUMA_STDERR,"%s: Retrieved Colmap named %s\n",
9508                      FuncName, CM->Name);
9509          /* Now you need to set the button menu to reflect the choice made */
9510          if (!SUMA_SetCmapMenuChoice (ado, LW->ALS->clist[ichoice])) {
9511             SUMA_SL_Err("Failed in SUMA_SetCmapMenuChoice");
9512          }
9513          if (!SUMA_SwitchColPlaneCmap(ado, CM)) {
9514             SUMA_SL_Err("Failed in SUMA_SwitchColPlaneCmap");
9515          }
9516       }
9517    } else {
9518       if (LocalHead) fprintf (SUMA_STDERR,"%s: NULL ALS\n", FuncName);
9519    }
9520 
9521    if (CloseShop) {
9522       SUMA_cb_CloseSwitchCmap( NULL,  (XtPointer)LW,  NULL);
9523    }
9524 
9525    /* update Lbl fields */
9526    SUMA_UpdateNodeLblField(ado);
9527 
9528 
9529    SUMA_RETURN(1);
9530 }
9531 
SUMA_SelectSwitchCmap(SUMA_ALL_DO * ado,SUMA_LIST_WIDGET * LW,int ichoice,SUMA_Boolean CloseShop,int setmen)9532 int SUMA_SelectSwitchCmap( SUMA_ALL_DO *ado, SUMA_LIST_WIDGET *LW,
9533                            int ichoice, SUMA_Boolean CloseShop, int setmen)
9534 {
9535    static char FuncName[]={"SUMA_SelectSwitchCmap"};
9536    SUMA_SurfaceObject *SO=NULL, *SOC=NULL;
9537    SUMA_OVERLAYS *colpC=NULL, *colp = NULL;
9538    SUMA_Boolean LocalHead = NOPE;
9539 
9540    SUMA_ENTRY;
9541 
9542    if (!ado || !LW) SUMA_RETURN(0);
9543 
9544    if (!SUMA_SelectSwitchCmap_one(ado, LW, ichoice, CloseShop, setmen)) {
9545       SUMA_RETURN(0);
9546    }
9547 
9548    if (ado->do_type == SO_type) {
9549       SO = (SUMA_SurfaceObject *)ado;
9550       colp = SUMA_ADO_CurColPlane(ado);
9551       colpC = SUMA_Contralateral_overlay(colp, SO, &SOC);
9552       if (colpC && SOC) {
9553          SUMA_LHv("Found contralateral equivalent to:\n"
9554                       " %s and %s in\n"
9555                       " %s and %s\n",
9556                       SO->Label, CHECK_NULL_STR(colp->Label),
9557                       SOC->Label, CHECK_NULL_STR(colpC->Label));
9558          if (!SUMA_SelectSwitchCmap_one((SUMA_ALL_DO *)SOC, LW, ichoice, 0, 1)) {
9559             SUMA_S_Warn("Failed in contralaterality");
9560             SUMA_RETURN(0);
9561          }
9562       }
9563    }
9564 
9565    SUMA_RETURN(1);
9566 }
9567 
9568 
9569 /*!
9570    \brief function that handles switching colormap from the list widget
9571    \sa SUMA_cb_SwitchCmap
9572 */
SUMA_cb_SelectSwitchCmap(Widget w,XtPointer client_data,XtPointer call_data)9573 void SUMA_cb_SelectSwitchCmap (Widget w, XtPointer client_data,
9574                                XtPointer call_data)
9575 {
9576    static char FuncName[]={"SUMA_cb_SelectSwitchCmap"};
9577    SUMA_ALL_DO *ado = NULL;
9578    SUMA_LIST_WIDGET *LW = NULL;
9579    SUMA_Boolean CloseShop = NOPE;
9580    XmListCallbackStruct *cbs = (XmListCallbackStruct *) call_data;
9581    int ichoice = -1;
9582    SUMA_Boolean LocalHead = NOPE;
9583 
9584    SUMA_ENTRY;
9585 
9586    SUMA_LH("Called");
9587    ado = (SUMA_ALL_DO *)client_data;
9588    LW = SUMAg_CF->X->SwitchCmapLst;
9589 
9590    ichoice = SUMA_GetListIchoice(cbs, LW, &CloseShop);
9591 
9592    if (!SUMA_SelectSwitchCmap(ado, LW, ichoice, CloseShop, 1)) {
9593       SUMA_S_Err("glitch");
9594       SUMA_RETURNe;
9595    }
9596 
9597    SUMA_RETURNe;
9598 }
9599 
SUMA_SwitchColPlaneCmap(SUMA_ALL_DO * ado,SUMA_COLOR_MAP * CM)9600 SUMA_Boolean SUMA_SwitchColPlaneCmap(SUMA_ALL_DO *ado, SUMA_COLOR_MAP *CM)
9601 {
9602    static char FuncName[]={"SUMA_SwitchColPlaneCmap"};
9603    SUMA_OVERLAYS *over = NULL;
9604    SUMA_X_SurfCont *SurfCont=NULL;
9605    SUMA_Boolean LocalHead = NOPE;
9606    static int nwarn=0;
9607 
9608    SUMA_ENTRY;
9609 
9610    SUMA_LH("Called");
9611    if (!ado || !CM) { SUMA_RETURN(NOPE); }
9612 
9613    SurfCont = SUMA_ADO_Cont(ado);
9614 
9615    if (!SurfCont) { SUMA_RETURN(NOPE); }
9616 
9617    over = SUMA_ADO_CurColPlane(ado);
9618    if (!over) { SUMA_RETURN(NOPE); }
9619 
9620    if (over->ShowMode == SW_SurfCont_DsetViewCon ||
9621        over->ShowMode == SW_SurfCont_DsetViewCaC ) { /* wants contours */
9622       if (SUMA_NeedsLinearizing(CM)) {
9623          if (!nwarn) {
9624             SUMA_SLP_Note("Cannot do contouring with colormaps\n"
9625                           "that panes of unequal sizes.\n"
9626                           "Contouring turned off.\n"
9627                           "Notice shown once per session.");
9628             ++nwarn;
9629          }
9630          over->ShowMode = SW_SurfCont_DsetViewCol;
9631          SUMA_Set_Menu_Widget( SurfCont->DsetViewModeMenu,
9632                         SUMA_ShowMode2ShowModeMenuItem(over->ShowMode));
9633          /* kill current contours */
9634          SUMA_KillOverlayContours(over);
9635       }
9636    }
9637 
9638    SUMA_STRING_REPLACE(over->cmapname, CM->Name);
9639    if (!SUMA_ColorizePlane (over)) {
9640          SUMA_SLP_Err("Failed to colorize plane.\n");
9641          SUMA_RETURN(NOPE);
9642    }
9643 
9644    /* reset zoom and translation vectors */
9645    SurfCont->cmp_ren->FOV = SUMA_CMAP_FOV_INITIAL;
9646    SurfCont->cmp_ren->translateVec[0] =
9647    SurfCont->cmp_ren->translateVec[1] =
9648    SurfCont->cmp_ren->translateVec[2] = 0.0;
9649 
9650    /* update the color map display NOW, no workprocess crap. ZSS Mar. 7 08*/
9651    #if 0
9652    /* With this, the next call to SUMA_Remixedisplay,
9653    causes an error: glXSwapBuffers: no context for this drawable
9654    because SUMA_cmap_wid_handleRedisplay is still to be processed
9655    as SUMA_cmap_wid_postRedisplay puts it in as a workprocess.
9656    You need to force the immediate execution of
9657    SUMA_cmap_wid_handleRedisplay which resets the context before
9658    returning */
9659    SUMA_LH("Calling SUMA_cmap_wid_postRedisplay");
9660    SUMA_cmap_wid_postRedisplay(NULL, (XtPointer)ado, NULL);
9661    #else
9662    SUMA_cmap_wid_handleRedisplay((XtPointer)ado);
9663    #endif
9664 
9665    SUMA_LH("Calling SUMA_Remixedisplay on %s", ADO_LABEL(ado));
9666    SUMA_Remixedisplay(ado);
9667 
9668    SUMA_LH("Returning");
9669    SUMA_RETURN(YUP);
9670 }
9671 /*!
9672    \brief function that handles closing switch colormap list widget
9673    expects LW in client_data
9674 */
SUMA_cb_CloseSwitchCmap(Widget w,XtPointer client_data,XtPointer call)9675 void SUMA_cb_CloseSwitchCmap (Widget w, XtPointer client_data, XtPointer call)
9676 {
9677    static char FuncName[]={"SUMA_cb_CloseSwitchCmap"};
9678    SUMA_LIST_WIDGET *LW = NULL;
9679    SUMA_Boolean LocalHead = NOPE;
9680 
9681    SUMA_ENTRY;
9682 
9683    SUMA_LH("Called");
9684 
9685    SUMA_cb_CloseSwitchLst(w, client_data, call);
9686       /* Now calling standard lst closing function       May 2009*/
9687    SUMA_RETURNe;  /* get out */
9688 
9689    /* Pre May 2009 */
9690    LW = (SUMA_LIST_WIDGET *)client_data;
9691 
9692    switch (SUMA_CLOSE_MODE)   {/* No open GL drawables in this widget*/
9693       case SUMA_WITHDRAW:
9694          if (LocalHead)
9695             fprintf (SUMA_STDERR,
9696                      "%s: Withdrawing list widget %s...\n",
9697                      FuncName, LW->Label);
9698 
9699          XWithdrawWindow(SUMAg_CF->X->DPY_controller1,
9700             XtWindow(LW->toplevel),
9701             XScreenNumberOfScreen(XtScreen(LW->toplevel)));
9702          break;
9703       case SUMA_DESTROY:
9704          if (LocalHead)
9705             fprintf (SUMA_STDERR,
9706                      "%s: Destroying list widget %s...\n", FuncName, LW->Label);
9707          XtDestroyWidget(LW->toplevel);
9708          LW->toplevel = NULL;
9709          break;
9710       default:
9711          SUMA_S_Err("Not setup to deal with this closing type");
9712          SUMA_RETURNe;
9713          break;
9714    }
9715 
9716    LW->isShaded = YUP;
9717 
9718 
9719 
9720    SUMA_RETURNe;
9721 }
9722 
9723 /* based on bbox.c's optmenu_EV */
SUMA_optmenu_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)9724 void SUMA_optmenu_EV( Widget w , XtPointer cd ,
9725                       XEvent *ev , Boolean *continue_to_dispatch )
9726 {
9727    static char FuncName[]={"SUMA_optmenu_EV"};
9728    Dimension lw=0 ;
9729    Widget * children , wl = NULL;
9730    XButtonEvent * bev = (XButtonEvent *) ev ;
9731    int  num_children , ic ;
9732    SUMA_ALL_DO *ado = (SUMA_ALL_DO *)cd;
9733    SUMA_Boolean LocalHead = NOPE;
9734 
9735    SUMA_ENTRY;
9736 
9737    SUMA_LH("Called");
9738 
9739    /* see note in bbox.c optmenu_EV for the condition below*/
9740    if( bev->button == Button2 ){
9741      XUngrabPointer( bev->display , CurrentTime ) ;
9742      SUMA_RETURNe ;
9743    }
9744 
9745    if( w == NULL || ado == NULL ) SUMA_RETURNe ;
9746 
9747    if( bev->button != Button3 ) SUMA_RETURNe ;
9748 
9749    if (LocalHead) {
9750       SUMA_LH("Les enfants de w");
9751       SUMA_ShowMeTheChildren(w);
9752    }
9753 
9754    /* get the widget named "OptionLabel" */
9755    wl = XtNameToWidget(w, "OptionLabel");
9756    if (!wl) {
9757       SUMA_SL_Err("Failed to find la widget"); /* do continue */
9758    } else {  /* confine yourself to the label, young man */
9759       XtVaGetValues( wl , XmNwidth, &lw , NULL ) ;
9760       if( bev->x > lw ) SUMA_RETURNe ;
9761    }
9762 
9763    /* Need to create a list */
9764    SUMA_LHv("Now creating list XtName(w)=%s \n", XtName(w));
9765    if (strcmp(XtName(w), "I") == 0) {
9766       if (!SUMA_DsetColSelectList(ado, 0, 0, 1)) {
9767          SUMA_SLP_Err("Failed to create DsetList");
9768          SUMA_RETURNe;
9769       }
9770    } else if (strcmp(XtName(w), "T") == 0){
9771       if (!SUMA_DsetColSelectList(ado, 1, 0, 1)) {
9772          SUMA_SLP_Err("Failed to create DsetList");
9773          SUMA_RETURNe;
9774       }
9775    } else if (strcmp(XtName(w), "B") == 0){
9776       if (!SUMA_DsetColSelectList(ado, 2, 0, 1)) {
9777          SUMA_SLP_Err("Failed to create DsetList");
9778          SUMA_RETURNe;
9779       }
9780    } else if (strcmp(XtName(w), "Cmp") == 0){
9781       if (!SUMA_CmapSelectList(ado, 0, 1)) {
9782          SUMA_SLP_Err("Failed to create DsetList");
9783          SUMA_RETURNe;
9784       }
9785    } else {
9786       SUMA_SLP_Err("wahtchyoutalkinaboutwillis?");
9787       SUMA_RETURNe;
9788    }
9789    SUMA_RETURNe;
9790 
9791 }
9792 
SUMA_CreateXhairWidgets(Widget parent,SUMA_ALL_DO * ado)9793 void SUMA_CreateXhairWidgets(Widget parent, SUMA_ALL_DO *ado)
9794 {
9795    static char FuncName[]={"SUMA_CreateXhairWidgets"};
9796    SUMA_ENTRY;
9797 
9798    if (!ado) {
9799       SUMA_RETURNe;
9800    }
9801    switch (ado->do_type) {
9802       case SO_type:
9803          SUMA_CreateXhairWidgets_SO(parent, ado);
9804          break;
9805       case GDSET_type:
9806          SUMA_S_Err("Should not create widgets for a DO that "
9807                     "can't be displayed without variant");
9808          SUMA_RETURNe;
9809       case CDOM_type:
9810          SUMA_CreateXhairWidgets_CO(parent, ado);
9811          SUMA_RETURNe;
9812          break;
9813       case GRAPH_LINK_type:
9814          SUMA_CreateXhairWidgets_GLDO(parent, ado);
9815          break;
9816       case TRACT_type:
9817          SUMA_CreateXhairWidgets_TDO(parent, ado);
9818          break;
9819       case MASK_type:
9820          SUMA_CreateXhairWidgets_MDO(parent, ado);
9821          break;
9822       case VO_type:
9823          SUMA_CreateXhairWidgets_VO(parent, ado);
9824          break;
9825       default:
9826          SUMA_S_Errv("Not ready for this beast %d (%s)\n",
9827             ado->do_type, SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
9828          break;
9829    }
9830    SUMA_RETURNe;
9831 }
9832 
SUMA_CreateXhairWidgets_SO(Widget parent,SUMA_ALL_DO * ado)9833 void SUMA_CreateXhairWidgets_SO(Widget parent, SUMA_ALL_DO *ado)
9834 {
9835    static char FuncName[]={"SUMA_CreateXhairWidgets_SO"};
9836    char *Xhair_tit[]=   {  "Xhr ", NULL};
9837    char *Xhair_hint[]=  {  "Crosshair coordinates.", NULL};
9838    char *Xhair_help[]=  {  SUMA_SurfContHelp_Xhr , NULL};
9839    char *Node_tit[]=    {  "Node"   , NULL};
9840    char *Node_hint[]=   {  "Node index", NULL};
9841    char *Node_help[]=   {  SUMA_SurfContHelp_Node , NULL};
9842    char *Face_tit[]=    {  "Tri ", NULL};
9843    char *Face_hint[]=   {  "1- Triangle index, 2- Nodes forming tiangle", NULL};
9844    char *Face_help[]=   {  SUMA_SurfContHelp_Tri , NULL};
9845    char *Data_tit[]=    {  "    ", "Intens", "Thresh", "Bright" , NULL};
9846    char *Data_colhint[]=      {  "Data Values at node in focus",
9847                                  "Intensity (I) value",
9848                                  "Threshold (T) value",
9849                                  "Brightness modulation (B) value" , NULL};
9850    char *Data_colhelp[]=      {  SUMA_SurfContHelp_NodeValTblc0,
9851                                  SUMA_SurfContHelp_NodeValTblc1,
9852                                  SUMA_SurfContHelp_NodeValTblc2,
9853                                  SUMA_SurfContHelp_NodeValTblc3 , NULL};
9854 
9855    char *Data_rtit[]=      {  "    ", "Val " , NULL};
9856    char *Data_rowhint[]=   {  "Data Values at node in focus",
9857                               "Data Values at node in focus" , NULL};
9858    char *Data_rowhelp[]=   {  SUMA_SurfContHelp_NodeValTblr0,
9859                               SUMA_SurfContHelp_NodeValTblr0 , NULL};
9860 
9861    char *Label_tit[]=   {  "Lbl ", NULL};
9862    char *Label_hint[]=  {  "Color at node in focus", NULL};
9863    char *Label_help[]=  {  SUMA_SurfContHelp_NodeLabelTblr0 , NULL};
9864    SUMA_X_SurfCont *SurfCont=NULL;
9865    Widget rcc;
9866 
9867    SUMA_Boolean LocalHead = NOPE;
9868 
9869    SUMA_ENTRY;
9870 
9871    if (!ado || ado->do_type != SO_type || !(SurfCont = SUMA_ADO_Cont(ado))) {
9872       SUMA_RETURNe;
9873    }
9874    /* a row column to contain them all */
9875    rcc = XtVaCreateWidget ("rowcolumn",
9876       xmRowColumnWidgetClass, parent,
9877       XmNpacking, XmPACK_TIGHT,
9878       XmNleftAttachment,XmATTACH_FORM ,
9879       XmNorientation , XmVERTICAL ,
9880       XmNmarginHeight , 0 ,
9881       XmNmarginWidth  , 0 ,
9882       NULL);
9883 
9884    /* a simple table with the xhair coordinate */
9885    SUMA_LH("Creating Xhair coordinates table");
9886    {
9887       int colw[] = { 4, 27 };
9888       SUMA_CreateTable(rcc,
9889          1, 2,
9890          "SurfCont->Xhair_Info->Xhr",
9891          Xhair_tit, NULL,
9892          Xhair_hint, NULL,
9893          Xhair_help, NULL,
9894          colw, YUP, SUMA_string,
9895          SUMA_XhairInput, (void*)ado,
9896          NULL, NULL,
9897          NULL, NULL,
9898          SurfCont->XhairTable);
9899    }
9900    /* a table for a node's index */
9901    SUMA_LH("Creating node table");
9902    {
9903       int colw[]={4, 6, 19};
9904       SUMA_CreateTable(rcc,
9905          1, 3,
9906          "SurfCont->Xhair_Info->Node",
9907          Node_tit, NULL,
9908          Node_hint, NULL,
9909          Node_help, NULL,
9910          colw, YUP, SUMA_int,
9911          SUMA_NodeInput, (void*)ado,
9912          NULL, NULL,
9913          NULL, NULL,
9914          SurfCont->NodeTable);
9915       /* disable the 3rd entry cell */
9916       SUMA_SetCellEditMode(SurfCont->NodeTable, 0, 2, 0);
9917    }
9918    /* a table for the triangle in focus */
9919    SUMA_LH("Creating Face  table");
9920    {
9921       int colw[]={4, 6, 19}  ;
9922       SUMA_CreateTable(rcc,
9923          1, 3,
9924          "SurfCont->Xhair_Info->Tri",
9925          Face_tit, NULL,
9926          Face_hint, NULL,
9927          Face_help, NULL,
9928          colw, YUP, SUMA_int,
9929          SUMA_TriInput, (void*)ado,
9930          NULL, NULL,
9931          NULL, NULL,
9932          SurfCont->FaceTable);
9933       /* disable the 3rd entry cell */
9934       SUMA_SetCellEditMode(SurfCont->FaceTable, 0, 2, 0);
9935    }
9936    /* a table for the Dset values at node in focus */
9937    SUMA_LH("Creating Dset Val  table");
9938    {
9939       int colw[]={ 4, 7, 7, 7};
9940       SUMA_CreateTable(rcc,
9941          2, 4,
9942          "SurfCont->Xhair_Info->Val",
9943          Data_rtit, Data_tit,
9944          Data_rowhint, Data_colhint,
9945          Data_rowhelp, Data_colhelp,
9946          colw, NOPE, SUMA_float,
9947          NULL, NULL,
9948          NULL, NULL,
9949          NULL, NULL,
9950          SurfCont->DataTable);
9951    }
9952    /* a table for a node's label*/
9953    SUMA_LH("Creating label  table");
9954    {
9955       int colw[]={4, 26};
9956       SUMA_CreateTable(rcc,
9957          1, 2,
9958          "SurfCont->Xhair_Info->Lbl",
9959          Label_tit, NULL,
9960          Label_hint, NULL,
9961          Label_help, NULL,
9962          colw, NOPE, SUMA_string,
9963          NULL, NULL,
9964          NULL, NULL,
9965          NULL, NULL,
9966          SurfCont->LabelTable);
9967    }
9968    XtManageChild(rcc);
9969    SUMA_RETURNe;
9970 
9971 }
9972 
SUMA_CreateXhairWidgets_GLDO(Widget parent,SUMA_ALL_DO * ado)9973 void SUMA_CreateXhairWidgets_GLDO(Widget parent, SUMA_ALL_DO *ado)
9974 {
9975    static char FuncName[]={"SUMA_CreateXhairWidgets_GLDO"};
9976    char *Xhair_tit[]=   {  "Xhr ", NULL};
9977    char *Xhair_hint[]=  {  "Crosshair coordinates.", NULL};
9978    char *Xhair_help[]=  {  SUMA_SurfContHelp_Xhr , NULL};
9979    char *Node_tit[]=    {  "Node"   , NULL};
9980    char *Node_hint[]=   {  "Closest Node index", NULL};
9981    char *Node_help[]=   {  SUMA_SurfContHelp_GNode , NULL};
9982    char *Edge_tit[]=    {  "Edge", NULL};
9983    char *Edge_hint[]=   {  "1- Edge index, 2- Nodes forming (directed) edge",
9984                                     NULL};
9985    char *Edge_help[]=   {  SUMA_SurfContHelp_GEdge , NULL};
9986    char *Data_tit[]=    {  "    ", "Intens", "Thresh", "Bright" , NULL};
9987    char *Data_colhint[]=      {  "Data Values at Edge in Focus",
9988                                  "Intensity (I) value",
9989                                  "Threshold (T) value",
9990                                  "Brightness modulation (B) value" , NULL};
9991    char *Data_colhelp[]=      {  SUMA_SurfContHelp_GEdgeValTblc0,
9992                                  SUMA_SurfContHelp_GEdgeValTblc1,
9993                                  SUMA_SurfContHelp_GEdgeValTblc2,
9994                                  SUMA_SurfContHelp_GEdgeValTblc3 , NULL};
9995 
9996    char *Data_rtit[]=      {  "    ", "Val " , NULL};
9997    char *Data_rowhint[]=   {  "Data Values at Edge in Focus",
9998                               "Data Values at Edge in Focus" , NULL};
9999    char *Data_rowhelp[]=   {  SUMA_SurfContHelp_GEdgeValTblr0,
10000                               SUMA_SurfContHelp_GEdgeValTblr0 , NULL};
10001 
10002    char *Label_tit[]=   {  "Lbl ", NULL};
10003    char *Label_hint[]=  {  "Label of edge in focus", NULL};
10004    char *Label_help[]=  {  SUMA_SurfContHelp_GEdgeLabelTblr0 , NULL};
10005    SUMA_X_SurfCont *SurfCont=NULL;
10006    Widget rcc;
10007    SUMA_Boolean LocalHead = NOPE;
10008 
10009    SUMA_ENTRY;
10010 
10011    if (!ado || ado->do_type != GRAPH_LINK_type ||
10012        !(SurfCont = SUMA_ADO_Cont(ado))) {
10013       SUMA_S_Errv("Something's amiss %p, type %d (%s) (must be GRAPH_LINK)\n",
10014                    ado, ado?ado->do_type:0, ADO_TNAME(ado));
10015       SUMA_RETURNe;
10016    }
10017 
10018    /* a row column to contain them all */
10019    rcc = XtVaCreateWidget ("rowcolumn",
10020       xmRowColumnWidgetClass, parent,
10021       XmNpacking, XmPACK_TIGHT,
10022       XmNleftAttachment,XmATTACH_FORM ,
10023       XmNorientation , XmVERTICAL ,
10024       XmNmarginHeight , 0 ,
10025       XmNmarginWidth  , 0 ,
10026       NULL);
10027 
10028    /* a simple table with the xhair coordinate */
10029    SUMA_LH("Creating Xhair coordinates table");
10030    {
10031       int colw[] = { 4, 27 };
10032       SUMA_CreateTable(rcc,
10033          1, 2,
10034          "GraphCont->Xhair_Info->Xhr",
10035          Xhair_tit, NULL,
10036          Xhair_hint, NULL,
10037          Xhair_help, NULL,
10038          colw, YUP, SUMA_string,
10039          SUMA_XhairInput, (void*)ado,
10040          NULL, NULL,
10041          NULL, NULL,
10042          SurfCont->XhairTable);
10043    }
10044    /* a table for the edge in focus */
10045    SUMA_LH("Creating Edge  table");
10046    {
10047       int colw[]={4, 6, 19}  ;
10048       SUMA_CreateTable(rcc,
10049          1, 3,
10050          "GraphCont->Xhair_Info->Edge",
10051          Edge_tit, NULL,
10052          Edge_hint, NULL,
10053          Edge_help, NULL,
10054          colw, YUP, SUMA_int,
10055          SUMA_NodeInput, (void*)ado,
10056          NULL, NULL,
10057          NULL, NULL,
10058          SurfCont->NodeTable);
10059       /* disable the 3rd entry cell */
10060       SUMA_SetCellEditMode(SurfCont->NodeTable, 0, 2, 0);
10061    }
10062    /* a table for a node's index */
10063    SUMA_LH("Creating graph node table");
10064    {
10065       int colw[]={4, 6, 19};
10066       SUMA_CreateTable(rcc,
10067          1, 3,
10068          "GraphCont->Xhair_Info->Node",
10069          Node_tit, NULL,
10070          Node_hint, NULL,
10071          Node_help, NULL,
10072          colw, YUP, SUMA_int,
10073          SUMA_GNodeInput, (void*)ado,
10074          NULL, NULL,
10075          NULL, NULL,
10076          SurfCont->FaceTable);
10077       /* disable the 3rd entry cell */
10078       SUMA_SetCellEditMode(SurfCont->FaceTable, 0, 2, 0);
10079    }
10080    /* a table for the Dset values at node in focus */
10081    SUMA_LH("Creating Dset Val  table");
10082    {
10083       int colw[]={ 4, 7, 7, 7};
10084       SUMA_CreateTable(rcc,
10085          2, 4,
10086          "GraphCont->Xhair_Info->Val",
10087          Data_rtit, Data_tit,
10088          Data_rowhint, Data_colhint,
10089          Data_rowhelp, Data_colhelp,
10090          colw, NOPE, SUMA_float,
10091          NULL, NULL,
10092          NULL, NULL,
10093          NULL, NULL,
10094          SurfCont->DataTable);
10095    }
10096    /* a table for a node's label*/
10097    SUMA_LH("Creating label  table");
10098    {
10099       int colw[]={4, 26};
10100       SUMA_CreateTable(rcc,
10101          1, 2,
10102          "GraphCont->Xhair_Info->Lbl",
10103          Label_tit, NULL,
10104          Label_hint, NULL,
10105          Label_help, NULL,
10106          colw, NOPE, SUMA_string,
10107          NULL, NULL,
10108          NULL, NULL,
10109          NULL, NULL,
10110          SurfCont->LabelTable);
10111    }
10112    XtManageChild(rcc);
10113    SUMA_RETURNe;
10114 
10115 }
10116 
SUMA_CreateXhairWidgets_TDO(Widget parent,SUMA_ALL_DO * ado)10117 void SUMA_CreateXhairWidgets_TDO(Widget parent, SUMA_ALL_DO *ado)
10118 {
10119    static char FuncName[]={"SUMA_CreateXhairWidgets_TDO"};
10120    char *Xhair_tit[]=   {  "Xhr ", NULL};
10121    char *Xhair_hint[]=  {  "Crosshair coordinates.", NULL};
10122    char *Xhair_help[]=  {  SUMA_SurfContHelp_Xhr , NULL};
10123    char *I_tit[]=      { "Ind ", NULL };
10124    char *I_hint[] =    { "Point index in whole network", NULL };
10125    char *I_help[] =    { SUMA_TractContHelp_I, NULL };
10126    char *BTP_tit[]=    {  "BTP"   , NULL};
10127    char *BTP_hint[]=   {  "Bundle index in network, Tract index in bundle, "
10128                           "Point index in tract",
10129                            NULL};
10130    char *BTP_help[]=   {  SUMA_SurfContHelp_BTP , NULL};
10131    char *Data_tit[]=    {  "    ", "Intens", "Thresh", "Bright" , NULL};
10132    char *Data_colhint[]=      {  "Data values at tract point in focus",
10133                                  "Intensity (I) value",
10134                                  "Threshold (T) value",
10135                                  "Brightness modulation (B) value" , NULL};
10136    char *Data_colhelp[]=      {  SUMA_TractContHelp_NodeValTblc0,
10137                                  SUMA_SurfContHelp_NodeValTblc1,
10138                                  SUMA_SurfContHelp_NodeValTblc2,
10139                                  SUMA_SurfContHelp_NodeValTblc3 , NULL};
10140 
10141    char *Data_rtit[]=      {  "    ", "Val " , NULL};
10142    char *Data_rowhint[]=   {  "Data Values at point in focus",
10143                               "Data Values at point in focus" , NULL};
10144    char *Data_rowhelp[]=   {  SUMA_SurfContHelp_NodeValTblr0,
10145                               SUMA_SurfContHelp_NodeValTblr0 , NULL};
10146 
10147    char *Label_tit[]=   {  "Lbl ", NULL};
10148    char *Label_hint[]=  {  "Label at selected point", NULL};
10149    char *Label_help[]=  {  SUMA_TractContHelp_NodeLabelTblr0 , NULL};
10150    SUMA_X_SurfCont *SurfCont=NULL;
10151    Widget rcc, rcch;
10152 
10153    SUMA_Boolean LocalHead = NOPE;
10154 
10155    SUMA_ENTRY;
10156 
10157    if (!ado || ado->do_type != TRACT_type || !(SurfCont = SUMA_ADO_Cont(ado))) {
10158       SUMA_RETURNe;
10159    }
10160    /* a row column to contain them all */
10161    rcc = XtVaCreateWidget ("rowcolumn",
10162       xmRowColumnWidgetClass, parent,
10163       XmNpacking, XmPACK_TIGHT,
10164       XmNleftAttachment,XmATTACH_FORM ,
10165       XmNorientation , XmVERTICAL ,
10166       XmNmarginHeight , 0 ,
10167       XmNmarginWidth  , 0 ,
10168       NULL);
10169 
10170    /* a simple table with the xhair coordinate */
10171    SUMA_LH("Creating Xhair coordinates table");
10172    {
10173       int colw[] = { 4, 27 };
10174       SUMA_CreateTable(rcc,
10175          1, 2,
10176          "TractCont->Xhair_Info->Xhr",
10177          Xhair_tit, NULL,
10178          Xhair_hint, NULL,
10179          Xhair_help, NULL,
10180          colw, YUP, SUMA_string,
10181          SUMA_XhairInput, (void*)ado,
10182          NULL, NULL,
10183          NULL, NULL,
10184          SurfCont->XhairTable);
10185    }
10186    rcch = XtVaCreateWidget ("rowcolumn",
10187       xmRowColumnWidgetClass, rcc,
10188       XmNpacking, XmPACK_TIGHT,
10189       XmNleftAttachment,XmATTACH_FORM ,
10190       XmNorientation , XmHORIZONTAL ,
10191       XmNmarginHeight , 0 ,
10192       XmNmarginWidth  , 0 ,
10193       NULL);
10194    /* a table for a point's index */
10195    SUMA_LH("Creating point table");
10196    {
10197       int colw[]={3, 5};
10198       SUMA_CreateTable(rcch,
10199          1, 2,
10200          "TractCont->Xhair_Info->Ind",
10201          I_tit, NULL,
10202          I_hint, NULL,
10203          I_help, NULL,
10204          colw, YUP, SUMA_int,
10205          SUMA_NodeInput, (void*)ado,
10206          NULL, NULL,
10207          NULL, NULL,
10208          SurfCont->NodeTable);
10209    }
10210    /* a table for a point's BTP index */
10211    SUMA_LH("Creating BTP table");
10212    {
10213       int colw[]={4, 15};
10214       SUMA_CreateTable(rcch,
10215          1, 2,
10216          "TractCont->Xhair_Info->BTP",
10217          BTP_tit, NULL,
10218          BTP_hint, NULL,
10219          BTP_help, NULL,
10220          colw, YUP, SUMA_string,
10221          SUMA_TpointInput, (void*)ado,
10222          NULL, NULL,
10223          NULL, NULL,
10224          SurfCont->FaceTable);
10225    }
10226    XtManageChild(rcch);
10227 
10228 
10229    /* a table for the Dset values at node in focus */
10230    SUMA_LH("Creating Dset Val  table");
10231    {
10232       int colw[]={ 4, 7, 7, 7};
10233       SUMA_CreateTable(rcc,
10234          2, 4,
10235          "TractCont->Xhair_Info->Val",
10236          Data_rtit, Data_tit,
10237          Data_rowhint, Data_colhint,
10238          Data_rowhelp, Data_colhelp,
10239          colw, NOPE, SUMA_float,
10240          NULL, NULL,
10241          NULL, NULL,
10242          NULL, NULL,
10243          SurfCont->DataTable);
10244    }
10245    /* a table for a node's label*/
10246    SUMA_LH("Creating label  table");
10247    {
10248       int colw[]={4, 26};
10249       SUMA_CreateTable(rcc,
10250          1, 2,
10251          "TractCont->Xhair_Info->Lbl",
10252          Label_tit, NULL,
10253          Label_hint, NULL,
10254          Label_help, NULL,
10255          colw, NOPE, SUMA_string,
10256          NULL, NULL,
10257          NULL, NULL,
10258          NULL, NULL,
10259          SurfCont->LabelTable);
10260    }
10261    XtManageChild(rcc);
10262    SUMA_RETURNe;
10263 }
10264 
SUMA_CreateXhairWidgets_MDO(Widget parent,SUMA_ALL_DO * ado)10265 void SUMA_CreateXhairWidgets_MDO(Widget parent, SUMA_ALL_DO *ado)
10266 {
10267    static char FuncName[]={"SUMA_CreateXhairWidgets_MDO"};
10268    char *Xhair_tit[]=   {  "Xhr ", NULL};
10269    char *Xhair_hint[]=  {  "Crosshair coordinates.", NULL};
10270    char *Xhair_help[]=  {  SUMA_SurfContHelp_Xhr , NULL};
10271    char *I_tit[]=      { "Ind ", NULL };
10272    char *I_hint[] =    { "Point index in whole network", NULL };
10273    char *I_help[] =    { SUMA_TractContHelp_I, NULL };
10274    char *BTP_tit[]=    {  "BTP"   , NULL};
10275    char *BTP_hint[]=   {  "Bundle index in network, Tract index in bundle, "
10276                           "Point index in tract",
10277                            NULL};
10278    char *BTP_help[]=   {  SUMA_SurfContHelp_BTP , NULL};
10279    char *Data_tit[]=    {  "    ", "Intens", "Thresh", "Bright" , NULL};
10280    char *Data_colhint[]=      {  "Data Values at tract point in focus",
10281                                  "Intensity (I) value",
10282                                  "Threshold (T) value",
10283                                  "Brightness modulation (B) value" , NULL};
10284    char *Data_colhelp[]=      {  SUMA_SurfContHelp_NodeValTblc0,
10285                                  SUMA_SurfContHelp_NodeValTblc1,
10286                                  SUMA_SurfContHelp_NodeValTblc2,
10287                                  SUMA_SurfContHelp_NodeValTblc3 , NULL};
10288 
10289    char *Data_rtit[]=      {  "    ", "Val " , NULL};
10290    char *Data_rowhint[]=   {  "Data Values at point in focus",
10291                               "Data Values at point in focus" , NULL};
10292    char *Data_rowhelp[]=   {  SUMA_SurfContHelp_NodeValTblr0,
10293                               SUMA_SurfContHelp_NodeValTblr0 , NULL};
10294 
10295    char *Label_tit[]=   {  "Lbl ", NULL};
10296    char *Label_hint[]=  {  "Label at node in focus", NULL};
10297    char *Label_help[]=  {  SUMA_SurfContHelp_NodeLabelTblr0 , NULL};
10298    SUMA_X_SurfCont *SurfCont=NULL;
10299    Widget rcc, rcch;
10300 
10301    SUMA_Boolean LocalHead = NOPE;
10302 
10303    SUMA_ENTRY;
10304 
10305    if (!ado || ado->do_type != MASK_type || !(SurfCont = SUMA_ADO_Cont(ado))) {
10306       SUMA_RETURNe;
10307    }
10308 
10309    SUMA_S_Warn("Nothing done below");
10310    SUMA_RETURNe;
10311 
10312    /* a row column to contain them all */
10313    rcc = XtVaCreateWidget ("rowcolumn",
10314       xmRowColumnWidgetClass, parent,
10315       XmNpacking, XmPACK_TIGHT,
10316       XmNleftAttachment,XmATTACH_FORM ,
10317       XmNorientation , XmVERTICAL ,
10318       XmNmarginHeight , 0 ,
10319       XmNmarginWidth  , 0 ,
10320       NULL);
10321 
10322    /* a simple table with the xhair coordinate */
10323    SUMA_LH("Creating Xhair coordinates table");
10324    {
10325       int colw[] = { 4, 27 };
10326       SUMA_CreateTable(rcc,
10327          1, 2,
10328          "MaskCont->NOT_DONE->Xhr",
10329          Xhair_tit, NULL,
10330          Xhair_hint, NULL,
10331          Xhair_help, NULL,
10332          colw, YUP, SUMA_string,
10333          SUMA_XhairInput, (void*)ado,
10334          NULL, NULL,
10335          NULL, NULL,
10336          SurfCont->XhairTable);
10337    }
10338    rcch = XtVaCreateWidget ("rowcolumn",
10339       xmRowColumnWidgetClass, rcc,
10340       XmNpacking, XmPACK_TIGHT,
10341       XmNleftAttachment,XmATTACH_FORM ,
10342       XmNorientation , XmHORIZONTAL ,
10343       XmNmarginHeight , 0 ,
10344       XmNmarginWidth  , 0 ,
10345       NULL);
10346    /* a table for a point's index */
10347    SUMA_LH("Creating point table");
10348    {
10349       int colw[]={3, 5};
10350       SUMA_CreateTable(rcch,
10351          1, 2,
10352          "MaskCont->NOT_DONE->I",
10353          I_tit, NULL,
10354          I_hint, NULL,
10355          I_help, NULL,
10356          colw, YUP, SUMA_int,
10357          SUMA_NodeInput, (void*)ado,
10358          NULL, NULL,
10359          NULL, NULL,
10360          SurfCont->NodeTable);
10361    }
10362    /* a table for a point's BTP index */
10363    SUMA_LH("Creating BTP table");
10364    {
10365       int colw[]={4, 15};
10366       SUMA_CreateTable(rcch,
10367          1, 2,
10368          "MaskCont->NOT_DONE->BTP",
10369          BTP_tit, NULL,
10370          BTP_hint, NULL,
10371          BTP_help, NULL,
10372          colw, YUP, SUMA_string,
10373          SUMA_TpointInput, (void*)ado,
10374          NULL, NULL,
10375          NULL, NULL,
10376          SurfCont->FaceTable);
10377    }
10378    XtManageChild(rcch);
10379 
10380 
10381    /* a table for the Dset values at node in focus */
10382    SUMA_LH("Creating Dset Val  table");
10383    {
10384       int colw[]={ 4, 7, 7, 7};
10385       SUMA_CreateTable(rcc,
10386          2, 4,
10387          "MaskCont->NOT_DONE->Val",
10388          Data_rtit, Data_tit,
10389          Data_rowhint, Data_colhint,
10390          Data_rowhelp, Data_colhelp,
10391          colw, NOPE, SUMA_float,
10392          NULL, NULL,
10393          NULL, NULL,
10394          NULL, NULL,
10395          SurfCont->DataTable);
10396    }
10397    /* a table for a node's label*/
10398    SUMA_LH("Creating label  table");
10399    {
10400       int colw[]={4, 26};
10401       SUMA_CreateTable(rcc,
10402          1, 2,
10403          "MaskCont->NOT_DONE->Lbl",
10404          Label_tit, NULL,
10405          Label_hint, NULL,
10406          Label_help, NULL,
10407          colw, NOPE, SUMA_string,
10408          NULL, NULL,
10409          NULL, NULL,
10410          NULL, NULL,
10411          SurfCont->LabelTable);
10412    }
10413    XtManageChild(rcc);
10414    SUMA_RETURNe;
10415 
10416 }
10417 
SUMA_CreateXhairWidgets_VO(Widget parent,SUMA_ALL_DO * ado)10418 void SUMA_CreateXhairWidgets_VO(Widget parent, SUMA_ALL_DO *ado)
10419 {
10420    static char FuncName[]={"SUMA_CreateXhairWidgets_VO"};
10421    char *Xhair_tit[]=   {  "Xhr ", NULL};
10422    char *Xhair_hint[]=  {  "Crosshair coordinates.", NULL};
10423    char *Xhair_help[]=  {  SUMA_SurfContHelp_Xhr , NULL};
10424    char *I_tit[]=      { "Ind ", NULL };
10425    char *I_hint[] =    { "Voxel 1D index in volume", NULL };
10426    char *I_help[] =    { SUMA_VolContHelp_I, NULL };
10427    char *BTP_tit[]=    {  "IJK"   , NULL};
10428    char *BTP_hint[]=   {  "Voxel 3D indices in volume",
10429                            NULL};
10430    char *BTP_help[]=   {  SUMA_SurfContHelp_IJK , NULL};
10431    char *Data_tit[]=    {  "    ", "Intens", "Thresh", "Bright" , NULL};
10432    char *Data_colhint[]=      {  "Data Values at voxel in focus",
10433                                  "Intensity (I) value",
10434                                  "Threshold (T) value",
10435                                  "Brightness modulation (B) value" , NULL};
10436    char *Data_colhelp[]=      {  SUMA_VolContHelp_NodeValTblc0,
10437                                  SUMA_SurfContHelp_NodeValTblc1,
10438                                  SUMA_SurfContHelp_NodeValTblc2,
10439                                  SUMA_SurfContHelp_NodeValTblc3 , NULL};
10440 
10441    char *Data_rtit[]=      {  "    ", "Val " , NULL};
10442    char *Data_rowhint[]=   {  "Data values at voxel in focus",
10443                               "Data values at voxel in focus" , NULL};
10444    char *Data_rowhelp[]=   {  SUMA_SurfContHelp_NodeValTblr0,
10445                               SUMA_SurfContHelp_NodeValTblr0 , NULL};
10446 
10447    char *Label_tit[]=   {  "Lbl ", NULL};
10448    char *Label_hint[]=  {  "Label at voxel in focus", NULL};
10449    char *Label_help[]=  {  SUMA_SurfContHelp_NodeLabelTblr0 , NULL};
10450    SUMA_X_SurfCont *SurfCont=NULL;
10451    Widget rcc, rcch;
10452 
10453    SUMA_Boolean LocalHead = NOPE;
10454 
10455    SUMA_ENTRY;
10456 
10457    if (!ado || ado->do_type != VO_type || !(SurfCont = SUMA_ADO_Cont(ado))) {
10458       SUMA_RETURNe;
10459    }
10460 
10461    /* a row column to contain them all */
10462    rcc = XtVaCreateWidget ("rowcolumn",
10463       xmRowColumnWidgetClass, parent,
10464       XmNpacking, XmPACK_TIGHT,
10465       XmNleftAttachment,XmATTACH_FORM ,
10466       XmNorientation , XmVERTICAL ,
10467       XmNmarginHeight , 0 ,
10468       XmNmarginWidth  , 0 ,
10469       NULL);
10470 
10471    /* a simple table with the xhair coordinate */
10472    SUMA_LH("Creating Xhair coordinates table");
10473    {
10474       int colw[] = { 4, 27 };
10475       SUMA_CreateTable(rcc,
10476          1, 2,
10477          "VolCont->Xhair_Info->Xhr",
10478          Xhair_tit, NULL,
10479          Xhair_hint, NULL,
10480          Xhair_help, NULL,
10481          colw, YUP, SUMA_string,
10482          SUMA_XhairInput, (void*)ado,
10483          NULL, NULL,
10484          NULL, NULL,
10485          SurfCont->XhairTable);
10486    }
10487    rcch = XtVaCreateWidget ("rowcolumn",
10488       xmRowColumnWidgetClass, rcc,
10489       XmNpacking, XmPACK_TIGHT,
10490       XmNleftAttachment,XmATTACH_FORM ,
10491       XmNorientation , XmHORIZONTAL ,
10492       XmNmarginHeight , 0 ,
10493       XmNmarginWidth  , 0 ,
10494       NULL);
10495    /* a table for a point's index */
10496    SUMA_LH("Creating point table");
10497    {
10498       int colw[]={3, 6};
10499       SUMA_CreateTable(rcch,
10500          1, 2,
10501          "VolCont->Xhair_Info->Ind",
10502          I_tit, NULL,
10503          I_hint, NULL,
10504          I_help, NULL,
10505          colw, YUP, SUMA_int,
10506          SUMA_NodeInput, (void*)ado,
10507          NULL, NULL,
10508          NULL, NULL,
10509          SurfCont->NodeTable);
10510    }
10511    /* a table for a point's BTP index */
10512    SUMA_LH("Creating IJK table");
10513    {
10514       int colw[]={4, 15};
10515       SUMA_CreateTable(rcch,
10516          1, 2,
10517          "VolCont->Xhair_Info->IJK",
10518          BTP_tit, NULL,
10519          BTP_hint, NULL,
10520          BTP_help, NULL,
10521          colw, YUP, SUMA_string,
10522          SUMA_IJKInput, (void*)ado,
10523          NULL, NULL,
10524          NULL, NULL,
10525          SurfCont->FaceTable);
10526    }
10527    XtManageChild(rcch);
10528 
10529 
10530    /* a table for the Dset values at node in focus */
10531    SUMA_LH("Creating Dset Val  table");
10532    {
10533       int colw[]={ 4, 7, 7, 7};
10534       SUMA_CreateTable(rcc,
10535          2, 4,
10536          "VolCont->Xhair_Info->Val",
10537          Data_rtit, Data_tit,
10538          Data_rowhint, Data_colhint,
10539          Data_rowhelp, Data_colhelp,
10540          colw, NOPE, SUMA_float,
10541          NULL, NULL,
10542          NULL, NULL,
10543          NULL, NULL,
10544          SurfCont->DataTable);
10545    }
10546    /* a table for a voxel's label*/
10547    SUMA_LH("Creating label  table");
10548    {
10549       int colw[]={4, 26};
10550       SUMA_CreateTable(rcc,
10551          1, 2,
10552          "VolCont->Xhair_Info->Lbl",
10553          Label_tit, NULL,
10554          Label_hint, NULL,
10555          Label_help, NULL,
10556          colw, NOPE, SUMA_string,
10557          NULL, NULL,
10558          NULL, NULL,
10559          NULL, NULL,
10560          SurfCont->LabelTable);
10561    }
10562    XtManageChild(rcc);
10563    SUMA_RETURNe;
10564 
10565 }
10566 
10567 /* I suspect this will be a mixture of _VO and _SO */
SUMA_CreateXhairWidgets_CO(Widget parent,SUMA_ALL_DO * ado)10568 void SUMA_CreateXhairWidgets_CO(Widget parent, SUMA_ALL_DO *ado)
10569 {
10570    static char FuncName[]={"SUMA_CreateXhairWidgets_CO"};
10571    char *Xhair_tit[]=   {  "Xhr ", NULL};
10572    char *Xhair_hint[]=  {  "Crosshair coordinates.", NULL};
10573    char *Xhair_help[]=  {  SUMA_SurfContHelp_Xhr , NULL};
10574    char *I_tit[]=      { "Ind ", NULL };
10575    char *I_hint[] =    { "Voxel 1D index in volume", NULL };
10576    char *I_help[] =    { SUMA_VolContHelp_I, NULL };
10577    char *BTP_tit[]=    {  "IJK"   , NULL};
10578    char *BTP_hint[]=   {  "Voxel 3D indices in volume",
10579                            NULL};
10580    char *BTP_help[]=   {  SUMA_SurfContHelp_IJK , NULL};
10581    char *Data_tit[]=    {  "    ", "Intens", "Thresh", "Bright" , NULL};
10582    char *Data_colhint[]=      {  "Data Values at voxel in focus",
10583                                  "Intensity (I) value",
10584                                  "Threshold (T) value",
10585                                  "Brightness modulation (B) value" , NULL};
10586    char *Data_colhelp[]=      {  SUMA_VolContHelp_NodeValTblc0,
10587                                  SUMA_SurfContHelp_NodeValTblc1,
10588                                  SUMA_SurfContHelp_NodeValTblc2,
10589                                  SUMA_SurfContHelp_NodeValTblc3 , NULL};
10590 
10591    char *Data_rtit[]=      {  "    ", "Val " , NULL};
10592    char *Data_rowhint[]=   {  "Data values at voxel in focus",
10593                               "Data values at voxel in focus" , NULL};
10594    char *Data_rowhelp[]=   {  SUMA_SurfContHelp_NodeValTblr0,
10595                               SUMA_SurfContHelp_NodeValTblr0 , NULL};
10596 
10597    char *Label_tit[]=   {  "Lbl ", NULL};
10598    char *Label_hint[]=  {  "Label at voxel in focus", NULL};
10599    char *Label_help[]=  {  SUMA_SurfContHelp_NodeLabelTblr0 , NULL};
10600    SUMA_X_SurfCont *SurfCont=NULL;
10601    Widget rcc, rcch;
10602 
10603    SUMA_Boolean LocalHead = NOPE;
10604 
10605    SUMA_ENTRY;
10606 
10607    if (!ado || ado->do_type != CDOM_type || !(SurfCont = SUMA_ADO_Cont(ado))) {
10608       SUMA_RETURNe;
10609    }
10610 
10611    SUMA_S_Err("Fill me up scotty, premium dude, premium");
10612 
10613    SUMA_RETURNe;
10614 }
10615 
SUMA_CreateCmapWidgets(Widget parent,SUMA_ALL_DO * ado)10616 void SUMA_CreateCmapWidgets(Widget parent, SUMA_ALL_DO *ado)
10617 {
10618    static char FuncName[]={"SUMA_CreateCmapWidgets"};
10619    char slabel[100], wname[64]={"NoTsEt"}, *blk=NULL;
10620    Widget rct, rcc, rco;
10621    XtVarArgsList arglist=NULL;
10622    SUMA_X_SurfCont *SurfCont=NULL;
10623    SUMA_Boolean LocalHead = NOPE;
10624 
10625    SUMA_ENTRY;
10626 
10627    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) {
10628       SUMA_S_Err("NULL input");
10629       SUMA_RETURNe;
10630    }
10631 
10632    if (SurfCont->opts_rc) {
10633       SUMA_SL_Err("Non null opts_rc\nThis should not be.");
10634       SUMA_RETURNe;
10635    }
10636 
10637    if (ado->do_type == GRAPH_LINK_type) {
10638       blk = "GDset_Mapping";
10639    } else {
10640       blk = "Dset_Mapping";
10641    }
10642 
10643    SurfCont->opts_form = XtVaCreateWidget ("form",
10644       xmFormWidgetClass, parent,
10645       NULL);
10646 
10647    SurfCont->opts_rc = XtVaCreateWidget ("rowcolumn",
10648       xmRowColumnWidgetClass, SurfCont->opts_form,
10649       XmNpacking, XmPACK_TIGHT,
10650       XmNleftAttachment,XmATTACH_FORM ,
10651       XmNorientation , XmHORIZONTAL ,
10652       XmNmarginHeight , 0 ,
10653       XmNmarginWidth  , 0 ,
10654       NULL);
10655 
10656    SUMA_LH("Creating the threshold bar widgets");
10657    { /* the threshold bar */
10658       rct = XtVaCreateWidget ("rowcolumn",
10659          xmRowColumnWidgetClass, SurfCont->opts_rc,
10660          XmNpacking, XmPACK_TIGHT,
10661          XmNresizeHeight, False, /* important that this rc is not to be resized
10662                                     automatically,
10663                                     otherwise, the fix SUMA_FORCE_SCALE_HEIGHT
10664                                     will fail
10665                                    */
10666          XmNresizeWidth, False,
10667          XmNwidth, SUMA_SCALE_WIDTH,
10668          XmNheight,  SUMA_SCALE_HEIGHT,
10669          XmNorientation , XmVERTICAL ,
10670          XmNmarginHeight , 0 ,
10671          XmNmarginWidth  , 0 ,
10672          NULL);
10673       /* convenient common arguments for scales */
10674       arglist = XtVaCreateArgsList( NULL,
10675                                     XmNshowValue, True,
10676                                     XmNmaximum, 255,
10677                                     XmNscaleMultiple, 5,
10678                                     XmNheight,  SUMA_SCALE_HEIGHT,
10679                                     XmNuserData, (XtPointer)0,
10680                                     NULL);
10681 
10682       /* put a string on top of the scale
10683       Can use XmNtitleString but it is placed on the side.
10684       Too much waisted space */
10685       #if 0
10686       sprintf(slabel,"Thr.");
10687       SurfCont->thr_lb = XtVaCreateManagedWidget (slabel,
10688                                           xmLabelWidgetClass, rct,
10689                                           XmNwidth, SUMA_SCALE_WIDTH,
10690                                           XmNrecomputeSize, False,
10691                                              /* don't let it change size,
10692                                              it messes up the slider */
10693                                           NULL);
10694       #else
10695       {
10696          int colw[]={6};
10697          char *lhint[]={ "Threshold Value (append 'p' to set by p value, "
10698                          "'%' to set by percentile)", NULL};
10699          char *lhelp[]={ SUMA_SurfContHelp_SetThreshTblr0, NULL};
10700          if (!SurfCont->SetThrScaleTable->cells) {
10701             snprintf(wname, 63, "%s->%s->ThrVal",
10702                      SUMA_do_type_2_contwname(SurfCont->do_type), blk);
10703             SUMA_CreateTable( rct,
10704                               1, 1,
10705                               wname,
10706                               NULL, NULL,
10707                               lhint, NULL,
10708                               lhelp, NULL,
10709                               colw, YUP, SUMA_float,
10710                               SUMA_cb_SetScaleThr, (void *)ado,
10711                               NULL, NULL,
10712                               NULL, NULL,
10713                               SurfCont->SetThrScaleTable);
10714          }
10715       }
10716       #endif
10717       /* add a vertical scale for the intensity */
10718       SurfCont->thr_sc = XtVaCreateManagedWidget("Thr.",
10719                                           xmScaleWidgetClass, rct,
10720                                           XtVaNestedList, arglist,
10721                                           NULL);
10722 #ifdef USING_LESSTIF
10723    if (LocalHead) fprintf(stderr,"\n========= setting width to %d\n",
10724                                  SUMA_SCALE_SLIDER_WIDTH);
10725    XtVaSetValues( SurfCont->thr_sc,
10726                   XmNscaleWidth, SUMA_SCALE_SLIDER_WIDTH , NULL ) ;
10727 #endif
10728 
10729 
10730       XtAddCallback (SurfCont->thr_sc,
10731                      XmNvalueChangedCallback,
10732                      SUMA_cb_set_threshold,
10733                      (XtPointer) ado);
10734 
10735       XtAddCallback (SurfCont->thr_sc,
10736                      XmNdragCallback,
10737                      SUMA_cb_set_threshold_label,
10738                      (XtPointer) ado);
10739       snprintf(wname, 63, "%s->%s->Cmap->scale",
10740                SUMA_do_type_2_contwname(SurfCont->do_type), blk);
10741       SUMA_Register_Widget_Help(SurfCont->thr_sc , 1,
10742                                 wname,
10743                                 "Set the threshold for 'T' values",
10744                                 SUMA_SurfContHelp_ThrScale);
10745 
10746       /* put a string for the pvalue */
10747       sprintf(slabel,"p [N/A]\nq [N/A]");
10748       SurfCont->thrstat_lb = XtVaCreateManagedWidget ("font8",
10749                                           xmLabelWidgetClass, rct,
10750                                           XmNwidth, SUMA_SCALE_WIDTH,
10751                                           XmNrecomputeSize, False,
10752                                           LABEL_ARG(slabel),
10753                                           XmNinitialResourcesPersistent, False ,
10754                                           NULL);
10755 
10756       snprintf(wname, 63, "%s->%s->Cmap->pval",
10757                SUMA_do_type_2_contwname(SurfCont->do_type), blk);
10758       SUMA_Register_Widget_Help(SurfCont->thrstat_lb , 1,
10759                                 wname,
10760                                 "Nominal p-value per node; FDR q-value",
10761                                 SUMA_SurfContHelp_ThreshStats);
10762       XtManageChild (rct);
10763    }/* the threshold bar */
10764 
10765    if (arglist) XtFree(arglist); arglist = NULL;
10766 
10767    SUMA_LH("The colorbar");
10768    {/* the color bar */
10769       Widget rcc2;
10770       rcc = XtVaCreateWidget ("rowcolumn",
10771          xmRowColumnWidgetClass, SurfCont->opts_rc,
10772          XmNpacking, XmPACK_TIGHT,
10773          XmNorientation , XmVERTICAL ,
10774          XmNmarginHeight , 0 ,
10775          XmNmarginWidth  , 0 ,
10776          NULL);
10777 
10778       sprintf(slabel,"   ");
10779       SurfCont->cmaptit_lb = XtVaCreateManagedWidget (slabel,
10780                                           xmLabelWidgetClass, rcc,
10781                                           NULL);
10782       /* need another rc for the cmap to avoid having
10783       the glxarea resized by cmaptit_lb
10784       and SwitchCmapMenu */
10785       rcc2 = XtVaCreateWidget ("rowcolumn",
10786          xmRowColumnWidgetClass, rcc,
10787          XmNpacking, XmPACK_TIGHT,
10788          XmNorientation , XmHORIZONTAL ,
10789          XmNmarginHeight , 0 ,
10790          XmNmarginWidth  , 0 ,
10791          NULL);
10792 
10793       /* open me a glxarea */
10794       SUMA_LH("Forming glxarea");
10795       {
10796          #ifdef SUMA_MOTIF_GLXAREA
10797             SurfCont->cmp_ren->cmap_wid = XtVaCreateManagedWidget("glxarea",
10798                 glwMDrawingAreaWidgetClass, rcc2,
10799                 GLwNvisualInfo, SUMAg_SVv[0].X->VISINFO,
10800                 XtNcolormap, SUMAg_SVv[0].X->CMAP,
10801                 XmNwidth,   SUMA_CMAP_WIDTH,
10802                 XmNheight,  SUMA_CMAP_HEIGHT,
10803                 NULL);
10804          #else
10805             SurfCont->cmp_ren->cmap_wid =
10806                   XtVaCreateManagedWidget("glxarea",
10807                                           glwDrawingAreaWidgetClass, rcc2,
10808                                        GLwNvisualInfo, SUMAg_SVv[0].X->VISINFO,
10809                                           XtNcolormap, SUMAg_SVv[0].X->CMAP,
10810                                           XmNwidth,   SUMA_CMAP_WIDTH,
10811                                           XmNheight,  SUMA_CMAP_HEIGHT,
10812                                           NULL);
10813          #endif
10814          snprintf(wname, 63, "%s->%s->Cmap->bar",
10815                   SUMA_do_type_2_contwname(SurfCont->do_type), blk);
10816          SUMA_Register_Widget_Help(SurfCont->cmp_ren->cmap_wid ,1,
10817                                    wname,
10818                                    "Colorbar for 'I' values",
10819                                    SUMA_SurfContHelp_ColorBar);
10820          XtManageChild (rcc2);
10821 
10822          SUMA_LH("Callbacks on glxarea");
10823          /* add me some callbacks */
10824          XtAddCallback( SurfCont->cmp_ren->cmap_wid,
10825                         GLwNginitCallback, SUMA_cmap_wid_graphicsInit,
10826                         (XtPointer )ado);
10827          XtAddCallback( SurfCont->cmp_ren->cmap_wid,
10828                         GLwNexposeCallback, SUMA_cmap_wid_expose,
10829                         (XtPointer )ado);
10830          XtAddCallback( SurfCont->cmp_ren->cmap_wid,
10831                         GLwNresizeCallback, SUMA_cmap_wid_resize,
10832                         (XtPointer )ado);
10833          XtAddCallback( SurfCont->cmp_ren->cmap_wid,
10834                         GLwNinputCallback, SUMA_cmap_wid_input,
10835                         (XtPointer )ado);
10836       }
10837 
10838       if (SUMAg_CF->Fake_Cmap) {
10839          #define NPANE_MIN        2
10840          #define NPANE_MAX       20
10841          #define PANE_WIDTH      15
10842          #define PANE_MIN_HEIGHT  5
10843          #define PANE_LOFF        6
10844          #define PANE_SPACING     2
10845 
10846          #define PANE_MAXMODE     2
10847          #define SASH_HNO         1
10848          Widget frm, pw;
10849          SUMA_S_Warn("Creating X11 cmap for snapshot taking only!");
10850 
10851          /*
10852          frm = XtVaCreateManagedWidget( "pbar" , xmFrameWidgetClass , rcc2 ,
10853                                      XmNshadowType , XmSHADOW_ETCHED_IN ,
10854                                   NULL ) ;
10855 
10856          pw = XtVaCreateManagedWidget( "pbar" , xmPanedWindowWidgetClass , frm ,
10857                                       XmNsashWidth , PANE_WIDTH-2*PANE_SPACING,
10858                                       XmNsashIndent , PANE_SPACING ,
10859                                       XmNsashHeight , SASH_HNO ,
10860                                       XmNmarginHeight , 0 ,
10861                                       XmNmarginWidth , 0 ,
10862                                       XmNspacing , PANE_SPACING ,
10863                                       XmNx , 0 , XmNy , 0 ,
10864                                       XmNtraversalOn, True  ,
10865                                       XmNinitialResourcesPersistent , False ,
10866                                    NULL ) ;
10867          SurfCont->Fake_pbar = XtVaCreateWidget(
10868                           "pbar" , xmDrawnButtonWidgetClass , pw ,
10869                               XmNpaneMinimum , PANE_MIN_HEIGHT ,
10870                               XmNallowResize , True ,
10871                               XmNheight , SUMA_CMAP_HEIGHT ,
10872                               XmNwidth , PANE_WIDTH,
10873                               XmNborderWidth , 0 ,
10874                               XmNmarginWidth , 0 ,
10875                               XmNmarginHeight , 0 ,
10876                               XmNhighlightThickness , 0 ,
10877                               XmNpushButtonEnabled , True ,
10878                               XmNuserData , (XtPointer)ado ,
10879                               XmNtraversalOn , True ,
10880                               XmNinitialResourcesPersistent , False ,
10881                             NULL ) ;
10882          */
10883          SurfCont->Fake_pbar = XmCreateDrawingArea(rcc2, "pbar", NULL, 0);
10884          XtVaSetValues(SurfCont->Fake_pbar, XmNheight , SUMA_CMAP_HEIGHT ,
10885                               XmNwidth , SUMA_CMAP_WIDTH,
10886                               XmNallowResize , False ,
10887                               NULL);
10888          XtManageChild (SurfCont->Fake_pbar);
10889          XtManageChild (rcc2);
10890          XtAddCallback( SurfCont->Fake_pbar, XmNexposeCallback,
10891                         SUMA_PBAR_bigexpose_CB, (XtPointer )ado ) ;
10892          /* The following commands were part of a failed attempt
10893          at getting the rest of the widgets - sub-brick selectors
10894          etc. to appear when the glxarea drawing widget was not
10895          created. For some reason, little other than the X11 colormap
10896          would show if I did not create SurfCont->cmp_ren->cmap_wid
10897          above. Interestingly, commenting out the SurfCont->cmp_ren->cmap_wid
10898          callbacks above also had the same effect.
10899          So the solution is to render both and make one super thin. It is
10900          rendered in black anyway when the picture is snapped so it makes
10901          little difference in the end.                ZSS Nov 2014 */
10902          XtAddCallback( SurfCont->Fake_pbar,
10903                         XmNresizeCallback, SUMA_PBAR_bigresize_CB,
10904                         (XtPointer )ado);
10905          XtAddCallback( SurfCont->Fake_pbar,
10906                         XmNinputCallback, SUMA_PBAR_biginput_CB,
10907                         (XtPointer )ado);
10908          XtVaSetValues( SurfCont->cmp_ren->cmap_wid,
10909                         XmNheight , 1,
10910                         XmNwidth , 1,
10911                         NULL);
10912       }
10913 
10914       XtManageChild (rcc);
10915    }  /* the colorbar */
10916 
10917    /* The options will be created as needed, when colorplanes are switched.
10918    see SUMA_InitializeColPlaneShell */
10919 
10920    XtManageChild (SurfCont->opts_rc);
10921    XtManageChild (SurfCont->opts_form);
10922 
10923    SUMA_RETURNe;
10924 }
10925 
SUMA_FreeMenuVector(SUMA_MenuItem * menu,int Nels)10926 SUMA_MenuItem *SUMA_FreeMenuVector(SUMA_MenuItem *menu, int Nels)
10927 {
10928    static char FuncName[]={"SUMA_FreeMenuVector"};
10929    int i;
10930 
10931    SUMA_ENTRY;
10932 
10933    if (!menu) {SUMA_RETURN(NULL);}
10934    if (Nels <= 0) {SUMA_RETURN(NULL);}
10935 
10936    for (i=0; i<Nels; ++i) {
10937       if (menu[i].label) SUMA_free(menu[i].label);
10938       if (menu[i].accelerator) SUMA_free(menu[i].accelerator);
10939       if (menu[i].accel_text) SUMA_free(menu[i].accel_text);
10940       if (menu[i].subitems) {
10941          SUMA_SL_Err("Don't know how to free subitems yet."); }
10942    }
10943    SUMA_free(menu);
10944 
10945    SUMA_RETURN(NULL);
10946 }
10947 
SUMA_FormSwitchColMenuVector(SUMA_ALL_DO * ado,int what,int * N_items)10948 SUMA_MenuItem *SUMA_FormSwitchColMenuVector(SUMA_ALL_DO *ado,
10949                                             int what, int *N_items)
10950 {
10951    static char FuncName[]={"SUMA_FormSwitchColMenuVector"};
10952    SUMA_MenuItem *menu = NULL;
10953    int i, isarrow;
10954    void (*callback)();
10955    NI_element *nel = NULL;
10956    SUMA_X_SurfCont *SurfCont=NULL;
10957    SUMA_OVERLAYS *curColPlane=NULL;
10958    SUMA_Boolean LocalHead = NOPE;
10959 
10960    SUMA_ENTRY;
10961 
10962    if (!ado) { SUMA_SL_Err("NULL ado"); SUMA_RETURN (menu);}
10963 
10964    SurfCont = SUMA_ADO_Cont(ado);
10965    curColPlane = SUMA_ADO_CurColPlane(ado);
10966 
10967 
10968    if (!SurfCont) { SUMA_SL_Err("NULL SurfCont"); SUMA_RETURN (menu);}
10969    if (!curColPlane) {
10970       SUMA_SL_Err("NULL curColPlane"); SUMA_RETURN (menu);}
10971    if (!curColPlane->dset_link) {
10972       SUMA_SL_Err("NULL curColPlane->dset_link");
10973       SUMA_RETURN (menu);}
10974 
10975    nel = curColPlane->dset_link->dnel;
10976    if (!nel) { SUMA_SL_Err("NULL nel"); SUMA_RETURN (menu);}
10977    if (!nel->vec_num) { SUMA_SL_Err("no vecs"); SUMA_RETURN (menu);}
10978 
10979    /* decide on callback */
10980    switch (what) {
10981       case 0:
10982          callback = SUMA_cb_SwitchIntensity;
10983          break;
10984       case 1:
10985          callback = SUMA_cb_SwitchThreshold;
10986          break;
10987       case 2:
10988          callback = SUMA_cb_SwitchBrightness;
10989          break;
10990       default:
10991          SUMA_SL_Err("No such what");
10992          SUMA_RETURN(menu);
10993    }
10994 
10995    /* Allocate for menu */
10996    menu = (SUMA_MenuItem *)SUMA_calloc((nel->vec_num+1), sizeof(SUMA_MenuItem));
10997    isarrow = SUMA_AllowArrowFieldMenus((nel->vec_num+1), "I");
10998                                           /* "I", or "B", or "T" OK */
10999 
11000    /* fillup menu */
11001    for (i=0; i < nel->vec_num; ++i) {
11002       if (!isarrow) {
11003          menu[i].label =
11004             SUMA_DsetColLabelCopy(curColPlane->dset_link, i, 1);
11005       } else {
11006          /* SUMA_DsetColLabelCopy is slow as a dog for very large numbers
11007             of sub-bricks. In any case, sub-brick labels are not that
11008             important here, this should be improved someday*/
11009          menu[i].label = (char*)malloc(13*sizeof(char));
11010          snprintf(menu[i].label,11*sizeof(char), "sb%d", i-1);
11011       }
11012       menu[i].class = &xmPushButtonWidgetClass;
11013       menu[i].mnemonic = '\0';
11014       menu[i].accelerator = NULL;
11015       menu[i].accel_text = NULL;
11016       menu[i].callback = callback;
11017       menu[i].callback_data = (XTP_CAST)(i+1); /* DO NOT USE THE zeroth item */
11018       menu[i].subitems = NULL;
11019    }
11020 
11021    /* add the stop sign. That's what SUMA_BuildMenu uses to figure out the
11022       number of elements */
11023    menu[nel->vec_num].label = NULL;
11024 
11025    *N_items = nel->vec_num;
11026 
11027    SUMA_RETURN (menu);
11028 }
11029 
SUMA_ShowMeTheChildren(Widget w)11030 void SUMA_ShowMeTheChildren(Widget w) {
11031    SUMA_DoForTheChildren(w,0, 0, 0);
11032 }
11033 
SUMA_UnmanageTheChildren(Widget w)11034 void SUMA_UnmanageTheChildren(Widget w) {
11035    SUMA_DoForTheChildren(w, -1, 0, 0);
11036 }
SUMA_ManageTheChildren(Widget w)11037 void SUMA_ManageTheChildren(Widget w) {
11038    SUMA_DoForTheChildren(w, 1, 0, 0);
11039 }
11040 
11041 /*!
11042    Perform operation on the children of a widget
11043    i = 0: Write out the names of the widgets
11044        1: Manage widgets
11045       -1: Unmanage widgets
11046 */
SUMA_DoForTheChildren(Widget w,int i,int lvl,int rec)11047 void SUMA_DoForTheChildren(Widget w, int i, int lvl, int rec)
11048 {
11049    static char FuncName[]={"SUMA_DoForTheChildren"};
11050    Widget * children = NULL;
11051    int  num_children=0, num_children2=0, ic , Nbutt=0, kk=0;
11052    SUMA_Boolean LocalHead = NOPE;
11053 
11054    SUMA_ENTRY;
11055 
11056    XtVaGetValues( w ,         XmNchildren    , &children ,
11057                               XmNnumChildren , &num_children ,
11058                               XmNbuttonCount, &Nbutt,
11059                               NULL ) ;
11060    for( ic=0 ; ic < num_children ; ic++ ){
11061       if (rec) { /* recursive, but ugly output */
11062          XtVaGetValues( children[ic] , XmNnumChildren , &num_children2, NULL);
11063          if (num_children2) SUMA_DoForTheChildren(children[ic],i, lvl+1, rec);
11064       }
11065       if (LocalHead) {
11066          /* what's the name jane ? */
11067          XtVaGetValues (children[ic], XmNbuttonCount, &Nbutt, NULL);
11068          for (kk=0; kk<lvl; ++kk) fprintf (SUMA_STDERR,"  ");
11069          fprintf (SUMA_STDERR,   "%d.%d: %s (%d N_butts)\n",
11070                                  lvl, ic, XtName(children[ic]), Nbutt);
11071       }
11072       switch (i) {
11073          case 1:
11074             XtManageChild(children[ic]);
11075             break;
11076          case -1:
11077             XtUnmanageChild(children[ic]);
11078             break;
11079          case 0:
11080             /* what's the name jane ? */
11081             XtVaGetValues (children[ic], XmNbuttonCount, &Nbutt, NULL);
11082             for (kk=0; kk<lvl; ++kk) fprintf (SUMA_STDERR,"  ");
11083             fprintf (SUMA_STDERR,   "%d.%d: %s (%d N_butts)\n",
11084                                      lvl,  ic, XtName(children[ic]), Nbutt);
11085             break;
11086          default:
11087             SUMA_S_Err("Action %d unknown", i);
11088             SUMA_RETURNe;
11089       }
11090    }
11091 
11092    if (i==0 || LocalHead) {
11093       for (kk=0; kk<lvl; ++kk) fprintf (SUMA_STDERR,"  ");
11094       fprintf (SUMA_STDERR,
11095             "%s: Widget '%s' (lvl %d) has (%d) children (%d N_butts):\n",
11096             FuncName, XtName(w), lvl, num_children, Nbutt);
11097    }
11098    SUMA_RETURNe;
11099 }
11100 
SUMA_FindChildWidgetNamed(Widget w,char * name)11101 Widget SUMA_FindChildWidgetNamed(Widget w, char *name)
11102 {
11103    static char FuncName[]={"SUMA_FindChildWidgetNamed"};
11104    Widget * children = NULL;
11105    int  num_children=0, num_children2=0, ic , Nbutt=0, kk=0;
11106    char *wn;
11107    SUMA_Boolean LocalHead = NOPE;
11108 
11109    SUMA_ENTRY;
11110    if (!w || !name) SUMA_RETURN(NULL);
11111    XtVaGetValues( w ,         XmNchildren    , &children ,
11112                               XmNnumChildren , &num_children ,
11113                               XmNbuttonCount, &Nbutt,
11114                               NULL ) ;
11115    for( ic=0 ; ic < num_children ; ic++ ){
11116       if ((wn = XtName(children[ic]))) {
11117          if (!strcmp(wn,name)) SUMA_RETURN(children[ic]);
11118       }
11119    }
11120    SUMA_RETURN(NULL);
11121 }
11122 
SUMA_FormSwitchCmapMenuVector(SUMA_COLOR_MAP ** CMv,int N_maps)11123 SUMA_MenuItem *SUMA_FormSwitchCmapMenuVector(SUMA_COLOR_MAP **CMv, int N_maps)
11124 {
11125    static char FuncName[]={"SUMA_FormSwitchCmapMenuVector"};
11126    SUMA_MenuItem *menu = NULL;
11127    int i;
11128    void (*callback)();
11129    NI_element *nel = NULL;
11130    SUMA_Boolean LocalHead = NOPE;
11131 
11132    SUMA_ENTRY;
11133 
11134    if (!CMv) { SUMA_SL_Err("NULL CMv"); SUMA_RETURN (menu);}
11135    if (N_maps <=0) { SUMA_SL_Err("N_maps <=0"); SUMA_RETURN (menu);}
11136 
11137    callback = SUMA_cb_SwitchCmap;
11138 
11139    /* Allocate for menu */
11140    menu = (SUMA_MenuItem *)SUMA_calloc((N_maps+1),sizeof(SUMA_MenuItem));
11141 
11142    /* fillup menu */
11143    for (i=0; i < N_maps; ++i) {
11144       menu[i].label = SUMA_copy_string(CMv[i]->Name);
11145       menu[i].class = &xmPushButtonWidgetClass;
11146       menu[i].mnemonic = '\0';
11147       menu[i].accelerator = NULL;
11148       menu[i].accel_text = NULL;
11149       menu[i].callback = callback;
11150       menu[i].callback_data = (XtPointer)CMv[i];
11151                         /* (used to be i+1)DO NOT USE THE 0 for the first button.                            0th index is reserved for the rc widget */
11152       menu[i].subitems = NULL;
11153    }
11154 
11155    /* add the stop sign. That's what SUMA_BuildMenu uses to figure out \
11156    the number of elements */
11157    menu[N_maps].label = NULL;
11158 
11159    SUMA_RETURN (menu);
11160 }
11161 
11162 /* This one here, recalculates the p and q value for a new threshold
11163 and displays the results on the widget
11164 */
SUMA_UpdatePvalueField(SUMA_ALL_DO * ado,float thresh)11165 void SUMA_UpdatePvalueField (SUMA_ALL_DO *ado, float thresh)
11166 {/* set the pvalue */
11167    static char FuncName[]={"SUMA_UpdatePvalueField"};
11168    float p[3], zval = -1.0;
11169    int statcode;
11170    SUMA_X_SurfCont *SurfCont=NULL;
11171    SUMA_OVERLAYS *curColPlane=NULL;
11172    SUMA_Boolean LocalHead = NOPE;
11173 
11174    SUMA_ENTRY;
11175 
11176    if (!ado) {
11177       SUMA_SL_Err("NULL ado");
11178       SUMA_RETURNe;
11179    }
11180    SurfCont = SUMA_ADO_Cont(ado);
11181    curColPlane = SUMA_ADO_CurColPlane(ado);
11182 
11183    if (!SurfCont ||
11184        !SurfCont->thr_sc ||
11185        !curColPlane ||
11186        !curColPlane->dset_link) {
11187       SUMA_SL_Err("NULL SurfCont");
11188       SUMA_RETURNe;
11189    }
11190 
11191    /* see if you can get the stat codes */
11192    if (!SUMA_GetDsetColStatAttr(
11193             curColPlane->dset_link,
11194             curColPlane->OptScl->tind,
11195             &statcode,
11196             p, (p+1), (p+2))) {
11197       SUMA_LH("Error");
11198    }else if (statcode) {
11199       SUMA_LHv("Have stats at sb %d\n"
11200                "statcode %d: %f %f %f\n",
11201                curColPlane->OptScl->tind,
11202                statcode, p[0], p[1], p[2]);
11203       curColPlane->OptScl->ThreshStats[0] =
11204             THD_stat_to_pval( thresh , statcode , p  ) ;
11205 
11206       SUMA_LHv("Have pval of %f\n",
11207                curColPlane->OptScl->ThreshStats[0]);
11208       if( curColPlane->OptScl->ThreshStats[0] >= 0.0 ){
11209          SUMA_LH("zvaling ...\n")
11210          zval = SUMA_fdrcurve_zval(
11211                            curColPlane->dset_link,
11212                            curColPlane->OptScl->tind,
11213                            thresh) ;
11214          if( zval > 0.0f ){
11215             curColPlane->OptScl->ThreshStats[1] =
11216                      2.0*qg(zval) ;         /* convert z back to FDR q */
11217          }
11218       }
11219    } else {
11220       /* no stats */
11221       curColPlane->OptScl->ThreshStats[0] = -1.0;
11222       curColPlane->OptScl->ThreshStats[1] = -1.0;
11223    }
11224    SUMA_LHv("statcode %d: %f %f %f\n"
11225             "Thresh %f, p %f, q %f\n",
11226             statcode, p[0], p[1], p[2],
11227             thresh,
11228             curColPlane->OptScl->ThreshStats[0],
11229             curColPlane->OptScl->ThreshStats[1]);
11230 
11231 
11232    { /* form the text, a la afni */
11233       char buf[100]={"Rien"};
11234       float pval = curColPlane->OptScl->ThreshStats[0];
11235       float qval = curColPlane->OptScl->ThreshStats[1];
11236       if( pval < 0.0 ){
11237         strcpy( buf , "p=N/A") ;
11238       } else {
11239         if( pval == 0.0 ){
11240           strcpy( buf , "p=0" ) ;
11241         } else if( pval >= 0.9999 ){
11242           strcpy( buf , "p=1" ) ;
11243         } else if( pval >= 0.0010 ){
11244           char qbuf[16] ;
11245           sprintf( qbuf , "%5.4f" , pval ) ;
11246           strcpy(buf,"p=");
11247           SUMA_strncat(buf,qbuf+1,99);/*qbuf+1 skips leading 0*/
11248         } else {
11249           int dec = (int)(0.999 - log10(pval)) ;
11250           zval = pval * pow( 10.0 , (double) dec ) ;  /* between 1 and 10 */
11251           if( dec < 10 ) sprintf( buf , "p=%3.1f-%1d" ,           zval , dec ) ;
11252           else           sprintf( buf , "p=%1d.-%2d"  , (int)rint(zval), dec ) ;
11253         }
11254       }
11255       if( qval > 0.0f && qval < 0.9999 ){
11256          char qbuf[16] ;
11257          if( qval >= 0.0010 ) sprintf(qbuf,"%5.4f",qval) ;
11258          else {
11259            int dec = (int)(0.999 - log10(qval)) ;
11260            zval = qval * pow( 10.0 , (double)dec ) ;  /* between 1 and 10 */
11261            if( dec < 10 ) sprintf( qbuf, " %3.1f-%1d",            zval, dec );
11262            else           sprintf( qbuf, " %1d.-%2d" , (int)rint(zval), dec );
11263          }
11264          strcat(buf,"\nq=") ; SUMA_strncat(buf,qbuf+1,99) ;
11265       } else {
11266          SUMA_strncat(buf,"\nq=N/A",99) ;
11267       }
11268 
11269       MCW_set_widget_label( SurfCont->thrstat_lb, buf );
11270    }
11271 
11272    SUMA_RETURNe;
11273 }
11274 
11275 
SUMA_SetScaleRange(SUMA_ALL_DO * ado,double range[2])11276 void SUMA_SetScaleRange(SUMA_ALL_DO *ado, double range[2])
11277 {
11278    static char FuncName[]={"SUMA_SetScaleRange"};
11279    int min_v, max_v, scl, dec, cv=0;
11280    Widget w ;
11281    double dtmp, rmult;
11282    char slabel[100];
11283    static int nwarn = 0;
11284    SUMA_X_SurfCont *SurfCont=NULL;
11285    SUMA_OVERLAYS *curColPlane=NULL;
11286    SUMA_Boolean LocalHead = NOPE;
11287 
11288    SUMA_ENTRY;
11289 
11290    if (!ado) {
11291       SUMA_SL_Err("NULL ado");
11292       SUMA_RETURNe;
11293    }
11294    SurfCont = SUMA_ADO_Cont(ado);
11295    curColPlane = SUMA_ADO_CurColPlane(ado);
11296 
11297    rmult = (double)SUMA_floatEnv("SUMA_Range_Multiplier", 0.0) ;
11298    if (rmult > 0.0f && rmult != 1.0f) {
11299       SUMA_LHv("Applying range multipler of %f\n", rmult);
11300       range[0] = range[0]*rmult;
11301       range[1] = range[1]*rmult;
11302    }
11303 
11304    if (!SurfCont->thr_sc) {
11305       SUMA_SL_Err("NULL widget");
11306       SUMA_RETURNe;
11307    }
11308 
11309    w = SurfCont->thr_sc;
11310 
11311    if (range[1] <= range[0]) range[1] = range[0] + 1;
11312 
11313    if (curColPlane->OptScl->ThrMode == SUMA_ABS_LESS_THAN) {
11314       SUMA_LH("Absolutizing Threshold Range");
11315       if (fabs((double)range[0]) > fabs((double)range[1])) {
11316          range[1] = fabs((double)range[0]); range[0] = 0.0;
11317       } else {
11318          range[1] = fabs((double)range[1]); range[0] = 0.0;
11319       }
11320    } else if (curColPlane->OptScl->ThrMode == SUMA_LESS_THAN) {
11321 
11322    } else {
11323       SUMA_S_Err("Not ready for ThrModeR == %d", curColPlane->OptScl->ThrMode);
11324    }
11325    if (range[1] - range[0] > pow(10.0,SUMAg_CF->SUMA_ThrScalePowerBias)) {
11326       /* no need for power */
11327       dec = 0;
11328       if (range[0] > MRI_maxint) min_v=MRI_maxint;
11329       else if (range[0] < -MRI_maxint) min_v=-MRI_maxint;
11330       else min_v = (int)(range[0] );
11331       if (range[1] > MRI_maxint) max_v=MRI_maxint;
11332       else if (range[1] < -MRI_maxint) max_v=-MRI_maxint;
11333       else max_v = (int)(range[1] );
11334       dtmp = 2.0*(max_v-min_v)/MRI_maxint;
11335       if (dtmp >= 0.499) {
11336          /* See comment for similar block below */
11337          if (!nwarn)
11338             SUMA_S_Warn( "Data range too big for threshold scale.\n"
11339                          "Range will be trimmed.\n"
11340                          "Similar messages will be muted");
11341           ++nwarn;
11342          /* Range cannot be too big.
11343                X11 Warning 1:
11344                Name: Thr.
11345                Class: XmScale
11346                (Maximum - minimum) cannot be greater than INT_MAX / 2;
11347                minimum has been set to zero,
11348                maximum may have been set to (INT_MAX/2).
11349          */
11350          max_v /= (dtmp+0.01);
11351          min_v /= (dtmp+0.01);
11352       }
11353       scl = (max_v -min_v) / 10;
11354    } else {
11355       /* what power of 10 is needed (based on Bob's settings in afni_wid.c)? */
11356       dec = (int)ceil( log((double)(range[1] - range[0] + 0.001)) / log (10) );
11357       /* Add the scale bias, so that dec is at least = bias*/
11358       if (dec < SUMAg_CF->SUMA_ThrScalePowerBias)
11359          dec = SUMAg_CF->SUMA_ThrScalePowerBias;
11360       dtmp = (range[0] * pow(10.0, dec));
11361       if (dtmp > MRI_maxint) min_v=MRI_maxint;
11362       else if (dtmp < -MRI_maxint) min_v=-MRI_maxint;
11363       else min_v = (int)(dtmp);
11364       dtmp = range[1] * pow(10.0, dec);
11365       if (dtmp > MRI_maxint) max_v=MRI_maxint;
11366       else if (dtmp < -MRI_maxint) max_v=-MRI_maxint;
11367       else max_v = (int)(dtmp + 0.001);
11368       dtmp = 2.0*(max_v-min_v)/MRI_maxint;
11369       if (dtmp >= 0.499) {
11370          /* Perhaps I should include a scale value multiplier = 1/dtmp
11371             so that users can still get the full range.
11372             Problem is that users will not see the proper value
11373             on the silder bar, unless I start setting it explicitly
11374             in the widget. Best to wait and see who'd need it. */
11375          if (!nwarn)
11376             SUMA_S_Warn( "Data range too big for threshold scale.\n"
11377                          "Range will be trimmed\n"
11378                          "Similar messages will be muted");
11379           ++nwarn;
11380           /* Range cannot be too big.
11381                X11 Warning 1:
11382                Name: Thr.
11383                Class: XmScale
11384                (Maximum - minimum) cannot be greater than INT_MAX / 2;
11385                minimum has been set to zero,
11386                maximum may have been set to (INT_MAX/2).
11387          */
11388          max_v /= (dtmp+0.01);
11389          min_v /= (dtmp+0.01);
11390       }
11391 
11392       scl = (max_v -min_v) / 10;
11393    }
11394 
11395    if (max_v <= min_v || scl < 0) {
11396       /* happens when max_v is so large that you get trash when typecast to int.
11397          That's the case when you're using the number of nodes in a surface
11398          for example and you set dec to something demented like 6 !
11399          Need a clever function here */
11400       SUMA_SLP_Note("Bad auto scaling \nparameters for threshold bar.\n"
11401                     "Using defaults");
11402       min_v = (int)(range[0]);
11403       max_v = (int)(range[1])+1;
11404       scl = (max_v - min_v) / 10;
11405       dec = 1;
11406    }
11407 
11408    #if 0
11409    /* make sure the current value is not less than the min or greater
11410       than the max */
11411    XtVaGetValues(w, XmNvalue, &cv, NULL);
11412    #else
11413    /* what was the slider's previous value in this dset ?*/
11414    dtmp = curColPlane->OptScl->ThreshRange[0] * pow(10.0, dec);
11415    if (dtmp > 0) cv = (int) (dtmp+0.5);
11416    else cv = (int) (dtmp-0.5);
11417    #endif
11418 
11419    if (LocalHead)
11420       fprintf (SUMA_STDERR,
11421                "%s:\n"
11422                " min %d max %d scalemult %d decimals %d\n"
11423                "Current scale value %d\n",
11424                   FuncName, min_v, max_v, scl, dec, cv);
11425    if (cv < min_v) {
11426       cv = min_v;
11427       /* must update threshold value in options structure*/
11428       curColPlane->OptScl->ThreshRange[0] =
11429          (float)cv / pow(10.0, dec);
11430    } else if (cv > max_v) {
11431       cv = max_v;
11432       curColPlane->OptScl->ThreshRange[0] =
11433          (float)cv / pow(10.0, dec);
11434    }
11435    /* set the slider bar */
11436    XtVaSetValues(w,
11437             XmNmaximum, max_v,
11438             XmNminimum, min_v,
11439             XmNvalue, cv,
11440             XmNscaleMultiple, scl,
11441             XmNdecimalPoints , dec,
11442             XmNuserData, (XTP_CAST)dec,
11443             NULL);
11444 
11445    /* set the label on top */
11446    if (curColPlane->OptScl->ThrMode != SUMA_ABS_LESS_THAN) {
11447       sprintf(slabel, "%5s", MV_format_fval((float)cv / pow(10.0, dec)));
11448    } else if (curColPlane->OptScl->ThrMode != SUMA_LESS_THAN){
11449       /* used to use this:
11450       sprintf(slabel, "|%5s|", ....
11451       but that does not work in the editable field ... */
11452       sprintf(slabel, "%5s", MV_format_fval((float)cv / pow(10.0, dec)));
11453    } else {
11454          SUMA_S_Err("Not ready to handle ThrModeR of %d yet",
11455                      curColPlane->OptScl->ThrMode);
11456    }
11457    /* SUMA_SET_LABEL(SurfCont->thr_lb,  slabel);*/
11458       SUMA_INSERT_CELL_STRING(SurfCont->SetThrScaleTable, 0,0,slabel);
11459 
11460    SUMA_UpdatePvalueField (ado,
11461                            curColPlane->OptScl->ThreshRange[0]);
11462 
11463    SUMA_RETURNe;
11464 }
11465 
11466 
11467 /*!
11468    \brief A function to update the field showing
11469    Xhair coordinates.
11470    Xhair is a property of the viewer rather than
11471    the surface but it makes more sense to display
11472    the coordinates, in certain cases, in the
11473    surface controllers
11474 */
SUMA_UpdateXhairField(SUMA_SurfaceViewer * sv)11475 SUMA_Boolean SUMA_UpdateXhairField(SUMA_SurfaceViewer *sv)
11476 {
11477    static char FuncName[]={"SUMA_UpdateXhairField"};
11478    int i=0, N_SOlist=0, SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS];
11479    SUMA_DO *dov = SUMAg_DOv;
11480    SUMA_ALL_DO *ado=NULL, *curDO=NULL;
11481    SUMA_X_SurfCont *SurfCont=NULL;
11482    SUMA_OVERLAYS *curColPlane=NULL;
11483    char str[100]={""};
11484    SUMA_Boolean LocalHead = NOPE;
11485 
11486    SUMA_ENTRY;
11487 
11488    if (!sv) SUMA_RETURN(NOPE);
11489 
11490    /* Which abjects are visible in this SV ? */
11491    N_SOlist = SUMA_Selectable_ADOs(sv, dov, SOlist);
11492    for (i=0; i<N_SOlist; ++i) {
11493       SUMA_LHv("working %d/%d shown surfaces/DOs ...\n", i, N_SOlist);
11494       ado = (SUMA_ALL_DO *)dov[SOlist[i]].OP;
11495       SurfCont = SUMA_ADO_Cont(ado);
11496       curColPlane = SUMA_ADO_CurColPlane(ado);
11497       if (ado->do_type == MASK_type) {/* No cross hair tricks */
11498          SUMA_RETURN(YUP);
11499       }
11500       if (SurfCont) { /* does this surface have surface controller ? */
11501          /* is this controller, displaying information for that surface ? */
11502          SUMA_LHv("Working controller for %s\n", SUMA_ADO_Label(ado));
11503          if (!(curDO = SUMA_SurfCont_GetcurDOp(SurfCont))) {
11504             SUMA_LH("No curDOp"); /* that's OK, happens when controller not
11505                                      yet created for this DO */
11506             continue;
11507          }
11508          if (curDO == ado) {
11509            /* OK, show the coordinate */
11510             SUMA_LHv("Setting cross hair at %f %f %f\n",
11511                                     sv->Ch->c[0],sv->Ch->c[1],sv->Ch->c[2]);
11512             SUMA_XHAIR_STRING(sv->Ch->c, str);
11513             SUMA_LH("%s",str);
11514             XtVaSetValues(SurfCont->XhairTable->cells[1],
11515                            XmNvalue, str, NULL);
11516             SUMA_UpdateCrossHairNodeLabelField(sv);
11517          }
11518       }
11519 
11520    }
11521 
11522    SUMA_RETURN(YUP);
11523 
11524 }
11525 
SUMA_UpdateNodeField(SUMA_ALL_DO * ado)11526 SUMA_Boolean SUMA_UpdateNodeField(SUMA_ALL_DO *ado)
11527 {
11528    static char FuncName[]={"SUMA_UpdateNodeField"};
11529    int i=0;
11530    SUMA_OVERLAYS *Sover=NULL, *targetSover=NULL;
11531    NI_group *ngr=NULL;
11532    DListElmt *el=NULL;
11533    SUMA_CALLBACK *cb=NULL;
11534    char *targetSO_idcode=NULL, *targetSover_name=NULL, *lbls=NULL;
11535    SUMA_X_SurfCont *SurfCont=NULL;
11536    SUMA_Boolean LocalHead = NOPE;
11537 
11538    SUMA_ENTRY;
11539 
11540    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) SUMA_RETURN(NOPE);
11541    SUMA_LHv("Entry, SurfCont=%p, ado %p\n",
11542             ado,   SurfCont);
11543    if (LocalHead) SUMA_DUMP_TRACE("Who Called Me?");
11544    if (!SUMA_isSurfContWidgetCreated(SurfCont)) {
11545       /* No controller created yet, return quietly */
11546       SUMA_RETURN(YUP);
11547    }
11548    Sover = SUMA_ADO_CurColPlane(ado);
11549    SUMA_LHv("Sover %p, ado type %d %s, callbacks %p, HoldClickCallbacks %d\n",
11550          Sover, ado->do_type, SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type),
11551          SUMAg_CF->callbacks, SUMAg_CF->HoldClickCallbacks);
11552    switch (ado->do_type) {
11553       case SO_type: {
11554          SUMA_SurfaceObject *curSO=NULL, *targetSO=NULL, *SO=NULL;
11555          SO = (SUMA_SurfaceObject *)ado;
11556          if (!(curSO =(SUMA_SurfaceObject *)SUMA_SurfCont_GetcurDOp(SurfCont))) {
11557             SUMA_S_Err("Failed to get curDOp");
11558             SUMA_RETURN(NOPE);
11559          }
11560 
11561          /* Do we have click callbacks pending? */
11562          if (SUMAg_CF->callbacks && !SUMAg_CF->HoldClickCallbacks) {
11563             el = dlist_head(SUMAg_CF->callbacks);
11564             while (el) {
11565                cb = (SUMA_CALLBACK *)el->data;
11566                if (  cb->event == SUMA_NEW_NODE_ACTIVATE_EVENT &&
11567                      cb->active > 0 &&
11568                      cb->pending) {
11569                   SUMA_LHv("Calling active pending click callback %s\n",
11570                            cb->FunctionName);
11571                   if (!SUMA_ExecuteCallback(cb, 1, ado, 0)) {
11572                      SUMA_S_Err("Failed to execute callback");
11573                      break;
11574                   }
11575                } else {
11576                   if (cb->active == -1) {
11577                      SUMA_LH("Callback inactive");
11578                   }
11579                }
11580                el = dlist_next(el);
11581             }
11582          }
11583 
11584          if (SUMA_isRelated_SO(SO, curSO, 1)) {
11585             SUMA_LH( "Updating GUI Node Fields, "
11586                      "whereami is handled in SUMA_UpdateNodeLblField");
11587             SUMA_UPDATE_ALL_NODE_GUI_FIELDS(ado);
11588          } else {
11589             SUMA_LH("No GUI Node Field Updates, but may use a whereami update");
11590             if (SUMAg_CF->X->Whereami_TextShell) {
11591                lbls = SUMA_GetLabelsAtSelection(ado, SO->SelectedNode, -1);
11592                if (lbls) SUMA_free(lbls); lbls = NULL;
11593             }
11594          }
11595 
11596          if (  !SO->SurfCont->ShowCurForeOnly ||
11597                SO->SurfCont->GraphHidden) {   /* graph updating can be done
11598                                                 for all planes */
11599             for (i=0; i<SO->N_Overlays; ++i) {
11600                Sover = SO->Overlays[i];
11601                if (     Sover
11602                      && Sover->dset_link
11603                      && Sover->rowgraph_mtd ) {
11604                   SUMA_OverlayGraphAtNode(Sover,
11605                                           (SUMA_ALL_DO *)SO,
11606                                           SO->SelectedNode);
11607                }
11608             }
11609          } else {
11610             Sover = SO->SurfCont->curColPlane;
11611             if (     Sover
11612                      && Sover->dset_link
11613                      && Sover->rowgraph_mtd ) {
11614                   SUMA_OverlayGraphAtNode(Sover,
11615                                           (SUMA_ALL_DO *)SO,
11616                                           SO->SelectedNode);
11617                }
11618          }
11619          break; }
11620       case GDSET_type: {
11621          SUMA_S_Err("Should not call with this type DO because without\n"
11622                     "a variant it cannot be displayed");
11623          SUMA_RETURN(NOPE);
11624          break; }
11625       case CDOM_type:
11626       case VO_type:
11627       case TRACT_type:
11628       case GRAPH_LINK_type:
11629          {
11630          SUMA_ALL_DO *curado=NULL;
11631          if (LocalHead && ado->do_type ==  GRAPH_LINK_type) {
11632             SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
11633             SUMA_DSET *dset=NULL;
11634             if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
11635                SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
11636                            SUMA_ADO_Label(ado));
11637                SUMA_RETURN(NOPE);
11638             }
11639          }
11640 
11641          if (!(curado = SUMA_SurfCont_GetcurDOp(SurfCont))) {
11642             SUMA_S_Err("Failed to get curDOp");
11643             break;
11644          }
11645          SUMA_LHv("Working %s, curado %s on label %s\n",
11646                   ADO_TNAME(ado), ADO_TNAME(curado), ADO_LABEL(ado));
11647 
11648          /* Do we have click callbacks pending? */
11649          if (SUMAg_CF->callbacks && !SUMAg_CF->HoldClickCallbacks) {
11650             el = dlist_head(SUMAg_CF->callbacks);
11651             while (el) {
11652                cb = (SUMA_CALLBACK *)el->data;
11653                if (  cb->event == SUMA_NEW_NODE_ACTIVATE_EVENT &&
11654                      cb->active > 0 &&
11655                      cb->pending) {
11656                   SUMA_S_Warnv("Click callback %s disabled on graphs\n",
11657                                cb->FunctionName);
11658                   #if 0 /* will need to deal with this when the need arises */
11659                   if (!SUMA_ExecuteCallback(cb, 1, ado, 0)) {
11660                      SUMA_S_Err("Failed to execute callback");
11661                      break;
11662                   }
11663                   #endif
11664                } else {
11665                   if (cb->active == -1) {
11666                      SUMA_LH("Callback inactive");
11667                   }
11668                }
11669                el = dlist_next(el);
11670             }
11671          }
11672 
11673          if (SUMA_isRelated(ado, curado, 1)) {
11674             SUMA_LH( "Updating GUI Node Fields, "
11675                      "whereami is handled in SUMA_UpdateNodeLblField");
11676             SUMA_UPDATE_ALL_NODE_GUI_FIELDS(ado);
11677          } else {
11678             SUMA_LH("No GUI Node Field Updates, but may use a whereami update");
11679             if (SUMAg_CF->X->Whereami_TextShell) {
11680                lbls = SUMA_GetLabelsAtSelection(ado,
11681                                          SUMA_ADO_SelectedDatum(ado, NULL, NULL),
11682                                              SUMA_ADO_SelectedSecondary(ado));
11683                if (lbls) SUMA_free(lbls); lbls = NULL;
11684             }
11685          }
11686 
11687          SUMA_LH("On to graphing");
11688          if (  !SurfCont->ShowCurForeOnly ||
11689                         SurfCont->GraphHidden) {   /* graph updating can be done
11690                                                       for all planes */
11691             for (i=0; i<SUMA_ADO_N_Overlays(ado); ++i) {
11692                Sover = SUMA_ADO_Overlay(ado,i);
11693                if (     Sover
11694                      && Sover->dset_link
11695                      && Sover->rowgraph_mtd ) {
11696                   SUMA_OverlayGraphAtNode(Sover,
11697                                           ado,
11698                                      SUMA_ADO_SelectedDatum(ado, NULL, NULL));
11699                }
11700             }
11701          } else {
11702             Sover = SurfCont->curColPlane;
11703             if (     Sover
11704                      && Sover->dset_link
11705                      && Sover->rowgraph_mtd ) {
11706                   SUMA_OverlayGraphAtNode(Sover,
11707                                           ado,
11708                                      SUMA_ADO_SelectedDatum(ado, NULL, NULL));
11709                }
11710          }
11711          SUMA_RETURN(YUP);
11712          break; }
11713       case MASK_type:
11714          SUMA_S_Warn("Anything to be done here for masks?");
11715          SUMA_RETURN(YUP);
11716       default:
11717          SUMA_S_Errv("Nothing to do with %s\n",
11718                SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
11719          SUMA_RETURN(NOPE);
11720    }
11721    SUMA_RETURN(YUP);
11722 
11723 }
11724 
SUMA_UpdatePointField(SUMA_ALL_DO * ado)11725 SUMA_Boolean SUMA_UpdatePointField(SUMA_ALL_DO*ado)
11726 {
11727    static char FuncName[]={"SUMA_UpdatePointField"};
11728    int i=0;
11729    SUMA_OVERLAYS *Sover=NULL;
11730    char str[100];
11731    float *fv=NULL;
11732    SUMA_X_SurfCont *SurfCont=NULL;
11733    SUMA_Boolean LocalHead = NOPE;
11734 
11735    SUMA_ENTRY;
11736 
11737    if (!ado || !(SurfCont = SUMA_ADO_Cont(ado))) SUMA_RETURN(NOPE);
11738    SUMA_LHv("Entry, SurfCont=%p, ado %p\n",
11739             ado,   SurfCont);
11740    if (!SUMA_isSurfContWidgetCreated(SurfCont)) {
11741       /* No controller created yet, return quietly */
11742       SUMA_RETURN(YUP);
11743    }
11744    Sover = SUMA_ADO_CurColPlane(ado);
11745    SUMA_LHv("Sover %p, ado type %d %s\n",
11746          Sover, ado->do_type, SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
11747    switch (ado->do_type) {
11748       case SO_type: {
11749          SUMA_S_Err("Not for SOs this!");
11750          break; }
11751 
11752       case GDSET_type: {
11753          SUMA_S_Err("Should not call with this type DO because without\n"
11754                     "a variant it cannot be displayed");
11755          SUMA_RETURN(NOPE);
11756          break; }
11757       case GRAPH_LINK_type:
11758          {
11759          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
11760          SUMA_DSET *dset=NULL;
11761          SUMA_GRAPH_SAUX *GSaux=NULL;
11762          SUMA_ALL_DO *curado=NULL;
11763          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
11764             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
11765                         SUMA_ADO_Label(ado));
11766             SUMA_RETURN(NOPE);
11767          }
11768           if (!(curado = SUMA_SurfCont_GetcurDOp(SurfCont))) {
11769             SUMA_S_Err("Failed to get curDOp");
11770             break;
11771          }
11772          GSaux = SDSET_GSAUX(dset);
11773          SUMA_LHv("Working %s (%s), curado %s (%s) on dset %s\n",
11774                   ADO_TNAME(ado), SUMA_ADO_Label(ado),
11775                   ADO_TNAME(curado), SUMA_ADO_Label(curado),
11776                   SDSET_LABEL(dset));
11777 
11778          if (!SurfCont->FaceTable||
11779              !SurfCont->FaceTable->num_value) { /* table widgets not set yet ?*/
11780             SUMA_RETURN(NOPE);
11781          }
11782 
11783          if (SUMA_isRelated(ado, curado, 1)) {
11784             SUMA_LH( "Updating GUI Point Fields, ");
11785             if (curado == ado) {
11786                if (GSaux->PR->iAltSel[SUMA_ENODE_0] >= 0) {
11787                   sprintf(str, "%ld", GSaux->PR->iAltSel[SUMA_ENODE_0]);
11788                   SurfCont->FaceTable->num_value[1] =
11789                         GSaux->PR->iAltSel[SUMA_ENODE_0];
11790                   XtVaSetValues(SurfCont->FaceTable->cells[1],
11791                                  XmNvalue, str, NULL);
11792                   fv = SUMA_GDSET_NodeXYZ(dset, GSaux->PR->iAltSel[SUMA_ENODE_0],
11793                                           SUMA_ADO_variant(ado),NULL);
11794                   sprintf(str, "%f, %f, %f", fv[0], fv[1], fv[2]);
11795 
11796                   XtVaSetValues(SurfCont->FaceTable->cells[2],
11797                                  XmNvalue, str, NULL);
11798                } else {
11799                   XtVaSetValues(SurfCont->FaceTable->cells[1],
11800                                  XmNvalue, "-1", NULL);
11801                   SurfCont->FaceTable->num_value[1] = -1;
11802                   XtVaSetValues(SurfCont->FaceTable->cells[2],
11803                           XmNvalue, "x, x, x", NULL);
11804                }
11805             }
11806          }
11807 
11808          SUMA_RETURN(YUP);
11809          break; }
11810 
11811       default:
11812          SUMA_S_Errv("Nothing to do with %s\n",
11813                SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
11814          SUMA_RETURN(NOPE);
11815    }
11816    SUMA_RETURN(YUP);
11817 }
11818 
SUMA_UpdateNodeNodeField(SUMA_ALL_DO * ado)11819 SUMA_Boolean SUMA_UpdateNodeNodeField(SUMA_ALL_DO *ado)
11820 {
11821    static char FuncName[]={"SUMA_UpdateNodeNodeField"};
11822    char str[101];
11823    SUMA_X_SurfCont *SurfCont=NULL;
11824    int SelectedNode, ivsel[SUMA_N_IALTSEL_TYPES];
11825    float *fv;
11826    SUMA_Boolean LocalHead = NOPE;
11827 
11828    SUMA_ENTRY;
11829 
11830    if (!ado) {
11831       SUMA_SL_Err("NULL ado");
11832       SUMA_RETURN(NOPE);
11833    }
11834    SurfCont = SUMA_ADO_Cont(ado);
11835    SelectedNode = SUMA_ADO_SelectedDatum(ado, NULL, NULL);
11836    SUMA_LH("Working %d on %s\n", SelectedNode, ADO_LABEL(ado));
11837    if (!SurfCont || !SurfCont->NodeTable) SUMA_RETURN(NOPE);
11838    if (SelectedNode < 0 || SelectedNode > SUMA_ADO_Max_Datum_Index(ado))
11839                                           SUMA_RETURN(NOPE);
11840    if (!SurfCont->NodeTable->num_value) { /* Table widgets not created yet? */
11841       SUMA_RETURN(NOPE);
11842    }
11843    sprintf(str, "%d", SelectedNode);
11844    SurfCont->NodeTable->num_value[1] = SelectedNode;
11845    XtVaSetValues(SurfCont->NodeTable->cells[1], XmNvalue, str, NULL);
11846    switch (ado->do_type) {
11847       case SO_type:
11848          fv = SUMA_ADO_DatumXYZ(ado,SelectedNode, NULL);
11849          sprintf(str, "%s, ",
11850                      MV_format_fval2(fv[0], 7));
11851          SUMA_strncat(str, MV_format_fval2(fv[1], 7), 100);
11852          SUMA_strncat(str, ", ", 100);
11853          SUMA_strncat(str, MV_format_fval2(fv[2], 7), 100 );
11854          XtVaSetValues(SurfCont->NodeTable->cells[2], XmNvalue, str, NULL);
11855          break;
11856       case GRAPH_LINK_type: {
11857          int i0, i1;
11858          SUMA_DSET *dset=SUMA_find_GLDO_Dset((SUMA_GraphLinkDO*)ado);
11859          SUMA_GRAPH_SAUX *GSaux=SDSET_GSAUX(dset);
11860          if (SUMA_GDSET_SegIndexToPoints(dset, SelectedNode,
11861                                           &i0, &i1, NULL)) {
11862             sprintf(str, "%d, %d", i0, i1);
11863          } else {
11864             sprintf(str, "-,-");
11865          }
11866          XtVaSetValues(SurfCont->NodeTable->cells[2], XmNvalue, str, NULL);
11867          break; }
11868       case TRACT_type: {
11869          if (!SurfCont->FaceTable) SUMA_RETURN(NOPE);
11870          SUMA_ADO_SelectedDatum(ado, (void *)ivsel, NULL);
11871          sprintf(str, "%d, %d, %d",
11872                  ivsel[SUMA_NET_BUN], ivsel[SUMA_BUN_TRC], ivsel[SUMA_TRC_PNT]);
11873          XtVaSetValues(SurfCont->FaceTable->cells[1], XmNvalue, str, NULL);
11874          break; }
11875       case MASK_type: {
11876          SUMA_S_Warn("Anything for this?");
11877          break; }
11878       case VO_type: {
11879          if (!SurfCont->FaceTable) SUMA_RETURN(NOPE);
11880          SUMA_ADO_SelectedDatum(ado, (void *)ivsel, NULL);
11881          sprintf(str, "%d, %d, %d",
11882                  ivsel[SUMA_VOL_I], ivsel[SUMA_VOL_J], ivsel[SUMA_VOL_K]);
11883          XtVaSetValues(SurfCont->FaceTable->cells[1], XmNvalue, str, NULL);
11884          break; }
11885       default:
11886          SUMA_S_Errv("No love for %s\n", ADO_TNAME(ado));
11887          break;
11888    }
11889 
11890    SUMA_RETURN(YUP);
11891 }
11892 
11893 /* A lazy wrapper for SUMA_FormNodeValFieldStrings to return
11894    values but not the strings.
11895    This function is not very efficient, since all the strings
11896    are formed and then discarded.
11897 */
SUMA_GetNodeValsAtSelection(SUMA_ALL_DO * ado,SUMA_DSET * dset,int Node,int find,int tind,int bind,double * I,double * T,double * B)11898 SUMA_Boolean SUMA_GetNodeValsAtSelection(SUMA_ALL_DO *ado,
11899                SUMA_DSET *dset, int Node,
11900                int find, int tind, int bind,
11901                double *I, double *T, double *B)
11902 {
11903    static char FuncName[] = {"SUMA_GetNodeValsAtSelection"};
11904    char **sar=NULL;
11905    int i;
11906 
11907    SUMA_ENTRY;
11908 
11909    sar = SUMA_FormNodeValFieldStrings(ado, dset, Node, find, tind, bind,
11910                                       1, I, T, B);
11911    if (!sar) SUMA_RETURN(NOPE);
11912    for (i=0; i<3; ++i) SUMA_ifree(sar[i]);
11913    SUMA_ifree(sar);
11914 
11915    SUMA_RETURN(YUP);
11916 }
11917 
SUMA_FormNodeValFieldStrings(SUMA_ALL_DO * ado,SUMA_DSET * dset,int Node,int find,int tind,int bind,int dec,double * I,double * T,double * B)11918 char **SUMA_FormNodeValFieldStrings(SUMA_ALL_DO *ado,
11919                                  SUMA_DSET *dset, int Node,
11920                                  int find, int tind, int bind,
11921                                  int dec, double *I, double *T, double *B)
11922 {
11923    static char FuncName[]={"SUMA_FormNodeValFieldStrings"};
11924    char **sar=NULL;
11925    double dval;
11926    int Found = -1;
11927    SUMA_DATUM_LEVEL lev = 0;
11928    int Max_Node_Index = -1;
11929    SUMA_Boolean LocalHead = NOPE;
11930 
11931    SUMA_ENTRY;
11932 
11933    if (!ado || !dset) SUMA_RETURN(sar);
11934    if (I) *I=-1.0;
11935    if (T) *T=-1.0;
11936    if (B) *B=-1.0;
11937    Max_Node_Index = SUMA_ADO_Max_Datum_Index(ado);
11938 
11939    /* What datum level do we have here ? */
11940    switch ((lev = SUMA_sdset_datum_level(dset))) {
11941       case SUMA_ELEM_DAT:
11942          SUMA_LH("Datum %d is expected to refer to an elementary datum level",
11943                  Node);
11944          break;
11945       case SUMA_LEV1_DAT:
11946          SUMA_LH("Datum %d is expected to refer to a level1 datum", Node);
11947          break;
11948       case SUMA_LEV2_DAT:
11949          SUMA_LH("Datum %d is expected to refer to a level2 datum", Node);
11950          break;
11951       default:
11952          SUMA_S_Err("You're not on the level %d", lev);
11953          break;
11954    }
11955 
11956    /* 1- Where is this node in the data set ? */
11957    if (Node > -1) {
11958       Found = SUMA_GetNodeRow_FromNodeIndex_s(  dset, Node, Max_Node_Index );
11959    } else {
11960       Found = -1;
11961    }
11962    if (LocalHead) {
11963       fprintf( SUMA_STDERR,
11964                "%s: Node index %d is at row %d in dset %p "
11965                "(label %s, filename %s).\n",
11966                FuncName, Node, Found,
11967                dset,
11968                SDSET_LABEL(dset),
11969                SDSET_FILENAME(dset));
11970    }
11971 
11972    if (Found >= 0) {
11973       sar = (char **)SUMA_calloc(3, sizeof(char *));
11974       /* 2- What is the value of the intensity */
11975       if ((sar[0] = SUMA_GetDsetValInCol(dset, find, Found, &dval))) {
11976          if (dec > 0) {
11977             SUMA_free(sar[0]);
11978             sar[0] = SUMA_copy_string(MV_format_fval2(dval, dec));
11979          }
11980          SUMA_LHv("str_int=%s, dval = %f\n",sar[0], dval);
11981          if (I) *I = dval;
11982       } else {
11983          sar[0] = SUMA_copy_string("X");
11984          SUMA_SL_Err("Failed to get str_int");
11985       }
11986       if ((sar[1] = SUMA_GetDsetValInCol(dset, tind, Found, &dval))) {
11987          if (dec > 0) {
11988             SUMA_free(sar[1]);
11989             sar[1] = SUMA_copy_string(MV_format_fval2(dval, dec));
11990          }
11991          SUMA_LHv("str_thr=%s, dval = %f\n",sar[1], dval);
11992          if (T) *T = dval;
11993       } else {
11994          sar[1] = SUMA_copy_string("X");
11995          SUMA_SL_Err("Failed to get str_thr");
11996       }
11997       if ((sar[2] = SUMA_GetDsetValInCol(dset, bind, Found, &dval))) {
11998          if (dec > 0) {
11999             SUMA_free(sar[2]);
12000             sar[2] = SUMA_copy_string(MV_format_fval2(dval, dec));
12001          }
12002          SUMA_LHv("str_brt=%s, dval = %f\n",sar[2], dval);
12003          if (B) *B = dval;
12004       } else {
12005          SUMA_SL_Err("Failed to get str_brt");
12006          sar[2] = SUMA_copy_string("X");
12007       }
12008    }
12009 
12010    SUMA_RETURN(sar);
12011 }
12012 
12013 /*!
12014    Like SUMA_ADO_SelectedDatum, except that
12015 if the overlay plane is for a non-elementary
12016 datum, the datum selection is adjusted properly
12017    Set Sover to NULL if you want to use
12018    the current overlay
12019 */
SUMA_ADO_ColPlane_SelectedDatum(SUMA_ALL_DO * ado,SUMA_OVERLAYS * Sover)12020 int SUMA_ADO_ColPlane_SelectedDatum(SUMA_ALL_DO *ado, SUMA_OVERLAYS *Sover)
12021 {
12022    static char FuncName[]={"SUMA_ADO_ColPlane_SelectedDatum"};
12023    int SelectedNode = -1, ivsel[SUMA_N_IALTSEL_TYPES];
12024    SUMA_Boolean LocalHead = NOPE;
12025 
12026    SUMA_ENTRY;
12027 
12028    if (!ado) {
12029       SUMA_LH("Null ado");
12030       SUMA_RETURN(-1);
12031    }
12032 
12033    if (!Sover) Sover = SUMA_ADO_CurColPlane(ado);
12034    if (!Sover) {
12035       SUMA_LH("Null Sover and no current overlay plane");
12036       SUMA_RETURN(-1);
12037    }
12038 
12039    SelectedNode = SUMA_ADO_SelectedDatum(ado, (void *)ivsel, NULL);
12040    SUMA_LH("Selection: %d -- %d %d %d %d",
12041                SelectedNode, ivsel[0], ivsel[1], ivsel[2], ivsel[3]);
12042    if (Sover->dtlvl != SUMA_ELEM_DAT) {
12043       switch (ado->do_type) {
12044          case TRACT_type:
12045             if (Sover->dtlvl == SUMA_LEV1_DAT)
12046                      SelectedNode = ivsel[SUMA_NET_TRC];
12047             else if (Sover->dtlvl == SUMA_LEV2_DAT)
12048                                  SelectedNode = ivsel[SUMA_NET_BUN];
12049             break;
12050          default:
12051             SUMA_S_Err("Not ready for non-elementary datum for type %s\n",
12052                        ADO_TNAME(ado));
12053             break;
12054       }
12055    }
12056 
12057    SUMA_RETURN(SelectedNode);
12058 }
12059 
SUMA_UpdateNodeValField(SUMA_ALL_DO * ado)12060 SUMA_Boolean SUMA_UpdateNodeValField(SUMA_ALL_DO *ado)
12061 {
12062    static char FuncName[]={"SUMA_UpdateNodeValField"};
12063    char **sar=NULL;
12064    double I, T, B;
12065    SUMA_OVERLAYS *Sover=NULL;
12066    SUMA_X_SurfCont *SurfCont=NULL;
12067    int SelectedNode = -1;
12068    SUMA_Boolean LocalHead = NOPE;
12069 
12070    SUMA_ENTRY;
12071 
12072    if (!ado) {
12073       SUMA_LH("Null ado");
12074       SUMA_RETURN(NOPE);
12075    }
12076 
12077    Sover = SUMA_ADO_CurColPlane(ado);
12078    if (!Sover) {
12079       SUMA_LH("Null Sover");
12080       SUMA_RETURN(NOPE);
12081    }
12082    SurfCont = SUMA_ADO_Cont(ado);
12083    if (!SurfCont || !SurfCont->DataTable ||
12084        !SurfCont->DataTable->cells) SUMA_RETURN(NOPE);
12085 
12086    SelectedNode = SUMA_ADO_ColPlane_SelectedDatum(ado, Sover);
12087    if (!(sar = SUMA_FormNodeValFieldStrings(ado, Sover->dset_link,
12088                            SelectedNode,
12089                            Sover->OptScl->find,
12090                            Sover->OptScl->tind,
12091                            Sover->OptScl->bind, 0, &I, &T, &B))) {
12092        SUMA_LH("Failed to get strings");
12093    } else {
12094       SUMA_LH("Got strings");
12095    }
12096    if (sar && sar[0]) {
12097       SUMA_INSERT_CELL_STRING(SurfCont->DataTable, 1, 1, sar[0]);
12098       SUMA_free(sar[0]);
12099    } else {
12100       SUMA_INSERT_CELL_STRING(SurfCont->DataTable, 1, 1, "Err");
12101    }
12102    /* Set the table num values too, otherwise you can't read out
12103       the numerical values if you wish and that's just a shame
12104       for numerical tables such as this one. */
12105    SUMA_SET_CELL_VALUE(SurfCont->DataTable, 1, 1, I);
12106    if (sar && sar[1]) {
12107       SUMA_INSERT_CELL_STRING(SurfCont->DataTable, 1, 2, sar[1]);
12108       SUMA_free(sar[1]);
12109    } else {
12110       SUMA_INSERT_CELL_STRING(SurfCont->DataTable, 1, 2, "Err");
12111    }
12112    SUMA_SET_CELL_VALUE(SurfCont->DataTable, 1, 1, T);
12113    if (sar && sar[2]) {
12114       SUMA_INSERT_CELL_STRING(SurfCont->DataTable, 1, 3, sar[2]);
12115       SUMA_free(sar[2]);
12116    } else {
12117       SUMA_INSERT_CELL_STRING(SurfCont->DataTable, 1, 3, "Err");
12118    }
12119    SUMA_SET_CELL_VALUE(SurfCont->DataTable, 1, 1, B);
12120    if (sar) SUMA_free(sar); sar = NULL;
12121 
12122    SUMA_RETURN(YUP);
12123 }
12124 
12125 /*!< Get values at current selection on current plane
12126      if (fromtable) then read the values from the
12127      displayed table structure.
12128 */
SUMA_GetValuesAtSelection(SUMA_ALL_DO * ado,int fromtable,float * I,float * T,float * B)12129 SUMA_Boolean SUMA_GetValuesAtSelection(SUMA_ALL_DO *ado, int fromtable,
12130                                        float *I, float *T, float *B)
12131 {
12132    static char FuncName[]={"SUMA_GetValuesAtSelection"};
12133    SUMA_OVERLAYS *Sover=NULL;
12134    SUMA_X_SurfCont *SurfCont=NULL;
12135    int SelectedNode = -1;
12136    double II=0.0, TT=0.0, BB=0.0;
12137    SUMA_Boolean LocalHead = NOPE;
12138 
12139    SUMA_ENTRY;
12140 
12141    if (!ado) {
12142       SUMA_LH("Null ado");
12143       SUMA_RETURN(NOPE);
12144    }
12145 
12146    Sover = SUMA_ADO_CurColPlane(ado);
12147    if (!Sover) {
12148       SUMA_LH("Null Sover");
12149       SUMA_RETURN(NOPE);
12150    }
12151    SurfCont = SUMA_ADO_Cont(ado);
12152    if (!SurfCont) SUMA_RETURN(NOPE);
12153 
12154    SelectedNode = SUMA_ADO_ColPlane_SelectedDatum(ado, Sover);
12155 
12156    if (fromtable && (!SurfCont->DataTable ||
12157           !SurfCont->DataTable->cells)) {
12158           SUMA_LH("Controller not initialized, "
12159                   "cannot retrieve values from table, trying without");
12160       fromtable = 0;
12161    }
12162    if (fromtable) {
12163       if (!SurfCont->DataTable ||
12164           !SurfCont->DataTable->cells) {
12165             SUMA_S_Err("Controller not initialized, "
12166                        "cannot retrieve values from table");
12167             SUMA_RETURN(NOPE);
12168       }
12169       /* Check that SelectedNode matches that in the node index table too */
12170       if (SelectedNode != SurfCont->NodeTable->num_value[1]) {
12171          /* table not updated yet perhaps  */
12172          SUMA_S_Note("Forced update of value fields (%d) (%f)to be safe",
12173                      SelectedNode, SurfCont->NodeTable->num_value[1]);
12174          SUMA_UpdateNodeValField(ado);
12175       }
12176       SUMA_LH("Fetching from table");
12177       if (I) SUMA_GET_CELL_VALUE(SurfCont->DataTable, 1, 1, *I);
12178       if (T) SUMA_GET_CELL_VALUE(SurfCont->DataTable, 1, 2, *T);
12179       if (B) SUMA_GET_CELL_VALUE(SurfCont->DataTable, 1, 3, *B);
12180    } else {
12181       if (!SUMA_GetNodeValsAtSelection(ado, Sover->dset_link,
12182                            SelectedNode,
12183                            Sover->OptScl->find,
12184                            Sover->OptScl->tind,
12185                            Sover->OptScl->bind,
12186                            &II, &TT, &BB)) {
12187 
12188          SUMA_S_Err("Failed to get sel values");
12189          SUMA_RETURN(NOPE);
12190       }
12191       if (I) *I = II;
12192       if (T) *T = TT;
12193       if (B) *B = BB;
12194    }
12195    SUMA_RETURN(YUP);
12196 }
12197 
SUMA_GetLabelsAtSelection(SUMA_ALL_DO * ado,int node,int sec)12198 char *SUMA_GetLabelsAtSelection(SUMA_ALL_DO *ado, int node, int sec)
12199 {
12200    static char FuncName[]={"SUMA_GetLabelsAtSelection"};
12201    SUMA_Boolean LocalHead = NOPE;
12202 
12203    SUMA_ENTRY;
12204 
12205    if (!ado) SUMA_RETURN(NULL);
12206 
12207    switch (ado->do_type) {
12208       case SO_type:
12209          SUMA_RETURN(SUMA_GetLabelsAtSelection_ADO(ado,node, sec));
12210          break;
12211       case GDSET_type:
12212          SUMA_S_Warn("Not ready to return labels for dsets, and should I be?");
12213          break;
12214       case CDOM_type:
12215       case VO_type:
12216       case MASK_type:
12217       case TRACT_type:
12218       case GRAPH_LINK_type:
12219          SUMA_RETURN(SUMA_GetLabelsAtSelection_ADO(ado,node, sec));
12220          break;
12221       default:
12222          SUMA_LHv("No labels ready for type %s\n",
12223             SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
12224          break;
12225    }
12226 
12227    SUMA_RETURN(NULL);
12228 }
12229 
12230 /* Do we have labels at this location ?
12231    node is the 'datum' index, primary selection - think node on surface,
12232                                                   or edge on graph
12233    sec is the secondary selection index - think FaceSet on surface,
12234                                                   or node on graph*/
SUMA_GetLabelsAtSelection_ADO(SUMA_ALL_DO * ado,int node,int sec)12235 char *SUMA_GetLabelsAtSelection_ADO(SUMA_ALL_DO *ado, int node, int sec)
12236 {
12237    static char FuncName[]={"SUMA_GetLabelsAtSelection_ADO"};
12238    char *lbls=NULL;
12239    int key = -1, OverInd=-1, i0, i, sp;
12240    SUMA_DSET *cdset=NULL, *dd=NULL;
12241    SUMA_OVERLAYS *colplane=NULL, *Sover=NULL;
12242    SUMA_COLOR_MAP *CM=NULL;
12243    DListElmt *el=NULL, *NextElm=NULL;
12244    DList *list=NULL;
12245    SUMA_EngineData *ED=NULL;
12246    char **sar=NULL, stmp[64]={""};
12247    char *seps[3]={"I=", " T=", " B="};
12248    SUMA_Boolean LocalHead = NOPE;
12249    SUMA_ENTRY;
12250 
12251    if (!ado) SUMA_RETURN(NULL);
12252 
12253    /* Any clusters? */
12254    SUMA_LHv("on ADO %s, looking for labels for selection %d and secondary %d\n",
12255             SUMA_ADO_Label(ado), node, sec);
12256 
12257    if (ado->do_type == SO_type) {
12258       SUMA_SurfaceObject *SO = (SUMA_SurfaceObject *)ado;
12259       el = dlist_head(SUMAg_CF->DsetList);
12260       while (el) {
12261          dd = (SUMA_DSET*)el->data;
12262          if (SUMA_isDsetRelated(dd, SO) &&
12263              (colplane = SUMA_Fetch_OverlayPointerByDset (
12264                                  (SUMA_ALL_DO*)SO, dd, &OverInd)) &&
12265              colplane->OptScl) {
12266             SUMA_LHv("Have Dset %s related to SO\n", SDSET_LABEL(dd));
12267             /* is dd a LabelDset ? */
12268             if (  (SUMA_is_Label_dset(dd, NULL) ||
12269                    SUMA_is_Label_dset_col(dd,colplane->OptScl->find))
12270                 && node >= 0 ) {
12271                SUMA_LHv("dset %s will work with SO", SDSET_LABEL(dd));
12272                key = SUMA_GetDsetNodeValInCol2( dd, colplane->OptScl->find,
12273                                                 node, -1);
12274                /* get the overlay for that dset */
12275                if (key >= 0) {
12276                   /* get the colormap for that colplane */
12277                   if ((CM = SUMA_FindNamedColMap (colplane->cmapname)) &&
12278                       CM->cname) {
12279                      if ((i0 = SUMA_ColMapKeyIndex(key, CM)) >= 0) {
12280                         if (!lbls) {
12281                            lbls = SUMA_copy_string(CM->cname[i0]);
12282                         } else {
12283                            lbls = SUMA_append_replace_string(lbls,CM->cname[i0],
12284                                                           "|", 1);
12285                         }
12286                      }
12287                   }
12288                }
12289             }
12290          }
12291          el = dlist_next(el);
12292       }
12293    }
12294 
12295 
12296    if ((Sover = SUMA_ADO_CurColPlane(ado))) {
12297       if (SDSET_TYPE(Sover->dset_link) != SUMA_NODE_RGB ) {/* Have labels */
12298          if (!(sar = SUMA_FormNodeValFieldStrings(ado,
12299                                  Sover->dset_link,
12300                                  node,
12301                                  Sover->OptScl->find,
12302                                  Sover->OptScl->tind,
12303                                  Sover->OptScl->bind, 5,
12304                                  NULL, NULL, NULL))) {
12305             SUMA_LH("No Sar");
12306          } else if (1) { /* include sub-brick labels */
12307             SUMA_LH("Sar: %s %s %s",
12308                    SUMA_CHECK_NULL_STR(sar[0]),SUMA_CHECK_NULL_STR(sar[1]),
12309                    SUMA_CHECK_NULL_STR(sar[2]));
12310             if (lbls) lbls = SUMA_append_replace_string(lbls,"\n","",1);
12311             if (sar[0] && sar[1] && sar[2]) {
12312                if (!strcmp(sar[0],sar[1]) && !strcmp(sar[2],sar[1])) {
12313                   lbls = SUMA_append_replace_string(lbls, "(I,T,B)", "",1);
12314                   lbls = SUMA_append_replace_string(lbls,
12315                            SUMA_DsetColLabel(Sover->dset_link,
12316                                              Sover->OptScl->find),
12317                                                     "",1);
12318                   lbls = SUMA_append_replace_string(lbls, sar[0], "=",1);
12319                } else if (!strcmp(sar[0],sar[1])) {
12320                   lbls = SUMA_append_replace_string(lbls, "(I,T)", "",1);
12321                   lbls = SUMA_append_replace_string(lbls,
12322                            SUMA_DsetColLabel(Sover->dset_link,
12323                                              Sover->OptScl->find),
12324                                                     "",1);
12325                   lbls = SUMA_append_replace_string(lbls, sar[0], "=",1);
12326 
12327                   lbls = SUMA_append_replace_string(lbls, " (B)", "",1);
12328                   lbls = SUMA_append_replace_string(lbls,
12329                            SUMA_DsetColLabel(Sover->dset_link,
12330                                              Sover->OptScl->bind),
12331                                                     "",1);
12332                   lbls = SUMA_append_replace_string(lbls, sar[2], "=", 1);
12333                } else if (!strcmp(sar[1],sar[2])) {
12334                   lbls = SUMA_append_replace_string(lbls, "(I)", "",1);
12335                   lbls = SUMA_append_replace_string(lbls,
12336                            SUMA_DsetColLabel(Sover->dset_link,
12337                                              Sover->OptScl->find),
12338                                                     "",1);
12339                   lbls = SUMA_append_replace_string(lbls, sar[0], "=",1);
12340 
12341                   lbls = SUMA_append_replace_string(lbls, " (B,T)", "",1);
12342                   lbls = SUMA_append_replace_string(lbls,
12343                            SUMA_DsetColLabel(Sover->dset_link,
12344                                              Sover->OptScl->bind),
12345                                                     "",1);
12346                   lbls = SUMA_append_replace_string(lbls, sar[2], "=", 1);
12347                } else if (!strcmp(sar[0],sar[2])) {
12348                   lbls = SUMA_append_replace_string(lbls, "(I,B)", "",1);
12349                   lbls = SUMA_append_replace_string(lbls,
12350                            SUMA_DsetColLabel(Sover->dset_link,
12351                                              Sover->OptScl->find),
12352                                                     "",1);
12353                   lbls = SUMA_append_replace_string(lbls, sar[0], "=",1);
12354 
12355                   lbls = SUMA_append_replace_string(lbls, " (T)", "",1);
12356                   lbls = SUMA_append_replace_string(lbls,
12357                            SUMA_DsetColLabel(Sover->dset_link,
12358                                              Sover->OptScl->tind),
12359                                                     "",1);
12360                   lbls = SUMA_append_replace_string(lbls, sar[1], "=", 1);
12361                } else {
12362                   for (sp=0,i=0;i<3;++i) {
12363                      if (sar[i]) {
12364                         if (sp)
12365                            lbls = SUMA_append_replace_string(lbls," ","", 1);
12366                         lbls = SUMA_append_replace_string(lbls,
12367                            SUMA_DsetColLabel(Sover->dset_link,
12368                                                 i==0 ? Sover->OptScl->find :
12369                                                 ( i == 1 ? Sover->OptScl->tind:
12370                                                            Sover->OptScl->bind)),
12371                                                     "",1);
12372                         lbls = SUMA_append_replace_string(lbls,sar[i],"=", 1);
12373                         sp=1;
12374                         SUMA_free(sar[i]); sar[i]=NULL;
12375                      }
12376                   }
12377                }
12378             } else {
12379                   for (sp=0,i=0;i<3;++i) {
12380                      if (sar[i]) {
12381                         if (sp)
12382                            lbls = SUMA_append_replace_string(lbls," ","", 1);
12383                         lbls = SUMA_append_replace_string(lbls,
12384                            SUMA_DsetColLabel(Sover->dset_link,
12385                                                 i==0 ? Sover->OptScl->find :
12386                                                 ( i == 1 ? Sover->OptScl->tind:
12387                                                            Sover->OptScl->bind)),
12388                                                     "",1);
12389                         lbls = SUMA_append_replace_string(lbls,sar[i],"=", 1);
12390                         sp=1;
12391                         SUMA_free(sar[i]); sar[i]=NULL;
12392                      }
12393                   }
12394 
12395             }
12396             SUMA_free(sar); sar=NULL;
12397             if (ado->do_type == SO_type) {
12398                if ((sp=SUMA_NodeClustNumber(Sover, node,
12399                                            (SUMA_SurfaceObject *)ado, NULL))) {
12400                   sprintf(stmp,"\nIn cluster %d", sp);
12401                   if (lbls) lbls = SUMA_append_replace_string(lbls,stmp,"",1);
12402                }
12403             }
12404         } else { /* old approach to labeling, I,T, business only */
12405             SUMA_LH("Old");
12406             if (lbls) lbls = SUMA_append_replace_string(lbls,"\n","",1);
12407             if (sar[0] && sar[1] && sar[2]) {
12408                if (!strcmp(sar[0],sar[1]) && !strcmp(sar[2],sar[1])) {
12409                   lbls = SUMA_append_replace_string(lbls, sar[0], "I,T,B=",1);
12410                } else if (!strcmp(sar[0],sar[1])) {
12411                   lbls = SUMA_append_replace_string(lbls, sar[0], "I,T=",1);
12412                   lbls = SUMA_append_replace_string(lbls, sar[2], " B=", 1);
12413                } else if (!strcmp(sar[1],sar[2])) {
12414                   lbls = SUMA_append_replace_string(lbls, sar[0], "I=",1);
12415                   lbls = SUMA_append_replace_string(lbls, sar[1], " B,T=", 1);
12416                } else {
12417                   for (i=0;i<3;++i) {
12418                      if (sar[i]) {
12419                         lbls = SUMA_append_replace_string(lbls,sar[i],
12420                                                        seps[i], 1);
12421                         SUMA_free(sar[i]); sar[i]=NULL;
12422                      }
12423                   }
12424                }
12425             } else {
12426                for (i=0;i<3;++i) {
12427                   if (sar[i]) {
12428                      lbls = SUMA_append_replace_string(lbls,sar[i],
12429                                                     seps[i], 1);
12430                      SUMA_free(sar[i]); sar[i]=NULL;
12431                   }
12432                }
12433             }
12434             SUMA_free(sar); sar=NULL;
12435          }
12436       }/* Have labels */
12437 
12438       /* Some coord info for select few ? */
12439 
12440       if (ado->do_type == GRAPH_LINK_type) {
12441          SUMA_DSET *gset=NULL;
12442          char *stmp=NULL, *pref=NULL;
12443          gset =  SUMA_find_GLDO_Dset((SUMA_GraphLinkDO*)ado);
12444          if (node >= 0) { /* an edge */
12445             pref = "\nGpair "; /* I was using "Cell" and "Edge"
12446                                  depending on the variant, but
12447                                  the label is shared across viewers
12448                                  so that does not work well */
12449             if ((stmp=SUMA_GDSET_Edge_Label(gset, node, pref, NULL))) {
12450                SUMA_LHv("Adding edge label %s\n", stmp);
12451                lbls = SUMA_append_replace_string(lbls,stmp,"", 1);
12452                SUMA_ifree(stmp);
12453             }
12454          } else {
12455             if (sec >= 0) { /* all from some node */
12456                if ((stmp=SUMA_GDSET_Node_Label(gset, sec))) {
12457                   SUMA_LHv("Got graph node label %s\n", stmp);
12458                   stmp = SUMA_append_replace_string("\nGnode ", stmp, "", 0);
12459                   lbls = SUMA_append_replace_string(lbls,stmp,"", 1);
12460                   SUMA_ifree(stmp);
12461                }
12462             }
12463          }
12464       }
12465 
12466       /* Bundles, tracts? */
12467       if (ado->do_type == TRACT_type) {
12468          SUMA_TractDO *tdo=(SUMA_TractDO *)ado;
12469          SUMA_TRACT_SAUX *TSaux = SUMA_ADO_TSaux(ado);
12470          TAYLOR_BUNDLE *tb=NULL;
12471          char stmp[256], *be=NULL;
12472          if (node >= 0) { /* spell out where you are */
12473             if (TSaux->PR->iAltSel[SUMA_NET_BUN] >= 0 &&
12474                 TSaux->PR->iAltSel[SUMA_BUN_TRC] >= 0 &&
12475                 TSaux->PR->iAltSel[SUMA_TRC_PNT] >= 0 ) {
12476                 if ( (tb = TDO_BUNDLE(tdo, TSaux->PR->iAltSel[SUMA_NET_BUN])) &&
12477                      tb->bundle_ends ) {
12478                    be = tb->bundle_ends;
12479                 }
12480                 snprintf(stmp, 256,
12481                      "%s%s%cPnt %ld, trct %ld, bnd %ld",
12482                        lbls?"\n":"", be ? be:"", be ? '\n':'\0',
12483                        TSaux->PR->iAltSel[SUMA_TRC_PNT],
12484                        TSaux->PR->iAltSel[SUMA_BUN_TRC],
12485                        TSaux->PR->iAltSel[SUMA_NET_BUN]);
12486                lbls = SUMA_append_replace_string(lbls,stmp,"", 0);
12487             }
12488          }
12489       }
12490 
12491       /* Volume object */
12492       if (ado->do_type == VO_type) {
12493          SUMA_VolumeObject *vo=(SUMA_VolumeObject *)ado;
12494          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
12495          char stmp[256];
12496          SUMA_LH("Vol consideration with %s and node %d",
12497                   lbls, node);
12498          if (node >= 0) { /* spell out where you are */
12499             if (VSaux->PR->iAltSel[SUMA_VOL_I] >= 0 &&
12500                 VSaux->PR->iAltSel[SUMA_VOL_J] >= 0 &&
12501                 VSaux->PR->iAltSel[SUMA_VOL_K] >= 0 ) {
12502                 snprintf(stmp, 256,
12503                   "%sVoxel [%ld,%ld,%ld] at [%.2f,%.2f,%.2f]",
12504                        lbls?"\n":"",
12505                        VSaux->PR->iAltSel[SUMA_VOL_I],
12506                        VSaux->PR->iAltSel[SUMA_VOL_J],
12507                        VSaux->PR->iAltSel[SUMA_VOL_K],
12508                        VSaux->PR->PickXYZ[0],
12509                        VSaux->PR->PickXYZ[1],
12510                        VSaux->PR->PickXYZ[2]);
12511                lbls = SUMA_append_replace_string(lbls,stmp,"", 0);
12512                if (LocalHead) { /* Just for fun */
12513                   char variant[8];
12514                   SUMA_dset_gui_slice_from_tex_slice_d(vo->VE, 0,
12515                                  VSaux->PR->dAltSel+SUMA_VOL_SLC_EQ0,
12516                                                       0, variant,NULL);
12517                   SUMA_LH("%s, slice %.2f,%.2f,%.2f, %.2f: %s\n", stmp,
12518                      VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ0],
12519                      VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ1],
12520                      VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ2],
12521                      VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ3],
12522                      variant);
12523                }
12524             }
12525          }
12526       }
12527 
12528       /* Mask object */
12529       if (ado->do_type == MASK_type) {
12530          char stmp[256];
12531          snprintf(stmp, 256,
12532                   "%sMask selected",
12533                   lbls?"\n":"");
12534          lbls = SUMA_append_replace_string(lbls,stmp,"", 0);
12535       }
12536    }
12537 
12538    /* Do we need to tell Santa? */
12539    if (ado->do_type == SO_type &&
12540       lbls && SUMAg_CF->X->Whereami_TextShell) {
12541       if (!list) list = SUMA_CreateList();
12542       ED = SUMA_InitializeEngineListData (SE_Whereami);
12543       if (!(NextElm = SUMA_RegisterEngineListCommand (  list, ED,
12544                                     SEF_vp, (void *)ado,
12545                                     SES_Suma, NULL, NOPE,
12546                                     SEI_Head, NULL))) {
12547          fprintf (SUMA_STDERR,
12548                   "Error %s: Failed to register command.\n",
12549                   FuncName);
12550       }
12551       if (!(NextElm = SUMA_RegisterEngineListCommand (  list, ED,
12552                                     SEF_s, (void *)lbls, /* Copy by value */
12553                                     SES_Suma, NULL, NOPE,
12554                                     SEI_In, NextElm))) {
12555          fprintf (SUMA_STDERR,
12556                   "Error %s: Failed to add data.\n",
12557                   FuncName);
12558       }
12559 
12560       if (!SUMA_Engine (&list)) {
12561          fprintf(stderr,
12562                   "Error %s: SUMA_Engine call failed.\n", FuncName);
12563       }
12564    }
12565    SUMA_LH("Returning %s", lbls);
12566    SUMA_RETURN(lbls);
12567 }
12568 
12569 /* transform string to a TextNIDO,
12570    If sv is not NULL,
12571       then NIDO is added to SUMAg_DOv and registered with sv
12572       Do not free what it returned because it is added to SUMA's DOv
12573    else
12574       the returned nido is all yours to manage
12575 
12576 */
SUMA_NodeLabelToTextNIDO(char * lbls,SUMA_ALL_DO * ado,SUMA_SurfaceViewer * sv)12577 SUMA_NIDO *SUMA_NodeLabelToTextNIDO (char *lbls, SUMA_ALL_DO *ado,
12578                                      SUMA_SurfaceViewer *sv)
12579 {
12580    static char FuncName[]={"SUMA_NodeLabelToTextNIDO"};
12581    static void * default_font=GLUT_BITMAP_9_BY_15;
12582    int i=0;
12583    float txcol[4] = {0.2, 0.5, 1, 1.0};
12584    float default_color[4] = {0.2, 0.5, 1, 1.0}, *v;
12585    float topscr[3]={ 0.5, 1.0, 0.0 };
12586    SUMA_DO_CoordType coord_type = SUMA_WORLD;
12587    SUMA_DO_CoordUnits default_coord_units = SUMA_WORLD_UNIT;
12588    SUMA_NIDO *nido=NULL;
12589    NI_element *nini = NULL;
12590 
12591    SUMA_ENTRY;
12592 
12593 
12594    if (0) { /* on crosshair, does not look so nice. Keep it for the record*/
12595       nido = SUMA_BlankNIDO(NULL, "AHorseWithNoName",
12596                          SUMA_ADO_LDP(ado), NULL, NULL);
12597       nini = NI_new_data_element("T", 0);
12598 
12599       v = SUMA_ADO_DatumXYZ(ado, SUMA_ADO_SelectedDatum(ado, NULL, NULL), NULL);
12600       coord_type = SUMA_WORLD;
12601    } else {/* fixed on screen */
12602       nido = SUMA_BlankNIDO(NULL, "AHorseWithNoName",
12603                          NULL, "fixed", NULL);
12604       nini = NI_new_data_element("T", 0);
12605       coord_type = SUMA_SCREEN;
12606       NI_set_attribute(nini,"v_align", "top");
12607       NI_set_attribute(nini,"h_align", "center");
12608       NI_set_attribute(nini,"shadow","yes"); /* Not ready for prime time */
12609       v = topscr;
12610    }
12611    NI_SET_FLOATv( nini, "coord", v, 3);
12612    NI_set_attribute(nini,"text", lbls);
12613    NI_set_attribute(nini, "font", SUMA_EnvVal("SUMA_CrossHairLabelFont"));
12614    for (i=0;i<3;++i) default_color[i] = 1.0 - sv->clear_color[i];
12615    NI_SET_FLOATv( nini, "col", default_color,3);
12616 
12617    NI_add_to_group(nido->ngr, nini);
12618 
12619    if (sv) {
12620       /* addDO (repeated nidos will get replaced)
12621          As long as its ID remains the same, then
12622          SUMA_AddDO, will free its precursor and
12623          replace with the new one*/
12624       if (!SUMA_AddDO(SUMAg_DOv, &SUMAg_N_DOv, (void *)nido,
12625                       NIDO_type, coord_type)) {
12626          fprintf( SUMA_STDERR,"Error %s: Failed in SUMA_AddDO. (leak)\n",
12627                   FuncName);
12628          SUMA_RETURN(NULL);
12629       }
12630 
12631       /* register DO with viewer */
12632       if (!SUMA_RegisterDO(SUMAg_N_DOv-1, sv)) {
12633          fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_RegisterDO. (leak)\n",
12634                  FuncName);
12635          SUMA_RETURN(NULL);
12636       }
12637    }
12638 
12639    SUMA_RETURN(nido);
12640 }
12641 
SUMA_UpdateNodeLblField(SUMA_ALL_DO * ado)12642 SUMA_Boolean SUMA_UpdateNodeLblField(SUMA_ALL_DO *ado)
12643 {
12644    static char FuncName[]={"SUMA_UpdateNodeLblField"};
12645 
12646    if (!ado) return(NOPE);
12647    switch(ado->do_type) {
12648       case SO_type: {
12649          return(SUMA_UpdateNodeLblField_ADO(ado));
12650          break; }
12651       case GDSET_type: {
12652          SUMA_S_Warn("Should I be updating this guy and not it GLDO?");
12653          return(YUP);
12654          break; }
12655       case CDOM_type:
12656       case VO_type:
12657       case TRACT_type:
12658       case MASK_type:
12659       case GRAPH_LINK_type: {
12660          return(SUMA_UpdateNodeLblField_ADO(ado));
12661          break; }
12662       default:
12663          SUMA_S_Errv("Bad type %s for this function\n",
12664                   SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
12665          return(NOPE);
12666    }
12667    return(NOPE);
12668 }
12669 
12670 /*!
12671    Updates places where a node's value is shown
12672 */
SUMA_UpdateNodeLblField_ADO(SUMA_ALL_DO * ado)12673 SUMA_Boolean SUMA_UpdateNodeLblField_ADO(SUMA_ALL_DO *ado)
12674 {
12675    static char FuncName[]={"SUMA_UpdateNodeLblField_ADO"};
12676    int Found = -1;
12677    char *lbls=NULL, *ltmp=NULL;
12678    char str_col[101];
12679    SUMA_OVERLAYS *Sover=NULL;
12680    SUMA_X_SurfCont *SurfCont=NULL;
12681    SUMA_Boolean LocalHead = NOPE;
12682 
12683    SUMA_ENTRY;
12684 
12685    if (!ado || (!(SurfCont=SUMA_ADO_Cont(ado))
12686                   && !SUMAg_CF->X->Whereami_TextShell)) {
12687       /* absolutely nothing to do */
12688       SUMA_RETURN(NOPE);
12689    }
12690 
12691    switch(ado->do_type) {
12692       case CDOM_type:
12693       case VO_type:
12694       case GRAPH_LINK_type:
12695       case MASK_type:
12696       case TRACT_type:
12697       case SO_type:
12698          /* get labels from Label Datasets, and update whereami
12699             window if needed*/
12700          lbls = SUMA_GetLabelsAtSelection_ADO(ado,
12701                                        SUMA_ADO_SelectedDatum(ado, NULL, NULL),
12702                                               SUMA_ADO_SelectedSecondary(ado));
12703          SUMA_LHv("Label Dsets: %s\n", lbls);
12704          break;
12705       case GDSET_type:
12706          SUMA_S_Warn("Should be using GRAPH_LINK_type instead");
12707          break;
12708       default:
12709          break;
12710    }
12711 
12712 
12713    if (SurfCont && SurfCont->LabelTable && SurfCont->LabelTable->cells) {
12714       Sover = SUMA_ADO_CurColPlane(ado);
12715       if (!Sover) {
12716          SUMA_RETURN(NOPE);
12717       }
12718       /* seems the '!' were remnants -                                 */
12719       /* revert to original logic, but avoid warnings
12720        * (to later evaluate changes) todo: apply ShowMode
12721        *   original     : if (!Sover->ShowMode > 0)
12722        *   fix??        : if ( Sover->ShowMode > 0)
12723        *                  - seems like we want to actually show here
12724        *   temp.as.orig : if ( !Sover->ShowMode )
12725        *
12726        *   comment      : orig/temp would only show on 0,
12727        *                  which does not make sense
12728        *                : since block adds, prob a show>0 condition
12729        *                                           19 Feb 2021 [rickr] */
12730       if ( ! Sover->ShowMode ) {
12731          SUMA_LH("Col plane hidden");
12732          sprintf(str_col,"hidden color overlay");
12733          if (lbls) lbls = SUMA_append_replace_string(lbls, str_col, "; col=", 1);
12734          else lbls = SUMA_copy_string(str_col);
12735          SUMA_INSERT_CELL_STRING(SurfCont->LabelTable, 0, 1, lbls);
12736          if (lbls) SUMA_free(lbls); lbls = NULL;
12737          SUMA_RETURN(YUP);
12738       }
12739 
12740       Found = SUMA_GetNodeOverInd(Sover,
12741                                   SUMA_ADO_ColPlane_SelectedDatum(ado, Sover));
12742 
12743       if (Found < 0) {
12744          SUMA_Boolean Reasoned = NOPE;
12745          SUMA_LH("Node not found.\nLikely masked by threshold");
12746          sprintf(str_col,"masked");
12747          /* try to find out why it is masked */
12748          if (!Reasoned && SurfCont->DataTable) {
12749             SUMA_LH("Checking if there is no data for this node");
12750             {
12751                void *n=NULL;
12752                XtVaGetValues(
12753                SurfCont->DataTable->cells[1*SurfCont->DataTable->Ni+1],
12754                   XmNvalue, &n, NULL);
12755                if (strcmp((char *)n, "NoData") == 0) {
12756                   /* no data at all */
12757                   sprintf(str_col,"no data for this node");
12758                   Reasoned = YUP;
12759                }
12760             }
12761          }
12762          if (!Reasoned && SurfCont->DataTable) { /* is the value 0 ? */
12763             SUMA_LH("Checking if node value is zero & zero is not being shown");
12764             if (Sover->OptScl->MaskZero &&
12765                   SurfCont->DataTable->num_value[1*SurfCont->DataTable->Ni+1]) {
12766                sprintf(str_col,"masked by zero value");
12767             }
12768          }
12769       } else {
12770          {
12771             /* Now we know what the index of this node
12772                is in the overlay plane (and the data) */
12773             sprintf(str_col,"%s",
12774                             MV_format_fval2(Sover->ColVec[3*Found],5));
12775             SUMA_strncat( str_col,", ", 100);
12776             SUMA_strncat( str_col,
12777                            MV_format_fval2(Sover->ColVec[3*Found+1],5), 100);
12778             SUMA_strncat( str_col,", ", 100);
12779             SUMA_strncat( str_col,
12780                            MV_format_fval2(Sover->ColVec[3*Found+2],5), 100);
12781             SUMA_LH("%s", str_col);
12782          }
12783       }
12784       if (lbls) ltmp = SUMA_append_replace_string(lbls, str_col, "; col=", 0);
12785       else ltmp = SUMA_copy_string(str_col);
12786       SUMA_INSERT_CELL_STRING(SurfCont->LabelTable, 0, 1, ltmp);
12787       SUMA_free(ltmp); ltmp=NULL;
12788    }
12789 
12790    if (lbls) SUMA_free(lbls); lbls = NULL;
12791 
12792    SUMA_RETURN(YUP);
12793 }
12794 
12795 
SUMA_UpdateCrossHairNodeLabelField(SUMA_SurfaceViewer * sv)12796 SUMA_Boolean SUMA_UpdateCrossHairNodeLabelField(SUMA_SurfaceViewer *sv)
12797 {
12798    static char FuncName[]={"SUMA_UpdateCrossHairNodeLabelField"};
12799    char *lbls=NULL;
12800    SUMA_ALL_DO *ado=NULL;
12801    SUMA_Boolean LocalHead = NOPE;
12802 
12803    SUMA_ENTRY;
12804 
12805    if (!sv || !sv->Ch || sv->Ch->adoID < 0) {
12806       /* nothing to do */
12807       SUMA_RETURN(NOPE);
12808    }
12809 
12810    if (!(ado = (SUMA_ALL_DO *)(SUMAg_DOv[sv->Ch->adoID].OP))) {
12811       SUMA_RETURN(NOPE);
12812    }
12813    if ( sv->ShowLabelAtXhair &&
12814        (lbls = SUMA_GetLabelsAtSelection(ado, sv->Ch->datumID, sv->Ch->secID))) {
12815       SUMA_LH("Got %s (%d)",lbls, sv->ShowLabelAtXhair);
12816       SUMA_NodeLabelToTextNIDO (lbls, ado, sv);
12817       SUMA_free(lbls); lbls = NULL;
12818    } else {
12819       SUMA_LH("Got NOTHING or %d", sv->ShowLabelAtXhair);
12820       SUMA_NodeLabelToTextNIDO ("", ado, sv);
12821    }
12822 
12823    SUMA_RETURN(YUP);
12824 }
12825 
SUMA_UpdateCrossHairNodeLabelFieldForDO(SUMA_ALL_DO * curDO)12826 int SUMA_UpdateCrossHairNodeLabelFieldForDO(SUMA_ALL_DO *curDO)
12827 {
12828    static char FuncName[]={"SUMA_UpdateCrossHairNodeLabelFieldForDO"};
12829    int i=0, iup=0;
12830    SUMA_SurfaceViewer *sv=NULL;
12831 
12832    SUMA_ENTRY;
12833 
12834    if (!curDO) SUMA_RETURN(0);
12835 
12836    /* update any viewer that is showing this
12837       surface */
12838    for (i=0; i<SUMAg_N_SVv; ++i) {
12839       if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
12840          /* is this viewer showing curDO ? */
12841          if (SUMA_isRegisteredDO(&(SUMAg_SVv[i]), SUMAg_DOv, curDO)) {
12842             sv = &(SUMAg_SVv[i]);
12843             SUMA_UpdateCrossHairNodeLabelField(sv);
12844             ++iup;
12845          }
12846       }
12847    }
12848 
12849    SUMA_RETURN(iup);
12850 }
12851 
12852 
SUMA_UpdateTriField(SUMA_SurfaceObject * SO)12853 SUMA_Boolean SUMA_UpdateTriField(SUMA_SurfaceObject *SO)
12854 {
12855    static char FuncName[]={"SUMA_UpdateTriField"};
12856    SUMA_SurfaceObject *curSO=NULL;
12857    char str[100];
12858    SUMA_Boolean LocalHead = NOPE;
12859 
12860    SUMA_ENTRY;
12861 
12862    if (!SO) SUMA_RETURN(NOPE);
12863 
12864    if (SO->SurfCont) {
12865       if (!SO->SurfCont->FaceTable||
12866           !SO->SurfCont->FaceTable->num_value) { /* table widgets not set yet ?*/
12867          SUMA_RETURN(NOPE);
12868       }
12869 
12870       if (!(curSO=(SUMA_SurfaceObject *)SUMA_SurfCont_GetcurDOp(SO->SurfCont))) {
12871          SUMA_S_Err("Failed to get curDOp");
12872          SUMA_RETURN(NOPE);
12873       }
12874       if (curSO == SO) {
12875          if (SO->SelectedFaceSet >= 0) {
12876             sprintf(str, "%d", SO->SelectedFaceSet);
12877             SO->SurfCont->FaceTable->num_value[1] = SO->SelectedFaceSet;
12878             XtVaSetValues(SO->SurfCont->FaceTable->cells[1],
12879                           XmNvalue, str, NULL);
12880             sprintf(str, "%d, %d, %d",
12881                SO->FaceSetList[3*SO->SelectedFaceSet],
12882                SO->FaceSetList[3*SO->SelectedFaceSet+1],
12883                SO->FaceSetList[3*SO->SelectedFaceSet+2]);
12884             XtVaSetValues(SO->SurfCont->FaceTable->cells[2],
12885                           XmNvalue, str, NULL);
12886          } else {
12887             XtVaSetValues(SO->SurfCont->FaceTable->cells[1],
12888                           XmNvalue, "-1", NULL);
12889             SO->SurfCont->FaceTable->num_value[1] = -1;
12890             XtVaSetValues(SO->SurfCont->FaceTable->cells[2],
12891                           XmNvalue, "x, x, x", NULL);
12892          }
12893       }
12894    }
12895 
12896    SUMA_RETURN(YUP);
12897 
12898 }
12899 
12900 /*!
12901    \brief set the values of the cross-hair group in the surface controller
12902 
12903    \sa SUMA_Init_SurfCont_SurfParam
12904    \sa SUMA_InitializeColPlaneShell
12905    \sa the set of SUMA_UpdateNode*Field functions
12906 */
SUMA_Init_SurfCont_CrossHair(SUMA_ALL_DO * ado)12907 SUMA_Boolean SUMA_Init_SurfCont_CrossHair(SUMA_ALL_DO *ado)
12908 {
12909    static char FuncName[]={"SUMA_Init_SurfCont_CrossHair"};
12910    int i;
12911    SUMA_Boolean LocalHead = NOPE;
12912 
12913    SUMA_ENTRY;
12914 
12915    if (!ado) SUMA_RETURN(YUP);
12916 
12917    /* set the cross hair and related fields */
12918    switch (ado->do_type) {
12919       case SO_type:
12920          SUMA_UpdateTriField((SUMA_SurfaceObject *)ado);
12921          SUMA_UpdateNodeField(ado);
12922          break;
12923       case GDSET_type:
12924          SUMA_S_Err("No init for a DO that cannot be dispalyed\n"
12925                     "without variant");
12926          SUMA_RETURN(NOPE);
12927          break;
12928       case CDOM_type:
12929          SUMA_S_Err("So much to do, so little time"
12930                     "Probably something like SUMA_UpdateNodeField");
12931          SUMA_RETURN(NOPE);
12932          break;
12933       case GRAPH_LINK_type: {
12934          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
12935          SUMA_DSET *dset=NULL;
12936          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
12937             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
12938                         SUMA_ADO_Label(ado));
12939             SUMA_RETURN(NOPE);
12940          }
12941          SUMA_UpdatePointField(ado);
12942          SUMA_UpdateNodeField(ado);
12943          break; }
12944       case TRACT_type: {
12945          SUMA_UpdateNodeField(ado);
12946          break; }
12947       case MASK_type: {
12948          static int ncnt;
12949          if (!ncnt) {
12950             ++ncnt;
12951             SUMA_LH("Nothing to be done for masks here");
12952          }
12953          break; }
12954       case VO_type: {
12955          SUMA_UpdateNodeField(ado);
12956          break; }
12957       default:
12958          SUMA_S_Errv("Nothing to do with %s\n",
12959                SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
12960          SUMA_RETURN(NOPE);
12961    }
12962 
12963    /* look for a viewer that is showing this surface and has
12964       this surface in focus*/
12965    for (i=0; i<SUMAg_N_SVv; ++i) {
12966       if (LocalHead) fprintf (SUMA_STDERR,
12967                               "%s: Checking viewer %d.\n", FuncName, i);
12968       if (!SUMAg_SVv[i].isShaded && SUMAg_SVv[i].X->TOPLEVEL) {
12969          /* is this viewer showing DO ? */
12970          if (SUMA_isVisibleDO(&(SUMAg_SVv[i]), SUMAg_DOv, ado)) {
12971             if (SUMA_SV_Focus_ADO(&(SUMAg_SVv[i])) == ado) {
12972                SUMA_UpdateXhairField(&(SUMAg_SVv[i]));
12973             }
12974          }
12975       }
12976    }
12977 
12978    SUMA_RETURN(YUP);
12979 }
12980 
12981 /*!
12982    Load Cmap callback
12983    Expect SO in data
12984 */
SUMA_cb_Cmap_Load(Widget w,XtPointer data,XtPointer client_data)12985 void SUMA_cb_Cmap_Load(Widget w, XtPointer data, XtPointer client_data)
12986 {
12987    static char FuncName[]={"SUMA_cb_Cmap_Load"};
12988    SUMA_LIST_WIDGET *LW=NULL;
12989    SUMA_ALL_DO *ado=NULL;
12990    SUMA_X_SurfCont *SurfCont=NULL;
12991    DList *list = NULL;
12992    SUMA_EngineData *ED = NULL;
12993    DListElmt *NextElm = NULL;
12994    SUMA_Boolean LocalHead = NOPE;
12995 
12996    SUMA_ENTRY;
12997 
12998    SUMA_LH("Called");
12999 
13000    if (!(ado = (SUMA_ALL_DO *)data) || !(SurfCont = SUMA_ADO_Cont(ado))) {
13001       SUMA_S_Err("NULL input");
13002       SUMA_RETURNe;
13003    }
13004    if (!list) list = SUMA_CreateList();
13005    ED = SUMA_InitializeEngineListData (SE_OpenCmapFileSelection);
13006    if (!(NextElm = SUMA_RegisterEngineListCommand (  list, ED,
13007                                           SEF_vp, (void *)ado,
13008                                           SES_Suma, NULL, NOPE,
13009                                           SEI_Head, NULL))) {
13010       fprintf (SUMA_STDERR, "Error %s: Failed to register command.\n", FuncName);
13011    }
13012    SUMA_RegisterEngineListCommand (  list, ED,
13013                                      SEF_ip, (void *)SurfCont->TLS,
13014                                      SES_Suma, NULL, NOPE,
13015                                      SEI_In, NextElm);
13016    if (!SUMA_Engine (&list)) {
13017       fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName);
13018    }
13019 
13020    SUMA_RETURNe;
13021 }
13022 
SUMA_LoadCmapFile_eng(char * filename)13023 SUMA_COLOR_MAP *SUMA_LoadCmapFile_eng(char *filename)
13024 {
13025    static char FuncName[]={"SUMA_LoadCmapFile_eng"};
13026    SUMA_COLOR_MAP *Cmap=NULL;
13027    SUMA_DSET_FORMAT form;
13028    SUMA_Boolean LocalHead = NOPE;
13029 
13030    SUMA_ENTRY;
13031 
13032    /* find out if file exists and how many values it contains */
13033    if (!SUMA_filexists(filename)) {
13034       SUMA_S_Err("File not found");
13035       SUMA_RETURN(NULL);
13036    }
13037 
13038    /* take a stab at the format */
13039    form = SUMA_GuessFormatFromExtension(filename, NULL);
13040 
13041    /* load the baby */
13042    Cmap = NULL;
13043    switch (form) {
13044       case  SUMA_1D:
13045          Cmap = SUMA_Read_Color_Map_1D (filename);
13046          if (Cmap == NULL) {
13047             SUMA_S_Err("Could not load colormap.");
13048             SUMA_RETURN(NULL);
13049          }
13050          break;
13051       case SUMA_ASCII_NIML:
13052       case SUMA_BINARY_NIML:
13053       case SUMA_NIML:
13054          Cmap = SUMA_Read_Color_Map_NIML(filename);
13055          break;
13056       default:
13057          SUMA_S_Err(  "Format not recognized.\n"
13058                        "I won't try to guess.\n"
13059                        "Do use the proper extension.");
13060          break;
13061    }
13062 
13063    SUMA_RETURN(Cmap);
13064 }
13065 
13066 /*! Loads a colormap file and adds it to the list of colormaps */
SUMA_LoadCmapFile(char * filename,void * data)13067 void SUMA_LoadCmapFile (char *filename, void *data)
13068 {
13069    static char FuncName[]={"SUMA_LoadCmapFile"};
13070    SUMA_ALL_DO *ado = NULL;
13071    SUMA_IRGB *irgb=NULL;
13072    int OverInd = -1, lnp=-1, loc[2];
13073    char *np=NULL;
13074    int bringup = 0;
13075    SUMA_DSET_FORMAT form;
13076    DList *list=NULL;
13077    SUMA_LIST_WIDGET *LW=NULL;
13078    SUMA_COLOR_MAP *Cmap=NULL;
13079    SUMA_PARSED_NAME * pn=NULL;
13080    SUMA_Boolean LocalHead = NOPE;
13081 
13082    SUMA_ENTRY;
13083 
13084    if (!SUMAg_CF->scm) {
13085       SUMAg_CF->scm = SUMA_Build_Color_maps();
13086       if (!SUMAg_CF->scm) {
13087          SUMA_SL_Err("Failed to build color maps.\n");
13088          SUMA_RETURNe;
13089       }
13090    }
13091 
13092    if (LocalHead) {
13093       fprintf (SUMA_STDERR,
13094                "%s: Received request to load %s \n",
13095                FuncName, filename);
13096    }
13097 
13098    if (!SUMA_filexists(filename)) {
13099       SUMA_SLP_Err("File not found");
13100       SUMA_RETURNe;
13101    }
13102 
13103    if (!(Cmap=SUMA_LoadCmapFile_eng(filename))) {
13104       SUMA_SLP_Err("Failed to load cmap. File format may not have been\n"
13105                    "recognized from filename extension.\n"
13106                    "Use either .1D.cmap or .niml.cmap for name extension.\n");
13107       SUMA_RETURNe;
13108    }
13109    /* have Cmap, add to dbase */
13110 
13111    /* remove path from name for pretty purposes */
13112    pn = SUMA_ParseFname(Cmap->Name, NULL);
13113    SUMA_STRING_REPLACE(Cmap->Name, pn->FileName_NoExt);
13114    SUMA_Free_Parsed_Name(pn); pn = NULL;
13115    SUMAg_CF->scm->CMv = SUMA_Add_ColorMap (Cmap, SUMAg_CF->scm->CMv,
13116                                              &(SUMAg_CF->scm->N_maps));
13117 
13118    /* Now you need to close any pre-existing switch Cmap window */
13119    bringup = 0;
13120    if (SUMAg_CF->X->SwitchCmapLst) {
13121       if (SUMAg_CF->X->SwitchCmapLst->toplevel &&
13122          !SUMAg_CF->X->SwitchCmapLst->isShaded) {
13123          /* close that baby */
13124          SUMA_cb_CloseSwitchCmap( NULL,  (XtPointer)SUMAg_CF->X->SwitchCmapLst,
13125                                   NULL);
13126          bringup = 1;
13127       }
13128    }
13129 
13130    if (data) {
13131       ado = (SUMA_ALL_DO *)data;
13132 
13133       if (LocalHead) {
13134          fprintf (SUMA_STDERR,
13135                   "%s: bonding colormap %s to surface %s.\n",
13136                   FuncName, filename, SUMA_ADO_Label(ado));
13137       }
13138 
13139       /* refresh the list */
13140       SUMA_CmapSelectList(ado, 1, bringup);
13141 
13142       /* update the menu buttons */
13143       SUMA_CreateUpdatableCmapMenu(ado);
13144 
13145       /* Set the menu button to the current choice */
13146       if (!SUMA_SetCmapMenuChoice (ado, Cmap->Name)) {
13147          SUMA_SL_Err("Failed in SUMA_SetCmapMenuChoice");
13148       }
13149 
13150       /* switch to the recently loaded  cmap */
13151       if (!SUMA_SwitchColPlaneCmap(ado, Cmap)) {
13152          SUMA_SL_Err("Failed in SUMA_SwitchColPlaneCmap");
13153       }
13154 
13155       /* update Lbl fields */
13156       SUMA_UpdateNodeLblField(ado);
13157    }
13158 
13159 
13160    SUMA_RETURNe;
13161 }
13162 
13163 /* Insert a color map from a dataset into the database.
13164    See function LoadCmapFile for details */
SUMA_Insert_Cmap_of_Dset(SUMA_DSET * dset)13165 SUMA_Boolean  SUMA_Insert_Cmap_of_Dset(SUMA_DSET *dset)
13166 {
13167    static char FuncName[]={"SUMA_Insert_Cmap_of_Dset"};
13168    NI_group *ngr=NULL;
13169    SUMA_COLOR_MAP *Cmap=NULL;
13170    SUMA_PARSED_NAME * pn=NULL;
13171 
13172    SUMA_ENTRY;
13173 
13174    if (!dset) SUMA_RETURN(NOPE);
13175    if (!SUMAg_CF->scm) {
13176       SUMAg_CF->scm = SUMA_Build_Color_maps();
13177       if (!SUMAg_CF->scm) {
13178          SUMA_SL_Err("Failed to build color maps.\n");
13179          SUMA_RETURN(NOPE);
13180       }
13181    }
13182 
13183    if (!(ngr = SUMA_NI_Cmap_of_Dset(dset))) {
13184       SUMA_RETURN(YUP); /* OK, nothing to do */
13185    }
13186 
13187    /* turn cmap into SUMA's structure */
13188    if (!(Cmap = SUMA_NICmapToCmap(ngr))) {
13189       SUMA_S_Err("Failed in translation");
13190       SUMA_RETURN(NOPE);
13191    }
13192 
13193    /* remove path from name for pretty purposes */
13194    pn = SUMA_ParseFname(Cmap->Name, NULL);
13195    SUMA_STRING_REPLACE(Cmap->Name, pn->FileName_NoExt);
13196    SUMA_Free_Parsed_Name(pn); pn = NULL;
13197    SUMAg_CF->scm->CMv = SUMA_Add_ColorMap (Cmap, SUMAg_CF->scm->CMv,
13198                                              &(SUMAg_CF->scm->N_maps));
13199 
13200    /* Set cmap name to go with dset SRT stands for SUMA_RUN_TIME attribute
13201    This might be a way to kill attributes before writing out dataset */
13202    NI_set_attribute(dset->ngr, "SRT_use_this_cmap", Cmap->Name);
13203 
13204    SUMA_RETURN(YUP);
13205 }
13206 
13207 
13208 /*!
13209    SUMA_ADO_CurColPlane: Return the current col plane for any DO
13210    This is meant to replace all of the old SO->SurfCont->curColPlane
13211 
13212    For some DO with a DOCont, such as DSET_type, the answer
13213    will be GSaux->Overlay
13214    For the rest the answer is NULL
13215 */
SUMA_ADO_CurColPlane(SUMA_ALL_DO * ado)13216 SUMA_OVERLAYS * SUMA_ADO_CurColPlane(SUMA_ALL_DO *ado)
13217 {
13218    static char FuncName[]={"SUMA_ADO_CurColPlane"};
13219    SUMA_Boolean LocalHead = NOPE;
13220 
13221    if (!ado) return(NULL);
13222    SUMA_LHv("Have %d\n", ado->do_type);
13223    switch(ado->do_type) {
13224       case SO_type: {
13225          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13226          if (!SO->SurfCont) return(NULL);
13227          return(SO->SurfCont->curColPlane);
13228          break; }
13229       case CDOM_type: {
13230          SUMA_CIFTI_SAUX *CSaux = SUMA_ADO_CSaux(ado);
13231          if (!CSaux || !CSaux->DOCont) return(NULL);
13232          return(CSaux->DOCont->curColPlane);
13233          break; }
13234       case GDSET_type: {
13235          SUMA_DSET *dset=(SUMA_DSET *)ado;
13236          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
13237          if (!GSaux) return(NULL);
13238          return(GSaux->Overlay);
13239          break; }
13240       case GRAPH_LINK_type: {
13241          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13242          SUMA_DSET *dset=NULL;
13243          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13244             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13245                         SUMA_ADO_Label(ado));
13246             return(NULL);
13247          }
13248          return(SUMA_ADO_CurColPlane((SUMA_ALL_DO *)dset));
13249          break; }
13250       case MASK_type: {
13251          SUMA_MASK_SAUX *MSaux = SUMA_ADO_MSaux(ado);
13252          if (!MSaux || !MSaux->DOCont) return(NULL);
13253          return(MSaux->DOCont->curColPlane);
13254          break; }
13255       case TRACT_type: {
13256          SUMA_TRACT_SAUX *TSaux = SUMA_ADO_TSaux(ado);
13257          if (!TSaux || !TSaux->DOCont) return(NULL);
13258          return(TSaux->DOCont->curColPlane);
13259          break; }
13260       case VO_type: {
13261          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
13262          if (!VSaux || !VSaux->DOCont) return(NULL);
13263          return(VSaux->DOCont->curColPlane);
13264          break; }
13265       default:
13266          return(NULL);
13267    }
13268    return(NULL);
13269 }
13270 
SUMA_ADO_Overlay0(SUMA_ALL_DO * ado)13271 SUMA_OVERLAYS * SUMA_ADO_Overlay0(SUMA_ALL_DO *ado)
13272 {
13273    static char FuncName[]={"SUMA_ADO_Overlay0"};
13274    return(SUMA_ADO_Overlay(ado, 0));
13275 }
13276 
SUMA_ADO_Overlay(SUMA_ALL_DO * ado,int i)13277 SUMA_OVERLAYS * SUMA_ADO_Overlay(SUMA_ALL_DO *ado, int i)
13278 {
13279    static char FuncName[]={"SUMA_ADO_Overlay"};
13280    SUMA_OVERLAYS **overlays=NULL;
13281    int N_over=0;
13282 
13283    if (!ado || i<0) return(NULL);
13284    if ((overlays = SUMA_ADO_Overlays(ado, &N_over))) {
13285       if (i < N_over) return(overlays[i]);
13286    }
13287    return(NULL);
13288 }
13289 
SUMA_ADO_Append_Overlay(SUMA_ALL_DO * ado,SUMA_OVERLAYS ** over)13290 SUMA_Boolean SUMA_ADO_Append_Overlay(SUMA_ALL_DO *ado, SUMA_OVERLAYS **over)
13291 {
13292    static char FuncName[]={"SUMA_ADO_Append_Overlay"};
13293    SUMA_OVERLAYS ** overlays = NULL;
13294    int N_over = -1;
13295 
13296    SUMA_ENTRY;
13297 
13298    if (!over || !*over) {
13299       SUMA_S_Err("No overlay to add !");
13300       SUMA_RETURN (NOPE);
13301    }
13302    overlays = SUMA_ADO_Overlays(ado, &N_over);
13303    if (!overlays || N_over < 0) {
13304       SUMA_S_Err("No overlays (%p) or N_over (%d)", overlays, N_over);
13305       SUMA_RETURN (NOPE);
13306    }
13307 
13308    if (N_over+1 >= SUMA_MAX_OVERLAYS) {
13309       SUMA_SL_Crit("Too many color overlays.");
13310       SUMA_RETURN (NOPE);
13311    }
13312 
13313    switch (ado->do_type) {
13314       case SO_type: {
13315          SUMA_SurfaceObject *SO = (SUMA_SurfaceObject *)ado;
13316          SUMA_S_Warn("Case not tested yet");
13317          overlays[N_over] = *over;
13318          *over = NULL;
13319          ++SO->N_Overlays;
13320          break; }
13321       case TRACT_type: {
13322          SUMA_TractDO *tdo = (SUMA_TractDO *)ado;
13323          SUMA_TRACT_SAUX *TSaux = SUMA_ADO_TSaux(ado);
13324          overlays[N_over] = *over;
13325          *over = NULL;
13326          ++TSaux->N_Overlays;
13327          break; }
13328       case MASK_type: {
13329          SUMA_MaskDO *mdo = (SUMA_MaskDO *)ado;
13330          SUMA_MASK_SAUX *MSaux = SUMA_ADO_MSaux(ado);
13331          overlays[N_over] = *over;
13332          *over = NULL;
13333          ++MSaux->N_Overlays;
13334          break; }
13335       case VO_type: {
13336          SUMA_VolumeObject *vo = (SUMA_VolumeObject *)ado;
13337          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
13338          overlays[N_over] = *over;
13339          *over = NULL;
13340          ++VSaux->N_Overlays;
13341          break; }
13342       case CDOM_type: {
13343          SUMA_CIFTI_SAUX *CSaux = SUMA_ADO_CSaux(ado);
13344          overlays[N_over] = *over;
13345          *over = NULL;
13346          ++CSaux->N_Overlays;
13347          break; }
13348       case GDSET_type: {
13349          SUMA_DSET *dset=(SUMA_DSET *)ado;
13350          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
13351          SUMA_S_Warn("Case not tested yet");
13352          if (!GSaux) {
13353             SUMA_S_Err("NULL GSaux");
13354             SUMA_RETURN(NOPE);
13355          }
13356          if (N_over > 0) {
13357             SUMA_S_Err("Not ready or shouldn't add more than one overlay \n"
13358                        "for dsets");
13359             SUMA_RETURN(NOPE);
13360          }
13361          GSaux->Overlay = *over;
13362          *over = NULL;
13363          break; }
13364       case GRAPH_LINK_type: {
13365          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13366          SUMA_DSET *dset=NULL;
13367          SUMA_Boolean ans = NOPE;
13368          SUMA_S_Warn("Case not tested yet");
13369          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13370             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13371                         SUMA_ADO_Label(ado));
13372             SUMA_RETURN(NOPE);
13373          }
13374          ans = SUMA_ADO_Append_Overlay((SUMA_ALL_DO *)dset, over);
13375          if (!ans) SUMA_RETURN(NOPE);
13376          *over = NULL;
13377          break; }
13378       default:
13379          SUMA_S_Err("Not ready for %d\n", ado->do_type);
13380          SUMA_RETURN(NOPE);
13381          break;
13382    }
13383 
13384    SUMA_RETURN(YUP);
13385 }
13386 
SUMA_ADO_Overlays(SUMA_ALL_DO * ado,int * N_over)13387 SUMA_OVERLAYS **  SUMA_ADO_Overlays(SUMA_ALL_DO *ado, int *N_over)
13388 {
13389    static char FuncName[]={"SUMA_ADO_Overlays"};
13390 
13391    if (!ado) return(NULL);
13392 
13393    if (N_over) *N_over = -1;
13394 
13395    switch(ado->do_type) {
13396       case SO_type: {
13397          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13398          if (N_over) *N_over = SO->N_Overlays;
13399          return(SO->Overlays);
13400          break; }
13401       case CDOM_type: {
13402          SUMA_CIFTI_SAUX *CSaux = SUMA_ADO_CSaux(ado);
13403          if (!CSaux) return(NULL);
13404          if (N_over) *N_over = CSaux->N_Overlays;
13405          return(CSaux->Overlays);
13406          break; }
13407       case GDSET_type: {
13408          SUMA_DSET *dset=(SUMA_DSET *)ado;
13409          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
13410          if (!GSaux || !GSaux->Overlay) return(NULL);
13411          if (N_over) *N_over = 1;
13412          return(&(GSaux->Overlay));
13413          break; }
13414       case GRAPH_LINK_type: {
13415          int N_n;
13416          SUMA_OVERLAYS **oo=NULL;
13417          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13418          SUMA_DSET *dset=NULL;
13419          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13420             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13421                         SUMA_ADO_Label(ado));
13422             return(NULL);
13423          }
13424          if ((oo = SUMA_ADO_Overlays((SUMA_ALL_DO *)dset, &N_n))){
13425             if (N_over) *N_over = N_n;
13426             return(oo);
13427          }
13428          break; }
13429       case TRACT_type: {
13430          SUMA_TRACT_SAUX *TSaux = SUMA_ADO_TSaux(ado);
13431          if (!TSaux) return(NULL);
13432          if (N_over) *N_over = TSaux->N_Overlays;
13433          return(TSaux->Overlays);
13434          break; }
13435       case MASK_type: {
13436          SUMA_MASK_SAUX *MSaux = SUMA_ADO_MSaux(ado);
13437          if (!MSaux) return(NULL);
13438          if (N_over) *N_over = MSaux->N_Overlays;
13439          return(MSaux->Overlays);
13440          break; }
13441       case VO_type: {
13442          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
13443          if (!VSaux) return(NULL);
13444          if (N_over) *N_over = VSaux->N_Overlays;
13445          return(VSaux->Overlays);
13446          break; }
13447       default:
13448          return(NULL);
13449    }
13450    return(NULL);
13451 }
13452 
13453 
SUMA_ADO_N_Overlays(SUMA_ALL_DO * ado)13454 int SUMA_ADO_N_Overlays(SUMA_ALL_DO *ado)
13455 {
13456    static char FuncName[]={"SUMA_ADO_N_Overlays"};
13457    if (!ado) return(-1);
13458    switch(ado->do_type) {
13459       case SO_type: {
13460          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13461          return(SO->N_Overlays);
13462          break; }
13463       case CDOM_type: {
13464          SUMA_CIFTI_SAUX *CSaux = SUMA_ADO_CSaux(ado);
13465          if (!CSaux) return(-1);
13466          return(CSaux->N_Overlays);
13467          break; }
13468       case GDSET_type: {
13469          SUMA_DSET *dset=(SUMA_DSET *)ado;
13470          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
13471          if (!GSaux) return(-1);
13472          return(1);
13473          break; }
13474       case GRAPH_LINK_type: {
13475          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13476          SUMA_DSET *dset=NULL;
13477          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13478             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13479                         SUMA_ADO_Label(ado));
13480             return(-1);
13481          }
13482          return(SUMA_ADO_N_Overlays((SUMA_ALL_DO *)dset));
13483          break; }
13484       case TRACT_type: {
13485          SUMA_TRACT_SAUX *TSaux = SUMA_ADO_TSaux(ado);
13486          if (!TSaux) return(-1);
13487          return(TSaux->N_Overlays);
13488          break; }
13489       case MASK_type: {
13490          SUMA_MASK_SAUX *MSaux = SUMA_ADO_MSaux(ado);
13491          if (!MSaux) return(-1);
13492          return(MSaux->N_Overlays);
13493          break; }
13494       case VO_type: {
13495          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
13496          if (!VSaux) return(-1);
13497          return(VSaux->N_Overlays);
13498          break; }
13499 
13500       default:
13501          return(-1);
13502    }
13503    return(-1);
13504 }
13505 
13506 /*!
13507    This function returns a selected datum for a DO
13508    For surfaces, this is always SurfCont->SelectedNode
13509    For SDSETs, it is GSaux->PR->datum_index
13510 */
SUMA_ADO_SelectedDatum(SUMA_ALL_DO * ado,void * extra,void * extra2)13511 int SUMA_ADO_SelectedDatum(SUMA_ALL_DO *ado, void *extra, void *extra2)
13512 {
13513    static char FuncName[]={"SUMA_ADO_SelectedDatum"};
13514    SUMA_Boolean LocalHead = NOPE;
13515 
13516    if (!ado) return(-1);
13517    SUMA_LHv("Here with %d (%s), %s\n",
13518              ado->do_type, ADO_TNAME(ado), SUMA_ADO_Label(ado));
13519    switch(ado->do_type) {
13520       case SO_type: {
13521          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13522          return(SO->SelectedNode);
13523          break; }
13524       case CDOM_type: {
13525          SUMA_CIFTI_SAUX *CSaux = SUMA_ADO_CSaux(ado);
13526          if (!CSaux) return(-1);
13527          /* Plenty of room to return extras, once we figure those out.
13528             Selections could be on surfaces or volumes so what needs
13529             to be filled out in the extras will depend on the type of
13530             domain over which the selection was made. */
13531          return(CSaux->PR->datum_index);
13532          break; }
13533       case GDSET_type: {
13534          SUMA_DSET *dset=(SUMA_DSET *)ado;
13535          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
13536          if (!GSaux) return(-1);
13537          return(GSaux->PR->datum_index);
13538          break; }
13539       case GRAPH_LINK_type: {
13540          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13541          SUMA_DSET *dset=NULL;
13542          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13543             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13544                         SUMA_ADO_Label(ado));
13545             return(-1);
13546          }
13547          return(SUMA_ADO_SelectedDatum((SUMA_ALL_DO *)dset, extra, extra2));
13548          break; }
13549       case TRACT_type: {
13550          SUMA_TRACT_SAUX *TSaux = SUMA_ADO_TSaux(ado);
13551          if (!TSaux) return(-1);
13552          if (extra) {
13553             int *ivsel = (int *)extra;
13554             ivsel[SUMA_NET_BUN] = TSaux->PR->iAltSel[SUMA_NET_BUN];
13555             ivsel[SUMA_BUN_TRC] = TSaux->PR->iAltSel[SUMA_BUN_TRC];
13556             ivsel[SUMA_TRC_PNT] = TSaux->PR->iAltSel[SUMA_TRC_PNT];
13557             ivsel[SUMA_NET_TRC] = TSaux->PR->iAltSel[SUMA_NET_TRC];
13558          }
13559          return(TSaux->PR->datum_index);
13560          break; }
13561       case VO_type: {
13562          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
13563          if (!VSaux) return(-1);
13564          if (extra) {
13565             int *ivsel = (int *)extra;
13566             ivsel[SUMA_VOL_I] = VSaux->PR->iAltSel[SUMA_VOL_I];
13567             ivsel[SUMA_VOL_J] = VSaux->PR->iAltSel[SUMA_VOL_J];
13568             ivsel[SUMA_VOL_K] = VSaux->PR->iAltSel[SUMA_VOL_K];
13569             ivsel[SUMA_VOL_IJK] = VSaux->PR->iAltSel[SUMA_VOL_IJK];
13570          }
13571          if (extra2) {
13572             float *fvsel = (float *)extra2;
13573             fvsel[SUMA_VOL_SLC_EQ0] = VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ0];
13574             fvsel[SUMA_VOL_SLC_EQ1] = VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ1];
13575             fvsel[SUMA_VOL_SLC_EQ2] = VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ2];
13576             fvsel[SUMA_VOL_SLC_EQ3] = VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ3];
13577          }
13578 
13579          return(VSaux->PR->datum_index);
13580          break; }
13581       case MASK_type: {
13582          static int ncnt=0;
13583          if (!ncnt) {
13584             SUMA_S_Warn("Not ready for mask objects, returning 0"); ++ncnt;
13585          }
13586          return(0);
13587          break; }
13588       default:
13589          return(-1);
13590    }
13591    return(-1);
13592 }
13593 
13594 /*!
13595    This function returns secondary selections a DO
13596    For surfaces, this is always SurfCont->SelectedFaceSet
13597    For SDSETs, it is GSaux->PR->iAltSel[SUMA_ENODE_0]
13598 */
SUMA_ADO_SelectedSecondary(SUMA_ALL_DO * ado)13599 int SUMA_ADO_SelectedSecondary(SUMA_ALL_DO *ado)
13600 {
13601    static char FuncName[]={"SUMA_ADO_SelectedSecondary"};
13602    SUMA_Boolean LocalHead = NOPE;
13603 
13604    if (!ado) return(-1);
13605    SUMA_LHv("Here with %d (%s), %s\n",
13606              ado->do_type, ADO_TNAME(ado), SUMA_ADO_Label(ado));
13607    switch(ado->do_type) {
13608       case SO_type: {
13609          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13610          return(SO->SelectedFaceSet);
13611          break; }
13612       case CDOM_type: {
13613          SUMA_S_Err("What gets set will depend on  PR->primitive. \n"
13614                     "Consider SUMA_ADO_SelectedSecondary() and ponder away.");
13615          return(-1);
13616          break; }
13617       case GDSET_type: {
13618          SUMA_DSET *dset=(SUMA_DSET *)ado;
13619          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
13620          if (!GSaux) return(-1);
13621          return(GSaux->PR->iAltSel[SUMA_ENODE_0]);
13622          break; }
13623       case GRAPH_LINK_type: {
13624          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13625          SUMA_DSET *dset=NULL;
13626          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13627             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13628                         SUMA_ADO_Label(ado));
13629             return(-1);
13630          }
13631          return(SUMA_ADO_SelectedSecondary((SUMA_ALL_DO *)dset));
13632          break; }
13633       case TRACT_type: {
13634          SUMA_LH("No secondary selections on tracts.");
13635          return(-1);
13636          break; }
13637       case MASK_type: {
13638          SUMA_LH("No secondary selections on masks.");
13639          return(-1);
13640          break; }
13641       case VO_type: {
13642          SUMA_LH("No secondary selections on volumes.");
13643          return(-1);
13644          break; }
13645       default:
13646          return(-1);
13647    }
13648    return(-1);
13649 }
13650 
13651 /* Was what was selected a primitive of the DO that carries
13652    data ?
13653    A selected edge on a graph would return YES
13654    A selected node on a graph would return NOPE
13655 */
SUMA_is_ADO_Datum_Primitive(SUMA_ALL_DO * ado,SUMA_COLID_OFFSET_DATUM * codf)13656 SUMA_Boolean SUMA_is_ADO_Datum_Primitive(SUMA_ALL_DO *ado,
13657                                           SUMA_COLID_OFFSET_DATUM *codf)
13658 {
13659    static char FuncName[]={"SUMA_is_ADO_Datum_Primitive"};
13660 
13661    if (!ado || !codf) return(NOPE);
13662 
13663    switch (ado->do_type) {
13664       case VO_type:
13665       case CDOM_type:
13666       case SO_type:
13667          SUMA_S_Err("Function not ready to handle colid selection modes"
13668                     "on surfaces or volumes");
13669          break;
13670       case GDSET_type:
13671       case GRAPH_LINK_type:
13672          if (codf->primitive && !strcmp(codf->primitive,"segments"))
13673             return(YUP);
13674          break;
13675       default:
13676          SUMA_S_Errv("Not ready to deal with type %s\n",
13677               SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
13678          break;
13679    }
13680 
13681    return(NOPE);
13682 }
13683 
SUMA_ADO_Set_SelectedDatum(SUMA_ALL_DO * ado,int sel,void * extra,void * extra2)13684 SUMA_Boolean SUMA_ADO_Set_SelectedDatum(SUMA_ALL_DO *ado, int sel,
13685                                         void *extra, void *extra2)
13686 {
13687    static char FuncName[]={"SUMA_ADO_Set_SelectedDatum"};
13688    if (!ado) return(0);
13689    switch(ado->do_type) {
13690       case SO_type: {
13691          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13692          if (!SO->SurfCont) return(0);
13693          SO->SelectedNode = sel;
13694          return(1);
13695          break; }
13696       case CDOM_type: {
13697          SUMA_CIFTI_DO *co = (SUMA_CIFTI_DO *)ado;
13698          SUMA_CIFTI_SAUX *CSaux = SUMA_ADO_CSaux(ado);
13699          int it, ip, ib, l1, *iv = (int *)extra;
13700          CSaux->PR->datum_index = sel;
13701          if (extra) {
13702             SUMA_S_Err("Not ready for extra");
13703          } else {
13704             /* Will need to setup other PR fields once we decide on extras */
13705          }
13706          break; }
13707       case GDSET_type: {
13708          SUMA_DSET *dset=(SUMA_DSET *)ado;
13709          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
13710          if (!GSaux) return(0);
13711          GSaux->PR->datum_index = sel;
13712          return(1);
13713          break; }
13714       case GRAPH_LINK_type: {
13715          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13716          SUMA_DSET *dset=NULL;
13717          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13718             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13719                         SUMA_ADO_Label(ado));
13720             return(0);
13721          }
13722          return(SUMA_ADO_Set_SelectedDatum((SUMA_ALL_DO *)dset, sel,
13723                                            extra, extra2));
13724          break; }
13725       case TRACT_type: {
13726          SUMA_TractDO *tdo = (SUMA_TractDO *)ado;
13727          SUMA_TRACT_SAUX *TSaux = SUMA_ADO_TSaux(ado);
13728          int it, ip, ib, l1, *iv = (int *)extra;
13729          TSaux->PR->datum_index = sel;
13730          if (extra) {
13731             TSaux->PR->iAltSel[SUMA_NET_BUN] = iv[SUMA_NET_BUN];
13732             TSaux->PR->iAltSel[SUMA_BUN_TRC] = iv[SUMA_BUN_TRC];
13733             TSaux->PR->iAltSel[SUMA_TRC_PNT] = iv[SUMA_TRC_PNT];
13734             TSaux->PR->iAltSel[SUMA_NET_TRC] = iv[SUMA_NET_TRC];
13735          } else {
13736             TSaux->PR->iAltSel[SUMA_NET_BUN] = TSaux->PR->iAltSel[SUMA_BUN_TRC] =
13737             TSaux->PR->iAltSel[SUMA_TRC_PNT] =
13738             TSaux->PR->iAltSel[SUMA_NET_TRC] = -1;
13739             if (tdo && tdo->net) {
13740                if (Network_1P_to_PTB(tdo->net, sel, &ip, &it, &ib, &l1)) {
13741                   TSaux->PR->iAltSel[SUMA_NET_BUN] = ib;
13742                   TSaux->PR->iAltSel[SUMA_BUN_TRC] = it;
13743                   TSaux->PR->iAltSel[SUMA_TRC_PNT] = ip;
13744                   TSaux->PR->iAltSel[SUMA_NET_TRC] = l1;
13745                }
13746             }
13747          }
13748          break; }
13749       case VO_type: {
13750          SUMA_VolumeObject *vo = (SUMA_VolumeObject *)ado;
13751          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
13752          SUMA_DSET *dset=NULL;
13753          int *iv = (int *)extra, *dims=NULL, iv4[4];
13754          int iv3[3];
13755          VSaux->PR->datum_index = sel;
13756          if (extra) {
13757             VSaux->PR->iAltSel[SUMA_VOL_I] = iv[SUMA_VOL_I];
13758             VSaux->PR->iAltSel[SUMA_VOL_J] = iv[SUMA_VOL_J];
13759             VSaux->PR->iAltSel[SUMA_VOL_K] = iv[SUMA_VOL_K];
13760             VSaux->PR->iAltSel[SUMA_VOL_IJK] = iv[SUMA_VOL_IJK];
13761             if (extra2) {
13762                float *fv = (float *)extra2;
13763                if (SUMA_PLANE_NOT_SET(fv+SUMA_VOL_SLC_EQ0)) {/* a sign that there
13764                                                is no good plane in input
13765                                               Try updating current plane */
13766                   if (vo &&
13767                       SUMA_PLANE_IS_SET(VSaux->PR->dAltSel+SUMA_VOL_SLC_EQ0)) {
13768                       iv3[0] = (int)VSaux->PR->iAltSel[SUMA_VOL_I];
13769                       iv3[1] = (int)VSaux->PR->iAltSel[SUMA_VOL_J];
13770                       iv3[2] = (int)VSaux->PR->iAltSel[SUMA_VOL_K];
13771                       SUMA_SHIFT_PLANE_TO_P(
13772                                  (VSaux->PR->dAltSel+SUMA_VOL_SLC_EQ0),
13773                                  SUMA_VO_PointXYZ(vo, -1, iv3, NULL));
13774                   } else {
13775                      /* Do nothing: Nothing set in the first place */
13776                   }
13777                } else {
13778                   VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ0] = fv[SUMA_VOL_SLC_EQ0];
13779                   VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ1] = fv[SUMA_VOL_SLC_EQ1];
13780                   VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ2] = fv[SUMA_VOL_SLC_EQ2];
13781                   VSaux->PR->dAltSel[SUMA_VOL_SLC_EQ3] = fv[SUMA_VOL_SLC_EQ3];
13782                }
13783             }
13784          } else {
13785             VSaux->PR->iAltSel[SUMA_VOL_I] = VSaux->PR->iAltSel[SUMA_VOL_J] =
13786             VSaux->PR->iAltSel[SUMA_VOL_K] =
13787             VSaux->PR->iAltSel[SUMA_VOL_IJK] = -1;
13788             SUMA_MARK_PLANE_NOT_SET(VSaux->PR->dAltSel+SUMA_VOL_SLC_EQ0);
13789             if (vo && (dset = SUMA_VO_dset(vo)) &&
13790                       (dims = SUMA_GetDatasetDimensions(dset)) ) {
13791                Vox1D2Vox3D(sel, dims[0], dims[0]*dims[1], iv4);
13792                   VSaux->PR->iAltSel[SUMA_VOL_I] = iv4[0];
13793                   VSaux->PR->iAltSel[SUMA_VOL_J] = iv4[1];
13794                   VSaux->PR->iAltSel[SUMA_VOL_K] = iv4[2];
13795                   VSaux->PR->iAltSel[SUMA_VOL_IJK] = sel;
13796                if (SUMA_PLANE_IS_SET(VSaux->PR->dAltSel+SUMA_VOL_SLC_EQ0)) {
13797                   iv3[0] = (int)VSaux->PR->iAltSel[SUMA_VOL_I];
13798                   iv3[1] = (int)VSaux->PR->iAltSel[SUMA_VOL_J];
13799                   iv3[2] = (int)VSaux->PR->iAltSel[SUMA_VOL_K];
13800                   SUMA_SHIFT_PLANE_TO_P((VSaux->PR->dAltSel+SUMA_VOL_SLC_EQ0),
13801                                         SUMA_VO_PointXYZ (vo, -1, iv3, NULL));
13802                }
13803             }
13804          }
13805          return(0);
13806          break; }
13807       case MASK_type: {
13808          SUMA_S_Warn("Not ready for mask type");
13809          return(0);
13810          break; }
13811       default:
13812          return(0);
13813    }
13814    return(0);
13815 }
13816 
SUMA_ADO_N_Datum(SUMA_ALL_DO * ado)13817 int SUMA_ADO_N_Datum(SUMA_ALL_DO *ado)
13818 {
13819    return(SUMA_ADO_N_Datum_Lev(ado, SUMA_ELEM_DAT));
13820 }
13821 
SUMA_ADO_N_Datum_Lev(SUMA_ALL_DO * ado,SUMA_DATUM_LEVEL dtlvl)13822 int SUMA_ADO_N_Datum_Lev(SUMA_ALL_DO *ado, SUMA_DATUM_LEVEL dtlvl)
13823 {
13824    static char FuncName[]={"SUMA_ADO_N_Datum_Lev"};
13825    if (!ado) return(-1);
13826    switch(ado->do_type) {
13827       case SO_type: {
13828          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13829          return(SO->N_Node);
13830          break; }
13831       case VO_type: {
13832          SUMA_VolumeObject *VO = (SUMA_VolumeObject *)ado;
13833          SUMA_DSET *dset = SUMA_VE_dset(VO->VE, 0);
13834          return(dset ? SDSET_NVOX(dset):-1);
13835          break; }
13836       case MASK_type: {
13837          SUMA_MaskDO *MDO = (SUMA_MaskDO *)ado;
13838          if (MDO->SO &&
13839              (MDO_IS_SURF(MDO) || MDO_IS_BOX(MDO) || MDO_IS_SPH(MDO)) ) {
13840             return(MDO->SO->N_Node);
13841          } else if (MDO_IS_BOX(MDO)) {
13842             return(MDO->N_obj*8);
13843          } else if (MDO_IS_SPH(MDO)) {
13844             SUMA_S_Err("No SO on spheres mask. Need to create your surfs");
13845             return(-1);
13846          } else if (MDO_IS_SHADOW(MDO)){
13847             return(0);
13848          } else {
13849             SUMA_S_Err("Not ready for this combo type >%s<", MDO->mtype);
13850             return(-1);
13851          }
13852          return(-1);
13853          break; }
13854       case CDOM_type: {
13855          SUMA_CIFTI_DO *CO=(SUMA_CIFTI_DO *)ado;
13856          switch(dtlvl) {
13857             int i, nn;
13858             case SUMA_ELEM_DAT: /* The maximum possible number of data
13859                                    assuming all domains are filled to
13860                                    the max */
13861                nn = 0;
13862                for (i=0; i<CO->N_subdoms; ++i) {
13863                   nn += SUMA_ADO_N_Datum(SUMA_CIFTI_subdom_ado(CO,i));
13864                }
13865                return(nn);
13866                break;
13867             default:
13868                SUMA_S_Err("Should not be here, not yet at least (dtlvl = %d)",
13869                           dtlvl);
13870                return(-1);
13871                break;
13872          }
13873          return(-1);
13874          break; }
13875       case GDSET_type: {
13876          SUMA_DSET *dset=(SUMA_DSET *)ado;
13877          return(SDSET_VECLEN(dset));
13878          break; }
13879       case GRAPH_LINK_type: {
13880          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13881          SUMA_DSET *dset=NULL;
13882          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13883             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13884                         SUMA_ADO_Label(ado));
13885             return(-1);
13886          }
13887          return(SUMA_ADO_N_Datum((SUMA_ALL_DO *)dset));
13888          break; }
13889       case TRACT_type: {
13890          SUMA_TractDO *tdo=(SUMA_TractDO *)ado;
13891          if (tdo->N_datum == -2) { /* initialize */
13892             tdo->N_datum = Network_N_points(tdo->net, 0);
13893          }
13894          switch(dtlvl) {
13895             default:
13896             case SUMA_ELEM_DAT:
13897                return(tdo->N_datum);
13898                break;
13899             case SUMA_LEV1_DAT:
13900                return(TDO_N_TRACTS(tdo));
13901                break;
13902             case SUMA_LEV2_DAT:
13903                return(TDO_N_BUNDLES(tdo));
13904                break;
13905          }
13906          break; }
13907       default:
13908          return(-1);
13909    }
13910    return(-1);
13911 }
13912 
SUMA_ADO_Max_Datum_Index(SUMA_ALL_DO * ado)13913 int SUMA_ADO_Max_Datum_Index(SUMA_ALL_DO *ado)
13914 {
13915    if (!ado) return(-1);
13916    return(SUMA_ADO_Max_Datum_Index_Lev(ado, SUMA_ELEM_DAT));
13917 }
13918 
13919 /*! This function needs revisiting for all objects.
13920     Its intention should be to return the highest index
13921     of a datum, but in a sparse set, this max could very
13922     well be different from the number of elements.
13923     Check use in code and replace with the maximum of the
13924     NodeDef element if change is needed */
SUMA_ADO_Max_Datum_Index_Lev(SUMA_ALL_DO * ado,SUMA_DATUM_LEVEL dtlvl)13925 int SUMA_ADO_Max_Datum_Index_Lev(SUMA_ALL_DO *ado, SUMA_DATUM_LEVEL dtlvl)
13926 {
13927    static char FuncName[]={"SUMA_ADO_Max_Datum_Index_Lev"};
13928    if (!ado) return(-1);
13929    switch(ado->do_type) {
13930       case SO_type: {
13931          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
13932          return(SO->N_Node-1);
13933          break; }
13934       case GDSET_type: {
13935          SUMA_DSET *dset=(SUMA_DSET *)ado;
13936          if (SUMA_isGraphDset(dset)) {
13937             int mm;
13938             GDSET_MAX_EDGE_INDEX(dset,mm);
13939             return(mm);
13940          } else {
13941             return(SDSET_VECLEN(dset)-1);
13942          }
13943          break; }
13944       case CDOM_type: {
13945          SUMA_S_Err("Riddle me this");
13946          return(-1);
13947          break; }
13948       case GRAPH_LINK_type: {
13949          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
13950          SUMA_DSET *dset=NULL;
13951          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
13952             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
13953                         SUMA_ADO_Label(ado));
13954             return(-1);
13955          }
13956          return(SUMA_ADO_Max_Datum_Index_Lev((SUMA_ALL_DO *)dset, dtlvl));
13957          break; }
13958       case TRACT_type: {
13959          SUMA_TractDO *tdo=(SUMA_TractDO *)ado;
13960          if (tdo->N_datum == -2) { /* initialize */
13961             tdo->N_datum = Network_N_points(tdo->net, 0);
13962          }
13963          switch(dtlvl) {
13964             default:
13965             case SUMA_ELEM_DAT:
13966                return(tdo->N_datum-1);
13967                break;
13968             case SUMA_LEV1_DAT:
13969                return(TDO_N_TRACTS(tdo)-1);
13970                break;
13971             case SUMA_LEV2_DAT:
13972                return(TDO_N_BUNDLES(tdo)-1);
13973                break;
13974          }
13975          break; }
13976       case VO_type: {
13977          SUMA_VolumeObject *VO = (SUMA_VolumeObject *)ado;
13978          SUMA_DSET *dset = SUMA_VE_dset(VO->VE, 0);
13979          return(dset ? SDSET_NVOX(dset)-1:-1);
13980          }
13981       case MASK_type: {
13982          SUMA_MaskDO *MDO = (SUMA_MaskDO *)ado;
13983          if (MDO_IS_SURF(MDO) || MDO_IS_BOX(MDO) || MDO_IS_SPH(MDO)) {
13984             if (!MDO->SO) {
13985                SUMA_S_Err("Need my SO baby");
13986                return(-1);
13987             }
13988             return(MDO->SO->N_Node-1);
13989          } else {
13990             SUMA_S_Warn("Not ready");
13991             return(-1);
13992          }
13993          }
13994       default:
13995          return(-1);
13996    }
13997    return(-1);
13998 
13999 }
14000 
14001 
SUMA_ADO_variant(SUMA_ALL_DO * ado)14002 char * SUMA_ADO_variant(SUMA_ALL_DO *ado) {
14003    static char FuncName[]={"SUMA_ADO_variant"};
14004    if (!ado) return("");
14005    switch(ado->do_type) {
14006       default: {
14007          return("");
14008          break; }
14009       case GRAPH_LINK_type: {
14010          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
14011          if (gldo->variant) {
14012             return(gldo->variant);
14013          }
14014          return("");
14015          break; }
14016    }
14017    return("");
14018 }
14019 
SUMA_ADO_Label(SUMA_ALL_DO * ado)14020 char * SUMA_ADO_Label(SUMA_ALL_DO *ado)
14021 {
14022    static char FuncName[]={"SUMA_ADO_Label"};
14023    if (!ado) return(NULL);
14024    switch(ado->do_type) {
14025       default: {
14026          return(ado->private_Label);
14027          break; }
14028       case GDSET_type:
14029       case MD_DSET_type:
14030       case ANY_DSET_type: {
14031          SUMA_DSET *dset=(SUMA_DSET *)ado;
14032          return(SDSET_LABEL(dset));
14033          break; }
14034    }
14035    return(NULL);
14036 }
14037 
14038 /* Like ADO_Label, but return empty string in err */
SUMA_ADO_sLabel(SUMA_ALL_DO * ado)14039 char *SUMA_ADO_sLabel(SUMA_ALL_DO *ado) {
14040    static char FuncName[]={"SUMA_ADO_sLabel"};
14041    char *cc = SUMA_ADO_Label(ado);
14042    if (!cc) return("");
14043    else return(cc);
14044 }
14045 
SUMA_ADO_CropLabel(SUMA_ALL_DO * ado,int len)14046 char * SUMA_ADO_CropLabel(SUMA_ALL_DO *ado, int len)
14047 {
14048    static char FuncName[]={"SUMA_ADO_CropLabel"};
14049    static char s[10][130];
14050    static int icall=0;
14051    char *str=NULL;
14052 
14053    ++icall;
14054    if (icall > 9) icall = 0;
14055    s[icall][0]='\0';
14056 
14057    if (!ado) { SUMA_S_Err("NULL input"); return(s[icall]); }
14058    if (len > 127) {
14059       SUMA_S_Warn("Label max length is 128, will truncate");
14060       len = 128;
14061    }
14062 
14063    str = SUMA_truncate_string(SUMA_ADO_Label(ado), len);
14064    if (!str) return(s[icall]);
14065 
14066    strcpy(s[icall], str);
14067    SUMA_ifree(str);
14068 
14069    return(s[icall]);
14070 }
14071 
14072 /* compare labels, NULL=NULL --> OK */
SUMA_ADO_isLabel(SUMA_ALL_DO * ado,char * lbl)14073 SUMA_Boolean SUMA_ADO_isLabel(SUMA_ALL_DO *ado, char *lbl)
14074 {
14075    static char FuncName[]={"SUMA_ADO_isLabelSUMA_ALL_DO"};
14076    char *cc=NULL;
14077 
14078    if (!ado) return(NOPE);
14079    cc = SUMA_ADO_Label(ado);
14080    if (!cc) {
14081       if (!lbl) return(YUP);
14082    } else {
14083       if (!strcmp(cc, lbl)) return(YUP);
14084    }
14085    return(NOPE);
14086 }
14087 
14088 /* Because of the damned SUMA_DSET * object, which needs
14089 the Linked Pointer fields on the top, never access
14090 ado->idcode_str directly, but use this function
14091 instead*/
SUMA_ADO_idcode(SUMA_ALL_DO * ado)14092 char * SUMA_ADO_idcode(SUMA_ALL_DO *ado)
14093 {
14094    static char FuncName[]={"SUMA_ADO_idcode"};
14095    if (!ado) return(NULL);
14096    switch(ado->do_type) {
14097       default: {
14098          return(ado->private_idcode_str);
14099          break; }
14100       case ANY_DSET_type:
14101       case MD_DSET_type:
14102       case GDSET_type: {/* The special beast */
14103          SUMA_DSET *dset=(SUMA_DSET *)ado;
14104          return(SDSET_ID(dset));
14105          break; }
14106    }
14107    return(NULL);
14108 }
14109 
SUMA_ADO_Parent_idcode(SUMA_ALL_DO * ado)14110 char * SUMA_ADO_Parent_idcode(SUMA_ALL_DO *ado)
14111 {
14112    static char FuncName[]={"SUMA_ADO_Parent_idcode"};
14113    if (!ado) return(NULL);
14114    switch(ado->do_type) {
14115       case ANY_DSET_type:
14116       case MD_DSET_type:
14117       case GDSET_type: {/* The special beast, as a DO, it is its own parent*/
14118          SUMA_DSET *dset=(SUMA_DSET *)ado;
14119          return(SDSET_ID(dset));
14120          break; }
14121       case GRAPH_LINK_type:
14122          return(((SUMA_GraphLinkDO*)ado)->Parent_idcode_str);
14123          break;
14124       case SP_type:
14125          return(((SUMA_SphereDO*)ado)->Parent_idcode_str);
14126          break;
14127       case TRACT_type:
14128          return(((SUMA_TractDO*)ado)->Parent_idcode_str);
14129          break;
14130       case MASK_type:
14131          return(((SUMA_MaskDO*)ado)->Parent_idcode_str);
14132          break;
14133       case NBLS_type:
14134       case NBOLS_type:
14135       case NBV_type:
14136       case ONBV_type:
14137       case NBSP_type:
14138       case NBT_type:
14139          return(((SUMA_NB_DO*)ado)->Parent_idcode_str);
14140          break;
14141       case NIDO_type:
14142          if (((SUMA_NIDO*)ado)->ngr) {
14143             return(NI_get_attribute(
14144                      ((SUMA_NIDO*)ado)->ngr, "Parent_idcode_str"));
14145          } else return(NULL);
14146          break;
14147       case SO_type:
14148          return(((SUMA_SurfaceObject*)ado)->LocalDomainParentID);
14149          break;
14150       case ROIdO_type:
14151          return(((SUMA_DRAWN_ROI*)ado)->Parent_idcode_str);
14152          break;
14153       case AO_type: /* those are their own parents */
14154       case PL_type:
14155       case CDOM_type:
14156       case VO_type:
14157          return(ado->private_idcode_str);
14158          break;
14159       default: {
14160          SUMA_S_Errv("Not ready for parent of %s\n",
14161                SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
14162          return(NULL);
14163          break; }
14164 
14165    }
14166    return(NULL);
14167 }
14168 
14169 /*!
14170    Return the "SurfaceController" for any DO
14171 */
SUMA_ADO_Cont(SUMA_ALL_DO * ado)14172 SUMA_X_SurfCont *SUMA_ADO_Cont(SUMA_ALL_DO *ado)
14173 {
14174    static char FuncName[]={"SUMA_ADO_Cont"};
14175    SUMA_Boolean LocalHead = NOPE;
14176 
14177    if (!ado) return(NULL);
14178    SUMA_LHv("Here with %d (%s), %s\n",
14179              ado->do_type, ADO_TNAME(ado), SUMA_ADO_Label(ado));
14180 
14181    switch(ado->do_type) {
14182       case SO_type: {
14183          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
14184          return(SO->SurfCont);
14185          break; }
14186       case CDOM_type: {
14187          SUMA_CIFTI_SAUX * CSaux = (SUMA_CIFTI_SAUX *)SUMA_ADO_Saux(ado);
14188          if (CSaux) return(CSaux->DOCont);
14189          else return(NULL);
14190          break; }
14191       case GDSET_type: {
14192          SUMA_DSET *dset=(SUMA_DSET *)ado;
14193          SUMA_GRAPH_SAUX *GSaux = SDSET_GSAUX(dset);
14194          if (!GSaux) return(NULL);
14195          return(GSaux->DOCont);
14196          break; }
14197       case GRAPH_LINK_type: {
14198          SUMA_DSET *dset=NULL;
14199          /* get the graph dset, which is the pointer holding
14200             the controller pointer */
14201          if (!(dset = SUMA_find_GLDO_Dset((SUMA_GraphLinkDO *)ado))) {
14202             SUMA_S_Err("No graph dset for GLDO???");
14203             return(NULL);
14204          }
14205          return(SUMA_ADO_Cont((SUMA_ALL_DO *)dset));
14206          break; }
14207       case TRACT_type: {
14208          SUMA_TRACT_SAUX * TSaux = (SUMA_TRACT_SAUX *)SUMA_ADO_Saux(ado);
14209          if (TSaux) return(TSaux->DOCont);
14210          else return(NULL);
14211          break; }
14212       case MASK_type: {
14213          SUMA_MASK_SAUX * MSaux = (SUMA_MASK_SAUX *)SUMA_ADO_Saux(ado);
14214          if (MSaux) return(MSaux->DOCont);
14215          else return(NULL);
14216          break; }
14217       case VO_type: {
14218          SUMA_VOL_SAUX * VSaux = (SUMA_VOL_SAUX *)SUMA_ADO_Saux(ado);
14219          SUMA_LH("Have %p", VSaux);
14220          if (VSaux) return(VSaux->DOCont);
14221          else return(NULL);
14222          break; }
14223       default:
14224          return(NULL);
14225    }
14226    return(NULL);
14227 }
14228 
SUMA_ADO_ShowCurForeOnly(SUMA_ALL_DO * ado)14229 SUMA_Boolean SUMA_ADO_ShowCurForeOnly(SUMA_ALL_DO *ado)
14230 {
14231    static char FuncName[]={"SUMA_ADO_ShowCurForeOnly"};
14232    SUMA_X_SurfCont *sc=NULL;
14233 
14234    if (!ado || !(sc = SUMA_ADO_Cont(ado))) return(NOPE);
14235 
14236    return(sc->ShowCurForeOnly);
14237 }
14238 
SUMA_Cont_ADO(SUMA_X_SurfCont * SurfCont)14239 SUMA_ALL_DO *SUMA_Cont_ADO(SUMA_X_SurfCont *SurfCont)
14240 {
14241    static char FuncName[]={"SUMA_Cont_ADO"};
14242    if (!SurfCont) return(NULL);
14243    return(SUMA_SurfCont_GetcurDOp(SurfCont));
14244 }
14245 
SUMA_Cont_SO(SUMA_X_SurfCont * SurfCont)14246 SUMA_SurfaceObject *SUMA_Cont_SO(SUMA_X_SurfCont *SurfCont)
14247 {
14248    static char FuncName[]={"SUMA_Cont_SO"};
14249    SUMA_ALL_DO *ado=NULL;
14250    if (!SurfCont) return(NULL);
14251    ado = SUMA_SurfCont_GetcurDOp(SurfCont);
14252    if (ado->do_type == SO_type)
14253       return((SUMA_SurfaceObject *)ado);
14254    return(NULL);
14255 }
14256 
14257 /*!
14258    SUMA_isCurColPlane: Is this color plane the current one ?
14259    This is meant to replace if (colp == SO->SurfCont->curColPlane)
14260    so that it would work for any DO that would have a colorplane.
14261    This query will always return yes for a DSET_type DO
14262 
14263    You might want to consider the alternative SUMA_isTopColPlane()
14264    which is identical to  SUMA_isCurColPlane() when using the old style
14265    multiple surface controller windows, versus the modern multi-page controller
14266 */
SUMA_isCurColPlane(SUMA_OVERLAYS * cp,SUMA_ALL_DO * ado)14267 SUMA_Boolean SUMA_isCurColPlane(SUMA_OVERLAYS *cp, SUMA_ALL_DO *ado)
14268 {
14269    static char FuncName[]={"SUMA_isCurColPlane"};
14270    if (!cp || !ado) return(NOPE);
14271    if (cp == SUMA_ADO_CurColPlane(ado)) return(YUP);
14272    return(NOPE);
14273 }
14274 
SUMA_isTopColPlane(SUMA_OVERLAYS * cp,SUMA_ALL_DO * ado)14275 SUMA_Boolean SUMA_isTopColPlane(SUMA_OVERLAYS *cp, SUMA_ALL_DO *ado)
14276 {
14277    static char FuncName[]={"SUMA_isTopColPlane"};
14278    SUMA_X_SurfCont *SurfCont=NULL;
14279    if (!SUMAg_CF->X->UseSameSurfCont) return(SUMA_isCurColPlane(cp, ado));
14280    else if (SUMA_isCurColPlane(cp, ado) && (SurfCont = SUMA_ADO_Cont(ado))) {
14281       /* OK, so that plane is current in some fashion,
14282       is it the top page of the uber controller ? */
14283       return(SUMA_isCurrentContPage(SUMAg_CF->X->SC_Notebook, SurfCont->Page));
14284    }
14285    return(NOPE);
14286 }
14287 
14288 /* Used to be MACRO  SUMA_SURFCONT_CREATED */
SUMA_isADO_Cont_Created(SUMA_ALL_DO * ado)14289 SUMA_Boolean SUMA_isADO_Cont_Created(SUMA_ALL_DO *ado)
14290 {
14291    static char FuncName[]={"SUMA_isADO_Cont_Created"};
14292    SUMA_X_SurfCont *SurfCont=NULL;
14293 
14294    if ((SurfCont = SUMA_ADO_Cont(ado)) && SurfCont->TLS ) return(1);
14295 
14296    return(0);
14297 }
14298 
14299 /* Used to be MACRO  SUMA_SURFCONT_REALIZED */
SUMA_isADO_Cont_Realized(SUMA_ALL_DO * ado)14300 SUMA_Boolean SUMA_isADO_Cont_Realized(SUMA_ALL_DO *ado)
14301 {
14302    static char FuncName[]={"SUMA_isADO_Cont_Realized"};
14303    SUMA_X_SurfCont *SurfCont=NULL;
14304 
14305    if ((SurfCont = SUMA_ADO_Cont(ado)) && SurfCont->TLS
14306        && XtIsRealized(SurfCont->TLS)) return(1);
14307 
14308    return(0);
14309 }
14310 
14311 #define NVALS_XYZ_NODE 3
SUMA_GDSET_NodeXYZ(SUMA_DSET * dset,int node,char * variant,float * here)14312 float *SUMA_GDSET_NodeXYZ(SUMA_DSET *dset, int node, char *variant, float *here)
14313 {
14314    static char FuncName[]={"SUMA_GDSET_NodeXYZ"};
14315    static int icall=0;
14316    static float fv[10][NVALS_XYZ_NODE];
14317    int N_Node=-1, *Node_Ind=NULL, cinode = -1;
14318    float *ff=NULL, *NodeList = NULL;
14319    SUMA_Boolean LocalHead = NOPE;
14320 
14321    SUMA_ENTRY;
14322 
14323    if (!here) {
14324       ++icall; if (icall > 9) icall = 0;
14325       here = (float *)(&fv[icall]);
14326    }
14327 
14328    SUMA_GDSET_NodeXYZ_eng(dset, node, variant, here);
14329 
14330    SUMA_RETURN(here);
14331 }
14332 
SUMA_GDSET_NodeXYZ_eng(SUMA_DSET * dset,int node,char * variant,float * here)14333 SUMA_Boolean SUMA_GDSET_NodeXYZ_eng(SUMA_DSET *dset, int node,
14334                                     char *variant, float *here)
14335 {
14336    static char FuncName[]={"SUMA_GDSET_NodeXYZ_eng"};
14337    int N_Node=-1, *Node_Ind=NULL, cinode = -1;
14338    float *ff=NULL, *NodeList = NULL;
14339    SUMA_Boolean LocalHead = NOPE;
14340 
14341    SUMA_ENTRY;
14342 
14343    if (!here) {
14344       SUMA_S_Err("Need output pointer");
14345       SUMA_RETURN(NOPE);
14346    }
14347    here[0] = here[1] = here[2] =  0.0;
14348 
14349    if (!dset || node < 0) SUMA_RETURN(NOPE);
14350 
14351    if (!(NodeList = SUMA_GDSET_NodeList(dset, &N_Node, 0, &Node_Ind, variant)))
14352                                                       SUMA_RETURN(NOPE);
14353 
14354    /* get position of node n in NodeList */
14355    cinode =  SUMA_NodeIndex_To_Index(Node_Ind, N_Node, node);
14356    SUMA_LHv("Node %d is in row %d of the nodelist of %d nodes\n",
14357             node, cinode, N_Node);
14358 
14359    if (cinode >= 0 && cinode < N_Node) {
14360       ff = NodeList+3*cinode;
14361       here[0] = *ff; ++ff;
14362       here[1] = *ff; ++ff;
14363       here[2] = *ff;
14364       SUMA_RETURN(YUP);
14365    } else {
14366       SUMA_LHv("Node %d not found in node list\n", node);
14367       SUMA_RETURN(NOPE);
14368    }
14369 
14370    SUMA_RETURN(NOPE);
14371 }
14372 
SUMA_TDO_PointXYZ(SUMA_TractDO * tdo,int point,int * BTP,float * here)14373 float *SUMA_TDO_PointXYZ(SUMA_TractDO *tdo, int point, int *BTP, float *here)
14374 {
14375    static char FuncName[]={"SUMA_TDO_PointXYZ"};
14376    static int icall=0;
14377    static float fv[10][NVALS_XYZ_NODE];
14378    int N_Node=-1, *Node_Ind=NULL, cinode = -1;
14379    float *ff=NULL, *NodeList = NULL;
14380    SUMA_Boolean LocalHead = NOPE;
14381 
14382    SUMA_ENTRY;
14383 
14384    if (!here) {
14385       ++icall; if (icall > 9) icall = 0;
14386       here = (float *)(&fv[icall]);
14387    }
14388 
14389    SUMA_TDO_PointXYZ_eng(tdo, point, BTP, here);
14390 
14391    SUMA_RETURN(here);
14392 }
14393 
SUMA_TDO_PointXYZ_eng(SUMA_TractDO * tdo,int point,int * BTP,float * here)14394 SUMA_Boolean SUMA_TDO_PointXYZ_eng(SUMA_TractDO *tdo, int point,
14395                                    int *BTP, float *here)
14396 {
14397    static char FuncName[]={"SUMA_TDO_PointXYZ_eng"};
14398    int N_Node=-1, *Node_Ind=NULL, cinode = -1, iv3[3], nn3;
14399    float *ff=NULL, *NodeList = NULL;
14400    SUMA_Boolean LocalHead = NOPE;
14401 
14402    SUMA_ENTRY;
14403 
14404    if (!here) {
14405       SUMA_S_Err("Need output pointer");
14406       SUMA_RETURN(NOPE);
14407    }
14408    here[0] = here[1] = here[2] =  0.0;
14409 
14410    if (!tdo || !tdo->net || point < 0) SUMA_RETURN(NOPE);
14411 
14412    if (BTP && BTP[0] >= 0 && BTP[1] >= 0 && BTP[2] >=0) {
14413       iv3[SUMA_NET_BUN] = BTP[SUMA_NET_BUN];
14414       iv3[SUMA_BUN_TRC] = BTP[SUMA_BUN_TRC];
14415       iv3[SUMA_TRC_PNT] = BTP[SUMA_TRC_PNT];
14416    } else if (point >= 0) {
14417       if (!Network_1P_to_PTB(tdo->net, point,
14418                iv3+SUMA_TRC_PNT, iv3+SUMA_BUN_TRC, iv3+SUMA_NET_BUN, NULL)) {
14419          SUMA_S_Err("Bad point index");
14420          SUMA_RETURN(NOPE);
14421       }
14422    }
14423 
14424    if (iv3[SUMA_NET_BUN] < TDO_N_BUNDLES(tdo)) {
14425       if (iv3[SUMA_BUN_TRC] < tdo->net->tbv[iv3[SUMA_NET_BUN]]->N_tracts) {
14426          nn3 = iv3[SUMA_TRC_PNT]*3;
14427          if (nn3 <
14428              tdo->net->tbv[iv3[SUMA_NET_BUN]]->tracts[iv3[SUMA_BUN_TRC]].N_pts3){
14429             ff =
14430              tdo->net->tbv[iv3[SUMA_NET_BUN]]->tracts[iv3[SUMA_BUN_TRC]].pts+nn3;
14431             here[0] = ff[0];
14432             here[1] = ff[1];
14433             here[2] = ff[2];
14434             SUMA_RETURN(YUP);
14435          }
14436       }
14437    } else {
14438       SUMA_LHv("Point %d (B%d T%d P%d) not found in node list\n",
14439          point, iv3[SUMA_NET_BUN], iv3[SUMA_BUN_TRC], iv3[SUMA_TRC_PNT]);
14440       SUMA_RETURN(NOPE);
14441    }
14442 
14443    SUMA_RETURN(NOPE);
14444 }
14445 
SUMA_VO_PointXYZ(SUMA_VolumeObject * vo,int point,int * IJK,float * here)14446 float *SUMA_VO_PointXYZ(SUMA_VolumeObject *vo, int point, int *IJK, float *here)
14447 {
14448    static char FuncName[]={"SUMA_VO_PointXYZ"};
14449    static int icall=0;
14450    static float fv[10][NVALS_XYZ_NODE];
14451    int N_Node=-1, *Node_Ind=NULL, cinode = -1;
14452    float *ff=NULL, *NodeList = NULL;
14453    SUMA_Boolean LocalHead = NOPE;
14454 
14455    SUMA_ENTRY;
14456 
14457    if (!here) {
14458       ++icall; if (icall > 9) icall = 0;
14459       here = (float *)(&fv[icall]);
14460    }
14461 
14462    SUMA_VO_PointXYZ_eng(vo, point, IJK, here);
14463 
14464    SUMA_RETURN(here);
14465 }
14466 
SUMA_VO_PointXYZ_eng(SUMA_VolumeObject * vo,int point,int * IJK,float * here)14467 SUMA_Boolean SUMA_VO_PointXYZ_eng(SUMA_VolumeObject *vo, int point,
14468                                    int *IJK, float *here)
14469 {
14470    static char FuncName[]={"SUMA_VO_PointXYZ_eng"};
14471    int N_Node=-1, *Node_Ind=NULL, cinode = -1, iv3[3]={0,0,0}, nn3;
14472    float *ff=NULL, *NodeList = NULL;
14473    float I[3];
14474    int *dims;
14475    SUMA_DSET *dset=NULL;
14476    SUMA_Boolean LocalHead = NOPE;
14477 
14478 
14479    SUMA_ENTRY;
14480 
14481 
14482    if (!here) {
14483       SUMA_S_Err("Need output pointer");
14484       SUMA_RETURN(NOPE);
14485    }
14486    here[0] = here[1] = here[2] =  0.0;
14487 
14488    if (!vo ||
14489       (point < 0 && !(IJK && IJK[0] >= 0 && IJK[1] >= 0 && IJK[2] >=0) ))
14490       SUMA_RETURN(NOPE);
14491    if (!(dset = SUMA_VO_dset(vo)) ||
14492        !(dims = SUMA_GetDatasetDimensions(dset)) ||
14493        !vo->VE || !vo->VE[0]) {
14494       SUMA_S_Err("no valid ijk_to_dicom_real") ;
14495       SUMA_RETURN(NOPE);
14496    }
14497 
14498 
14499    if (IJK && IJK[0] >= 0 && IJK[1] >= 0 && IJK[2] >=0) {
14500       iv3[SUMA_VOL_I] = IJK[SUMA_VOL_I];
14501       iv3[SUMA_VOL_J] = IJK[SUMA_VOL_J];
14502       iv3[SUMA_VOL_K] = IJK[SUMA_VOL_K];
14503    } else if (point >= 0 && point < SDSET_NVOX(dset)) {
14504       Vox1D2Vox3D(point, dims[0], dims[0]*dims[1], (iv3+SUMA_VOL_I));
14505    }
14506 
14507    if (iv3[SUMA_VOL_I] < dims[0]) {
14508       if (iv3[SUMA_VOL_J] < dims[1]) {
14509          if (iv3[SUMA_VOL_K] < dims[2] ) {
14510             AFF44_MULT_I(here, vo->VE[0]->I2X, (iv3+SUMA_VOL_I));
14511             SUMA_RETURN(YUP);
14512          }
14513       }
14514    } else {
14515       SUMA_LHv("Point %d (I%d J%d K%d) not found in grid\n",
14516          point, iv3[SUMA_VOL_I], iv3[SUMA_VOL_J], iv3[SUMA_VOL_K]);
14517       SUMA_RETURN(NOPE);
14518    }
14519 
14520    SUMA_RETURN(NOPE);
14521 }
14522 
SUMA_MDO_PointXYZ(SUMA_MaskDO * mo,int point,int * IJK,float * here)14523 float *SUMA_MDO_PointXYZ(SUMA_MaskDO *mo, int point, int *IJK, float *here)
14524 {
14525    static char FuncName[]={"SUMA_MDO_PointXYZ"};
14526    static int icall=0;
14527    static float fv[10][NVALS_XYZ_NODE];
14528    int N_Node=-1, *Node_Ind=NULL, cinode = -1;
14529    float *ff=NULL, *NodeList = NULL;
14530    SUMA_Boolean LocalHead = NOPE;
14531 
14532    SUMA_ENTRY;
14533 
14534    if (!here) {
14535       ++icall; if (icall > 9) icall = 0;
14536       here = (float *)(&fv[icall]);
14537    }
14538 
14539    SUMA_MDO_PointXYZ_eng(mo, point, IJK, here);
14540 
14541    SUMA_RETURN(here);
14542 }
14543 
SUMA_MDO_PointXYZ_eng(SUMA_MaskDO * mo,int point,int * IJK,float * here)14544 SUMA_Boolean SUMA_MDO_PointXYZ_eng(SUMA_MaskDO *mo, int point,
14545                                    int *IJK, float *here)
14546 {
14547    static char FuncName[]={"SUMA_MDO_PointXYZ_eng"};
14548    int N_Node=-1, *Node_Ind=NULL, cinode = -1, iv3[3]={0,0,0}, nn3;
14549    float *ff=NULL, *NodeList = NULL;
14550    float I[3];
14551    int *dims;
14552    SUMA_Boolean LocalHead = NOPE;
14553 
14554 
14555    SUMA_ENTRY;
14556 
14557    if (!here) {
14558       SUMA_S_Err("Need output pointer");
14559       SUMA_RETURN(NOPE);
14560    }
14561    here[0] = here[1] = here[2] =  0.0;
14562 
14563    if (!mo || point < 0) SUMA_RETURN(NOPE);
14564 
14565    if (MDO_IS_BOX(mo) || MDO_IS_SPH(mo)) {
14566       if (IJK && IJK[0] >= 0 && IJK[1] >= 0) { /* obj index and point within */
14567          point = 3*IJK[0]+IJK[1];
14568       }
14569    }
14570 
14571    if (point < 0 || point >= SUMA_ADO_N_Datum((SUMA_ALL_DO *)mo))
14572       SUMA_RETURN(NOPE);
14573 
14574    if (!mo->SO) {
14575       SUMA_S_Err("SO no formed yet");
14576       SUMA_RETURN(NOPE);
14577    }
14578 
14579    here[0] = mo->SO->NodeList[3*point];
14580    here[1] = mo->SO->NodeList[3*point+1];
14581    here[2] = mo->SO->NodeList[3*point+2];
14582 
14583    SUMA_RETURN(NOPE);
14584 }
14585 
14586 
SUMA_GDSET_XYZ_Range(SUMA_DSET * dset,char * variant,float * here)14587 float *SUMA_GDSET_XYZ_Range(SUMA_DSET *dset,  char *variant, float *here)
14588 {
14589    static char FuncName[]={"SUMA_GDSET_XYZ_Range"};
14590    static int icall=0;
14591    static float fv[10][6];
14592    float *X, *Y, *Z;
14593    int *I;
14594    double nums[6];
14595    int iicoord;
14596    NI_element *nelxyz = NULL;
14597    char *ctmp=NULL, *rs=NULL, *cs=NULL, sbuf[24];
14598    SUMA_Boolean LocalHead = NOPE;
14599 
14600    SUMA_ENTRY;
14601 
14602    if (!here) {
14603       ++icall; if (icall > 9) icall = 0;
14604       here = (float *)(&fv[icall]);
14605    }
14606    here[0] = here[1] = here[2] =  -10.0;
14607    here[0] = here[1] = here[2] =  10.0;
14608 
14609    if (!dset || !variant) SUMA_RETURN(here);
14610 
14611    if (!strcmp(variant,"G3D")) {
14612       if (!(nelxyz = SUMA_FindGDsetNodeListElement(dset))) {
14613          SUMA_S_Errv("Failed to find Dset %s's NodeListElement\n",
14614                            SDSET_LABEL(dset));
14615          SUMA_RETURN(here);
14616       }
14617       if (!(cs = NI_get_attribute(nelxyz,"COLMS_LABS"))) {
14618          SUMA_S_Err("What can I say?");
14619          SUMA_RETURN(here);
14620       }
14621       if (!(rs = NI_get_attribute(nelxyz,"COLMS_RANGE"))) {
14622          SUMA_S_Err("Zut alors!");
14623          SUMA_RETURN(here);
14624       }
14625 
14626       /* Get the X range */
14627       if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode X"))<0) {
14628          SUMA_S_Err("Failed to find X");
14629          SUMA_RETURN(here);
14630       }
14631       ctmp = SUMA_Get_Sub_String(rs, SUMA_NI_CSS, iicoord);
14632       if (SUMA_StringToNum(ctmp, (void *)nums, 4, 2) != 4) {
14633          SUMA_SL_Err("Failed to read 6 nums from range.");
14634          SUMA_RETURN(here);
14635       }
14636       here[0]=nums[0]; here[1]=nums[1];
14637 
14638       /* Get the Y range */
14639       if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode Y"))<0) {
14640          SUMA_S_Err("Failed to find Y");
14641          SUMA_RETURN(here);
14642       }
14643       ctmp = SUMA_Get_Sub_String(rs, SUMA_NI_CSS, iicoord);
14644       if (SUMA_StringToNum(ctmp, (void *)nums, 4, 2) != 4) {
14645          SUMA_SL_Err("Failed to read 6 nums from range.");
14646          SUMA_RETURN(here);
14647       }
14648       here[2]=nums[0]; here[3]=nums[1];
14649 
14650       /* Get the Z range */
14651       if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode Z"))<0) {
14652          SUMA_S_Err("Failed to find Y");
14653          SUMA_RETURN(here);
14654       }
14655       ctmp = SUMA_Get_Sub_String(rs, SUMA_NI_CSS, iicoord);
14656       if (SUMA_StringToNum(ctmp, (void *)nums, 4, 2) != 4) {
14657          SUMA_SL_Err("Failed to read 6 nums from range.");
14658          SUMA_RETURN(here);
14659       }
14660       here[4]=nums[0]; here[5]=nums[1];
14661    } else if (!strcmp(variant,"GMATRIX")) {
14662       /* This would be the range of the FrameSO */
14663       SUMA_SurfaceObject *SO = SUMA_GDSET_FrameSO(dset);
14664       if (SO) {
14665          SUMA_LHv("%f -- %f, %f -- %f, %f -- %f\n",
14666                   SO->MinDims[0], SO->MaxDims[0],
14667                   SO->MinDims[1], SO->MaxDims[1],
14668                   SO->MinDims[2], SO->MaxDims[2]);
14669          here[0] = SO->MinDims[0]; here[1] = SO->MaxDims[0];
14670          here[2] = SO->MinDims[1]; here[3] = SO->MaxDims[2];
14671          here[4] = SO->MinDims[2]; here[5] = SO->MaxDims[2];
14672       }
14673       SUMA_RETURN(here);
14674    } else if (!strcmp(variant,"GRELIEF")) {
14675       SUMA_S_Err("Not ready yet for GRELIEF");
14676       SUMA_RETURN(here);
14677    } else if (!strncmp(variant,"TheShadow", 9)) {
14678       SUMA_LH("Who knows what evil lurks in the hearts of men?");
14679       SUMA_RETURN(here);
14680    } else {
14681       SUMA_S_Errv("Bad draw variant >%s< for %s\n",
14682                   variant, SDSET_LABEL(dset));
14683       SUMA_DUMP_TRACE("Bad draw variant");
14684       SUMA_RETURN(here);
14685    }
14686 
14687    SUMA_RETURN(here);
14688 }
14689 
SUMA_GDSET_XYZ_Center(SUMA_DSET * dset,char * variant,float * here)14690 float *SUMA_GDSET_XYZ_Center(SUMA_DSET *dset,  char *variant, float *here)
14691 {
14692    static char FuncName[]={"SUMA_GDSET_XYZ_Center"};
14693    static int icall=0;
14694    static float fv[10][3];
14695    float *X, *Y, *Z, meanI;
14696    double nums[6];
14697    int iicoord, *I;
14698    NI_element *nelxyz = NULL;
14699    char *cen=NULL, *ctmp=NULL, *rs=NULL, *cs=NULL, *stmp=NULL, sbuf[24];
14700    SUMA_Boolean LocalHead = NOPE;
14701 
14702    SUMA_ENTRY;
14703 
14704    if (!here) {
14705       ++icall; if (icall > 9) icall = 0;
14706       here = (float *)(&fv[icall]);
14707    }
14708    here[0] = here[1] = here[2] =  0.0;
14709 
14710    if (!dset || !variant) SUMA_RETURN(here);
14711 
14712    if (!strcmp(variant,"G3D")) {
14713       if (!(nelxyz = SUMA_FindGDsetNodeListElement(dset))) {
14714          SUMA_S_Errv("Failed to find Dset %s's NodeListElement\n",
14715                            SDSET_LABEL(dset));
14716          SUMA_RETURN(here);
14717       }
14718       /* create and store the thing */
14719       if (!(cs = NI_get_attribute(nelxyz,"COLMS_LABS"))) {
14720          SUMA_S_Err("What can I say?");
14721          SUMA_RETURN(here);
14722       }
14723       if (!(cen = NI_get_attribute(nelxyz,"COLMS_AVG"))) {
14724         /* Stupid but have to do it for COLMS_AVG */
14725          /* Get the I col */
14726          if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS,
14727                                               "Gnode Index"))<0) {
14728             SUMA_S_Err("Failed to find I");
14729             SUMA_RETURN(here);
14730          }
14731          I = (int *)nelxyz->vec[iicoord];
14732          SUMA_MEAN_VEC(I, nelxyz->vec_len, meanI, 0);
14733          sprintf(sbuf,"%f", meanI);
14734          if (!SUMA_Set_Sub_String(&stmp, SUMA_NI_CSS, iicoord,sbuf)) {
14735             SUMA_LHv("Failed to set substring to %s\n", stmp);
14736             SUMA_RETURN(here);
14737          }
14738 
14739          /* Get the X col */
14740          if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode X"))<0) {
14741             SUMA_S_Err("Failed to find X");
14742             SUMA_RETURN(here);
14743          }
14744          X = (float *)nelxyz->vec[iicoord];
14745          SUMA_MEAN_VEC(X, nelxyz->vec_len, here[0], 0);
14746          sprintf(sbuf,"%f", here[0]);
14747          if (!SUMA_Set_Sub_String(&stmp, SUMA_NI_CSS, iicoord,sbuf)) {
14748             SUMA_LHv("Failed to set substring to %s\n", stmp);
14749             SUMA_RETURN(here);
14750          }
14751 
14752          /* Get the Y col */
14753          if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode Y"))<0) {
14754             SUMA_S_Err("Failed to find Y");
14755             SUMA_RETURN(here);
14756          }
14757          Y = (float *)nelxyz->vec[iicoord];
14758          SUMA_MEAN_VEC(Y, nelxyz->vec_len, here[1], 0);
14759          sprintf(sbuf,"%f", here[1]);
14760          if (!SUMA_Set_Sub_String(&stmp, SUMA_NI_CSS, iicoord,sbuf)) {
14761             SUMA_LHv("Failed to set substring to %s\n", stmp);
14762             SUMA_RETURN(here);
14763          }
14764 
14765          /* Get the Z col */
14766          if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode Z"))<0) {
14767             SUMA_S_Err("Failed to find Z");
14768             SUMA_RETURN(here);
14769          }
14770          Z = (float *)nelxyz->vec[iicoord];
14771          SUMA_MEAN_VEC(Z, nelxyz->vec_len, here[2], 0);
14772          sprintf(sbuf,"%f", here[2]);
14773          if (!SUMA_Set_Sub_String(&stmp, SUMA_NI_CSS, iicoord,sbuf)) {
14774             SUMA_LHv("Failed to set substring to %s\n", stmp);
14775             SUMA_RETURN(here);
14776          }
14777 
14778          NI_set_attribute(nelxyz,"COLMS_AVG", stmp);
14779          SUMA_LHv("Computed for %s to be: %f %f %f: (stored in %s)\n",
14780                   variant, here[0], here[1], here[2], stmp);
14781          SUMA_ifree(stmp);
14782       } else {
14783          if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode X"))<0) {
14784             SUMA_S_Err("Failed to find X");
14785             SUMA_RETURN(here);
14786          }
14787          ctmp = SUMA_Get_Sub_String(cen, SUMA_NI_CSS, iicoord);
14788          if (SUMA_StringToNum(ctmp, (void *)nums, 1, 2) != 1) {
14789             SUMA_SL_Err("Failed to read 1 num from range.");
14790             SUMA_RETURN(here);
14791          }
14792          here[0]=nums[0];
14793 
14794          if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode Y"))<0) {
14795             SUMA_S_Err("Failed to find Y");
14796             SUMA_RETURN(here);
14797          }
14798          ctmp = SUMA_Get_Sub_String(cen, SUMA_NI_CSS, iicoord);
14799          if (SUMA_StringToNum(ctmp, (void *)nums, 1, 2) != 1) {
14800             SUMA_SL_Err("Failed to read 1 num from range.");
14801             SUMA_RETURN(here);
14802          }
14803          here[1]=nums[0];
14804 
14805          if ((iicoord=SUMA_NI_find_in_cs_string(cs, SUMA_NI_CSS, "Gnode Z"))<0) {
14806             SUMA_S_Err("Failed to find Z");
14807             SUMA_RETURN(here);
14808          }
14809          ctmp = SUMA_Get_Sub_String(cen, SUMA_NI_CSS, iicoord);
14810          if (SUMA_StringToNum(ctmp, (void *)nums, 1, 2) != 1) {
14811             SUMA_SL_Err("Failed to read 1 num from range.");
14812             SUMA_RETURN(here);
14813          }
14814          here[2]=nums[0];
14815          SUMA_LHv("Retrieved (%s) from header for %s to be: %f %f %f:\n",
14816                      cen, variant, here[0], here[1], here[2]);
14817       }
14818    } else if (!strcmp(variant,"GMATRIX")) {
14819       SUMA_SurfaceObject *SO=SUMA_GDSET_FrameSO(dset);
14820       if (!SO) {
14821          SUMA_S_Warnv("No Frame SO for %s?\n", SDSET_LABEL(dset));
14822          SUMA_RETURN(here);
14823       }
14824       here[0] = SO->Center[0]; here[1] = SO->Center[1]; here[2] = SO->Center[2];
14825       SUMA_LHv("From SO for %s : %f %f %f:\n",
14826                   variant, here[0], here[1], here[2]);
14827       SUMA_RETURN(here);
14828    } else if (!strcmp(variant,"GRELIEF")) {
14829       SUMA_S_Err("Not ready yet for GRELIEF");
14830       SUMA_RETURN(here);
14831    } else if (!strncmp(variant,"TheShadow", 9)) {
14832       SUMA_LH("Who knows what evil lurks in the hearts of men?");
14833       SUMA_RETURN(here);
14834    } else {
14835       SUMA_S_Errv("Bad draw variant >%s< for %s\n",
14836                   variant, SDSET_LABEL(dset));
14837       SUMA_DUMP_TRACE("Bad draw variant");
14838       SUMA_RETURN(here);
14839    }
14840 
14841    SUMA_RETURN(here);
14842 }
14843 
14844 #define NVALS_XYZ_EDGE 6
SUMA_GDSET_EdgeXYZ(SUMA_DSET * dset,int isel,char * variant,float * here)14845 float *SUMA_GDSET_EdgeXYZ(SUMA_DSET *dset, int isel, char *variant, float *here)
14846 {
14847    static char FuncName[]={"SUMA_GDSET_EdgeXYZ"};
14848    static int icall=0;
14849    static float fv[10][NVALS_XYZ_EDGE];
14850 
14851    SUMA_ENTRY;
14852 
14853    if (!here) {
14854       ++icall; if (icall > 9) icall = 0;
14855       here = (float *)(&fv[icall]);
14856    }
14857 
14858    SUMA_GDSET_EdgeXYZ_eng(dset, isel, variant, here);
14859 
14860    SUMA_RETURN(here);
14861 }
14862 
SUMA_GDSET_EdgeXYZ_eng(SUMA_DSET * dset,int isel,char * variant,float * here)14863 SUMA_Boolean SUMA_GDSET_EdgeXYZ_eng(SUMA_DSET *dset, int isel,
14864                                     char *variant, float *here)
14865 {
14866    static char FuncName[]={"SUMA_GDSET_EdgeXYZ_eng"};
14867    int N_Node=-1, *ind0=NULL, *ind1=NULL, *inde=NULL, i1=-1, i2=0;
14868    SUMA_GraphLinkDO *gldo=NULL;
14869    SUMA_Boolean LocalHead = NOPE;
14870 
14871    SUMA_ENTRY;
14872 
14873    if (!here) {
14874       SUMA_S_Err("Must give me a pointer for results");
14875       SUMA_RETURN(NOPE);
14876    }
14877 
14878    SUMA_LHv("Looking for XYZ of edge ID %d, variant %s on dset %s\n",
14879             isel, variant, SDSET_LABEL(dset));
14880 
14881    here[0] = here[1] = here[2] =
14882    here[3] = here[4] = here[5] = 0.0;
14883 
14884    if (!dset || isel < 0) SUMA_RETURN(NOPE);
14885    if (!variant) {
14886       SUMA_S_Err("No XYZ on dset without variant");
14887       SUMA_RETURN(NOPE);
14888    }
14889 
14890    if (isel <= SUMA_GDSET_Max_Edge_Index(dset)) {
14891       SDSET_EDGE_NODE_INDEX_COLS(dset, inde, ind0, ind1);
14892       if (!ind0 || !ind1 || !inde) {
14893          SUMA_LH("No explicit node idexing information");
14894          SUMA_RETURN(NOPE);
14895       }
14896       if (inde[isel] != isel) {
14897          SUMA_LHv("Hard way for segment index %d: i1=%d, i2 = %d\n",
14898                         isel, i1, i2);
14899          /* Fetch the indices of the nodes forming the edge */
14900          if (!SUMA_GDSET_SegIndexToPoints(dset, isel, &i1, &i2, NULL)) {
14901             SUMA_S_Errv("Failed to locate nodes of edge %d on dset %s\n",
14902                         isel, SDSET_LABEL(dset));
14903             SUMA_RETURN(NOPE);
14904          }
14905       } else { /* the easy way */
14906          SUMA_LHv("Easy way: inde[%d]=%d [%d %d]\n",
14907                   isel, inde[isel], ind0[isel], ind1[isel]);
14908          i1 = ind0[isel];
14909          i2 = ind1[isel];
14910       }
14911 
14912       if (i1 < 0 || i2 < 0) SUMA_RETURN(NOPE);
14913 
14914       if (!strcmp(variant,"GMATRIX")) {
14915          SUMA_LHv("Here looking for XYZ of %d %d\n", i1, i2);
14916          /* Get an edge coord based on the matrix being displayed */
14917          if (SUMA_GDSET_edgeij_to_GMATRIX_XYZ(dset, i1, i2, here, 0)) {
14918             /* duplicate the 1st three vals to make results consistent
14919                with G3D case */
14920             here[3] = here[0]; here[4]=here[1]; here[5]=here[2];
14921          } else {
14922             SUMA_S_Err("Should this happen ?");
14923             SUMA_RETURN(NOPE);
14924          }
14925       } else { /* the 3D one */
14926          if (!(SUMA_GDSET_NodeXYZ_eng(dset, i1, variant, here)))
14927                SUMA_RETURN(NOPE);
14928          if (!(SUMA_GDSET_NodeXYZ(dset, i2, variant, here+3)))
14929                SUMA_RETURN(NOPE);
14930       }
14931 
14932       SUMA_LHv("Selection request for edge %d [%d %d] variant %s\n"
14933                    "here=[%f %f %f %f %f %f]\n",
14934                    isel, i1, i2, variant,
14935                    here[0], here[1], here[2], here[3], here[4], here[5]);
14936    } else {
14937       SUMA_LHv("isel=%d, veclen=%d, max edge index %d\n",
14938                isel, SDSET_VECLEN(dset), SUMA_GDSET_Max_Edge_Index(dset));
14939    }
14940 
14941    SUMA_RETURN(YUP);
14942 }
14943 
SUMA_GDSET_FrameSO(SUMA_DSET * dset)14944 SUMA_SurfaceObject *SUMA_GDSET_FrameSO(SUMA_DSET *dset)
14945 {
14946    static char FuncName[]={"SUMA_GDSET_FrameSO"};
14947    SUMA_GRAPH_SAUX *GSaux = NULL;
14948 
14949    SUMA_ENTRY;
14950 
14951    if (!(GSaux = SDSET_GSAUX(dset))) {
14952       SUMA_S_Err("Cannot create an SO this early, or dset is not graph");
14953       SUMA_RETURN(NULL);
14954    }
14955    if (!GSaux->nido && !(GSaux->nido = SUMA_GDSET_matrix_nido(dset))) {
14956       SUMA_S_Err("No milk!");
14957       SUMA_DUMP_TRACE("%s", FuncName);
14958       SUMA_RETURN(NULL);
14959    }
14960 
14961    if (!GSaux->FrameSO) {
14962       /* need to make one */
14963       GSaux->FrameSO = SUMA_Surface_Of_NIDO_Matrix(GSaux->nido);
14964    }
14965 
14966    SUMA_RETURN(GSaux->FrameSO);
14967 }
14968 
SUMA_GDSET_GMATRIX_Aff(SUMA_DSET * dset,double Aff[4][4],int I2X)14969 SUMA_Boolean SUMA_GDSET_GMATRIX_Aff(SUMA_DSET *dset, double Aff[4][4], int I2X)
14970 {
14971    static char FuncName[]={"SUMA_GDSET_GMATRIX_Aff"};
14972    SUMA_GRAPH_SAUX *GSaux=NULL;
14973    double V[12];
14974    SUMA_Boolean LocalHead = NOPE;
14975 
14976    SUMA_ENTRY;
14977 
14978    if (!(GSaux = SDSET_GSAUX(dset)) || !GSaux->nido) SUMA_RETURN(NOPE);
14979 
14980    if (I2X) {
14981       NI_GET_DOUBLEv(GSaux->nido->ngr, "ijk_to_dicom_real", V, 12, LocalHead);
14982       if (!NI_GOT) {
14983          SUMA_S_Err("No ijk_to_dicom_real");
14984          SUMA_RETURN(NOPE);
14985       }
14986       V12_TO_AFF44(Aff, V);
14987    } else {
14988       NI_GET_DOUBLEv(GSaux->nido->ngr, "dicom_real_to_ijk", V, 12, LocalHead);
14989       if (!NI_GOT) {
14990          SUMA_S_Err("No dicom_real_to_ijk");
14991          SUMA_RETURN(NOPE);
14992       }
14993       V12_TO_AFF44(Aff, V);
14994    }
14995 
14996    SUMA_RETURN(YUP);
14997 }
14998 /* Return coordinates of a datum, failure returns 0 0 0
14999    Note that what a datum represents will differ
15000    depending on the object*/
15001 #define NVALS_XYZ_DATUM 6
SUMA_ADO_DatumXYZ(SUMA_ALL_DO * ado,int isel,char * variant)15002 float *SUMA_ADO_DatumXYZ(SUMA_ALL_DO *ado, int isel, char *variant)
15003 {
15004    static char FuncName[]={"SUMA_ADO_DatumXYZ"};
15005    static int icall=0;
15006    static float fv[10][NVALS_XYZ_DATUM];
15007 
15008    SUMA_ENTRY;
15009 
15010    ++icall; if (icall > 9) icall = 0;
15011    fv[icall][0] = fv[icall][1] = fv[icall][2] =
15012    fv[icall][3] = fv[icall][4] = fv[icall][5] = 0.0;
15013 
15014    if (!ado || isel < 0) SUMA_RETURN(fv[icall]);
15015    switch (ado->do_type) {
15016       case SO_type: {
15017          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
15018          if (SO->NodeList && isel < SO->N_Node) {
15019             float *ff = SO->NodeList+SO->NodeDim*isel;
15020             fv[icall][0] = *ff;++ff;
15021             if (SO->NodeDim > 1) fv[icall][1] = *ff;++ff;
15022             if (SO->NodeDim > 2) fv[icall][2] = *ff;++ff;
15023          }
15024          break; }
15025       case CDOM_type: {
15026          SUMA_S_Err("Not ready: 1- find domain from index.\n"
15027                     "           2- find index on domain\n"
15028                     "           3- return XYZ\n");
15029          return(NULL);
15030          break;
15031          }
15032       case GDSET_type: {
15033          SUMA_DSET *dset=(SUMA_DSET *)ado;
15034          if (!variant) {
15035             SUMA_S_Err("No XYZ without variant on dsets");
15036          } else {
15037             return(SUMA_GDSET_EdgeXYZ(dset, isel, variant,
15038                                       (float *)(&fv[icall])));
15039          }
15040          break; }
15041       case GRAPH_LINK_type: {
15042          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
15043          SUMA_DSET *dset=NULL;
15044          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
15045             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
15046                         SUMA_ADO_Label(ado));
15047             SUMA_RETURN(fv[icall]);
15048          }
15049          if (!variant) variant = SUMA_ADO_variant(ado);
15050          return(SUMA_GDSET_EdgeXYZ(dset, isel, variant, (float *)(&fv[icall])));
15051          break; }
15052       default:
15053          /* no coords */
15054          break;
15055    }
15056 
15057    SUMA_RETURN(fv[icall]);
15058 }
15059 
15060 /*! Return the local domain parent for an ado */
SUMA_ADO_LDP(SUMA_ALL_DO * ado)15061 char *SUMA_ADO_LDP(SUMA_ALL_DO *ado)
15062 {
15063    static char FuncName[]={"SUMA_ADO_LDP"};
15064 
15065    if (!ado) return(NULL);
15066    switch (ado->do_type) {
15067       case SO_type: {
15068          SUMA_SurfaceObject *SO=(SUMA_SurfaceObject *)ado;
15069          return(SO->LocalDomainParentID);
15070          break; }
15071       case ANY_DSET_type:
15072       case MD_DSET_type:
15073       case GDSET_type: {
15074          SUMA_DSET *dset = (SUMA_DSET *)ado;
15075          return(SDSET_ID(dset)); /* itself */
15076          break; }
15077       case GRAPH_LINK_type: {
15078          SUMA_GraphLinkDO *gldo=(SUMA_GraphLinkDO *)ado;
15079          SUMA_DSET *dset=NULL;
15080          if (!(dset=SUMA_find_GLDO_Dset(gldo))) {
15081             SUMA_S_Errv("Failed to find dset for gldo %s!!!\n",
15082                         SUMA_ADO_Label(ado));
15083             return(NULL);
15084          }
15085          return(SUMA_ADO_LDP((SUMA_ALL_DO *)dset));
15086          break; }
15087       case CDOM_type: {
15088          SUMA_S_Warn("Not sure if this will apply yet.");
15089          return(NULL);
15090          break; }
15091       default:
15092          return(NULL);
15093    }
15094    return(NULL);
15095 }
15096 
SUMA_ADO_CSaux(SUMA_ALL_DO * ado)15097 SUMA_CIFTI_SAUX *SUMA_ADO_CSaux(SUMA_ALL_DO *ado)
15098 {
15099    static char FuncName[]={"SUMA_ADO_CSaux"};
15100 
15101    if (!ado) return(NULL);
15102    switch (ado->do_type) {
15103       case CDOM_type:
15104          return((SUMA_CIFTI_SAUX *)SUMA_ADO_Saux(ado));
15105          break;
15106       default:
15107          return(NULL);
15108    }
15109    return(NULL);
15110 }
15111 
SUMA_ADO_GSaux(SUMA_ALL_DO * ado)15112 SUMA_GRAPH_SAUX *SUMA_ADO_GSaux(SUMA_ALL_DO *ado)
15113 {
15114    static char FuncName[]={"SUMA_ADO_GSaux"};
15115 
15116    if (!ado) return(NULL);
15117    switch (ado->do_type) {
15118       case GDSET_type:
15119       case GRAPH_LINK_type:
15120          return((SUMA_GRAPH_SAUX *)SUMA_ADO_Saux(ado));
15121          break;
15122       default:
15123          return(NULL);
15124    }
15125    return(NULL);
15126 }
15127 
SUMA_ADO_TSaux(SUMA_ALL_DO * ado)15128 SUMA_TRACT_SAUX *SUMA_ADO_TSaux(SUMA_ALL_DO *ado)
15129 {
15130    static char FuncName[]={"SUMA_ADO_TSaux"};
15131 
15132    if (!ado) return(NULL);
15133    switch (ado->do_type) {
15134       case TRACT_type:
15135          return((SUMA_TRACT_SAUX *)SUMA_ADO_Saux(ado));
15136          break;
15137       default:
15138          return(NULL);
15139    }
15140    return(NULL);
15141 }
15142 
SUMA_ADO_MSaux(SUMA_ALL_DO * ado)15143 SUMA_MASK_SAUX *SUMA_ADO_MSaux(SUMA_ALL_DO *ado)
15144 {
15145    static char FuncName[]={"SUMA_ADO_MSaux"};
15146 
15147    if (!ado) return(NULL);
15148    switch (ado->do_type) {
15149       case MASK_type:
15150          return((SUMA_MASK_SAUX *)SUMA_ADO_Saux(ado));
15151          break;
15152       default:
15153          return(NULL);
15154    }
15155    return(NULL);
15156 }
15157 
SUMA_ADO_SSaux(SUMA_ALL_DO * ado)15158 SUMA_SURF_SAUX *SUMA_ADO_SSaux(SUMA_ALL_DO *ado)
15159 {
15160    static char FuncName[]={"SUMA_SURF_SAUX"};
15161 
15162    if (!ado) return(NULL);
15163    switch (ado->do_type) {
15164       case SO_type:
15165          return((SUMA_SURF_SAUX *)SUMA_ADO_Saux(ado));
15166          break;
15167       default:
15168          return(NULL);
15169    }
15170    return(NULL);
15171 }
15172 
SUMA_ADO_VSaux(SUMA_ALL_DO * ado)15173 SUMA_VOL_SAUX *SUMA_ADO_VSaux(SUMA_ALL_DO *ado)
15174 {
15175    static char FuncName[]={"SUMA_ADO_VSaux"};
15176 
15177    if (!ado) return(NULL);
15178    switch (ado->do_type) {
15179       case VO_type:
15180          return((SUMA_VOL_SAUX *)SUMA_ADO_Saux(ado));
15181          break;
15182       default:
15183          return(NULL);
15184    }
15185    return(NULL);
15186 }
15187 
SUMA_ADO_Saux(SUMA_ALL_DO * ado)15188 void *SUMA_ADO_Saux(SUMA_ALL_DO *ado)
15189 {
15190    static char FuncName[]={"SUMA_ADO_Saux"};
15191 
15192    if (!ado) return(NULL);
15193    switch (ado->do_type) {
15194       case SO_type:
15195          return((void *)SDO_SSAUX((SUMA_SurfaceObject *)ado));
15196          break;
15197       case CDOM_type:
15198          return((void *)CDO_CSAUX((SUMA_CIFTI_DO *)ado));
15199          break;
15200       case GDSET_type:
15201          return((void *)SDSET_GSAUX((SUMA_DSET *)ado));
15202          break;
15203       case GRAPH_LINK_type: {
15204          SUMA_DSET *dset = SUMA_find_GLDO_Dset((SUMA_GraphLinkDO *)ado);
15205          return((void *)SUMA_ADO_Saux((SUMA_ALL_DO *)dset));
15206          break; }
15207       case TRACT_type: {
15208          return((void *)TDO_TSAUX((SUMA_TractDO *)ado));
15209          break; }
15210       case MASK_type: {
15211          return((void *)MDO_MSAUX((SUMA_MaskDO *)ado));
15212          break; }
15213       case VO_type: {
15214          return((void *)VDO_VSAUX((SUMA_VolumeObject *)ado));
15215          break; }
15216       default:
15217          return(NULL);
15218    }
15219    return(NULL);
15220 }
15221 
SUMA_ADO_Dset(SUMA_ALL_DO * ado)15222 SUMA_DSET *SUMA_ADO_Dset(SUMA_ALL_DO *ado)
15223 {
15224    static char FuncName[]={"SUMA_ADO_Dset"};
15225 
15226    if (!ado) return(NULL);
15227    switch (ado->do_type) {
15228       case SO_type:
15229          return(NULL);
15230          break;
15231       case CDOM_type:
15232          SUMA_S_Note("Decide what should be done here. A CDOM is created from a "
15233                      "certain CIFTI dataset that one could return. However it "
15234                      "is envisioned that multiple CIFTI datasets can share the "
15235                      "same CIFTI domain so then which dset to return in that "
15236                      "instance. For now, let us return NULL");
15237          return(NULL);
15238          break;
15239       case ANY_DSET_type:
15240       case MD_DSET_type:
15241       case GDSET_type:
15242          return((SUMA_DSET *)ado);
15243          break;
15244       case GRAPH_LINK_type: {
15245          return(SUMA_find_GLDO_Dset((SUMA_GraphLinkDO *)ado));
15246          break; }
15247       default:
15248          return(NULL);
15249    }
15250    return(NULL);
15251 }
15252 
15253 /*!
15254    How many and which DOs are anatomically correct ?
15255 */
SUMA_Anatomical_DOs(SUMA_DO * dov,int N_dov,int * rdov)15256 int SUMA_Anatomical_DOs(SUMA_DO *dov, int N_dov, int *rdov)
15257 {
15258    static char FuncName[]={"SUMA_Anatomical_DOs"};
15259    SUMA_ALL_DO *ado=NULL;
15260    int ii, N=0;
15261 
15262    if (!dov) {
15263       dov = SUMAg_DOv;
15264       N_dov = SUMAg_N_DOv;
15265    }
15266    for (ii=0; ii<N_dov; ++ii) {
15267       ado = (SUMA_ALL_DO *)dov[ii].OP;
15268       if (SUMA_ADO_is_AnatCorrect(ado)) {
15269          ++N;
15270          if (rdov) rdov[N-1] = ii;
15271       }
15272    }
15273 
15274    return(N);
15275 
15276 }
15277