1 #include "SUMA_suma.h"
2 #include "coxplot.h"
3 #include "SUMA_plot.h"
4 
5 /* SUMA_display.c is too big for my own good.
6    This is part the second                    */
7 
SUMA_cb_createSurfaceCont_MDO(Widget w,XtPointer data,XtPointer callData)8 void SUMA_cb_createSurfaceCont_MDO(Widget w, XtPointer data,
9                                      XtPointer callData)
10 {
11    static char FuncName[] = {"SUMA_cb_createSurfaceCont_MDO"};
12    Widget tl, pb, form,
13           rc_left, rc_right, rc_mamma, rc_gmamma, tls=NULL;
14    Display *dpy;
15    SUMA_ALL_DO *ado;
16    SUMA_MaskDO *mdo;
17    char *slabel, *lbl30, *sss=NULL;
18    XmString xmstmp;
19    SUMA_X_SurfCont *SurfCont=NULL;
20    SUMA_OVERLAYS *curColPlane=NULL, *over0=NULL;
21    SUMA_Boolean LocalHead = NOPE;
22 
23    SUMA_ENTRY;
24 
25    ado = (SUMA_ALL_DO *)data;
26    if (ado->do_type != MASK_type) {
27       SUMA_S_Errv("Calling me with (%s) other than MASK_type type,\n"
28                   "I don't like that, call me with MDO",
29                   SUMA_ObjectTypeCode2ObjectTypeName(ado->do_type));
30       SUMA_RETURNe;
31    }
32    mdo = (SUMA_MaskDO *)ado;
33 
34    SUMA_LHv("Creating SurfaceCont for type %s, label %s\n",
35             ADO_TNAME(ado), SUMA_ADO_Label(ado));
36    if (LocalHead) {
37       SUMA_DUMP_TRACE("Creating SurfaceCont");
38    }
39 
40    if (!(SurfCont = SUMA_ADO_Cont(ado))) {
41       SUMA_S_Errv("Failed to get Controller for ado %s\n",
42                   SUMA_ADO_Label(ado));
43       SUMA_RETURNe;
44    }
45 
46    if (!SUMA_SurfCont_SetcurDOp(SurfCont, ado)) {
47       SUMA_S_Errv("Failed to Set curDOp for %s\n",
48                   SUMA_ADO_Label(ado));
49       SUMA_RETURNe;
50    }
51 
52    if (!(curColPlane = SUMA_ADO_CurColPlane(ado))) {
53       SUMA_LH("No current col plane for ado %s, OK for masks\n",
54               SUMA_ADO_Label(ado));
55    }
56 
57    if (SurfCont->TLS) {
58       fprintf (SUMA_STDERR,
59                "Error %s: SurfCont->TopLevelShell!=NULL.\n"
60                "Should not be here.\n", FuncName);
61       SUMA_RETURNe;
62    }
63 
64    tl = SUMA_GetTopShell(w); /* top level widget */
65    dpy = XtDisplay(tl);
66 
67    slabel = (char *)SUMA_malloc(sizeof(char) *
68                                  (strlen(SUMA_ADO_Label(ado)) + 100));
69    if (strlen(SUMA_ADO_Label(ado)) > 40) {
70       char *tmpstr=NULL;
71       tmpstr = SUMA_truncate_string(SUMA_ADO_Label(ado), 40);
72       if (tmpstr) {
73          sprintf(slabel,"[%s] Mask Controller", tmpstr);
74          free(tmpstr); tmpstr=NULL;
75       }
76    } else {
77       sprintf(slabel,"[%s] Mask Controller", SUMA_ADO_Label(ado));
78    }
79 
80    /* March 12 08: Made font8 default for surface controller */
81    if (SUMA_isEnv("SUMA_SurfContFontSize", "BIG")) {
82       sss = "font9";
83    } else {
84       sss = "font8";
85    }
86 
87    SUMA_LH("Creating dialog shell.");
88    if (!SUMAg_CF->X->UseSameSurfCont ||
89        !SUMAg_CF->X->CommonSurfContTLW) { /* need a new one */
90       #if SUMA_CONTROLLER_AS_DIALOG /* xmDialogShellWidgetClass,
91                                        topLevelShellWidgetClass*/
92       tls = XtVaCreatePopupShell (sss,
93          XmNtitle, slabel,
94          xmDialogShellWidgetClass, tl,
95          XmNallowShellResize, True, /* let code resize shell */
96          XmNdeleteResponse, XmDO_NOTHING,
97          NULL);
98       #else
99       SUMA_LH("Creating toplevel shell.");
100       /** Feb 03/03:    I was using XtVaCreatePopupShell to create a
101                         topLevelShellWidgetClass.
102                         XtVaCreatePopupShell is used to create dialog
103                         shells not toplevel or appshells.
104                         Of course, it made no difference! */
105       tls = XtVaAppCreateShell (sss, "Suma",
106          topLevelShellWidgetClass, SUMAg_CF->X->DPY_controller1 ,
107          XmNtitle, slabel,
108          XmNdeleteResponse, XmDO_NOTHING,
109          NULL);
110       #endif
111 
112       /* allow for code to resize the shell */
113       XtVaSetValues (tls,
114             XmNresizePolicy , XmRESIZE_NONE ,
115             XmNallowShellResize , True ,       /* let code resize shell */
116             NULL);
117 
118       /* handle the close button from window manager */
119       XmAddWMProtocolCallback(/* make "Close" window menu work */
120          tls,
121          XmInternAtom( dpy , "WM_DELETE_WINDOW" , False ) ,
122          SUMA_cb_closeSurfaceCont, (XtPointer) ado) ;
123 
124       if (SUMAg_CF->X->UseSameSurfCont) {
125          Widget scroller;
126          SUMAg_CF->X->CommonSurfContTLW = tls;
127          SUMAg_CF->X->SC_Notebook =
128             XtVaCreateWidget("ControllerBook", xmNotebookWidgetClass,
129                              SUMAg_CF->X->CommonSurfContTLW,
130                              XmNbindingWidth, XmNONE,
131                              XmNbackPageNumber, 0,
132                              XmNmajorTabSpacing, 0,
133                              XmNminorTabSpacing, 0,
134                              NULL);
135             /*XmCreateNotebook (SUMAg_CF->X->CommonSurfContTLW, "ControllerBook",
136                               NULL, 0);
137               XtVaSetValues(SUMAg_CF->X->SC_Notebook,
138                           XmNbindingWidth, XmNONE,
139                           NULL); */
140 
141 
142          /* Kill the scroller from hell otherwise no keyboard input
143             gets to the baby widgets. Better write my own scroller
144             if need be in the future */
145          scroller = XtNameToWidget (SUMAg_CF->X->SC_Notebook, "PageScroller");
146          XtUnmanageChild (scroller);
147       }
148    }
149 
150    if (SUMAg_CF->X->UseSameSurfCont) {
151       SurfCont->TLS = SUMAg_CF->X->CommonSurfContTLW;
152    } else {
153       SurfCont->TLS = tls;
154    }
155 
156    if (!SurfCont->TLS) {
157       SUMA_S_Err("Bad logic");
158       SUMA_RETURNe;
159    }
160 
161    SUMA_LH("Widgets...");
162    if (SUMAg_CF->X->UseSameSurfCont) {
163       Arg args[20];
164       /* add the page */
165       XtSetArg (args[0], XmNnotebookChildType, XmPAGE);
166       SurfCont->Page =
167          XmCreateRowColumn (SUMAg_CF->X->SC_Notebook,
168                      SUMA_ADO_Label(ado)?SUMA_ADO_Label(ado):"page",
169                                               args, 1);
170    }
171 
172    /* create a form widget, manage it at the end ...*/
173    SurfCont->Mainform = XtVaCreateWidget ("dialog",
174       xmFormWidgetClass, SurfCont->Page ?
175                               SurfCont->Page:SurfCont->TLS,
176       XmNborderWidth , 0 ,
177       XmNmarginHeight , SUMA_MARGIN ,
178       XmNmarginWidth  , SUMA_MARGIN ,
179       XmNshadowThickness, 2,
180       XmNshadowType, XmSHADOW_ETCHED_IN,
181       NULL);
182 
183    rc_gmamma = XtVaCreateWidget ("rowcolumn",
184             xmRowColumnWidgetClass, SurfCont->Mainform,
185             XmNpacking, XmPACK_TIGHT,
186             XmNorientation , XmVERTICAL ,
187             XmNmarginHeight, SUMA_MARGIN ,
188             XmNmarginWidth , SUMA_MARGIN ,
189             XmNtopAttachment  , XmATTACH_FORM ,
190             XmNbottomAttachment  , XmATTACH_FORM ,
191             NULL);
192 
193 
194    SurfCont->DispFrame = SUMA_CloseBhelp_Frame(rc_gmamma,
195                      SUMA_cb_closeSurfaceCont, (XtPointer) ado,
196                      "MaskCont", "Close Surface controller",
197                      SUMA_closeSurfaceCont_help,
198                      NULL, NULL, NULL, NULL);
199    SUMA_Register_Widget_Help( SurfCont->DispFrame , 0,
200                               "MaskCont",
201                               "Network tracts mask controller",
202 "The mask controller is used for manipulating masks for network tracts"
203 ":SPX:"
204 "You can launch the :ref:`Mask Controller <MaskCont>` from the "
205 ":ref:`tract controller <TractCont>` by clicking on :ref:`Masks<TractCont->Coloring_Controls->Masks>` twice."
206 "\n\n"
207 ".. figure:: media/MaskController.02.jpg\n"
208 "   :align: center\n"
209 "   :name: media/MaskController.02.jpg\n"
210 "\n"
211 "   :ref:`(link)<media/MaskController.02.jpg>`\n"
212 "   ..\n\n"
213 ":DEF:"
214 "You can launch the Mask Controller by clicking twice on the 'Masks' "
215 "button of the tract controller.\n"
216 ":SPX:"
217 "\n"  );
218 
219    /* Also stick in some help for fictitious widget of mask manipulation mode*/
220    SUMA_Register_Widget_Help( NULL , 0,
221                               "Mask_Manipulation_Mode",
222                               "Mask Manipulation Mode",
223 "To move the mask interactively, right-double click on it to place SUMA "
224 "in :term:`Mask Manipulation Mode` which is indicated by displaying the "
225 "moveable mask in mesh mode (see help in SUMA, (:ref:`ctrl+h<LC_Ctrl+h>`),"
226 " section :ref:`Button 3-DoubleClick<Button_3-DoubleClick>` for details.)."
227 " Selecting a location on the tracts, the slices, or surfaces, will make the"
228 " mask jump to that location. The mask should also be visibile in AFNI (if "
229 "SUMA is launched with -dev option), and clicking in AFNI will make the mask "
230 "move in SUMA also.\n\n"
231 "To turn off 'Mask Manipulation Mode' right-double click in open air, or on the"
232 " manipulated mask itself.\n"
233 ":SPX:\n"
234 ".. figure:: media/MaskManipulationMode_OFF.jpg\n"
235 "   :align: left\n"
236 "   :figwidth: 45%\n"
237 "   :name: media/MaskManipulationMode_OFF.jpg\n"
238 "\n"
239 "   :ref:`Mask manipulation OFF.<media/MaskManipulationMode_OFF.jpg>\n"
240 "\n"
241 ".. figure:: media/MaskManipulationMode_ON.jpg\n"
242 "   :align: right\n"
243 "   :figwidth: 45%\n"
244 "   :name: media/MaskManipulationMode_ON.jpg\n"
245 "\n"
246 "   :ref:`Mask manipulation ON.<media/MaskManipulationMode_ON.jpg>`\n"
247 SUMA_SHPINX_BREAK
248 ":SPX:"
249    );
250 
251    XtVaCreateManagedWidget ("sep", xmSeparatorWidgetClass, rc_gmamma , NULL);
252 
253    rc_mamma = XtVaCreateWidget ("rowcolumn",
254             xmRowColumnWidgetClass, rc_gmamma,
255             XmNpacking, XmPACK_TIGHT,
256             XmNorientation , XmHORIZONTAL ,
257             XmNmarginHeight, SUMA_MARGIN ,
258             XmNmarginWidth , SUMA_MARGIN ,
259             XmNleftAttachment , XmATTACH_FORM ,
260             XmNtopAttachment  , XmATTACH_FORM ,
261             XmNrightAttachment , XmATTACH_FORM ,
262             NULL);
263 
264    rc_left = XtVaCreateWidget ("rowcolumn",
265             xmRowColumnWidgetClass, rc_mamma,
266             XmNpacking, XmPACK_TIGHT,
267             XmNorientation , XmVERTICAL ,
268             XmNmarginHeight, SUMA_MARGIN ,
269             XmNmarginWidth , SUMA_MARGIN ,
270             NULL);
271 
272    rc_right = XtVaCreateWidget ("rowcolumn",
273             xmRowColumnWidgetClass, rc_mamma,
274             XmNpacking, XmPACK_TIGHT,
275             XmNorientation , XmVERTICAL ,
276             XmNmarginHeight, SUMA_MARGIN ,
277             XmNmarginWidth , SUMA_MARGIN ,
278             NULL);
279 
280    {/*surface properties */
281       Widget rc, label, rc_SurfProp, pb, www;
282 
283       /* put a frame */
284       SurfCont->SurfFrame = XtVaCreateWidget ("dialog",
285          xmFrameWidgetClass, rc_left,
286          XmNshadowType , XmSHADOW_ETCHED_IN ,
287          XmNshadowThickness , 5 ,
288          XmNtraversalOn , False ,
289          NULL);
290 
291       www = XtVaCreateManagedWidget ("Masks",
292             xmLabelWidgetClass, SurfCont->SurfFrame,
293             XmNchildType, XmFRAME_TITLE_CHILD,
294             XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING,
295             NULL);
296       SUMA_Register_Widget_Help( www , 0,
297                                  "MaskCont->Masks",
298                           "Create/delete masks and setup masking expression",
299                   ":SPX:\n\n"
300                   ".. figure:: media/MaskCont.auto.Masks.jpg\n"
301                   "   :align: right\n"
302                   "   :name: media/MaskCont.auto.Masks.jpg\n"
303                   "\n"
304                   "   :ref:`(link)<media/MaskCont.auto.Masks.jpg>`\n"
305                   "   ..\n\n"
306                   ":SPX:") ;
307 
308       rc_SurfProp = XtVaCreateWidget ("rowcolumn",
309             xmRowColumnWidgetClass, SurfCont->SurfFrame,
310             XmNpacking, XmPACK_TIGHT,
311             XmNorientation , XmVERTICAL ,
312             XmNmarginHeight, 0 ,
313             XmNmarginWidth , 0 ,
314             NULL);
315 
316       if (!SurfCont->rcswr) {
317          /* This row column is typically for the dataset range
318             values. For masks we repurpose the variable */
319          SurfCont->rcswr = XtVaCreateWidget ("rowcolumn",
320                   xmRowColumnWidgetClass, rc_SurfProp,
321                   XmNpacking, XmPACK_TIGHT,
322                   XmNorientation , XmVERTICAL ,
323                   XmNtopAttachment, XmATTACH_WIDGET ,
324                   NULL);
325       }
326 
327       if (1) {
328          /* add the mask equation region */
329          char *row_tit[]=  {  "Mask Eval", NULL };
330          char *row_hint[]= {  "Evaluate mask expression", NULL};
331          char *row_help[]= {  SUMA_SurfContHelp_EvalMaskExpr_r0, NULL};
332          Widget rc_maskeval;
333          rc_maskeval = XtVaCreateManagedWidget ("rowcolumn",
334                                        xmRowColumnWidgetClass, SurfCont->rcswr,
335                                                 XmNorientation , XmHORIZONTAL ,
336                                                 XmNmarginHeight, 0,
337                                                 XmNmarginHeight, 0,
338                                                 XmNmarginWidth, 0,
339                                                 NULL);
340          if (!SurfCont->MaskEvalTable->cells) {
341             int colw[6] = { 3, 24 };
342             SUMA_CreateTable( rc_maskeval,
343                               1, 2,
344                               "MaskCont->Masks->Mask_Eval",
345                               row_tit, NULL,
346                               row_hint, NULL,
347                               row_help, NULL,
348                               colw, YUP, SUMA_string,
349                               SUMA_cb_SetMaskEvalTableValue, NULL,
350                               SUMA_MaskEvalTableLabel_EV, NULL,
351                               SUMA_MaskEvalTableCell_EV, NULL,
352                               SurfCont->MaskEvalTable);
353          }
354          /* And baby toggle  */
355          SurfCont->MaskEval_tb = XtVaCreateManagedWidget("v",
356                                  xmToggleButtonWidgetClass, rc_maskeval, NULL);
357          XtAddCallback (SurfCont->MaskEval_tb,
358                         XmNvalueChangedCallback, SUMA_cb_UseMaskEval_toggled,
359                         NULL);
360          SUMA_Register_Widget_Help(SurfCont->MaskEval_tb, 1,
361                                    "MaskCont->Masks->Mask_Eval->v",
362                            "Enable (ON)/Disable Mask expression evaluation",
363                            "Enable (ON)/Disable Mask expression evaluation");
364 
365          SUMA_SET_SELECT_COLOR(SurfCont->MaskEval_tb);
366          XmToggleButtonSetState (SurfCont->MaskEval_tb,
367                                  SurfCont->UseMaskEval , NOPE);
368 
369          if (!SurfCont->MaskLenTable->cells) {
370             int colw[6] = { 3, 4, 4 };
371             char *row_tit[]=  {  " Tract Length", NULL };
372             char *row_hint[]= {  "Mask based on tract length", NULL};
373             char *row_help[]= {  SUMA_SurfContHelp_DistMask_r0, NULL};
374 
375             XtVaCreateManagedWidget (  "sep",
376                               xmSeparatorWidgetClass, rc_maskeval,
377                               XmNorientation, XmVERTICAL,NULL);
378 
379             SUMA_CreateTable( rc_maskeval,
380                               1, 3,
381                               "MaskCont->Masks->Tract_Length",
382                               row_tit, NULL,
383                               row_hint, NULL,
384                               row_help, NULL,
385                               colw, YUP, SUMA_float,
386                               SUMA_cb_SetMaskLenTableValue, NULL,
387                               SUMA_MaskLenTableLabel_EV, NULL,
388                               SUMA_MaskLenTableCell_EV, NULL,
389                               SurfCont->MaskLenTable);
390             SUMA_INSERT_CELL_VALUE(SurfCont->MaskLenTable, 0, 1,
391                                       SurfCont->tract_length_mask[0]);
392             SUMA_INSERT_CELL_VALUE(SurfCont->MaskLenTable, 0, 2,
393                                       SurfCont->tract_length_mask[1]);
394          }
395          /* And baby toggle  */
396          SurfCont->MaskLen_tb = XtVaCreateManagedWidget("v",
397                                  xmToggleButtonWidgetClass, rc_maskeval, NULL);
398          XtAddCallback (SurfCont->MaskLen_tb,
399                         XmNvalueChangedCallback, SUMA_cb_UseMaskLen_toggled,
400                         NULL);
401          SUMA_Register_Widget_Help(SurfCont->MaskLen_tb, 1,
402                                    "MaskCont->Masks->Tract_Length->v",
403                            "Enable (ON)/Disable Tract Length masking",
404                            "Enable (ON)/Disable Tract Length masking");
405 
406          SUMA_SET_SELECT_COLOR(SurfCont->MaskLen_tb);
407          XmToggleButtonSetState (SurfCont->MaskLen_tb,
408                                  SurfCont->UseMaskLen , NOPE);
409       }
410 
411       if (1) { /* The properties area */
412          char *col_tit[]=  {  "+", " ", "Label", "Type", "Center", "Size",
413                                     "RGB", "A", "T", "D", NULL};
414          char *col_hint[]= {  "Add new mask",
415                               "Variable",
416                               "Label",
417                               "Type ('box' or 'sphere')",
418                               "Center X,Y,Z",
419                               "Size Sx,Sy,Sz",
420                               "Color R G B (A)",
421                               "A",
422                               "T", "D", NULL };
423          char *col_help[]= {  SUMA_SurfContHelp_MaskTypeTbl_c0,
424                               SUMA_SurfContHelp_MaskTypeTbl_c05,
425                               SUMA_SurfContHelp_MaskTypeTbl_c1,
426                               SUMA_SurfContHelp_MaskTypeTbl_c2,
427                               SUMA_SurfContHelp_MaskTypeTbl_c3,
428                               SUMA_SurfContHelp_MaskTypeTbl_c4,
429                               SUMA_SurfContHelp_MaskTypeTbl_c5,
430                               SUMA_SurfContHelp_MaskTypeTbl_c6,
431                               SUMA_SurfContHelp_MaskTypeTbl_c7,
432                               SUMA_SurfContHelp_MaskTypeTbl_c8,
433                               NULL };
434          char *row_tit[]=  {  "+", "x", NULL };
435          char *row_hint[]= {  "Add new mask", "Mask Properties", NULL};
436          char *row_help[]= {  SUMA_SurfContHelp_MaskTypeTbl_c0,
437                               SUMA_SurfContHelp_MaskTypeTbl_r1, NULL};
438          if (!SurfCont->MaskTable->cells) {
439             int colw[15] = { 1, 1, 6, 6, 11, 11, 11, 1, 1, 1};
440             SUMA_CreateTable( SurfCont->rcswr,
441                               2, 10,
442                               "MaskCont->Masks->Table",
443                               row_tit, col_tit,
444                               row_hint, col_hint,
445                               row_help, col_help,
446                               colw, YUP, SUMA_string,
447                               SUMA_cb_SetMaskTableValue, NULL,
448                               SUMA_MaskTableLabel_EV, NULL,
449                               SUMA_MaskTableCell_EV, NULL,
450                               SurfCont->MaskTable);
451          }
452       }
453 
454       XtVaCreateManagedWidget (  "sep",
455                                  xmSeparatorWidgetClass, SurfCont->rcswr,
456                                  XmNorientation, XmHORIZONTAL,NULL);
457 
458       /* row column for Switch, Load, Delete */
459       rc = XtVaCreateWidget ("rowcolumn",
460          xmRowColumnWidgetClass, SurfCont->rcswr,
461          XmNpacking, XmPACK_TIGHT,
462          XmNorientation , XmHORIZONTAL ,
463          NULL);
464 
465       pb = XtVaCreateWidget ("Load Masks",
466             xmPushButtonWidgetClass, rc,
467             NULL);
468          XtAddCallback (pb, XmNactivateCallback,
469                         SUMA_cb_Masks_Load, (XtPointer) ado);
470          SUMA_Register_Widget_Help(pb, 1, "MaskCont->Masks->Load_Masks",
471                                    "Load the masks (much more with BHelp)",
472                                    SUMA_SurfContHelp_MasksLoad ) ;
473          XtManageChild (pb);
474 
475       pb = XtVaCreateWidget ("Save Masks",
476             xmPushButtonWidgetClass, rc,
477             NULL);
478          XtAddCallback (pb, XmNactivateCallback,
479                         SUMA_cb_Masks_Save, (XtPointer) ado);
480          SUMA_Register_Widget_Help(pb, 1, "MaskCont->Masks->Save_Masks",
481                                    "Save the masks (much more with BHelp)",
482                                    SUMA_SurfContHelp_MasksSave ) ;
483          XtManageChild (pb);
484 
485       XtManageChild (rc);
486 
487       XtManageChild (rc_SurfProp);
488       if (!XtIsManaged(SurfCont->rcswr)) XtManageChild (SurfCont->rcswr);
489       XtManageChild (SurfCont->SurfFrame);
490    }
491 
492    if (!SUMA_InitMasksTable(SurfCont)) {
493       SUMA_S_Err("Failed to initialize table");
494       SUMA_RETURNe;
495    }
496 
497    if (SUMAg_CF->X->UseSameSurfCont) {
498       Widget rc=NULL;
499       /* put something to cycle through objects */
500       if ((rc = SUMA_FindChildWidgetNamed(SurfCont->DispFrame,"rowcolumnCBF"))) {
501          XtVaCreateManagedWidget (  "sep",
502                               xmSeparatorWidgetClass, rc,
503                               XmNorientation, XmVERTICAL,NULL);
504          pb = XtVaCreateWidget ("All Objs.",
505                   xmPushButtonWidgetClass, rc,
506                   NULL);
507          XtAddCallback (pb, XmNactivateCallback,
508                         SUMA_cb_AllConts, NULL);
509          SUMA_Register_Widget_Help(pb, 1, "MaskCont->Disp_Cont->AllObjs",
510                                 "Initialize Controllers for All Objects",
511                                 SUMA_SurfContHelp_AllObjs) ;
512          XtManageChild (pb);
513 
514          SUMA_CreateArrowField ( rc, "Switch",
515                            1, 1, 20, 1,
516                            2, SUMA_int,
517                            YUP,
518                            SUMA_cb_SurfCont_SwitchPage, (void *)ado,
519                            "MaskCont->Disp_Cont->Switch",
520                            "Switch to other object controller",
521                            SUMA_Switch_Cont_BHelp,
522                            SurfCont->SurfContPage);
523          xmstmp = XmStringCreateLtoR (SUMA_ADO_CropLabel(ado,
524                                        SUMA_SURF_CONT_SWITCH_LABEL_LENGTH),
525                                       XmSTRING_DEFAULT_CHARSET);
526          SurfCont->SurfContPage_label = XtVaCreateManagedWidget ("dingel-7",
527                xmLabelWidgetClass, rc,
528                XmNlabelString, xmstmp,
529                NULL);
530          XmStringFree (xmstmp);
531       }
532    }
533 
534 
535 
536 
537    SUMA_LHv("Management ...%p %p %p %p %p\n",
538             rc_right, rc_left, rc_mamma, SurfCont->Mainform, SurfCont->Page);
539 
540    XtManageChild (rc_right);
541    XtManageChild (rc_left);
542    XtManageChild (rc_mamma);
543    XtManageChild (rc_gmamma);
544    XtManageChild (SurfCont->Mainform);
545    if (SUMAg_CF->X->UseSameSurfCont) XtManageChild (SurfCont->Page);
546 
547    #if SUMA_CONTROLLER_AS_DIALOG
548    #else
549    /** Feb 03/03: pop it up if it is a topLevelShellWidgetClass,
550    you should do the popping after all the widgets have been created.
551    Otherwise, the window does not size itself correctly when open */
552    XtPopup(SurfCont->TLS, XtGrabNone);
553    #endif
554 
555    /* realize the widget */
556    if (SUMAg_CF->X->UseSameSurfCont) XtManageChild (SUMAg_CF->X->SC_Notebook);
557    XtRealizeWidget (SurfCont->TLS);
558 
559    SUMA_LH("%s",slabel);
560    SUMA_free (slabel);
561 
562    #if USING_LESSTIF
563    SUMA_LH("Less tif fix");
564    /* A quick fix to ensure Dset_Mapping
565       gets displayed properly the first time */
566    SUMA_cb_ToggleManagementColPlaneWidget(NULL, (XtPointer)(&ado), NULL);
567    SUMA_cb_ToggleManagementColPlaneWidget(NULL, (XtPointer)(&ado), NULL);
568    #endif
569 
570    SUMA_LH("going home.");
571 
572    SUMA_MarkSurfContOpen(1, ado);
573    SUMA_RETURNe;
574 }
575 
SUMA_Set_UseMaskEval(int v,int redisp,int setmen)576 SUMA_Boolean SUMA_Set_UseMaskEval(int v, int redisp, int setmen)
577 {
578    static char FuncName[]={"SUMA_Set_UseMaskEval"};
579    SUMA_X_SurfCont *SurfCont=NULL;
580    DList *list=NULL;
581    int vi=0;
582    SUMA_Boolean LocalHead = NOPE;
583 
584    SUMA_ENTRY;
585 
586    SurfCont = SUMAg_CF->X->AllMaskCont;
587    if (v) v = 1;
588    else v = 0;
589    if (setmen && SurfCont->MaskEval_tb) {
590       vi = XmToggleButtonGetState (SurfCont->MaskEval_tb);
591       if (v != vi) {
592          XmToggleButtonSetState(SurfCont->MaskEval_tb, v, NOPE);
593       }
594    }
595    SurfCont->UseMaskEval = v;
596 
597    if (redisp) {
598       SUMA_NEW_MASKSTATE();
599       /* redisplay */
600       if (!list) list = SUMA_CreateList ();
601       SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
602                                          SES_Suma, NULL);
603       if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
604    }
605 
606    SUMA_RETURN(NOPE);
607 }
608 
SUMA_cb_UseMaskEval_toggled(Widget w,XtPointer data,XtPointer client_data)609 void SUMA_cb_UseMaskEval_toggled(Widget w, XtPointer data, XtPointer client_data)
610 {
611    static char FuncName[]={"SUMA_cb_UseMaskEval_toggled"};
612    SUMA_ALL_DO *ado = NULL;
613    SUMA_X_SurfCont *SurfCont=NULL;
614    DList *list=NULL;
615    SUMA_Boolean LocalHead = NOPE;
616 
617    SUMA_ENTRY;
618 
619    SUMA_LH("Called");
620 
621    SurfCont = SUMAg_CF->X->AllMaskCont;
622 
623    SUMA_Set_UseMaskEval(XmToggleButtonGetState(SurfCont->MaskEval_tb),1,0);
624 
625    SUMA_RETURNe;
626 }
627 
628 
SUMA_Set_UseMaskLen(int v,int redisp,int setmen)629 SUMA_Boolean SUMA_Set_UseMaskLen(int v, int redisp, int setmen)
630 {
631    static char FuncName[]={"SUMA_Set_UseMaskLen"};
632    SUMA_X_SurfCont *SurfCont=NULL;
633    DList *list=NULL;
634    int vi=0;
635    SUMA_Boolean LocalHead = NOPE;
636 
637    SUMA_ENTRY;
638 
639    SurfCont = SUMAg_CF->X->AllMaskCont;
640    if (v) v = 1;
641    else v = 0;
642    if (setmen && SurfCont->MaskLen_tb) {
643       vi = XmToggleButtonGetState (SurfCont->MaskLen_tb);
644       if (v != vi) {
645          XmToggleButtonSetState(SurfCont->MaskLen_tb, v, NOPE);
646       }
647    }
648    SurfCont->UseMaskLen = v;
649 
650    if (redisp) {
651       SUMA_NEW_MASKSTATE();
652       /* redisplay */
653       if (!list) list = SUMA_CreateList ();
654       SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
655                                          SES_Suma, NULL);
656       if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
657    }
658 
659    SUMA_RETURN(NOPE);
660 }
661 
SUMA_cb_UseMaskLen_toggled(Widget w,XtPointer data,XtPointer client_data)662 void SUMA_cb_UseMaskLen_toggled(Widget w, XtPointer data, XtPointer client_data)
663 {
664    static char FuncName[]={"SUMA_cb_UseMaskLen_toggled"};
665    SUMA_ALL_DO *ado = NULL;
666    SUMA_X_SurfCont *SurfCont=NULL;
667    DList *list=NULL;
668    SUMA_Boolean LocalHead = NOPE;
669 
670    SUMA_ENTRY;
671 
672    SUMA_LH("Called");
673 
674    SurfCont = SUMAg_CF->X->AllMaskCont;
675 
676    SUMA_Set_UseMaskLen(XmToggleButtonGetState(SurfCont->MaskLen_tb),1,0);
677 
678    SUMA_RETURNe;
679 }
680 
681 
682 /*!
683    Called when user clicks on Mask table cell
684    expects in cd
685 */
SUMA_MaskTableCell_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)686 void SUMA_MaskTableCell_EV ( Widget w , XtPointer cd ,
687                       XEvent *ev , Boolean *continue_to_dispatch )
688 {
689    static char FuncName[]={"SUMA_MaskTableCell_EV"};
690    SUMA_ALL_DO *ado=NULL, *curDO=NULL;
691    SUMA_X_SurfCont *SurfCont=NULL;
692    XButtonEvent * bev = (XButtonEvent *) ev ;
693    int  i, j, n, Found, incr=0, ii;
694    float fv[4];
695    void *cv=NULL;
696    SUMA_MaskDO *mdo = NULL;
697    DList *list=NULL;
698    SUMA_TABLE_FIELD *TF = NULL;
699    SUMA_Boolean LocalHead = NOPE;
700 
701    SUMA_ENTRY;
702 
703    SUMA_LH("Called Button %d", bev->button);
704 
705    SurfCont = SUMAg_CF->X->AllMaskCont;
706    curDO = SUMA_Cont_ADO(SurfCont);
707    TF = SurfCont->MaskTable;
708 
709    /* see note in bbox.c optmenu_EV for the condition below*/
710    if( bev->button == Button2 ) {
711      XUngrabPointer( bev->display , CurrentTime ) ;
712      SUMA_RETURNe ;
713    }
714 
715    if( w == NULL || TF == NULL ) { SUMA_RETURNe ; }
716 
717    incr = 0;
718    switch (bev->button) {
719       case Button1:
720          SUMA_LH("Button 1");
721          break;
722       case Button2:
723          SUMA_LH("Button 2");
724          break;
725       case Button3:
726          SUMA_LH("Button 3");
727          break;
728       case Button4:
729       case 6:  /* This is shift and wheel on mac, Button6 is not in X.h ! */
730          SUMA_LH("Button 4/6 %d", bev->button);
731          incr = -1;
732          break;
733       case Button5:
734       case 7:
735          SUMA_LH("Button 5/7 %d", bev->button);
736          incr = 1;
737          break;
738       default:
739          SUMA_RETURNe;
740    }
741 
742    /* which cell is calling? */
743    n = 0;
744    Found = -1;
745    while (n<TF->Nj*TF->Ni && Found == -1) {
746       if (TF->cells[n] == w) {
747          Found = n;
748       } else ++n;
749    }
750 
751    if (Found <0) {
752       SUMA_SL_Err("Widget not found ????");
753       SUMA_RETURNe;
754    }
755 
756    /* find out widget's place in table*/
757    i = Found % TF->Ni; j = Found / TF->Ni ;
758    n = Found;
759 
760    /* ado from above is not the mask we are to work with */
761    if (!(ado = SUMA_whichADOg(TF->rowobject_id[i]))) {
762       SUMA_S_Err("Failed to find mask object from row %d!", i);
763       SUMA_RETURNe;
764    }
765    if (ado->do_type != MASK_type) {
766       SUMA_S_Err("Need masks only here");
767       SUMA_RETURNe;
768    }
769    mdo = (SUMA_MaskDO *)ado;
770 
771    switch (j) {
772       case 0:
773          break;
774       case 1:
775          break;
776       case 2:
777          SUMA_LH("Need to set label for mask %s", ADO_LABEL(ado));
778          break;
779       case 3:
780          SUMA_LH("Need to set type for mask %s", ADO_LABEL(ado));
781          break;
782       case 4:
783          SUMA_LH("Need to set center for mask %s", ADO_LABEL(ado));
784          if (incr) {
785          } else{
786             if (bev->button == Button3) {/* reset dim */
787                SUMA_MDO_New_Cen(mdo,mdo->init_cen);
788             }
789             SUMA_InitMasksTable_row(SurfCont,mdo, i);
790             SUMA_NEW_MASKSTATE();
791             /* redisplay */
792             if (!list) list = SUMA_CreateList ();
793             SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
794                                                SES_Suma, NULL);
795             if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
796          }
797          break;
798       case 5:
799          if (incr) {
800             fv[0] = mdo->hdim[0]+(incr*0.2*mdo->init_hdim[0]);
801             fv[1] = mdo->hdim[1]+(incr*0.2*mdo->init_hdim[1]);
802             fv[2] = mdo->hdim[2]+(incr*0.2*mdo->init_hdim[2]);
803             SUMA_MDO_New_Dim(mdo, fv);
804          } else {
805             if (bev->button == Button3) {/* reset dim */
806                SUMA_MDO_New_Dim(mdo,mdo->init_hdim);
807             }
808          }
809          SUMA_InitMasksTable_row(SurfCont,mdo, i);
810 
811          SUMA_NEW_MASKSTATE();
812          /* redisplay */
813          if (!list) list = SUMA_CreateList ();
814          SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
815                                             SES_Suma, NULL);
816          if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
817          break;
818       case 6:
819          SUMA_LH("Need to set color for mask %s", ADO_LABEL(ado));
820          break;
821       case 7:
822          if (incr) {
823             fv[0] = mdo->init_col[0]; fv[1] = mdo->init_col[1];
824             fv[2] = mdo->init_col[2];
825             ii = SUMA_A_to_1dig(mdo->init_col[3])+incr;
826             fv[3] = SUMA_1dig_to_A(ii);
827             if (fv[3] != mdo->init_col[3]) {
828                SUMA_MDO_New_Alpha(mdo, fv[3]);
829                SUMA_InitMasksTable_row(SurfCont,mdo, i);
830 
831                if (SurfCont->UseMaskEval) SUMA_NEW_MASKSTATE();
832                /* redisplay */
833                if (!list) list = SUMA_CreateList ();
834                SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
835                                                   SES_Suma, NULL);
836                if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
837             } else {
838                SUMA_InitMasksTable_row(SurfCont,mdo, i);
839             }
840          }
841          break;
842       case 8:
843          if (incr) {
844             ii = SUMA_T_to_1dig(mdo->SO->TransMode)+incr;
845             if (ii >= 0 && ii < 10) {
846                SUMA_Set_MaskDO_Trans(mdo,(SUMA_TRANS_MODES)SUMA_1dig_to_T(ii));
847                SUMA_InitMasksTable_row(SurfCont,mdo, i);
848                /* redisplay */
849                if (!list) list = SUMA_CreateList ();
850                SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
851                                                   SES_Suma, NULL);
852                if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
853             } else {
854                SUMA_InitMasksTable_row(SurfCont,mdo, i);
855             }
856          }
857          break;
858       case 9:
859          if (incr) {
860             fv[0] = mdo->init_col[0]; fv[1] = mdo->init_col[1];
861             fv[2] = mdo->init_col[2];
862             ii = SUMA_A_to_1dig(mdo->dim)+incr;
863             fv[3] = SUMA_1dig_to_A(ii);
864             if (fv[3] != mdo->dim) {
865                SUMA_MDO_New_CDim(mdo, fv[3]);
866                SUMA_InitMasksTable_row(SurfCont,mdo, i);
867 
868                if (SurfCont->UseMaskEval) SUMA_NEW_MASKSTATE();
869                /* redisplay */
870                if (!list) list = SUMA_CreateList ();
871                SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
872                                                   SES_Suma, NULL);
873                if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
874             } else {
875                SUMA_InitMasksTable_row(SurfCont,mdo, i);
876             }
877          }
878          break;
879       default:
880          SUMA_SL_Err("Did not know you had so many");
881          break;
882    }
883 
884    SUMA_RETURNe;
885 }
886 
887 /*
888    Turns a user typed expression to one that the parser likes.
889    Must have spaces around vars for parser, but a little ugly for
890    typing.
891    string expr is not changed.
892    string evale must be pre-allocated and be about twice as long as expr,
893    just to be safe.
894    string tight is perhaps a nicer to look at version of expr
895 */
896 
SUMA_DispExpr_To_EvalExpr(char * uexpr,char * evale,char * tight)897 SUMA_Boolean SUMA_DispExpr_To_EvalExpr(char *uexpr, char *evale, char *tight)
898 {
899    static char FuncName[]={"SUMA_DispExpr_To_EvalExpr"};
900    int n, k, t, havevar, nex, pad;
901    char *expr=NULL;
902    SUMA_Boolean LocalHead = NOPE;
903 
904    SUMA_ENTRY;
905 
906    if (!uexpr || !evale) SUMA_RETURN(NOPE);
907 
908    expr = SUMA_copy_string(uexpr);
909    deblank_name(expr);
910    SUMA_LH("Have %s", expr);
911 
912    if (!strcasecmp(expr,"AND")) {
913       /* All AND */
914       sprintf(evale,"AND");
915       sprintf(tight,"AND");
916       SUMA_RETURN(YUP);
917    } else if (!strcasecmp(expr,"OR")) {
918       /* All OR */
919       sprintf(evale,"OR");
920       sprintf(tight,"OR");
921       SUMA_RETURN(YUP);
922    }
923 
924    /* switch AND and OR to | and & and trim && and || */
925    nex = strlen(expr);
926    n = 0; k = 0;
927    while (expr[n] != '\0') {
928       if (expr[n]   == 'A' && n<nex-3 &&
929           expr[n+1] == 'N' && expr[n+2] == 'D') {
930           evale[k++] = '&';
931          n = n + 2;
932       } else if (expr[n]   == 'O' && n<nex-2 &&
933           expr[n+1] == 'R') {
934           evale[k++] = '|';
935          n = n + 1;
936       } else if (expr[n] == '+') {
937          evale[k++] = '|';
938       } else if (expr[n] == '*') {
939          evale[k++] = '&';
940       } else {
941          if ((k > 0 && expr[n] != evale[k])
942              || k == 0) { /* to skip dups of | and & */
943             evale[k++]=expr[n];
944          } else {
945          }
946       }
947       n = n + 1;
948    }
949    evale[k] = '\0';
950    SUMA_STRING_REPLACE(expr, evale);
951    SUMA_LH("Now have %s", expr);
952 
953    /* remove all blanks from expr */
954    n = 0; k = 0; t= 0;
955    while (expr[n] != '\0') {
956       if (SUMA_IS_BLANK((expr[n]))) {
957       } else {
958          evale[k++] = expr[n];
959          if (tight) tight[t++] = expr[n];
960       }
961       ++n;
962    }
963    evale[k] = '\0';
964    SUMA_STRING_REPLACE(expr, evale);
965    SUMA_LH("No blank has %s", expr);
966 
967    /* Now insert space between each character */
968    evale[0] = expr[0];
969    n = 1; k = 1; t= 0;
970    while (expr[n] != '\0') {
971       if (SUMA_IS_BLANK((expr[n]))) {
972       } else {
973          if (!SUMA_IS_BLANK(evale[k-1])) {
974             evale[k++] = ' ';
975             evale[k++] = expr[n];
976             if (expr[n+1] != '\0') evale[k++] = ' ';
977          } else {
978             evale[k++] = expr[n];
979          }
980       }
981       ++n;
982    }
983    evale[k] = '\0';
984    SUMA_LH("And now have %s", evale);
985 
986    /* Make sure everything is blank separatd */
987 
988 
989    /* Now make sure the equation has nothing but acceptable chars */
990    k = 0;
991    while (evale[k] != '\0') {
992       if (evale[k] == '|' || evale[k] == '&'   ||
993           (evale[k] >= 'a' && evale[k] <= 'z') ||
994           evale[k] == '(' || evale[k] == ')'   ||
995           evale[k] == '!'                      ||
996           SUMA_IS_BLANK(evale[k])              ) {
997          /* all good */
998       } else {
999          SUMA_S_Err("Character %c (#%d) in %s from %s not allowed",
1000                      evale[k], k, evale, expr);
1001          SUMA_ifree(expr);
1002          SUMA_RETURN(NOPE);
1003       }
1004       ++k;
1005    }
1006 
1007    /* And make sure the equation does not start or end with and or or */
1008    k = 0; havevar = 0;
1009    while (evale[k] != '\0' && !havevar) {
1010       if ((evale[k] == '|' || evale[k] == '&') && !havevar) {
1011          SUMA_S_Err(
1012             "Encountered operator %c before variable at char #%d in %s from %s",
1013             evale[k], k, evale, expr);
1014          SUMA_ifree(expr);
1015          SUMA_RETURN(NOPE);
1016       } else if (evale[k] >= 'a' && evale[k] <= 'z') {
1017          havevar = 1;
1018       }
1019       ++k;
1020    }
1021    k = strlen(evale)-1; havevar = 0;
1022    while (k >=0 && !havevar) {
1023       if ((evale[k] == '|' || evale[k] == '&') && !havevar) {
1024          SUMA_S_Err(
1025          "Encountered operator %c after last variable at char #%d in %s from %s",
1026             evale[k], k, evale, expr);
1027          SUMA_ifree(expr);
1028          SUMA_RETURN(NOPE);
1029       } else if (evale[k] >= 'a' && evale[k] <= 'z') {
1030          havevar = 1;
1031       }
1032       --k;
1033    }
1034 
1035    SUMA_LH("About to return: expr %s, tight %s, evale %s",
1036             expr, tight, evale);
1037    SUMA_ifree(expr);
1038    SUMA_RETURN(YUP);
1039 }
1040 
SUMA_MaskEvalTableCell_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)1041 void SUMA_MaskEvalTableCell_EV ( Widget w , XtPointer cd ,
1042                       XEvent *ev , Boolean *continue_to_dispatch )
1043 {
1044    static char FuncName[]={"SUMA_MaskEvalTableCell_EV"};
1045    SUMA_ALL_DO *ado=NULL, *curDO=NULL;
1046    SUMA_X_SurfCont *SurfCont=NULL;
1047    XButtonEvent * bev = (XButtonEvent *) ev ;
1048    int  i, j, n, Found, incr=0;
1049    float fv[4];
1050    char evale[256]={""}, tight[128]={""}, exp[128]={""};
1051    void *cv=NULL;
1052    SUMA_MaskDO *mdo = NULL;
1053    DList *list=NULL;
1054    SUMA_TABLE_FIELD *TF = NULL;
1055    SUMA_Boolean LocalHead = NOPE;
1056 
1057    SUMA_ENTRY;
1058 
1059    SUMA_LH("Called Button %d", bev->button);
1060 
1061    SurfCont = SUMAg_CF->X->AllMaskCont;
1062    curDO = SUMA_Cont_ADO(SurfCont);
1063    TF = SurfCont->MaskEvalTable;
1064 
1065    /* see note in bbox.c optmenu_EV for the condition below*/
1066    if( bev->button == Button2 ) {
1067      XUngrabPointer( bev->display , CurrentTime ) ;
1068      SUMA_RETURNe ;
1069    }
1070 
1071    if( w == NULL || TF == NULL ) { SUMA_RETURNe ; }
1072 
1073    incr = 0;
1074    switch (bev->button) {
1075       case Button1:
1076          SUMA_LH("Button 1");
1077          break;
1078       case Button2:
1079          SUMA_LH("Button 2");
1080          break;
1081       case Button3:
1082          SUMA_LH("Button 3");
1083          break;
1084       case Button4:
1085       case 6:  /* This is shift and wheel on mac, Button6 is not in X.h ! */
1086          SUMA_LH("Button 4/6 %d", bev->button);
1087          break;
1088       case Button5:
1089       case 7:
1090          SUMA_LH("Button 5/7 %d", bev->button);
1091          break;
1092       default:
1093          SUMA_RETURNe;
1094    }
1095 
1096    /* which cell is calling? */
1097    n = 0;
1098    Found = -1;
1099    while (n<TF->Nj*TF->Ni && Found == -1) {
1100       if (TF->cells[n] == w) {
1101          Found = n;
1102       } else ++n;
1103    }
1104 
1105    if (Found <0) {
1106       SUMA_SL_Err("Widget not found ????");
1107       SUMA_RETURNe;
1108    }
1109 
1110    /* find out widget's place in table*/
1111    i = Found % TF->Ni; j = Found / TF->Ni ;
1112    n = Found;
1113 
1114    switch (j) {
1115       case 0:
1116          break;
1117       case 1:
1118          break;
1119       case 2:
1120          break;
1121       case 3:
1122          break;
1123       case 4:
1124          break;
1125       case 5:
1126          break;
1127       default:
1128          SUMA_SL_Err("Did not know you had so many");
1129          break;
1130    }
1131    SUMA_RETURNe;
1132 }
1133 
SUMA_MaskLenTableCell_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)1134 void SUMA_MaskLenTableCell_EV ( Widget w , XtPointer cd ,
1135                       XEvent *ev , Boolean *continue_to_dispatch )
1136 {
1137    static char FuncName[]={"SUMA_MaskLenTableCell_EV"};
1138    SUMA_ALL_DO *ado=NULL, *curDO=NULL;
1139    SUMA_X_SurfCont *SurfCont=NULL;
1140    XButtonEvent * bev = (XButtonEvent *) ev ;
1141    int  i, j, n, Found, incr=0;
1142    float fv[4];
1143    char evale[256]={""}, tight[128]={""}, exp[128]={""};
1144    void *cv=NULL;
1145    SUMA_MaskDO *mdo = NULL;
1146    DList *list=NULL;
1147    SUMA_TABLE_FIELD *TF = NULL;
1148    SUMA_Boolean LocalHead = NOPE;
1149 
1150    SUMA_ENTRY;
1151 
1152    SUMA_LH("Called Button %d", bev->button);
1153 
1154    SurfCont = SUMAg_CF->X->AllMaskCont;
1155    curDO = SUMA_Cont_ADO(SurfCont);
1156    TF = SurfCont->MaskLenTable;
1157 
1158    /* see note in bbox.c optmenu_EV for the condition below*/
1159    if( bev->button == Button2 ) {
1160      XUngrabPointer( bev->display , CurrentTime ) ;
1161      SUMA_RETURNe ;
1162    }
1163 
1164    if( w == NULL || TF == NULL ) { SUMA_RETURNe ; }
1165 
1166    incr = 0;
1167    switch (bev->button) {
1168       case Button1:
1169          SUMA_LH("Button 1");
1170          break;
1171       case Button2:
1172          SUMA_LH("Button 2");
1173          break;
1174       case Button3:
1175          SUMA_LH("Button 3");
1176          break;
1177       case Button4:
1178       case 6:  /* This is shift and wheel on mac, Button6 is not in X.h ! */
1179          SUMA_LH("Button 4/6 %d", bev->button);
1180          incr = -1;
1181          break;
1182       case Button5:
1183       case 7:
1184          SUMA_LH("Button 5/7 %d", bev->button);
1185          incr = 1;
1186          break;
1187       default:
1188          SUMA_RETURNe;
1189    }
1190 
1191    /* which cell is calling? */
1192    n = 0;
1193    Found = -1;
1194    while (n<TF->Nj*TF->Ni && Found == -1) {
1195       if (TF->cells[n] == w) {
1196          Found = n;
1197       } else ++n;
1198    }
1199 
1200    if (Found <0) {
1201       SUMA_SL_Err("Widget not found ????");
1202       SUMA_RETURNe;
1203    }
1204 
1205    /* find out widget's place in table*/
1206    i = Found % TF->Ni; j = Found / TF->Ni ;
1207    n = Found;
1208 
1209    switch (j) {
1210       case 0:
1211          break;
1212       case 1:
1213       case 2:
1214          if (incr) {
1215               if (TF->num_value[n]>1000) incr = incr*100;
1216             else if (TF->num_value[n]>100) incr = incr*10;
1217             else if (TF->num_value[n]>50) incr = incr*5;
1218             else if (TF->num_value[n]>10) incr = incr*2;
1219             SUMA_SetMaskLenTableValueNew(i, j,
1220                           TF->num_value[n]+incr,
1221                           1, 1, TF->num_units);
1222          }
1223          break;
1224       case 3:
1225          break;
1226       case 4:
1227          break;
1228       case 5:
1229          break;
1230       default:
1231          SUMA_SL_Err("Did not know you had so many");
1232          break;
1233    }
1234 
1235 
1236    SUMA_RETURNe;
1237 }
1238 
1239 /*!
1240    Called when user clicks on table title
1241    Expects SUMA_SRV_DATA in TF->NewValueCallbackData
1242 */
SUMA_MaskTableLabel_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)1243 void SUMA_MaskTableLabel_EV ( Widget w , XtPointer cd ,
1244                       XEvent *ev , Boolean *continue_to_dispatch )
1245 {
1246    static char FuncName[]={"SUMA_MaskTableLabel_EV"};
1247    Dimension lw ;
1248    Widget * children , wl = NULL;
1249    XButtonEvent * bev = (XButtonEvent *) ev ;
1250    int  num_children , i, j, Found, AutoHist;
1251    DList *list=NULL;
1252    SUMA_TABLE_FIELD *TF = (SUMA_TABLE_FIELD *)cd;
1253    SUMA_X_SurfCont *SurfCont=NULL;
1254    SUMA_OVERLAYS *curColPlane=NULL;
1255    SUMA_Boolean LocalHead = NOPE;
1256 
1257    SUMA_ENTRY;
1258 
1259    SUMA_LH("Called");
1260 
1261    /* see note in bbox.c optmenu_EV for the condition below*/
1262    if( bev->button == Button2 ){
1263      XUngrabPointer( bev->display , CurrentTime ) ;
1264      SUMA_RETURNe ;
1265    }
1266 
1267    if( w == NULL || TF == NULL ) SUMA_RETURNe ;
1268 
1269    switch (bev->button) {
1270       case Button1:
1271          SUMA_LH("Button 1");
1272          break;
1273       case Button2:
1274          SUMA_LH("Button 2");
1275          break;
1276       case Button3:
1277          SUMA_LH("Button 3");
1278          break;
1279       default:
1280          SUMA_RETURNe;
1281    }
1282 
1283    /* which column title (i == 0) widget is calling ? */
1284    /* check the first column */
1285    i = 0; j = 0;
1286    Found = 0;
1287    while (j<TF->Nj && !Found) {
1288       if (TF->cells[j*TF->Ni+i] == w) {
1289          Found = 1;
1290       } else ++j;
1291    }
1292 
1293    if (!Found) { /* maybe it is a row title */
1294       i = 0; j = 0;
1295       Found = 0;
1296       while (i<TF->Ni && !Found) {
1297          if (TF->cells[j*TF->Ni+i] == w) {
1298             Found = 1;
1299          } else ++i;
1300       }
1301    }
1302 
1303    if (Found >= 0) {
1304       SUMA_LHv("Click on cell [%d %d]\n", i, j);
1305    } else {
1306       SUMA_SL_Err("CEll not found!");
1307       SUMA_RETURNe;
1308    }
1309 
1310    SurfCont = SUMAg_CF->X->AllMaskCont;
1311 
1312    if (!SurfCont) {
1313       SUMA_SL_Err("No  SurfCont !");
1314       SUMA_RETURNe;
1315    }
1316 
1317    /* Now do something */
1318    if (j == 0) { /* clicked on one of the row's titles */
1319       switch (i) {
1320          case 0:
1321             if (bev->button == Button1) {
1322                /* Add a new mask and update the table */
1323                if (SUMA_NewSymMaskDO(NULL)<0) {
1324                   SUMA_S_Err("Failed create new mask");
1325                   SUMA_RETURNe;
1326                }
1327 
1328                if (!SUMA_InitMasksTable(SurfCont)) {
1329                   SUMA_S_Err("Failed to add row");
1330                   SUMA_RETURNe;
1331                }
1332                SUMA_NEW_MASKSTATE();
1333                /* redisplay */
1334                if (!list) list = SUMA_CreateList ();
1335                SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
1336                                                   SES_Suma, NULL);
1337                if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
1338             }
1339             break;
1340          default:
1341             if (bev->button == Button1) { /* delete? */
1342                SUMA_cb_Mask_Delete(w, (XtPointer)TF->rowobject_id[i], NULL);
1343             }else if (bev->button == Button3) {
1344 
1345             }
1346             break;
1347       }
1348    }
1349    if (i == 0) { /* clicked on one of the column's titles */
1350       switch (j) {
1351          case 1:
1352             break;
1353          case 2:
1354             break;
1355          case 3:
1356             break;
1357          default:
1358             break;
1359       }
1360    }
1361 
1362    SUMA_RETURNe;
1363 }
1364 
SUMA_MaskEvalTableLabel_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)1365 void SUMA_MaskEvalTableLabel_EV ( Widget w , XtPointer cd ,
1366                       XEvent *ev , Boolean *continue_to_dispatch )
1367 {
1368    static char FuncName[]={"SUMA_MaskEvalTableLabel_EV"};
1369    Dimension lw ;
1370    Widget * children , wl = NULL;
1371    XButtonEvent * bev = (XButtonEvent *) ev ;
1372    int  num_children , i, j, Found, AutoHist;
1373    DList *list=NULL;
1374    SUMA_TABLE_FIELD *TF = (SUMA_TABLE_FIELD *)cd;
1375    SUMA_X_SurfCont *SurfCont=NULL;
1376    SUMA_OVERLAYS *curColPlane=NULL;
1377    SUMA_Boolean LocalHead = NOPE;
1378 
1379    SUMA_ENTRY;
1380 
1381    SUMA_LH("Called");
1382 
1383    /* see note in bbox.c optmenu_EV for the condition below*/
1384    if( bev->button == Button2 ){
1385      XUngrabPointer( bev->display , CurrentTime ) ;
1386      SUMA_RETURNe ;
1387    }
1388 
1389    if( w == NULL || TF == NULL ) SUMA_RETURNe ;
1390 
1391    switch (bev->button) {
1392       case Button1:
1393          SUMA_LH("Button 1");
1394          break;
1395       case Button2:
1396          SUMA_LH("Button 2");
1397          break;
1398       case Button3:
1399          SUMA_LH("Button 3");
1400          break;
1401       default:
1402          SUMA_RETURNe;
1403    }
1404 
1405    /* which column title (i == 0) widget is calling ? */
1406    /* check the first column */
1407    i = 0; j = 0;
1408    Found = 0;
1409    while (j<TF->Nj && !Found) {
1410       if (TF->cells[j*TF->Ni+i] == w) {
1411          Found = 1;
1412       } else ++j;
1413    }
1414 
1415    if (!Found) { /* maybe it is a row title */
1416       i = 0; j = 0;
1417       Found = 0;
1418       while (i<TF->Ni && !Found) {
1419          if (TF->cells[j*TF->Ni+i] == w) {
1420             Found = 1;
1421          } else ++i;
1422       }
1423    }
1424 
1425    if (Found >= 0) {
1426       SUMA_LHv("Click on cell [%d %d]\n", i, j);
1427    } else {
1428       SUMA_SL_Err("CEll not found!");
1429       SUMA_RETURNe;
1430    }
1431 
1432    SurfCont = SUMAg_CF->X->AllMaskCont;
1433 
1434    if (!SurfCont) {
1435       SUMA_SL_Err("No  SurfCont !");
1436       SUMA_RETURNe;
1437    }
1438 
1439    /* Now do something */
1440    if (j == 0) { /* clicked on one of the row's titles */
1441       switch (i) {
1442          case 0:
1443             if (bev->button == Button1) {
1444             }
1445             break;
1446          default:
1447             if (bev->button == Button1) {
1448 
1449             }else if (bev->button == Button3) {
1450 
1451             }
1452             break;
1453       }
1454    }
1455    if (i == 0) { /* clicked on one of the column's titles */
1456       switch (j) {
1457          case 1:
1458             break;
1459          case 2:
1460             break;
1461          case 3:
1462             break;
1463          default:
1464             break;
1465       }
1466    }
1467 
1468    SUMA_RETURNe;
1469 }
1470 
SUMA_cb_SetMaskEvalTableValue(void * data)1471 void SUMA_cb_SetMaskEvalTableValue (void *data)
1472 {
1473    static char FuncName[]={"SUMA_cb_SetMaskEvalTableValue"};
1474    SUMA_ALL_DO *ado=NULL;
1475    int n=-1,row=-1,col=-1, an=0;
1476    void *cv=NULL;
1477    SUMA_TABLE_FIELD *TF=NULL;
1478    SUMA_X_SurfCont *SurfCont=NULL;
1479    SUMA_Boolean LocalHead = NOPE;
1480 
1481    SUMA_ENTRY;
1482 
1483    SurfCont = SUMAg_CF->X->AllMaskCont;
1484 
1485    TF = SurfCont->MaskEvalTable;
1486    if (LocalHead) {
1487       fprintf(SUMA_STDERR,
1488          "%s:\n Entered mask eval table cell, cell modified %d \n",
1489          FuncName, TF->cell_modified);
1490    }
1491 
1492    if (TF->cell_modified<0) SUMA_RETURNe;
1493    n = TF->cell_modified;
1494    row = n % TF->Ni;
1495    col = n / TF->Ni;
1496    XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
1497    if (LocalHead) {
1498       fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s, %s\n",
1499                            FuncName, row, col, (char *)cv, TF->str_value[n]);
1500    }
1501 
1502    an = SUMA_SetMaskEvalTableValueNew(row, col,
1503                           (char *)cv,
1504                           0, 1, TF->num_units);
1505    if (an < 0) {
1506       SUMA_BEEP;
1507    }
1508 
1509    SUMA_RETURNe;
1510 }
1511 
SUMA_MaskLenTableLabel_EV(Widget w,XtPointer cd,XEvent * ev,Boolean * continue_to_dispatch)1512 void SUMA_MaskLenTableLabel_EV ( Widget w , XtPointer cd ,
1513                       XEvent *ev , Boolean *continue_to_dispatch )
1514 {
1515    static char FuncName[]={"SUMA_MaskLenTableLabel_EV"};
1516    Dimension lw ;
1517    Widget * children , wl = NULL;
1518    XButtonEvent * bev = (XButtonEvent *) ev ;
1519    int  num_children , i, j, Found, AutoHist;
1520    DList *list=NULL;
1521    SUMA_TABLE_FIELD *TF = (SUMA_TABLE_FIELD *)cd;
1522    SUMA_X_SurfCont *SurfCont=NULL;
1523    SUMA_OVERLAYS *curColPlane=NULL;
1524    SUMA_Boolean LocalHead = NOPE;
1525 
1526    SUMA_ENTRY;
1527 
1528    SUMA_LH("Called");
1529 
1530    /* see note in bbox.c optmenu_EV for the condition below*/
1531    if( bev->button == Button2 ){
1532      XUngrabPointer( bev->display , CurrentTime ) ;
1533      SUMA_RETURNe ;
1534    }
1535 
1536    if( w == NULL || TF == NULL ) SUMA_RETURNe ;
1537 
1538    switch (bev->button) {
1539       case Button1:
1540          SUMA_LH("Button 1");
1541          break;
1542       case Button2:
1543          SUMA_LH("Button 2");
1544          break;
1545       case Button3:
1546          SUMA_LH("Button 3");
1547          break;
1548       default:
1549          SUMA_RETURNe;
1550    }
1551 
1552    /* which column title (i == 0) widget is calling ? */
1553    /* check the first column */
1554    i = 0; j = 0;
1555    Found = 0;
1556    while (j<TF->Nj && !Found) {
1557       if (TF->cells[j*TF->Ni+i] == w) {
1558          Found = 1;
1559       } else ++j;
1560    }
1561 
1562    if (!Found) { /* maybe it is a row title */
1563       i = 0; j = 0;
1564       Found = 0;
1565       while (i<TF->Ni && !Found) {
1566          if (TF->cells[j*TF->Ni+i] == w) {
1567             Found = 1;
1568          } else ++i;
1569       }
1570    }
1571 
1572    if (Found >= 0) {
1573       SUMA_LHv("Click on cell [%d %d]\n", i, j);
1574    } else {
1575       SUMA_SL_Err("CEll not found!");
1576       SUMA_RETURNe;
1577    }
1578 
1579    SurfCont = SUMAg_CF->X->AllMaskCont;
1580 
1581    if (!SurfCont) {
1582       SUMA_SL_Err("No  SurfCont !");
1583       SUMA_RETURNe;
1584    }
1585 
1586    /* Now do something */
1587    if (j == 0) { /* clicked on one of the row's titles */
1588       switch (i) {
1589          case 0:
1590             if (bev->button == Button1) {
1591             }
1592             break;
1593          default:
1594             if (bev->button == Button1) {
1595 
1596             }else if (bev->button == Button3) {
1597 
1598             }
1599             break;
1600       }
1601    }
1602    if (i == 0) { /* clicked on one of the column's titles */
1603       switch (j) {
1604          case 1:
1605             break;
1606          case 2:
1607             break;
1608          case 3:
1609             break;
1610          default:
1611             break;
1612       }
1613    }
1614 
1615    SUMA_RETURNe;
1616 }
1617 
SUMA_cb_SetMaskLenTableValue(void * data)1618 void SUMA_cb_SetMaskLenTableValue (void *data)
1619 {
1620    static char FuncName[]={"SUMA_cb_SetMaskLenTableValue"};
1621    SUMA_ALL_DO *ado=NULL;
1622    int n=-1,row=-1,col=-1, an=0;
1623    void *cv=NULL;
1624    SUMA_TABLE_FIELD *TF=NULL;
1625    SUMA_X_SurfCont *SurfCont=NULL;
1626    SUMA_Boolean LocalHead = NOPE;
1627 
1628    SUMA_ENTRY;
1629 
1630    SurfCont = SUMAg_CF->X->AllMaskCont;
1631 
1632    TF = SurfCont->MaskLenTable;
1633    if (LocalHead) {
1634       fprintf(SUMA_STDERR,
1635          "%s:\n Entered mask dist table cell, cell modified %d \n",
1636          FuncName, TF->cell_modified);
1637    }
1638 
1639    if (TF->cell_modified<0) SUMA_RETURNe;
1640    n = TF->cell_modified;
1641    row = n % TF->Ni;
1642    col = n / TF->Ni;
1643    if (LocalHead) {
1644       fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%f\n",
1645                            FuncName, row, col, TF->num_value[n]);
1646    }
1647 
1648    an = SUMA_SetMaskLenTableValueNew(row, col,
1649                           TF->num_value[n],
1650                           0, 1, TF->num_units);
1651    if (an < 0) {
1652       SUMA_BEEP;
1653    }
1654 
1655    SUMA_RETURNe;
1656 }
1657 
SUMA_cb_SetMaskTableValue(void * data)1658 void SUMA_cb_SetMaskTableValue (void *data)
1659 {
1660    static char FuncName[]={"SUMA_cb_SetMaskTableValue"};
1661    SUMA_ALL_DO *ado=NULL;
1662    int n=-1,row=-1,col=-1, an=0;
1663    void *cv=NULL;
1664    SUMA_TABLE_FIELD *TF=NULL;
1665    SUMA_X_SurfCont *SurfCont=NULL;
1666    SUMA_Boolean LocalHead = NOPE;
1667 
1668    SUMA_ENTRY;
1669 
1670    SurfCont = SUMAg_CF->X->AllMaskCont;
1671 
1672    TF = SurfCont->MaskTable;
1673    if (LocalHead) {
1674       fprintf(SUMA_STDERR,
1675          "%s:\n Entered mask table cell, cell modified %d \n",
1676          FuncName, TF->cell_modified);
1677    }
1678 
1679    if (TF->cell_modified<0) SUMA_RETURNe;
1680    n = TF->cell_modified;
1681    row = n % TF->Ni;
1682    col = n / TF->Ni;
1683    XtVaGetValues(TF->cells[n], XmNvalue, &cv, NULL);
1684    if (LocalHead) {
1685       fprintf(SUMA_STDERR,"%s:\nTable cell[%d, %d]=%s, %s\n",
1686                            FuncName, row, col, (char *)cv, TF->str_value[n]);
1687    }
1688 
1689    an = SUMA_SetMaskTableValueNew(row, col,
1690                           (char *)cv,
1691                           0, 1, TF->num_units);
1692    if (an < 0) {
1693       SUMA_BEEP;
1694    }
1695 
1696    SUMA_RETURNe;
1697 }
1698 
1699 /*!
1700    \brief modify an existing table widget
1701 */
SUMA_ModifyTable(SUMA_TABLE_FIELD * TF,int Nrows)1702 SUMA_Boolean SUMA_ModifyTable(SUMA_TABLE_FIELD *TF, int Nrows)
1703 {
1704    static char FuncName[]={"SUMA_ModifyTable"};
1705    char *row_tit_buf=NULL, *col_tit_buf=NULL, wname[64]={"NOTSETATALL"};
1706    char **row_tit=NULL,  **col_tit=NULL,  /* These should be passed if you */
1707         **row_hint=NULL, **row_help=NULL,/* desire them.  */
1708         **col_hint=NULL, **col_help=NULL,
1709         **sv=NULL;
1710    int i, j, n, titw, xmw, shad;
1711    int init_modified_row=-1, init_modified_col=-1;
1712    float *nv=NULL;
1713    byte *bf=NULL;
1714    Widget rcc, *wn=NULL;
1715    XtPointer cd;
1716    SUMA_Boolean LocalHead = NOPE;
1717 
1718    SUMA_ENTRY;
1719 
1720    if (!TF) {
1721       SUMA_S_Err("NULL TF");
1722       SUMA_RETURN(NOPE);
1723    }
1724 
1725    if (Nrows < 0) {
1726       SUMA_S_Err("Negative Nrows (%d)", Nrows);
1727       SUMA_RETURN(NOPE);
1728    }
1729 
1730    if (Nrows == TF->Ni) {
1731       SUMA_LH("Nrows (%d) == Number of rows in table. Nothing to do.", TF->Ni);
1732       SUMA_RETURN(NOPE);
1733    }
1734 
1735    if (TF->cell_modified >= 0) {
1736       init_modified_row = TF->cell_modified % TF->Ni;
1737       init_modified_col = TF->cell_modified / TF->Ni;
1738       TF->cell_modified = -1; /* Will be useless soon */
1739    } else {
1740       init_modified_row = -1; init_modified_col = -1;
1741    }
1742 
1743    if (TF->Ni > Nrows) {
1744       SUMA_LH("Removing %d rows", TF->Ni-Nrows);
1745       SUMA_LH("First get rid of the widgets");
1746 
1747       i = TF->Ni-1; j = 0;
1748       while (i >= Nrows && i >= 0) {
1749          n = j * TF->Ni + i;
1750          rcc = XtParent(TF->cells[n]);
1751          XtDestroyWidget(rcc);
1752          SUMA_ifree(TF->str_value[n]);
1753          --i;
1754       }
1755       SUMA_LH("And now to reallocate..");
1756       /* new allocation, can't just realloc, storage is column major! */
1757       wn = (Widget *)SUMA_calloc(Nrows*TF->Nj, sizeof(Widget));
1758       bf = (byte *)SUMA_calloc(Nrows*TF->Nj, sizeof(byte));
1759       if (!bf || !wn) {  SUMA_SL_Crit("Failed to allocate"); SUMA_RETURN(NOPE); }
1760       /* copy old pointers */
1761       for (i=0; i<Nrows; ++i) { for (j=0; j<TF->Nj; ++j) {
1762          wn[j*Nrows+i] = TF->cells[j*TF->Ni+i];
1763          bf[j*Nrows+i] = TF->but_flag[j*TF->Ni+i];
1764       } }
1765       SUMA_free(TF->cells); TF->cells = wn; wn = NULL;
1766       SUMA_free(TF->but_flag); TF->but_flag = bf; bf = NULL;
1767       TF->rowobject_id = (char **)SUMA_realloc(TF->rowobject_id,
1768                                                       Nrows*sizeof(char *));
1769       switch (TF->type) {
1770          case SUMA_int:
1771          case SUMA_float:
1772             nv = (float *)SUMA_calloc(TF->Nj*Nrows, sizeof(float));
1773             for (i=0; i<Nrows; ++i) { for (j=0; j<TF->Nj; ++j) {
1774                nv[j*Nrows+i] = TF->num_value[j*TF->Ni+i];
1775             } }
1776             SUMA_free(TF->num_value); TF->num_value = nv; nv = NULL;
1777             break;
1778          case SUMA_string:
1779             sv = (char **)SUMA_calloc(TF->Nj*Nrows, sizeof(char *));
1780             for (i=0; i<Nrows; ++i) { for (j=0; j<TF->Nj; ++j) {
1781                sv[j*Nrows+i] = TF->str_value[j*TF->Ni+i];
1782             } }
1783             SUMA_free(TF->str_value); TF->str_value = sv; sv = NULL;
1784             break;
1785          default:
1786             SUMA_SL_Err("Comme tu es bete!");
1787             SUMA_RETURN(NOPE);
1788             break;
1789       }
1790 
1791       TF->Ni = Nrows;
1792    } else if (TF->Ni < Nrows){
1793       SUMA_LH("Adding %d rows", Nrows-TF->Ni);
1794       SUMA_LH("First reallocating");
1795       /* new allocation, can't just realloc, storage is column major! */
1796       wn = (Widget *)SUMA_calloc(Nrows*TF->Nj, sizeof(Widget));
1797       bf = (byte *)SUMA_calloc(Nrows*TF->Nj, sizeof(byte));
1798       if (!bf || !wn) {  SUMA_SL_Crit("Failed to allocate"); SUMA_RETURN(NOPE); }
1799       /* copy old pointers */
1800       for (i=0; i<TF->Ni; ++i) { for (j=0; j<TF->Nj; ++j) {
1801          wn[j*Nrows+i] = TF->cells[j*TF->Ni+i];
1802          bf[j*Nrows+i] = TF->but_flag[j*TF->Ni+i];
1803       } }
1804       SUMA_free(TF->cells); TF->cells = wn; wn = NULL;
1805       SUMA_free(TF->but_flag); TF->but_flag = bf; bf = NULL;
1806       TF->rowobject_id = (char **)SUMA_realloc(TF->rowobject_id,
1807                                                    Nrows*sizeof(char *));
1808       for (i=TF->Ni; i<Nrows; i++) TF->rowobject_id[i] = NULL;
1809       switch (TF->type) {
1810          case SUMA_int:
1811          case SUMA_float:
1812             nv = (float *)SUMA_calloc(TF->Nj*Nrows, sizeof(float));
1813             for (i=0; i<TF->Ni; ++i) { for (j=0; j<TF->Nj; ++j) {
1814                nv[j*Nrows+i] = TF->num_value[j*TF->Ni+i];
1815             } }
1816             SUMA_free(TF->num_value); TF->num_value = nv; nv = NULL;
1817             break;
1818          case SUMA_string:
1819             sv = (char **)SUMA_calloc(TF->Nj*Nrows, sizeof(char *));
1820             for (i=0; i<TF->Ni; ++i) { for (j=0; j<TF->Nj; ++j) {
1821                sv[j*Nrows+i] = TF->str_value[j*TF->Ni+i];
1822             } }
1823             SUMA_free(TF->str_value); TF->str_value = sv; sv = NULL;
1824             break;
1825          default:
1826             SUMA_SL_Err("Comme tu es bete!");
1827             SUMA_RETURN(NOPE);
1828             break;
1829       }
1830       /* Now adding rows */
1831       i = TF->Ni;
1832       TF->Ni = Nrows;
1833       while (i != TF->Ni) {
1834          rcc = XtVaCreateManagedWidget ("rowcolumn",
1835          xmRowColumnWidgetClass, TF->rco,
1836          XmNorientation , XmHORIZONTAL ,
1837          XmNmarginHeight, 0,
1838          XmNmarginHeight, 0,
1839          XmNmarginWidth, 0,
1840          NULL);
1841 
1842          if (i == 0 && TF->HasColTit) {
1843             /* See comment in comparable section of SUMA_CreateTable() */
1844             XtVaSetValues (rcc, XmNpacking, XmPACK_TIGHT, NULL);
1845          } else {
1846             XtVaSetValues (rcc, XmNpacking, XmPACK_TIGHT, NULL);
1847          }
1848 
1849          for (j=0; j<TF->Nj; ++j) { /* for each column */
1850             n = j * TF->Ni + i;
1851             switch (SUMA_cellvariety(TF, n)) {
1852                case SUMA_ROW_TIT_CELL: /* row's title */
1853                   if (!row_tit || !row_tit[i]) {
1854                      SUMA_LH("No row_tit assuming default");
1855                      row_tit_buf = "x";
1856                   } else {
1857                      row_tit_buf = row_tit[i];
1858                   }
1859                   if (LocalHead)
1860                      fprintf( SUMA_STDERR,
1861                               "%s:\nAdding RT [%d %d] (%d) %s\n",
1862                               FuncName, i, j, n, row_tit_buf );
1863                   TF->cells[n] =
1864                      XtVaCreateManagedWidget("table",
1865                            xmTextFieldWidgetClass, rcc,
1866                            XmNvalue, row_tit_buf,
1867                            XmNmarginHeight, 0,
1868                            XmNmarginWidth, 0,
1869                            XmNmarginTop, 0,
1870                            XmNmarginBottom, 0,
1871                            XmNmarginLeft, 0,
1872                            XmNmarginRight, 0,
1873                            XmNeditable, False,
1874                            XmNshadowThickness , 0,
1875                            XmNcursorPositionVisible, False,
1876                            XmNcolumns, strlen(row_tit_buf),
1877                            NULL);
1878                   XtVaSetValues( TF->cells[n],
1879                                  XmNfontList,
1880                                  SUMAg_CF->X->TableTextFontList, NULL);
1881 
1882                   if (!TF->TitLabelEVHandlerData)
1883                      cd = (XtPointer) TF;
1884                   else cd = (XtPointer)TF->TitLabelEVHandlerData;
1885                   if (TF->TitLabelEVHandler) {
1886                      /* insert handler to catch clicks on titles */
1887                      XtInsertEventHandler(
1888                         TF->cells[n] ,      /* handle events in title cell */
1889                         ButtonPressMask ,  /* button presses */
1890                         FALSE ,            /* nonmaskable events? */
1891                         TF->TitLabelEVHandler,  /* handler */
1892                         cd ,   /* client data */
1893                         XtListTail ) ;
1894                   }
1895                   snprintf(wname, 63, "%s.r%02d", TF->wname, i);
1896                   SUMA_Register_Widget_Help(TF->cells[n], 1, wname,
1897                                             row_hint?row_hint[i]:NULL,
1898                                             row_help?row_help[i]:NULL ) ;
1899                   break;
1900 
1901                case SUMA_COL_TIT_CELL: /* column's title */
1902                   if (!col_tit || !col_tit[i]) {
1903                      SUMA_S_Err("No col_tit assuming default");
1904                      col_tit_buf = "x";
1905                   } else {
1906                      col_tit_buf = col_tit[i];
1907                   }
1908                   if (LocalHead)
1909                      fprintf( SUMA_STDERR,
1910                               "%s:\nAdding CT [%d %d] (%d) %s\n",
1911                               FuncName, i, j, n, col_tit_buf);
1912                   /* padd to fit cell entry fields*/
1913                   if (i == 0 && j != 0 && TF->HasColTit) {
1914                      titw = TF->cwidth[j];
1915                      /* set the margins to meet those of cell entries */
1916                      xmw = 5;
1917                      shad = 1;
1918                   } else {
1919                      titw = TF->cwidth[j];
1920                      /* set the margins to meet those of Labels */
1921                      xmw = 0;
1922                      shad = 0;
1923                   }
1924 
1925                   TF->cells[n] =
1926                      XtVaCreateManagedWidget("table",
1927                            xmTextFieldWidgetClass, rcc,
1928                            XmNvalue, col_tit_buf,
1929                            XmNmarginHeight, 0,
1930                            XmNmarginWidth, xmw+shad,/*include shadow size
1931                                                      of text entry cells*/
1932                            XmNmarginTop, 0,
1933                            XmNmarginBottom, 0,
1934                            XmNmarginLeft, 0,
1935                            XmNmarginRight, 0,
1936                            XmNeditable, False,
1937                            XmNshadowThickness , 0,       /* hide the border */
1938                            XmNcursorPositionVisible, False, /* hide the cursor */
1939                               /* Keep these two out: See SUMA_CreateTable()
1940                                  for comments ...
1941                               XmNfontList, SUMAg_CF->X->TableTextFontList,
1942                               XmNcolumns, titw,
1943                               */
1944                            NULL);
1945 
1946                   XtVaSetValues( TF->cells[n],
1947                                  XmNfontList,
1948                                  SUMAg_CF->X->TableTextFontList, NULL);
1949                   XtVaSetValues( TF->cells[n], XmNcolumns, titw,
1950                            NULL);
1951 
1952                   if (i == 0 && j != 0) {
1953                      XtVaSetValues( TF->cells[n],
1954                                     XmNalignment, XmALIGNMENT_BEGINNING, NULL);
1955                   }
1956 
1957                   /* insert handler to catch clicks on titles */
1958                   if (!TF->TitLabelEVHandlerData)
1959                      cd = (XtPointer) TF;
1960                   else cd = (XtPointer)TF->TitLabelEVHandlerData;
1961                   if (TF->TitLabelEVHandler) {
1962                      /* insert handler to catch clicks on titles */
1963                      XtInsertEventHandler(
1964                         TF->cells[n] ,      /* handle events in title cell */
1965                         ButtonPressMask ,  /* button presses */
1966                         FALSE ,            /* nonmaskable events? */
1967                         TF->TitLabelEVHandler,  /* handler */
1968                         cd ,   /* client data */
1969                         XtListTail ) ;
1970                   }
1971                   snprintf(wname, 63, "%s.c%02d", TF->wname, i);
1972                   SUMA_Register_Widget_Help(TF->cells[n], 1, wname,
1973                                             col_hint?col_hint[j]:NULL,
1974                                             col_help?col_help[j]:NULL ) ;
1975                   break;
1976                case SUMA_ENTRY_CELL: /* entry cell */
1977                   if (LocalHead)
1978                      fprintf( SUMA_STDERR,
1979                               "%s:\nAdding [%d %d] (%d) entry cell\n",
1980                               FuncName, i, j, n);
1981                   TF->cells[n] = XtVaCreateManagedWidget(
1982                                  "entry",
1983                                  xmTextFieldWidgetClass, rcc,
1984                                  XmNuserData, (XTP_CAST)n,
1985                                  XmNvalue, "-",
1986                                  XmNmarginHeight, 0,
1987                                  XmNmarginTop, 0,
1988                                  XmNmarginBottom, 0,
1989                                  XmNmarginWidth, 5,
1990                                  NULL);
1991                   XtVaSetValues( TF->cells[n],
1992                                     XmNfontList,
1993                                     SUMAg_CF->X->TableTextFontList, NULL);
1994                   if (col_help || col_hint || row_help || row_hint)  {
1995                      if (!row_tit && !col_tit && TF->Ni == 1 && TF->Nj == 1) {
1996                         char *shh=NULL, *sii=NULL;
1997                         if (col_help) shh = col_help[0] ;
1998                         else if (row_help) shh = row_help[0] ;
1999                         if (col_hint) sii = col_hint[0] ;
2000                         else if (row_hint) sii =  row_hint[0] ;
2001                         if (shh || sii) {
2002                            if (TF->Ni>1) {
2003                               snprintf(wname, 63, "%s[%d,%d]", TF->wname, i,j);
2004                            } else {
2005                               snprintf(wname, 63, "%s[%d]", TF->wname, n);
2006                            }
2007                            SUMA_Register_Widget_Help(TF->cells[n], 1, wname,
2008                                             sii,
2009                                             shh ) ;
2010                         }
2011 
2012                      } else {
2013                         if (TF->Ni>1) {
2014                            snprintf(wname, 63, "%s[%d,%d]", TF->wname, i,j);
2015                         } else {
2016                            snprintf(wname, 63, "%s[%d]", TF->wname, n);
2017                         }
2018                         SUMA_Register_Widget_Help(TF->cells[n], 1, wname,
2019                                     NULL,
2020                                     "Use BHelp on table's column and row titles"
2021                                     "for usage information.") ;
2022                      }
2023                   }
2024                   if (TF->cwidth[j] > 0) {
2025                      XtVaSetValues(TF->cells[n], XmNcolumns,
2026                                    TF->cwidth[j], NULL);
2027                   }
2028                   if (!TF->editable) {
2029                      SUMA_SetCellEditMode(TF, i, j, 0);
2030                   } else {
2031                      SUMA_SetCellEditMode(TF, i, j, 1);
2032                   }
2033 
2034                   /* insert handlers if any */
2035                   if (!TF->CellEVHandlerData) cd = (XtPointer) TF;
2036                      else cd = (XtPointer)TF->CellEVHandlerData;
2037                   if (TF->CellEVHandler) {
2038                      /* insert handler to catch clicks on cells */
2039                      XtInsertEventHandler(
2040                                  TF->cells[n] ,      /* handle events in cell */
2041                                  ButtonPressMask ,  /* button presses */
2042                                  FALSE ,            /* nonmaskable events? */
2043                                  TF->CellEVHandler,  /* handler */
2044                                  cd ,   /* client data */
2045                                  XtListTail ) ;
2046                   }
2047                   break;
2048                default:
2049                   SUMA_SL_Err("Bad cell type");
2050                   SUMA_RETURN(NOPE);
2051                   break;
2052             }
2053          }
2054          ++i;
2055       }/* until we have enough rows */
2056 
2057    }
2058 
2059    /* Reset the cell's user data, some of the Set calls may be redundant.*/
2060    for (i=0; i<TF->Ni; ++i) {
2061       for (j=0; j<TF->Nj; ++j) {
2062          n  = j * TF->Ni + i;
2063          switch (SUMA_cellvariety(TF, n)) {
2064             case SUMA_ENTRY_CELL:
2065                XtVaSetValues(TF->cells[n], XmNuserData, (XTP_CAST)n, NULL);
2066                break;
2067          }
2068       }
2069    }
2070 
2071    /* Reset cell_modified */
2072    TF->cell_modified =
2073          SUMA_CELL_ROW_COL_2_1D(TF, init_modified_row, init_modified_col);
2074 
2075    SUMA_RETURN(YUP);
2076 }
2077 
2078 
SUMA_AssembleMasksList(int withShadow)2079 DList *SUMA_AssembleMasksList(int withShadow)
2080 {
2081    return(SUMA_AssembleMasksList_inDOv(NULL, -1, withShadow));
2082 }
2083 
SUMA_AssembleMasksList_inDOv(SUMA_DO * dov,int N_dov,int withShadow)2084 DList *SUMA_AssembleMasksList_inDOv(SUMA_DO *dov, int N_dov, int withShadow)
2085 {
2086    static char FuncName[]={"SUMA_AssembleMasksList_inDOv"};
2087    SUMA_MaskDO *MDO;
2088    int i;
2089    DList *dl=NULL;
2090 
2091    SUMA_ENTRY;
2092 
2093    if (!dov) {
2094       dov = SUMAg_DOv; N_dov = SUMAg_N_DOv;
2095    }
2096    for (i=0; i<N_dov; ++i) {
2097       if (dov[i].ObjectType == MASK_type) {
2098          if (!dl) {
2099             dl = (DList *)SUMA_calloc(1,sizeof(DList));
2100             dlist_init(dl, NULL);
2101          }
2102          MDO = (SUMA_MaskDO *)dov[i].OP;
2103          if (!MDO_IS_SHADOW(MDO)) {
2104             dlist_ins_next(dl, dlist_tail(dl), (void *)MDO);
2105          } else {
2106             if (withShadow) { /* Shadow will always be 1st */
2107                dlist_ins_prev(dl, dlist_head(dl), (void *)MDO);
2108             }
2109          }
2110       }
2111    }
2112 
2113    SUMA_RETURN(dl);
2114 }
2115 
2116 /* Change a color alpha to range from 0 to 9 */
SUMA_A_to_1dig(float v)2117 int SUMA_A_to_1dig(float v)
2118 {
2119    if (v<0) v = 0;
2120    else if (v>1) v = 1.0;
2121    return((int)(v*9.0));
2122 }
2123 
SUMA_1dig_to_A(int i)2124 float SUMA_1dig_to_A(int i)
2125 {
2126    if (i < 0) i = 0;
2127    else if (i > 9) i = 9;
2128    return(i/9.0);
2129 }
2130 
2131 /* Change a transparency setting to a range from 0 to 9 */
SUMA_T_to_1dig(SUMA_TRANS_MODES stm)2132 int SUMA_T_to_1dig(SUMA_TRANS_MODES stm)
2133 {
2134    switch(stm) {
2135       case STM_ViewerDefault:
2136          return(0);
2137       case STM_0:
2138       case STM_1:
2139          return(1);
2140       case STM_2:
2141       case STM_3:
2142          return(2);
2143       case STM_4:
2144       case STM_5:
2145          return(3);
2146       case STM_6:
2147       case STM_7:
2148          return(4);
2149       case STM_8:
2150       case STM_9:
2151          return(5);
2152       case STM_10:
2153       case STM_11:
2154          return(6);
2155       case STM_12:
2156       case STM_13:
2157          return(7);
2158       case STM_14:
2159       case STM_15:
2160          return(8);
2161       case STM_16:
2162          return(9);
2163       default:
2164          return(0);
2165    }
2166    return(0);
2167 }
2168 
SUMA_1dig_to_T(int i)2169 SUMA_TRANS_MODES SUMA_1dig_to_T(int i)
2170 {
2171    switch(i){
2172       default:
2173       case 0:
2174          return(STM_ViewerDefault);
2175       case 1:
2176          return(STM_0);
2177       case 2:
2178          return(STM_2);
2179       case 3:
2180          return(STM_4);
2181       case 4:
2182          return(STM_6);
2183       case 5:
2184          return(STM_8);
2185       case 6:
2186          return(STM_10);
2187       case 7:
2188          return(STM_12);
2189       case 8:
2190          return(STM_14);
2191       case 9:
2192          return(STM_16);
2193    }
2194 }
2195 
2196 
2197 
SUMA_InitMasksTable_row(SUMA_X_SurfCont * SurfCont,SUMA_MaskDO * mdo,int row)2198 SUMA_Boolean  SUMA_InitMasksTable_row(SUMA_X_SurfCont *SurfCont,
2199                                       SUMA_MaskDO *mdo, int row)
2200 {
2201    static char FuncName[]={"SUMA_InitMasksTable_row"};
2202    char str[256];
2203    SUMA_Boolean LocalHead = NOPE;
2204 
2205    SUMA_ENTRY;
2206 
2207    if (!SurfCont || !SurfCont->MaskTable || !mdo) SUMA_RETURN(NOPE);
2208    if (row < 0 || row > SurfCont->MaskTable->Ni-1) {
2209       SUMA_S_Err("Bad row index of %d", row);
2210       SUMA_RETURN(NOPE);
2211    }
2212    SUMA_LH("MDO %s, row %d/%d, (%p)",
2213             ADO_LABEL((SUMA_ALL_DO *)mdo), row,
2214             SurfCont->MaskTable->Ni,
2215             SurfCont->MaskTable->rowobject_id);
2216 
2217    /* First set object id for entire row. Should come in handy */
2218    SUMA_STRING_REPLACE(SurfCont->MaskTable->rowobject_id[row],
2219                        ADO_ID((SUMA_ALL_DO *)mdo));
2220    if (row == 0) {
2221       /* that's all folks */
2222       SUMA_RETURN(YUP);
2223    }
2224 
2225    /* get rid of initial delete press */
2226    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable,row, 0, "x");
2227 
2228    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable,row, 1, mdo->varname);
2229 
2230    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 2,
2231                            ADO_LABEL((SUMA_ALL_DO *)mdo));
2232 
2233    if      (MDO_IS_SPH(mdo)) {
2234       SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 3, "sphere");
2235    } else if (MDO_IS_BOX(mdo)) {
2236       SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 3, "box");
2237    } else {
2238       SUMA_S_Err("Not ready for type %s, not here at least", mdo->mtype);
2239    }
2240 
2241    SUMA_RGBA_to_string(mdo->cen, 3, 1.0, str, NULL, ",",4);
2242    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 4,  str);
2243 
2244    SUMA_RGBA_to_string(mdo->hdim, 3, 1.0, str, NULL, ",",5);
2245    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 5,  str);
2246 
2247    SUMA_RGBA_to_string(mdo->init_col, 4, 1.0, str, NULL, ",",-1);
2248    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 6,  str);
2249 
2250    sprintf(str,"%d", SUMA_A_to_1dig(mdo->init_col[3]));
2251    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 7,  str);
2252 
2253    sprintf(str,"%d", SUMA_T_to_1dig(mdo->trans));
2254    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 8,  str);
2255 
2256    sprintf(str,"%d", SUMA_A_to_1dig(mdo->dim));
2257    SUMA_INSERT_CELL_STRING(SurfCont->MaskTable, row, 9,  str);
2258 
2259    SUMA_RETURN(YUP);
2260 }
2261 
SUMA_InitMasksTable(SUMA_X_SurfCont * SurfCont)2262 SUMA_Boolean  SUMA_InitMasksTable(SUMA_X_SurfCont *SurfCont)
2263 {
2264    static char FuncName[]={"SUMA_InitMasksTable"};
2265    DList *dl=NULL;
2266    DListElmt *el=NULL;
2267    int cnt;
2268    SUMA_MaskDO *mdo;
2269 
2270    SUMA_ENTRY;
2271 
2272    if (!SurfCont || !SurfCont->MaskTable) SUMA_RETURN(NOPE);
2273 
2274    dl = SUMA_AssembleMasksList_inDOv(SUMAg_DOv, SUMAg_N_DOv, 0);
2275    if (!dl || dlist_size(dl) == 0) {
2276       SUMA_ModifyTable(SurfCont->MaskTable, 1);
2277       SUMA_RETURN(YUP);
2278    } else {
2279       SUMA_ModifyTable(SurfCont->MaskTable, dlist_size(dl)+1);
2280    }
2281 
2282    if (SUMA_ShadowMaskDO(&mdo)>=0) { /* add the shadow to row 0 */
2283       if (!SUMA_InitMasksTable_row(SurfCont, mdo, 0)) {
2284          SUMA_S_Err("Failed to init row 0");
2285          SUMA_RETURN(NOPE);
2286       }
2287    }
2288 
2289    cnt = 0; el = NULL;
2290    do {
2291       if (!el) el = dlist_head(dl);
2292       else el = dlist_next(el);
2293       mdo = (SUMA_MaskDO *)el->data;
2294       if (!SUMA_InitMasksTable_row(SurfCont, mdo, cnt+1)) {
2295          SUMA_S_Err("Failed to init row %d", cnt+1);
2296          SUMA_RETURN(NOPE);
2297       }
2298       ++cnt;
2299    } while (el != dlist_tail(dl));
2300 
2301    dlist_destroy(dl);SUMA_free(dl);
2302 
2303    SUMA_RETURN(YUP);
2304 }
2305 
SUMA_NewSymMaskDO(SUMA_ALL_DO * ado)2306 int SUMA_NewSymMaskDO(SUMA_ALL_DO *ado)
2307 {
2308    static char FuncName[]={"SUMA_NewSymMaskDO"};
2309    SUMA_MaskDO *mdo=NULL;
2310    float cen[3] = {0, 0, 0};
2311    int ido;
2312    static int icall=0;
2313    char mtype[32], hid[32];
2314    char symstr[256]={"sphere(0, 0, 0; 20, 20, 20)"};
2315    SUMA_Boolean LocalHead = NOPE;
2316 
2317    SUMA_ENTRY;
2318 
2319    ido = -1;
2320    sprintf(hid,"msk%d", icall);
2321    mdo = SUMA_SymMaskDO(symstr, mtype, hid, 0);
2322 
2323    if (!ado) {
2324       ado = (SUMA_ALL_DO *)SUMA_findanyTDOp_inDOv(SUMAg_DOv, SUMAg_N_DOv, NULL);
2325    }
2326    if (ado) {
2327       SUMA_ADO_Center(ado, cen);
2328    }
2329 
2330    switch(icall) {
2331       case 0:{
2332          float cc[4] = {1, 1, 1, 1};
2333          SUMA_Set_MaskDO_Cen(mdo, cen);
2334          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2335          break; }
2336       case 1:{
2337          float cc[4] = {1, 0, 0, 1};
2338          cen[0] += 40;
2339          cen[1] -= 65;
2340          cen[2] -= 20;
2341          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2342          SUMA_Set_MaskDO_Cen(mdo, cen);
2343          break; }
2344       case 2:{
2345          float cc[4] = {0, 1, 0, 1};
2346          cen[0] -= 25;
2347          cen[1] -= 65;
2348          cen[2] -= 5;
2349          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2350          SUMA_Set_MaskDO_Cen(mdo, cen);
2351          break; }
2352       case 3:{
2353          float cc[4] = {0, 0, 1, 1};
2354          cen[0] += 0;
2355          cen[1] += 35;
2356          cen[2] += 10;
2357          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2358          SUMA_Set_MaskDO_Cen(mdo, cen);
2359          break; }
2360       case 4: {
2361          float cc[4] = {1, 1, 0, 1};
2362          cen[0] += 60;
2363          cen[1] -= 10;
2364          cen[2] -= 40;
2365          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2366          SUMA_Set_MaskDO_Cen(mdo, cen);
2367          break; }
2368       case 5: {
2369          float cc[4] = {0, 1, 1, 1};
2370          cen[0] += 20;
2371          cen[1] -= 40;
2372          cen[2] += 10;
2373          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2374          SUMA_Set_MaskDO_Cen(mdo, cen);
2375          break; }
2376       case 6: {
2377          float cc[4] = {1, 0, 1, 1};
2378          cen[0] -= 20;
2379          cen[1] += 40;
2380          cen[2] -= 10;
2381          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2382          SUMA_Set_MaskDO_Cen(mdo, cen);
2383          break; }
2384       default: {
2385          float cc[4] = {1, 0, 1, 1};
2386          SUMA_a_good_col("ROI_i256", icall-6,cc);
2387          SUMA_Set_MaskDO_Color(mdo, cc, -1);
2388          break; }
2389    }
2390    if (!SUMA_AccessorizeMDO(mdo)) {
2391       SUMA_S_Err("No accessorizing");
2392       SUMA_RETURN(ido);
2393    }
2394 
2395    /* addDO */
2396    SUMA_LH("Adding DO");
2397    if (!SUMA_AddDO(SUMAg_DOv, &SUMAg_N_DOv,
2398                    (void *)mdo, MASK_type, SUMA_WORLD)) {
2399       fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_AddDO.\n", FuncName);
2400       SUMA_RETURN(ido);
2401    }
2402    ido = SUMAg_N_DOv-1;
2403 
2404    /* register DO with viewer */
2405    SUMA_LH("Registrar");
2406    if (!SUMA_RegisterDO(ido, NULL)) {
2407       fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_RegisterDO.\n", FuncName);
2408       SUMA_RETURN(-1);
2409    }
2410    ++icall;
2411    SUMA_RETURN(ido);
2412 }
2413 
SUMA_ShadowMaskDO(SUMA_MaskDO ** mdop)2414 int SUMA_ShadowMaskDO(SUMA_MaskDO **mdop)
2415 {
2416    static char FuncName[]={"SUMA_ShadowMaskDO"};
2417    SUMA_MaskDO *mdo=NULL;
2418    int ido;
2419    char mtype[32], hid[32];
2420    SUMA_Boolean LocalHead = NOPE;
2421 
2422    SUMA_ENTRY;
2423 
2424    if (mdop) *mdop = NULL;
2425 
2426    /* If it exists, return it */
2427    ido = -1;
2428    SUMA_findShadowMDOp_inDOv(SUMAg_DOv, SUMAg_N_DOv, &ido);
2429    if (ido >=0) {
2430       if (mdop) *mdop = (SUMA_MaskDO *)iDO_ADO(ido);
2431       SUMA_RETURN(ido);
2432    }
2433    /* Otherwise create it */
2434    sprintf(hid,"TheShadow");
2435 
2436    /* Now create the mask */
2437    SUMA_LH("Creating mask");
2438    if (!(mdo = SUMA_Alloc_MaskDO (1, hid, hid, NULL, 1))) {
2439       SUMA_S_Err("Failed in SUMA_Allocate_MaskDO.");
2440       SUMA_RETURN(-1);
2441    }
2442    strcpy(mdo->mtype, "CASPER");
2443 
2444    if (!SUMA_AddMaskSaux(mdo)) {
2445       SUMA_S_Err("Failed to add Mask Saux");
2446       SUMA_RETURN(-1);
2447    }
2448 
2449    /* addDO */
2450    SUMA_LH("Adding DO");
2451    if (!SUMA_AddDO(SUMAg_DOv, &SUMAg_N_DOv,
2452                    (void *)mdo, MASK_type, SUMA_WORLD)) {
2453       fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_AddDO.\n", FuncName);
2454       SUMA_RETURN(-1);
2455    }
2456    ido = SUMAg_N_DOv-1;
2457 
2458    /* register DO with viewer */
2459    SUMA_LH("Registrar");
2460    if (!SUMA_RegisterDO(ido, NULL)) {
2461       fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_RegisterDO.\n", FuncName);
2462       SUMA_RETURN(-1);
2463    }
2464 
2465    if (mdop) *mdop = (SUMA_MaskDO *)iDO_ADO(ido);
2466 
2467    SUMA_RETURN(ido);
2468 }
2469 
2470 /*!
2471    \brief Switches to the controller of Masks.
2472    Creates a new Mask if none exists
2473 */
SUMA_cb_Mask(Widget w,XtPointer client_data,XtPointer callData)2474 void SUMA_cb_Mask (Widget w, XtPointer client_data, XtPointer callData)
2475 {
2476    static char FuncName[] = {"SUMA_cb_Mask"};
2477    SUMA_ALL_DO *ado=NULL;
2478    SUMA_MaskDO *mdo=NULL;
2479    SUMA_TractDO *tdo=NULL;
2480    SUMA_TRACT_SAUX *TSaux=NULL;
2481    int ido;
2482    void *n=NULL;
2483    char *s = NULL;
2484    SUMA_X_SurfCont *SurfCont=NULL;
2485    SUMA_CREATE_TEXT_SHELL_STRUCT *TextShell = NULL;
2486    SUMA_Boolean LocalHead = NOPE;
2487 
2488    SUMA_ENTRY;
2489 
2490    if (!client_data) {
2491       SUMA_S_Err("Bad call, no clients.");
2492       SUMA_RETURNe;
2493    }
2494    ado = (SUMA_ALL_DO *)client_data;
2495    if (ado->do_type != TRACT_type) {
2496       SUMA_S_Err("Expect tracts only here");
2497       SUMA_RETURNe;
2498    }
2499    tdo = (SUMA_TractDO *)ado;
2500    if (!(SurfCont = SUMA_ADO_Cont(ado))) {
2501       SUMA_S_Err("No surfcont? Work with me please!");
2502       SUMA_RETURNe;
2503    }
2504    TSaux = TDO_TSAUX(tdo);
2505    if (!w || !callData) {
2506       /* OK, callback used by driver too */
2507       SUMA_LH("Driven? Make sure tracts controller already up");
2508       if (!SUMA_isADO_Cont_Created(ado)) {
2509          if (!SUMA_OpenCloseSurfaceCont(w, ado, NULL)) {
2510             SUMA_S_Err("Could not open tract cont");
2511             SUMA_RETURNe;
2512          }
2513       }
2514    }
2515 
2516    /* How many masks do we have so far? */
2517    if (!SUMA_findanyMDOp_inDOv(SUMAg_DOv, SUMAg_N_DOv, &ido)) {
2518       /* Create a dummy uber owner that will never get displayed
2519          but can always be relied upon to exit. Other masks can
2520          get deleted, leaving the mask controller ownerless */
2521       SUMA_ShadowMaskDO(NULL);
2522       /* Now Need to create a new Mask for real*/
2523       SUMA_LH("Need a new mask");
2524       if ((ido = SUMA_NewSymMaskDO(NULL))<0) {
2525          SUMA_S_Err("Failed to create SymMask");
2526          SUMA_RETURNe;
2527       }
2528       mdo = (SUMA_MaskDO *)iDO_ADO(ido);
2529       SUMA_LH("Outa here");
2530       XtSetSensitive(SurfCont->TractMaskMenu->mw[SW_SurfCont_TractMask], 1);
2531       XtSetSensitive(SurfCont->TractMaskGray->rc, 1);
2532 
2533       SUMA_NEW_MASKSTATE();
2534 
2535       /* Redisplay related */
2536       SUMA_RedisplayAllShowing(iDO_idcode(ido), NULL, 0);
2537       SUMA_RETURNe;
2538    } else {
2539       SUMA_LH("Have ido %d %s", ido, iDO_label(ido));
2540       mdo = (SUMA_MaskDO *)iDO_ADO(ido);
2541    }
2542 
2543    /* Have something to work with, switch to the controller of the Mask */
2544    SurfCont = SUMA_ADO_Cont((SUMA_ALL_DO *)mdo);
2545    if (!SUMA_viewSurfaceCont(NULL, (SUMA_ALL_DO *)mdo,
2546                              SUMA_BestViewerForADO(ado))) {
2547       SUMA_S_Err("Failed to view surface cont");
2548       SUMA_RETURNe;
2549    }
2550    if (!SUMA_InitMasksTable(SurfCont)) {
2551       SUMA_S_Err("Failed to initialize table");
2552       SUMA_RETURNe;
2553    }
2554    SUMA_RETURNe;
2555 }
2556 
2557 
2558 
SUMA_cb_Mask_Delete(Widget wcall,XtPointer cd1,XtPointer cbs)2559 void SUMA_cb_Mask_Delete(Widget wcall, XtPointer cd1, XtPointer cbs)
2560 {
2561    static char *PlaneName=NULL, FuncName[] = {"SUMA_cb_Mask_Delete"};
2562    XmPushButtonCallbackStruct * pbcbs = (XmPushButtonCallbackStruct *) cbs ;
2563    static int ErrCnt =0;
2564    DList *list=NULL;
2565    SUMA_MaskDO *mdo=NULL;
2566    SUMA_ALL_DO *ado=NULL, *curDO=NULL;
2567    int found=0, ii, rownum=-1;
2568    char *ado_id = NULL;
2569    SUMA_X_SurfCont *SurfCont = NULL;
2570    SUMA_SurfaceViewer *sv=NULL;
2571    SUMA_Boolean LocalHead = NOPE;
2572 
2573    SUMA_ENTRY;
2574 
2575    SUMA_LH("Called with: %p %s %p", wcall, ado_id?ado_id:"NULL", cbs);
2576 
2577    SurfCont = SUMAg_CF->X->AllMaskCont;
2578    if (!SurfCont || !SurfCont->MaskTable) {
2579       SUMA_S_Err("Should not happen for mask interface");
2580       SUMA_RETURNe;
2581    }
2582 
2583    if (wcall) { /* This is a call from the delete 'x' button,
2584                    call from callback does not have widget set */
2585       if (SurfCont->MaskTable->Ni < 1) {
2586          if (!ErrCnt) SUMA_SLP_Note ("No mask to delete");
2587          ErrCnt ++;
2588          SUMA_RETURNe;
2589       }
2590       ado_id = (char *)cd1;
2591    } else {/* Call from callback, reset the button to lowercase */
2592       rownum = (int)((long)cd1);
2593       SUMA_LH("Resetting button for row %d.\n", rownum);
2594       if (rownum == SurfCont->DeleteMask_row) {
2595          /* reset the x and clear up selection */
2596          SUMA_INSERT_CELL_STRING(SurfCont->MaskTable,
2597                            SUMA_RowTitCell(SurfCont->MaskTable,rownum), 0, "x");
2598          SurfCont->DeleteMask_first = YUP ;
2599          SurfCont->DeleteMask_row = -1;
2600          SUMA_RETURNe ;
2601       } else if (SurfCont->DeleteMask_row = -1) {
2602                      /* row must have been deleted, nothing to be done */
2603          SUMA_RETURNe ;
2604       } else { /* row index and delete row don't match, reset all */
2605          for (ii=1; ii<SurfCont->MaskTable->Ni; ++ii) {
2606             SUMA_INSERT_CELL_STRING(SurfCont->MaskTable,ii, 0, "x");
2607          }
2608          SurfCont->DeleteMask_first = YUP ;
2609          SurfCont->DeleteMask_row = -1;
2610          SUMA_RETURNe ;
2611       }
2612       SUMA_RETURNe ;
2613    }
2614 
2615    if (!ado_id) {
2616       SUMA_S_Err("Should not be without ado_id at this stage");
2617    }
2618 
2619    if( SurfCont->DeleteMask_first ){/* First press -->  change button label */
2620       if (SurfCont->DeleteMask_row != -1) {
2621          SUMA_S_Warn("DeleteMask_row not initialized?");
2622       }
2623       if ((found = SUMA_ObjectID_Row(SurfCont->MaskTable, ado_id))< 0) {
2624          SUMA_S_Err("Failed to find object");
2625          SUMA_RETURNe ;
2626       }
2627       SUMA_INSERT_CELL_STRING(SurfCont->MaskTable,
2628                            SUMA_RowTitCell(SurfCont->MaskTable,found), 0, "X" ) ;
2629       SurfCont->DeleteMask_first = NOPE ;
2630       SurfCont->DeleteMask_row = found;
2631 
2632       /* if not re-pressed in 5 seconds, will reset to lowercase */
2633       SUMA_LH("First Press, adding time out.");
2634       (void) XtAppAddTimeOut(
2635                XtWidgetToApplicationContext(SurfCont->MaskTable->cells[0]) ,
2636                5000 , SUMA_delete_mask_timeout_CB , (XtPointer)((long)found) ) ;
2637 
2638        SUMA_RETURNe;
2639    } else { /* Second press --> delete row */
2640       if ((found = SUMA_ObjectID_Row(SurfCont->MaskTable, ado_id))< 0) {
2641          SUMA_S_Err("Failed to find object");
2642          SUMA_RETURNe ;
2643       }
2644       if (ado = SUMA_whichADOg(ado_id)) {
2645          SUMA_LH("ado_id is for %s", ADO_LABEL(ado));
2646       } else {
2647          SUMA_LH("ado_id has no object");
2648       }
2649       if (SurfCont->DeleteMask_row != found) {
2650          SUMA_LH("Clicking left and right?");
2651          for (ii=1; ii<SurfCont->MaskTable->Ni; ++ii) {
2652             SUMA_INSERT_CELL_STRING(SurfCont->MaskTable,ii, 0, "x");
2653          }
2654          SurfCont->DeleteMask_first = YUP ;
2655          SurfCont->DeleteMask_row = -1;
2656          SUMA_RETURNe;
2657       } else {
2658          /* delete mask SEE ALSO function SUMA_DeleteMask(), might want to use
2659             it instead of this chunk */
2660          ErrCnt = 0;
2661          SUMA_LHv("Should be deleting Masks here ...\n");
2662          if (SurfCont->MaskTable->Ni>1) {
2663             curDO = SUMA_SurfCont_GetcurDOp(SurfCont);
2664             if (curDO == ado) {
2665                /* Need to find another DO */
2666                for (ii=SurfCont->MaskTable->Ni-1; ii<=0; ++ii) {
2667                   if (SurfCont->MaskTable->rowobject_id[ii] &&
2668                       strcmp(SurfCont->MaskTable->rowobject_id[ii],ado_id)) {
2669                    curDO = SUMA_whichADOg(SurfCont->MaskTable->rowobject_id[ii]);
2670                      SUMA_SurfCont_SetcurDOp(SurfCont, curDO);
2671                      SUMA_LH("CurDO now %s", ADO_LABEL(curDO));
2672                   }
2673                }
2674             }
2675 
2676             /* Make sure  object is not the one selected for mouse movement */
2677             for (ii=0; ii<SUMAg_N_SVv; ++ii) {
2678                sv = SUMAg_SVv+ii;
2679                if ( sv && sv->MouseMode_ado_idcode_str) {
2680                   if ( !strcmp(sv->MouseMode_ado_idcode_str, ado_id)) {
2681                      SUMA_LH("Mask selected mask will be deleted, leave mask"
2682                              "manip mode.");
2683                      if (!SUMA_SetMouseMode(sv,SUMA_MASK_MANIP_MMODE,NULL)) {
2684                         SUMA_S_Warn("Mask manip mode could not be set");
2685                      }
2686                   }
2687                }
2688             }
2689 
2690 
2691 
2692             /* unregister do from all viewers */
2693             SUMA_UnRegisterDO_idcode(ado_id,NULL);
2694 
2695             /* delelte the current mask from DOv */
2696             if (!SUMA_RemoveDO(SUMAg_DOv, &SUMAg_N_DOv, (void *)ado, 1)){
2697                SUMA_S_Err("Failed to dump DO");
2698                SUMA_RETURNe;
2699             }
2700             if (!SUMA_ModifyTable(SurfCont->MaskTable,
2701                                   SurfCont->MaskTable->Ni-1)) {
2702                SUMA_S_Err("Failed to delete table row");
2703                SUMA_RETURNe;
2704             }
2705             SurfCont->DeleteMask_first = YUP ;
2706             SurfCont->DeleteMask_row = -1;
2707             /* ModifyTable, just deletes the bottom row of widgets. You need to
2708                reinitialize */
2709             SUMA_InitMasksTable(SurfCont);
2710          }
2711 
2712          SUMA_NEW_MASKSTATE();
2713 
2714          /* redisplay */
2715          if (!list) list = SUMA_CreateList ();
2716          SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
2717                                             SES_Suma, NULL);
2718          if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
2719       }
2720    }
2721 
2722    SUMA_RETURNe;
2723 }
2724 
SUMA_delete_mask_timeout_CB(XtPointer client_data,XtIntervalId * id)2725 void SUMA_delete_mask_timeout_CB( XtPointer client_data , XtIntervalId * id )
2726 {
2727    static char FuncName[] = {"SUMA_delete_mask_timeout_CB"};
2728 
2729    SUMA_ENTRY;
2730 
2731    SUMA_cb_Mask_Delete(NULL, client_data, NULL);
2732 
2733    SUMA_RETURNe;
2734 }
2735 
SUMA_DeleteAllMasks(char * labeled,SUMA_DO * dov,int N_dov)2736 SUMA_Boolean SUMA_DeleteAllMasks(char *labeled, SUMA_DO *dov, int N_dov)
2737 {
2738    static char FuncName[]= {"SUMA_DeleteAllMask"};
2739    int i = 0;
2740    SUMA_MaskDO *MDO = NULL;
2741    SUMA_ALL_DO *ado = NULL;
2742 
2743    SUMA_ENTRY;
2744 
2745    if (!dov) {
2746       dov = SUMAg_DOv;
2747       N_dov = SUMAg_N_DOv;
2748    }
2749    for (i=0; i< N_dov; ++i) {
2750       if (dov[i].ObjectType != MASK_type) continue;
2751       MDO = (SUMA_MaskDO *)dov[i].OP;
2752       ado = (SUMA_ALL_DO *)MDO;
2753 
2754       if (!MDO_IS_SHADOW(MDO) &&
2755           (!labeled || (!strcmp(labeled,ADO_LABEL(ado)))) ) {
2756          if (!(SUMA_DeleteMask(ADO_ID(ado)))) {
2757             SUMA_S_Err("Failed to delete MDO");
2758          }
2759       }
2760    }
2761 
2762    SUMA_RETURN(YUP);
2763 }
2764 
2765 /* Delete a MaskDO from everything and everywhere.
2766    Make sure changes here, parallel those in function SUMA_cb_Mask_Delete()
2767    right where SUMA_DeleteMask() is mentioned.*/
SUMA_DeleteMask(char * ado_id)2768 SUMA_Boolean SUMA_DeleteMask(char *ado_id)
2769 {
2770    static char FuncName[]= {"SUMA_DeleteMask"};
2771    SUMA_ALL_DO *ado = NULL, *curDO = NULL;
2772    int found = -1, OKtable=0, ii;
2773    SUMA_X_SurfCont *SurfCont = NULL;
2774    SUMA_SurfaceViewer *sv = NULL;
2775    SUMA_Boolean LocalHead = NOPE;
2776 
2777    SUMA_ENTRY;
2778 
2779    if (!ado_id) SUMA_RETURN(YUP); /* Don't complain, nothing to delete */
2780 
2781    if (ado = SUMA_whichADOg(ado_id)) {
2782       SUMA_LH("ado_id is for %s", ADO_LABEL(ado));
2783       if (ado->do_type != MASK_type) {
2784          SUMA_S_Err("ADOid not for mask type");
2785          SUMA_RETURN(NOPE);
2786       }
2787    } else {
2788       SUMA_LH("ado_id does not exist, return without complaint");
2789       SUMA_RETURN(YUP);
2790    }
2791 
2792    SurfCont = SUMAg_CF->X->AllMaskCont;
2793 
2794    found = -1;
2795    if (SurfCont && SurfCont->MaskTable) {
2796       if ((found = SUMA_ObjectID_Row(SurfCont->MaskTable, ado_id))< 0) {
2797          SUMA_LH("ado not in table");
2798       } else {
2799          SUMA_LH("Making sure current is OK");
2800          if (SurfCont->MaskTable->Ni>1) {
2801             curDO = SUMA_SurfCont_GetcurDOp(SurfCont);
2802             if (curDO == ado) {
2803                /* Need to find another DO */
2804                for (ii=SurfCont->MaskTable->Ni-1; ii<=0; ++ii) {
2805                   if (SurfCont->MaskTable->rowobject_id[ii] &&
2806                       strcmp(SurfCont->MaskTable->rowobject_id[ii],ado_id)) {
2807                    curDO = SUMA_whichADOg(SurfCont->MaskTable->rowobject_id[ii]);
2808                      SUMA_SurfCont_SetcurDOp(SurfCont, curDO);
2809                      SUMA_LH("CurDO now %s", ADO_LABEL(curDO));
2810                   }
2811                }
2812             }
2813          }
2814       }
2815    }
2816 
2817    /* Make sure this object is not the one selected for mouse movement */
2818    for (ii=0; ii<SUMAg_N_SVv; ++ii) {
2819       sv = SUMAg_SVv+ii;
2820       if ( sv && sv->MouseMode_ado_idcode_str) {
2821          if ( !strcmp(sv->MouseMode_ado_idcode_str, ado_id)) {
2822             SUMA_LH("Woops, can't be in mask manip mode any more");
2823             if (!SUMA_SetMouseMode(sv,SUMA_MASK_MANIP_MMODE,NULL)) {
2824                SUMA_S_Warn("Mask manip mode could not be set");
2825             }
2826          }
2827       }
2828    }
2829 
2830    /* unregister do from all viewers */
2831    SUMA_UnRegisterDO_idcode(ado_id,NULL);
2832 
2833    /* delelte the current mask from DOv */
2834    if (!SUMA_RemoveDO(SUMAg_DOv, &SUMAg_N_DOv, (void *)ado, 1)){
2835       SUMA_S_Err("Failed to dump DO");
2836       SUMA_RETURN(NOPE);
2837    }
2838 
2839    if (found >= 0 && SurfCont && SurfCont->MaskTable) {
2840       if (!SUMA_ModifyTable(SurfCont->MaskTable,
2841                            SurfCont->MaskTable->Ni-1)) {
2842          SUMA_S_Err("Failed to delete table row");
2843          SUMA_RETURN(NOPE);
2844       } else {
2845          SUMA_InitMasksTable(SurfCont);
2846       }
2847    }
2848 
2849 
2850    SUMA_NEW_MASKSTATE();
2851 
2852    SUMA_RETURN(YUP);
2853 }
2854 
SUMA_SetMaskTableValueNew(int row,int col,char * s1,int setmen,int redisplay,SUMA_NUMERICAL_UNITS num_units)2855 int SUMA_SetMaskTableValueNew(  int row, int col,
2856                                 char *s1,
2857                                 int setmen,
2858                                 int redisplay,
2859                                 SUMA_NUMERICAL_UNITS num_units)
2860 {
2861    static char FuncName[]={"SUMA_SetMaskTableValueNew"};
2862    int NewDisp=0, isCur=0, Err=0, init_row=0;
2863    SUMA_MaskDO *mdo=NULL;
2864    SUMA_X_SurfCont *SurfCont=NULL;
2865    SUMA_TABLE_FIELD *TF=NULL;
2866    float *fv;
2867    int dg;
2868    SUMA_ALL_DO *ado=NULL;
2869    char str[256];
2870    SUMA_Boolean LocalHead = NOPE;
2871 
2872    SUMA_ENTRY;
2873 
2874    if (LocalHead) {
2875       SUMA_LH("Called on cell[%d %d] with %s", row, col, s1?s1:"NULL");
2876       SUMA_DUMP_TRACE("Who called SUMA_SetMaskTableValueNew?");
2877    }
2878 
2879    if (!(SurfCont=SUMAg_CF->X->AllMaskCont)) {
2880       SUMA_RETURN(0);
2881    }
2882 
2883    TF = SurfCont->MaskTable;
2884    if (!TF) setmen = 0; /* can't set nothing */
2885 
2886    if (num_units == SUMA_PERC_VALUE_UNITS) {
2887       SUMA_S_Err("No percentiles allowed here");
2888       SUMA_RETURN(NOPE);
2889    }
2890 
2891    if (row < 1) {
2892       SUMA_S_Err("What is for row %d < 1?", row); SUMA_RETURN(NOPE);
2893    }
2894    if (col < 1) {
2895       SUMA_S_Err("What is for col %d < 1?", col); SUMA_RETURN(NOPE);
2896    }
2897    NewDisp = NOPE;
2898 
2899    /* ado for that row */
2900    if (!(ado = SUMA_whichADOg(TF->rowobject_id[row]))) {
2901       SUMA_S_Err("Failed to find mask object from row %d!", row);
2902       SUMA_RETURN(NOPE);
2903    }
2904    if (ado->do_type != MASK_type) {
2905       SUMA_S_Err("Need MDO");
2906       SUMA_RETURN(NOPE);
2907    }
2908    mdo = (SUMA_MaskDO *)ado;
2909    /* What are we dealing with ? */
2910    switch (col) {
2911       case 1:
2912          if (SUMA_MDO_OkVarName(s1)) {
2913             if (setmen) {
2914                SUMA_INSERT_CELL_STRING(TF, row, col, mdo->varname);
2915             }
2916             SUMA_MDO_SetVarName(mdo, s1);
2917             init_row = 2;
2918          } else {
2919             SUMA_INSERT_CELL_STRING(TF, row, col, mdo->varname);
2920          }
2921          break;
2922       case 2:
2923          SUMA_LHv("Setting Label of %s to %s, isCur=%d [%d %d] \n",
2924                    ADO_LABEL(ado), s1, isCur, row, col);
2925          if (SUMA_MDO_New_Label(mdo, s1)) {
2926             if (setmen) {
2927                SUMA_LHv("Inserting ado label back %s\n",
2928                         ADO_LABEL(ado));
2929                SUMA_INSERT_CELL_STRING(TF, row, col, ADO_LABEL(ado));
2930             }
2931          } else { /* failed, reset string */
2932                SUMA_LHv("Resetting ado label back %s\n",
2933                         ADO_LABEL(ado));
2934                SUMA_INSERT_CELL_STRING(TF, row, col, ADO_LABEL(ado));
2935          }
2936          break;
2937       case 3:
2938          SUMA_LHv("Setting Type of %s to %s, isCur=%d [%d %d] \n",
2939                    mdo->mtype, s1, isCur, row, col);
2940          if (SUMA_Ok_Sym_MaskDO_Type(s1)) {
2941             SUMA_MDO_New_Type(mdo, s1);
2942             if (setmen) {
2943                SUMA_LHv("Inserting ado type back %s\n",
2944                         mdo->mtype);
2945                SUMA_INSERT_CELL_STRING(TF, row, col, mdo->mtype);
2946             }
2947             init_row = 1; /* dims can also get changed by changing type,
2948                            make sure table reflects this */
2949          } else { /* failed, reset string */
2950                SUMA_LHv("Resetting ado mtype back %s\n",
2951                         mdo->mtype);
2952                SUMA_INSERT_CELL_STRING(TF, row, col, mdo->mtype);
2953          }
2954          break;
2955       case 4:
2956          SUMA_LHv("Setting Center of %f %f %f to %s, isCur=%d [%d %d] \n",
2957                    mdo->cen[0], mdo->cen[1], mdo->cen[2], s1, isCur, row, col);
2958          fv = SUMA_string_to_RGBA(s1, NULL, 1.0, &Err);
2959          if (!Err) {
2960             SUMA_MDO_New_Cen(mdo, fv);
2961             if (setmen) {
2962                SUMA_RGBA_to_string(mdo->cen, 3, 1.0, str, NULL, ",",-1);
2963                SUMA_LHv("Inserting ado cen back %s\n",
2964                         str);
2965                SUMA_INSERT_CELL_STRING(TF, row, col, str);
2966             }
2967          } else { /* failed, reset string */
2968             SUMA_RGBA_to_string(mdo->cen, 3, 1.0, str, NULL, ",",-1);
2969             SUMA_LHv("Resetting ado center string back %s\n",
2970                      str);
2971             SUMA_INSERT_CELL_STRING(TF, row, col, str);
2972          }
2973          break;
2974       case 5:
2975          SUMA_LHv("Setting Size of %f %f %f to %s, isCur=%d [%d %d] \n",
2976                   mdo->hdim[0], mdo->hdim[1], mdo->hdim[2], s1, isCur, row, col);
2977          fv = SUMA_string_to_RGBA(s1, NULL, 1.0, &Err);
2978          if (!Err) {
2979             SUMA_MDO_New_Dim(mdo, fv);
2980             if (setmen) {
2981                SUMA_RGBA_to_string(mdo->hdim, 3, 1.0, str, NULL, ",",3);
2982                SUMA_LHv("Inserting ado dim back %s\n",
2983                         str);
2984                SUMA_INSERT_CELL_STRING(TF, row, col, str);
2985             }
2986          } else { /* failed, reset string */
2987             SUMA_RGBA_to_string(mdo->hdim, 3, 1.0, str, NULL, ",",3);
2988             SUMA_LHv("Resetting ado center string back %s\n",
2989                      str);
2990             SUMA_INSERT_CELL_STRING(TF, row, col, str);
2991          }
2992          break;
2993       case 6:
2994          SUMA_LHv("Setting color of %f %f %f %f to %s, isCur=%d [%d %d] \n",
2995                   mdo->init_col[0], mdo->init_col[1],
2996                   mdo->init_col[2], mdo->init_col[3],
2997                   s1, isCur, row, col);
2998          fv = SUMA_string_to_RGBA(s1, NULL, 1.0, &Err);
2999          if (!Err) {
3000             SUMA_MDO_New_Color(mdo, fv);
3001             if (setmen) {
3002                SUMA_RGBA_to_string(mdo->init_col, 4, 1.0, str, NULL, ",",4);
3003                SUMA_LHv("Inserting ado col back %s\n",
3004                         str);
3005                SUMA_INSERT_CELL_STRING(TF, row, col, str);
3006             }
3007          } else { /* failed, reset string */
3008             SUMA_RGBA_to_string(mdo->init_col, 4, 1.0, str, NULL, ",", 4);
3009             SUMA_LHv("Resetting ado colv string back %s\n",
3010                      str);
3011             SUMA_INSERT_CELL_STRING(TF, row, col, str);
3012          }
3013          break;
3014       case 7:
3015          dg = (int)atoi(s1);
3016          if (dg < 0) dg = 0;
3017          else if (dg > 9) dg = 9;
3018          SUMA_LH("Setting Alpha from %s (%d, %f)(setmen is %d)\n"
3019                  "%f %f %f %f\n",
3020                   s1, dg, SUMA_1dig_to_A(dg), setmen,
3021                   mdo->init_col[0], mdo->init_col[1],
3022                   mdo->init_col[2], mdo->init_col[3]);
3023          SUMA_MDO_New_Alpha(mdo, SUMA_1dig_to_A(dg));
3024          /* changing A affects the color string */
3025          SUMA_RGBA_to_string(mdo->init_col, 4, 1.0, str, NULL, ",",4);
3026          SUMA_LH("Setting RGB to %s %f %f %f %f\n",
3027                   str,
3028                   mdo->init_col[0], mdo->init_col[1],
3029                   mdo->init_col[2], mdo->init_col[3]);
3030          SUMA_INSERT_CELL_STRING(TF, row, 6, str);
3031          if (setmen) {
3032             sprintf(str,"%d",dg);
3033             SUMA_LHv("Inserting ado A back %s\n", str);
3034             SUMA_INSERT_CELL_STRING(TF, row, col, str);
3035          }
3036          break;
3037       case 8:
3038          SUMA_LH("Setting Trans from %s", s1);
3039          dg = (int)atoi(s1);
3040          if (dg < 0) dg = 0;
3041          else if (dg > 9) dg = 9;
3042          SUMA_MDO_New_Trans(mdo, SUMA_1dig_to_T(dg));
3043          if (setmen) {
3044             sprintf(str,"%d",dg);
3045             SUMA_LHv("Inserting ado tran back %s\n",
3046                      str);
3047             SUMA_INSERT_CELL_STRING(TF, row, col, str);
3048          }
3049          break;
3050       case 9:
3051          dg = (int)atoi(s1);
3052          if (dg < 0) dg = 0;
3053          else if (dg > 9) dg = 9;
3054          SUMA_LH("Setting dim from %s (%d, %f)(setmen is %d)\n"
3055                  "%f %f %f %f\n",
3056                   s1, dg, SUMA_1dig_to_A(dg), setmen,
3057                   mdo->init_col[0], mdo->init_col[1],
3058                   mdo->init_col[2], mdo->init_col[3]);
3059          SUMA_MDO_New_CDim(mdo, SUMA_1dig_to_A(dg));
3060          if (setmen) {
3061             sprintf(str,"%d",dg);
3062             SUMA_LHv("Inserting ado Dim back %s\n", str);
3063             SUMA_INSERT_CELL_STRING(TF, row, col, str);
3064          }
3065          break;
3066       default:
3067          SUMA_SL_Err("You make me sick");
3068          break;
3069    }
3070 
3071    if (init_row == 1) {
3072       SUMA_InitMasksTable_row(SurfCont, mdo, row);
3073    } else if (init_row == 2) { /* The whole table needs love */
3074       SUMA_InitMasksTable(SurfCont);
3075    }
3076 
3077    SUMA_NEW_MASKSTATE();
3078 
3079    /* Now, you need to redraw the deal */
3080    if (redisplay) {
3081       DList *list = NULL;
3082       /* redisplay */
3083       if (!list) list = SUMA_CreateList ();
3084       SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
3085                                          SES_Suma, NULL);
3086       if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
3087    }
3088 
3089 
3090    SUMA_RETURN(1);
3091 }
3092 
SUMA_GetMaskEvalExpr(void)3093 char *SUMA_GetMaskEvalExpr(void)
3094 {
3095    static char FuncName[]={"SUMA_GetMaskEvalExpr"};
3096    static int icall=0;
3097    static char expv[10][128];
3098    char evale[256]={""}, tight[128]={""};
3099    char *exp=NULL;
3100    SUMA_X_SurfCont *SurfCont=NULL;
3101    SUMA_TABLE_FIELD *TF=NULL;
3102    SUMA_Boolean LocalHead = NOPE;
3103 
3104    SUMA_ENTRY;
3105 
3106    ++icall;
3107    if (icall > 9) icall = 0;
3108    exp = expv[icall];
3109    exp[0] = '\0';
3110 
3111    if (!(SurfCont=SUMAg_CF->X->AllMaskCont) ||
3112        !(TF = SurfCont->MaskEvalTable) ||
3113        TF->Ni < 1 /* Ensure it is actually created */) {
3114       SUMA_RETURN(exp);
3115    }
3116 
3117    if (!SurfCont->UseMaskEval) {
3118       SUMA_RETURN(exp);
3119    }
3120 
3121    if (TF->str_value[1*TF->Ni+0]) {
3122       strncpy(exp, TF->str_value[1*TF->Ni+0], 127);
3123       if (!SUMA_DispExpr_To_EvalExpr(exp, evale, tight)) {
3124          SUMA_SLP_Warn("Parsing error encountered. Check command line");
3125          exp[0] = '\0';
3126          SUMA_RETURN(exp);
3127       } else {
3128          SUMA_LH("exp >%s<, evale >%s<, tight >%s<",
3129                   exp, evale, tight);
3130          /* use the eval version */
3131          strncpy(exp, evale, 127);
3132          /* and set the tight version for display */
3133          if (strcmp(exp, tight)) SUMA_INSERT_CELL_STRING(TF, 0, 1, tight);
3134       }
3135    }
3136    SUMA_RETURN(exp);
3137 }
3138 
SUMA_SetMaskEvalTableValueNew(int row,int col,char * s1,int setmen,int redisplay,SUMA_NUMERICAL_UNITS num_units)3139 int SUMA_SetMaskEvalTableValueNew(  int row, int col,
3140                                 char *s1,
3141                                 int setmen,
3142                                 int redisplay,
3143                                 SUMA_NUMERICAL_UNITS num_units)
3144 {
3145    static char FuncName[]={"SUMA_SetMaskEvalTableValueNew"};
3146    int NewDisp=0, isCur=0, Err=0, init_row=0;
3147    SUMA_MaskDO *mdo=NULL;
3148    SUMA_X_SurfCont *SurfCont=NULL;
3149    SUMA_TABLE_FIELD *TF=NULL;
3150    float *fv;
3151    SUMA_ALL_DO *ado=NULL;
3152    char evale[256]={""}, tight[128]={""};
3153    char str[256];
3154    SUMA_Boolean LocalHead = NOPE;
3155 
3156    SUMA_ENTRY;
3157 
3158    if (LocalHead) {
3159       SUMA_LH("Called on cell[%d %d] with %s", row, col, s1?s1:"NULL");
3160       SUMA_DUMP_TRACE("Who called SUMA_SetMaskEvalTableValueNew?");
3161    }
3162 
3163    if (!(SurfCont=SUMAg_CF->X->AllMaskCont)) {
3164       SUMA_RETURN(0);
3165    }
3166 
3167 
3168    TF = SurfCont->MaskEvalTable;
3169    if (!TF) setmen = 0; /* can't set nothing */
3170 
3171    if (num_units == SUMA_PERC_VALUE_UNITS) {
3172       SUMA_S_Err("No percentiles allowed here");
3173       SUMA_RETURN(NOPE);
3174    }
3175 
3176    if (row < 0) {
3177       SUMA_S_Err("What is for row %d < 0?", row); SUMA_RETURN(NOPE);
3178    }
3179    if (col < 1) {
3180       SUMA_S_Err("What is for col %d < 1?", col); SUMA_RETURN(NOPE);
3181    }
3182    NewDisp = NOPE;
3183 
3184    /* What are we dealing with ? */
3185    switch (col) {
3186       case 1:
3187          SUMA_LHv("Setting expression to %s [%d %d] \n",
3188                     s1, row, col);
3189          if (SUMA_DispExpr_To_EvalExpr(s1, evale, tight)) {
3190             if (setmen) {
3191                SUMA_INSERT_CELL_STRING(TF, row, col, tight);
3192             } else { /* Just the table field */
3193                if (TF->str_value) {
3194                   SUMA_STRING_REPLACE(TF->str_value[col*TF->Ni+row], tight);
3195                }
3196             }
3197          } else { /* failed, reset string */
3198             SUMA_INSERT_CELL_STRING(TF, row, col,
3199                                     TF->str_value[col*TF->Ni+row]);
3200             SUMA_RETURN(NOPE);
3201          }
3202          break;
3203       default:
3204          SUMA_SL_Err("You make me sick");
3205          break;
3206    }
3207 
3208    SUMA_NEW_MASKSTATE();
3209 
3210    /* Now, you need to redraw the deal */
3211    if (redisplay) {
3212       DList *list = NULL;
3213       /* redisplay */
3214       if (!list) list = SUMA_CreateList ();
3215       SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
3216                                          SES_Suma, NULL);
3217       if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
3218    }
3219 
3220 
3221    SUMA_RETURN(1);
3222 }
3223 
SUMA_SetMaskLenTableValueNew(int row,int col,float v,int setmen,int redisplay,SUMA_NUMERICAL_UNITS num_units)3224 int SUMA_SetMaskLenTableValueNew(  int row, int col,
3225                                 float v,
3226                                 int setmen,
3227                                 int redisplay,
3228                                 SUMA_NUMERICAL_UNITS num_units)
3229 {
3230    static char FuncName[]={"SUMA_SetMaskLenTableValueNew"};
3231    int NewDisp=0, isCur=0, Err=0, init_row=0;
3232    SUMA_MaskDO *mdo=NULL;
3233    SUMA_X_SurfCont *SurfCont=NULL;
3234    SUMA_TABLE_FIELD *TF=NULL;
3235    float *fv;
3236    SUMA_ALL_DO *ado=NULL;
3237    char evale[256]={""}, tight[128]={""};
3238    char str[256];
3239    SUMA_Boolean LocalHead = NOPE;
3240 
3241    SUMA_ENTRY;
3242 
3243    if (LocalHead) {
3244       SUMA_LH("Called on cell[%d %d] with %f", row, col, v);
3245       SUMA_DUMP_TRACE("Who called SUMA_SetMaskLenTableValueNew?");
3246    }
3247 
3248    if (!(SurfCont=SUMAg_CF->X->AllMaskCont)) {
3249       SUMA_RETURN(0);
3250    }
3251 
3252 
3253    TF = SurfCont->MaskLenTable;
3254    if (!TF) setmen = 0; /* can't set nothing */
3255 
3256    if (num_units == SUMA_PERC_VALUE_UNITS) {
3257       SUMA_S_Err("No percentiles allowed here");
3258       SUMA_RETURN(NOPE);
3259    }
3260 
3261    if (row < 0) {
3262       SUMA_S_Err("What is for row %d < 0?", row); SUMA_RETURN(NOPE);
3263    }
3264    if (col < 1) {
3265       SUMA_S_Err("What is for col %d < 1?", col); SUMA_RETURN(NOPE);
3266    }
3267    NewDisp = NOPE;
3268 
3269    /* What are we dealing with ? */
3270    switch (col) {
3271       case 1:
3272          SUMA_LHv("Setting min to %f [%d %d] (%f)\n",
3273                    v, row, col, SurfCont->tract_length_mask[1]);
3274          if (v>=0.0 && v<=2000) {
3275             if (v > SurfCont->tract_length_mask[1]-1)
3276                                  v = SurfCont->tract_length_mask[1]-1;
3277             if (SurfCont->tract_length_mask[0] == v) {
3278                SUMA_BEEP;
3279                /* floor, get out */
3280                SUMA_RETURN(YUP);
3281             }
3282             SurfCont->tract_length_mask[0] = v;
3283             if (setmen) {
3284                SUMA_INSERT_CELL_VALUE(TF, 0, col,
3285                                       SurfCont->tract_length_mask[0]);
3286             }
3287          } else { /* failed, reset string */
3288             SUMA_BEEP;
3289             SUMA_INSERT_CELL_VALUE(TF, 0, col, SurfCont->tract_length_mask[0]);
3290             SUMA_RETURN(NOPE);
3291          }
3292          break;
3293       case 2:
3294          SUMA_LHv("Setting max to %f [%d %d] (%f)\n",
3295                    v, row, col, SurfCont->tract_length_mask[0]);
3296          if (v>=0.0 && v<=2000) {
3297             if (v < SurfCont->tract_length_mask[0]+1)
3298                                  v = SurfCont->tract_length_mask[0]+1;
3299             if (SurfCont->tract_length_mask[1] == v) {
3300                SUMA_BEEP;
3301                /* ceiling, get out */
3302                SUMA_RETURN(YUP);
3303             }
3304             SurfCont->tract_length_mask[1] = v;
3305             if (setmen) {
3306                SUMA_INSERT_CELL_VALUE(TF, 0, col,
3307                                       SurfCont->tract_length_mask[1]);
3308             }
3309          } else { /* failed, reset string */
3310             SUMA_BEEP;
3311             SUMA_INSERT_CELL_VALUE(TF, 0, col, SurfCont->tract_length_mask[1]);
3312             SUMA_RETURN(NOPE);
3313          }
3314          break;
3315       default:
3316          SUMA_SL_Err("You make me sick");
3317          break;
3318    }
3319 
3320    if (0) { /* Should not need this */
3321       SUMA_NEW_MASKSTATE();
3322    }
3323 
3324    /* Now, you need to redraw the deal */
3325    if (redisplay) {
3326       DList *list = NULL;
3327       /* redisplay */
3328       if (!list) list = SUMA_CreateList ();
3329       SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
3330                                          SES_Suma, NULL);
3331       if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
3332    }
3333 
3334 
3335    SUMA_RETURN(1);
3336 }
3337 
3338 
3339 /*!
3340    \brief create VrF selection widgets
3341 */
SUMA_CreateVrFields(Widget parent,char * tit,char * hint,char * help,int Nslc,SUMA_ALL_DO * ado,void (* NewValueCallback)(void * data),void * cb_data,SUMA_VR_FIELD * VrF)3342 void SUMA_CreateVrFields(  Widget parent,
3343                         char *tit, char *hint, char *help,
3344                         int Nslc, SUMA_ALL_DO *ado,
3345                         void (*NewValueCallback)(void * data), void *cb_data,
3346                         SUMA_VR_FIELD *VrF)
3347 {
3348    static char FuncName[]={"SUMA_CreateVrFields"};
3349    int i, j, n, titw, xmw, shad, mult;
3350    char *tmp, sbuf[12], wname[64];
3351    XtPointer cd;
3352    XtVarArgsList arglist=NULL;
3353    XtCallbackProc slcb, sllbcb, slcactcb, shwslccb;
3354    int shw_init = 0;
3355    SUMA_VOL_SAUX *VSaux=NULL;
3356    SUMA_Boolean LocalHead = NOPE;
3357 
3358    SUMA_ENTRY;
3359 
3360    if (!parent) { SUMA_SL_Err("NULL parent"); SUMA_RETURNe; }
3361    if (!ado) { SUMA_S_Err("NULL ado"); SUMA_RETURNe; }
3362    if (!(VSaux = SUMA_ADO_VSaux(ado))) { SUMA_S_Err("No VSaux"); SUMA_RETURNe; }
3363 
3364    if (LocalHead) {
3365       SUMA_S_Warn("Are NewValueCallback and its data needed at all?");
3366    }
3367    /* initialize font list if need be */
3368    if (!SUMAg_CF->X->TableTextFontList) {
3369       if (SUMA_isEnv("SUMA_SurfContFontSize", "BIG")) {
3370          SUMAg_CF->X->TableTextFontList =
3371                SUMA_AppendToFontList( SUMAg_CF->X->TableTextFontList,
3372                                        parent, "*9x15*", NULL);
3373       } else {
3374          SUMAg_CF->X->TableTextFontList =
3375                SUMA_AppendToFontList( SUMAg_CF->X->TableTextFontList,
3376                                        parent, "*8x13*", NULL);
3377       }
3378    }
3379 
3380    if (!VrF) { SUMA_SL_Err("NULL VrF"); SUMA_RETURNe; }
3381    SUMA_LH("Init");
3382    VrF->Nslc = Nslc;
3383    VrF->NewValueCallback = NewValueCallback;
3384    VrF->NewValueCallbackData = cb_data;
3385    /* An outer row column to keep the inner one from resizing with parent
3386    YOU COULD HAVE SET XmNadjustLast to False, instead ....*/
3387    VrF->rc = XtVaCreateManagedWidget ("rowcolumn",
3388       xmRowColumnWidgetClass, parent,
3389       XmNorientation , XmHORIZONTAL ,
3390       XmNpacking, XmPACK_TIGHT,
3391       XmNmarginHeight, 0,
3392       XmNmarginWidth, 0,
3393       NULL);
3394 
3395    SUMA_LH("Widgets, Nslc = %d",
3396             VrF->Nslc);
3397    VrF->lab = XtVaCreateManagedWidget(tit, xmLabelWidgetClass, VrF->rc,
3398                            XmNfontList, SUMAg_CF->X->TableTextFontList,
3399                                      NULL);
3400    if (hint || help) {
3401       snprintf(wname,63,"%s->lab", VrF->wname);
3402       SUMA_Register_Widget_Help(VrF->lab, 1, wname, hint, help);
3403    }
3404 
3405    if (VrF->N_slice_num < 0) {
3406       VrF->N_slice_num = SUMA_VO_N_Slices((SUMA_VolumeObject *)ado, "Mx");
3407    }
3408    if (VrF->N_slice_num <= 0) VrF->N_slice_num = 150;
3409    sprintf(sbuf,"%-3d", (int)VrF->N_slice_num);
3410    VrF->text = XtVaCreateManagedWidget(
3411                      "slice",
3412                      xmTextFieldWidgetClass, VrF->rc,
3413                      XmNuserData, (XTP_CAST)ado,
3414                      XmNvalue, sbuf,
3415                      XmNmarginHeight, 0,
3416                      XmNmarginTop, 0,
3417                      XmNmarginBottom, 0,
3418                      XmNmarginWidth, 5,
3419                      NULL);
3420    XtVaSetValues( VrF->text, XmNfontList,
3421                   SUMAg_CF->X->TableTextFontList, NULL);
3422 
3423    if (hint || help) {
3424       snprintf(wname,63,"%s->Ns", VrF->wname);
3425       SUMA_Register_Widget_Help(VrF->text, 1, wname, hint, help);
3426    }
3427    XtVaSetValues(VrF->text, XmNcolumns, 3, NULL);
3428    XtVaSetValues(VrF->text, XmNeditable, True,
3429                  XmNshadowThickness , 2,
3430                  XmNcursorPositionVisible, True,
3431                  NULL);
3432 
3433    XtAddCallback (VrF->text, XmNactivateCallback,
3434                SUMA_VrF_cb_N_slc_change, (XtPointer)VrF);
3435    /* add event handler to notify when widget was left */
3436 
3437    XtInsertEventHandler( VrF->text ,        /* notify when */
3438                          LeaveWindowMask ,  /* pointer leaves */
3439                          FALSE ,            /* this window */
3440                          SUMA_leave_NslcField,
3441                          (XtPointer) VrF ,
3442                          XtListTail ) ;     /* last in queue */
3443 
3444    /* Now for the view toggle button */
3445    VrF->tb = XtVaCreateManagedWidget("v",
3446       xmToggleButtonWidgetClass, VrF->rc, NULL);
3447    XtAddCallback (VrF->tb,
3448          XmNvalueChangedCallback, SUMA_cb_ShowVrF_toggled, ado);
3449    if (hint || help) {
3450       snprintf(wname,63,"%s->Ns->v", VrF->wname);
3451       SUMA_Register_Widget_Help(VrF->tb, 1, wname,
3452                                 "View (ON)/Hide VrF",
3453                                 SUMA_SurfContHelp_ShowVrFTgl);
3454    }
3455 
3456    SUMA_SET_SELECT_COLOR(VrF->tb);
3457    XmToggleButtonSetState (VrF->tb, VSaux->ShowVrSlc , NOPE);
3458 
3459    /* Now for the selectable toggle button */
3460    VrF->tbs = XtVaCreateManagedWidget("s",
3461       xmToggleButtonWidgetClass, VrF->rc, NULL);
3462    XtAddCallback (VrF->tbs,
3463          XmNvalueChangedCallback, SUMA_cb_VrSelect_toggled, ado);
3464    if (hint || help) {
3465       snprintf(wname,63,"%s->Ns->s", VrF->wname);
3466       SUMA_Register_Widget_Help(VrF->tbs, 1, wname,
3467                                 "Allow voxel selection on rendered volume (ON)",
3468                                 SUMA_SurfContHelp_VrSelectTgl);
3469    }
3470 
3471    SUMA_SET_SELECT_COLOR(VrF->tbs);
3472    XmToggleButtonSetState (VrF->tbs, VSaux->VrSelect , NOPE);
3473 
3474    SUMA_RETURNe;
3475 }
3476 
SUMA_cb_ShowVrF_toggled(Widget w,XtPointer data,XtPointer client_data)3477 void SUMA_cb_ShowVrF_toggled(Widget w, XtPointer data, XtPointer client_data)
3478 {
3479    static char FuncName[]={"SUMA_cb_ShowVrF_toggled"};
3480    SUMA_ALL_DO *ado = NULL;
3481    SUMA_X_SurfCont *SurfCont=NULL;
3482    SUMA_Boolean LocalHead = NOPE;
3483 
3484    SUMA_ENTRY;
3485 
3486    SUMA_LH("Called");
3487 
3488    ado = (SUMA_ALL_DO *)data;
3489    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
3490       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
3491 
3492    SUMA_SetShowSlice((SUMA_VolumeObject *)ado, "Vr",
3493                       XmToggleButtonGetState (SurfCont->VR_fld->tb));
3494    SUMA_RETURNe;
3495 }
3496 
SUMA_cb_VrSelect_toggled(Widget w,XtPointer data,XtPointer client_data)3497 void SUMA_cb_VrSelect_toggled(Widget w, XtPointer data, XtPointer client_data)
3498 {
3499    static char FuncName[]={"SUMA_cb_VrSelect_toggled"};
3500    SUMA_ALL_DO *ado = NULL;
3501    SUMA_X_SurfCont *SurfCont=NULL;
3502    SUMA_Boolean LocalHead = NOPE;
3503 
3504    SUMA_ENTRY;
3505 
3506    SUMA_LH("Called");
3507 
3508    ado = (SUMA_ALL_DO *)data;
3509    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
3510       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
3511 
3512    SUMA_SetShowSlice((SUMA_VolumeObject *)ado, "Sel",
3513                       XmToggleButtonGetState (SurfCont->VR_fld->tbs));
3514    SUMA_RETURNe;
3515 }
3516 
SUMA_cb_VSliceAtXYZ_toggled(Widget w,XtPointer data,XtPointer client_data)3517 void SUMA_cb_VSliceAtXYZ_toggled(Widget w, XtPointer data, XtPointer client_data)
3518 {
3519    static char FuncName[]={"SUMA_cb_VSliceAtXYZ_toggled"};
3520    SUMA_ALL_DO *ado = NULL;
3521    SUMA_X_SurfCont *SurfCont=NULL;
3522    SUMA_Boolean LocalHead = NOPE;
3523 
3524    SUMA_ENTRY;
3525 
3526    SUMA_LH("Called");
3527 
3528    ado = (SUMA_ALL_DO *)data;
3529    if (!ado || !(SurfCont=SUMA_ADO_Cont(ado))) {
3530       SUMA_S_Warn("NULL input"); SUMA_RETURNe; }
3531 
3532    SUMA_SetShowSlice((SUMA_VolumeObject *)ado, "AtXYZ",
3533                       XmToggleButtonGetState (SurfCont->VSliceAtXYZ_tb));
3534    SUMA_RETURNe;
3535 }
3536 
3537 /*!
3538    \brief This function is called when mouse pointer leaves slice field
3539    modeled after SUMA_leave_SliceField
3540 */
SUMA_leave_NslcField(Widget w,XtPointer client_data,XEvent * ev,Boolean * continue_to_dispatch)3541 void SUMA_leave_NslcField( Widget w , XtPointer client_data ,
3542                             XEvent * ev , Boolean * continue_to_dispatch )
3543 {
3544    static char FuncName[]={"SUMA_leave_NslcField"};
3545    SUMA_VR_FIELD *VrF=NULL;
3546    XLeaveWindowEvent * lev = (XLeaveWindowEvent *) ev ;
3547    XmAnyCallbackStruct cbs ;
3548    SUMA_Boolean LocalHead = NOPE;
3549 
3550    SUMA_ENTRY;
3551 
3552    SUMA_LH("Called");
3553    VrF = (SUMA_VR_FIELD *)client_data ;
3554    if( lev->type != LeaveNotify) SUMA_RETURNe;
3555 
3556    if (LocalHead) fprintf (SUMA_STDERR, "%s: Leave notification.\n", FuncName);
3557 
3558    SUMA_VrF_cb_N_slc_change( w , (XtPointer)VrF , NULL ) ;
3559 
3560    SUMA_RETURNe;
3561 }
3562 
3563 /*!
3564    \brief User entered new slice value
3565    modeled after: SUMA_SliceF_cb_label_change
3566 */
SUMA_VrF_cb_N_slc_change(Widget w,XtPointer client_data,XtPointer call_data)3567 void SUMA_VrF_cb_N_slc_change (  Widget w, XtPointer client_data,
3568                                     XtPointer call_data)
3569 {
3570    static char FuncName[]={"SUMA_VrF_cb_N_slc_change"};
3571    SUMA_VR_FIELD *VrF=NULL;
3572    float val;
3573    int N_words = 0;
3574    XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *) call_data;
3575    void *n=NULL;
3576    char *cs=NULL;
3577    int unt = SUMA_NO_NUM_UNITS;
3578    SUMA_Boolean DoCallBacks;
3579    SUMA_Boolean LocalHead = NOPE;
3580 
3581    SUMA_ENTRY;
3582 
3583    SUMA_LH("Called");
3584    /* make call to NewValue callback */
3585    VrF = (SUMA_VR_FIELD *)client_data;
3586 
3587    DoCallBacks = NOPE;
3588    if (call_data) {
3589       /* do the call backs if carriage return even if nothing is modified */
3590       if (LocalHead)
3591          fprintf (SUMA_STDERR,"%s: cbs->reason = %d (CR=%d)\n",
3592                               FuncName, cbs->reason, XmCR_ACTIVATE);
3593       if (cbs->reason == XmCR_ACTIVATE) {
3594          DoCallBacks = YUP;
3595       }
3596    }
3597 
3598    DoCallBacks = YUP;   /* do the callbacks even if no carriage return ... */
3599    /* Check if the string is numerical, and get unit */
3600    XtVaGetValues (w, XmNvalue, &n, NULL);
3601    cs = (char *)n;
3602    if (!cs || !strlen(cs)) {/* empty cell, leave it alone */
3603       SUMA_LHv("empty %s", cs);
3604       SUMA_RETURNe;
3605    } else  {
3606       SUMA_COUNT_WORDS(cs, NULL, N_words);
3607       if (!N_words) { /* no harm, go back */
3608          SUMA_LHv("spacy %s", cs);
3609          SUMA_RETURNe;
3610       }
3611    }
3612    unt = SUMA_NumStringUnits(cs, 0);
3613    if (SUMA_StringToNum(cs, (void *)&val, 1, 1) != 1) {
3614       SUMA_BEEP;
3615       /* bad syntax, reset value*/
3616       if (LocalHead) fprintf (SUMA_STDERR, "%s: Bad syntax.\n", FuncName);
3617       SUMA_RegisterMessage (SUMAg_CF->MessageList,
3618                             "Bad value in text field", FuncName,
3619                             SMT_Error, SMA_Log);
3620       SUMA_VrF_SetNslcString (VrF);
3621    }else {
3622       if (VrF->N_slice_num == val &&
3623           VrF->N_slice_units == unt) {
3624             SUMA_LH("Same value");
3625             SUMA_RETURNe;
3626       }
3627       SUMA_LH("A new beast? %f, %f, %d %d",
3628               VrF->N_slice_num, val, VrF->N_slice_units, unt);
3629       VrF->N_slice_num = val;
3630       VrF->N_slice_units = unt;
3631       SUMA_VrF_SetNslcString (VrF);
3632    }
3633 
3634    if (DoCallBacks) {
3635       SUMA_set_slice((SUMA_ALL_DO *)VrF->NewValueCallbackData, "VR",
3636                       &val, "text_field", 1);
3637    }
3638 
3639    SUMA_RETURNe;
3640 }
3641 
3642 /* model based on SUMA_SliceF_SetString */
SUMA_VrF_SetNslcString(SUMA_VR_FIELD * VrF)3643 void SUMA_VrF_SetNslcString(SUMA_VR_FIELD * VrF)
3644 {
3645    static char FuncName[]={"SUMA_VrF_SetNslcString"};
3646    char buf[36];
3647 
3648    SUMA_ENTRY;
3649 
3650    if (VrF->N_slice_units == SUMA_NO_NUM_UNITS) {
3651       sprintf (buf, "%-4d", (int)VrF->N_slice_num);
3652    }else if (VrF->N_slice_units == SUMA_MM_UNITS) {
3653       sprintf (buf, "%s",
3654                MV_format_fval2(  VrF->N_slice_num, 3));
3655    }else {
3656       /* fair enough, must be stringy */
3657    }
3658 
3659    XtVaSetValues (VrF->text, XmNvalue, buf, NULL);
3660    SUMA_RETURNe;
3661 }
3662 
3663 /*!
3664    \brief set polymode, if SurfCont is not null, also set related widget
3665 
3666    if delta != 0, then increment current transparency by delta.
3667                   When using delta, you should pass sv->TransMode
3668                   in i, for when the starting transparency is that of the viewer.
3669 */
SUMA_Set_ADO_RenderMode(SUMA_ALL_DO * ado,int i,int delta,int update_widgets)3670 SUMA_Boolean SUMA_Set_ADO_RenderMode(SUMA_ALL_DO *ado, int i, int delta,
3671                                     int update_widgets )
3672 {
3673    static char FuncName[]={"SUMA_Set_ADO_RenderMode"};
3674    SUMA_X_SurfCont *SurfCont=NULL;
3675    SUMA_Boolean LocalHead = NOPE;
3676 
3677    SUMA_ENTRY;
3678 
3679    if (!ado) SUMA_RETURN(NOPE);
3680    if (update_widgets) SurfCont = SUMA_ADO_Cont(ado);
3681 
3682    switch (ado->do_type) {
3683       case SO_type: {
3684          SUMA_SurfaceObject *SO = (SUMA_SurfaceObject *)ado;
3685          if (delta) {
3686             if (SO->PolyMode == SRM_ViewerDefault) {
3687                /* ambiguous case, start at i */
3688                SO->PolyMode = i;
3689             }
3690             if (delta < 0) {
3691                i = ((SO->PolyMode-delta) % SRM_N_RenderModes);
3692                if (i <= SRM_ViewerDefault) i = SRM_Fill;
3693             } else if (delta > 0) {
3694                i = ((SO->PolyMode-delta) % (SRM_N_RenderModes));
3695                if (i <= SRM_ViewerDefault) i = SRM_Points;
3696             }
3697          }
3698          SO->PolyMode = (i % SRM_N_RenderModes);
3699          if (SO->PolyMode <= SRM_ViewerDefault) SO->PolyMode = SRM_Fill;
3700          if (SurfCont && SurfCont->RenderModeMenu) { /* also set widgets */
3701              SUMA_Set_Menu_Widget( SurfCont->RenderModeMenu,
3702                         SUMA_RenderMode2RenderModeMenuItem(SO->PolyMode+1));
3703          }
3704          break; }
3705       case VO_type: {
3706          SUMA_VolumeObject *VO = (SUMA_VolumeObject *)ado;
3707          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
3708          if (!VSaux) SUMA_RETURN(NOPE);
3709          SUMA_LH("What to do for VO polymode %s (%s)?",
3710                     ADO_LABEL(ado), ADO_TNAME(ado));
3711          break; }
3712       default:
3713          SUMA_S_Err("Not ready for %s (%s)", ADO_LABEL(ado), ADO_TNAME(ado));
3714          break;
3715    }
3716 
3717    SUMA_RETURN(YUP);
3718 }
3719 
3720 /*!
3721    \brief set transmode, if SurfCont is not null, also set related widget
3722 
3723    if delta != 0, then increment current transparency by delta.
3724                   When using delta, you should pass sv->TransMode
3725                   in i, for when the starting transparency is that of the viewer.
3726 */
SUMA_Set_ADO_TransMode(SUMA_ALL_DO * ado,int i,int delta,int update_widgets)3727 SUMA_Boolean SUMA_Set_ADO_TransMode(SUMA_ALL_DO *ado, int i, int delta,
3728                                     int update_widgets )
3729 {
3730    static char FuncName[]={"SUMA_Set_ADO_TransMode"};
3731    SUMA_X_SurfCont *SurfCont=NULL;
3732    SUMA_ENTRY;
3733 
3734    if (!ado) SUMA_RETURN(NOPE);
3735    if (update_widgets) SurfCont = SUMA_ADO_Cont(ado);
3736 
3737    switch (ado->do_type) {
3738       case SO_type: {
3739          SUMA_SurfaceObject *SO = (SUMA_SurfaceObject *)ado;
3740          if (delta) {
3741             if (SO->TransMode == STM_ViewerDefault) {
3742                /* ambiguous case, start at i */
3743                SO->TransMode = i;
3744             }
3745             if (delta < 0) {
3746                i = ((SO->TransMode-delta) % (STM_N_TransModes-2));
3747                if (i <= STM_ViewerDefault) i = STM_16;
3748             } else if (delta > 0) {
3749                i = ((SO->TransMode-delta) % (STM_N_TransModes-2));
3750                if (i <= STM_ViewerDefault) i = STM_0;
3751             }
3752          }
3753          if (i < 0 || i >= STM_N_TransModes) {
3754             SO->TransMode = STM_ViewerDefault;
3755          } else { SO->TransMode = i; }
3756          if (SO->TransMode == STM_16) { SO->Show = NOPE; }
3757          else { SO->Show = YUP; }
3758          if (SurfCont && SurfCont->TransModeMenu) { /* also set widgets */
3759             SUMA_Set_Menu_Widget(SurfCont->TransModeMenu,
3760                               SUMA_TransMode2TransModeMenuItem(SO->TransMode+1));
3761          }
3762          break; }
3763       case VO_type: {
3764          SUMA_VolumeObject *VO = (SUMA_VolumeObject *)ado;
3765          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
3766          if (!VSaux) SUMA_RETURN(NOPE);
3767          if (delta) {
3768             if (VSaux->TransMode == SATM_ViewerDefault) {
3769                /* ambiguous case, start at i */
3770                VSaux->TransMode = SUMA_TransMode2ATransMode(i);
3771             }
3772             if (delta < 0) {
3773                i = ((VSaux->TransMode-delta) % (SATM_N_TransModes-2));
3774                if (i <= SATM_ViewerDefault) i = SATM_16;
3775             } else if (delta > 0) {
3776                i = ((VSaux->TransMode-delta) % (SATM_N_TransModes-2));
3777                if (i <= SATM_ViewerDefault) i = SATM_0;
3778             }
3779          }
3780          if (i < 0 || i >= SATM_N_TransModes) {
3781             VSaux->TransMode = SATM_ViewerDefault;
3782          } else { VSaux->TransMode = i; }
3783          if (VSaux->TransMode == SATM_16) { VO->Show = NOPE; }
3784          else { VO->Show = YUP; }
3785          if (SurfCont && SurfCont->VTransModeMenu) { /* also set widgets */
3786             SUMA_Set_Menu_Widget(SurfCont->VTransModeMenu,
3787                          SUMA_ATransMode2ATransModeMenuItem(VSaux->TransMode+1));
3788          }
3789          break; }
3790       default:
3791          SUMA_S_Err("Not ready for %s (%s)", ADO_LABEL(ado), ADO_TNAME(ado));
3792          break;
3793    }
3794 
3795    SUMA_RETURN(YUP);
3796 }
3797 
SUMA_Get_ADO_TransMode(SUMA_ALL_DO * ado)3798 int SUMA_Get_ADO_TransMode(SUMA_ALL_DO *ado)
3799 {
3800    static char FuncName[]={"SUMA_Get_ADO_TransMode"};
3801 
3802    SUMA_ENTRY;
3803 
3804    if (!ado) SUMA_RETURN(STM_ViewerDefault);
3805 
3806    switch (ado->do_type) {
3807       case SO_type: {
3808          SUMA_SurfaceObject *SO = (SUMA_SurfaceObject *)ado;
3809          SUMA_RETURN((int)SO->TransMode);
3810          break; }
3811       case VO_type: {
3812          SUMA_VolumeObject *VO = (SUMA_VolumeObject *)ado;
3813          SUMA_VOL_SAUX *VSaux = SUMA_ADO_VSaux(ado);
3814          if (!VSaux) SUMA_RETURN(NOPE);
3815          SUMA_RETURN((int)VSaux->TransMode);
3816          break; }
3817       default:
3818          SUMA_S_Err("Not ready for %s (%s)", ADO_LABEL(ado), ADO_TNAME(ado));
3819          break;
3820    }
3821 
3822    SUMA_RETURN(STM_ViewerDefault);
3823 }
3824 
SUMA_TransMode2ATransMode(SUMA_TRANS_MODES ii)3825 SUMA_ATRANS_MODES SUMA_TransMode2ATransMode(SUMA_TRANS_MODES ii)
3826 {
3827    static char FuncName[]={"SUMA_TransMode2ATransMode"};
3828 
3829    if (ii < 0 || ii > STM_N_TransModes) {
3830       SUMA_S_Err("Bad TransMode %d, returning viewerdefault", ii);
3831       return(SATM_ViewerDefault);
3832    }
3833    switch (ii) {
3834       case STM_ViewerDefault:
3835          return(SATM_ViewerDefault);
3836       case STM_N_TransModes:
3837          return(SATM_N_TransModes);
3838       default:
3839          return(SATM_0+ii-STM_0);
3840    }
3841    return(SATM_ViewerDefault);
3842 }
3843 
SUMA_ATransMode2TransMode(SUMA_ATRANS_MODES ii)3844 SUMA_TRANS_MODES SUMA_ATransMode2TransMode(SUMA_ATRANS_MODES ii)
3845 {
3846    static char FuncName[]={"SUMA_ATransMode2TransMode"};
3847 
3848    if (ii < 0 || ii > SATM_N_TransModes) {
3849       SUMA_S_Err("Bad ATransMode %d, returning viewerdefault", ii);
3850       return(STM_ViewerDefault);
3851    }
3852    switch (ii) {
3853       case SATM_ALPHA:
3854          SUMA_S_Warn("No alpha available, returning viewerdefault");
3855          return(STM_ViewerDefault);
3856       case SATM_ViewerDefault:
3857          return(STM_ViewerDefault);
3858       case SATM_N_TransModes:
3859          return(STM_N_TransModes);
3860       default:
3861          return(STM_0+ii-SATM_0);
3862    }
3863    return(STM_ViewerDefault);
3864 }
3865 
3866 /*!
3867    Load Masks
3868 */
SUMA_cb_Masks_Load(Widget w,XtPointer data,XtPointer client_data)3869 void SUMA_cb_Masks_Load(Widget w, XtPointer data, XtPointer client_data)
3870 {
3871    static char FuncName[]={"SUMA_cb_Masks_Load"};
3872    SUMA_LIST_WIDGET *LW=NULL;
3873    DList *list = NULL;
3874    SUMA_EngineData *ED = NULL;
3875    DListElmt *NextElm = NULL;
3876    SUMA_Boolean LocalHead = NOPE;
3877 
3878    SUMA_ENTRY;
3879 
3880    SUMA_LH("Called");
3881 
3882    if (!list) list = SUMA_CreateList();
3883    ED = SUMA_InitializeEngineListData (SE_OpenMaskFileSelection);
3884    if (!(NextElm = SUMA_RegisterEngineListCommand (  list, ED,
3885                                           SEF_vp, (void *)data,
3886                                           SES_Suma, NULL, NOPE,
3887                                           SEI_Head, NULL))) {
3888       fprintf (SUMA_STDERR,
3889          "Error %s: Failed to register command.\n", FuncName);
3890    }
3891    if (!SUMA_RegisterEngineListCommand (  list, ED,
3892                                           SEF_ip, (int *)w,
3893                                           SES_Suma, NULL, NOPE,
3894                                           SEI_In, NextElm)) {
3895       fprintf (SUMA_STDERR,
3896          "Error %s: Failed to register command.\n", FuncName);
3897    }
3898 
3899    if (!SUMA_Engine (&list)) {
3900       fprintf(SUMA_STDERR,
3901          "Error %s: SUMA_Engine call failed.\n", FuncName);
3902    }
3903 
3904    SUMA_RETURNe;
3905 }
3906 
3907 /*!
3908    \brief Save the masks to disk
3909 */
SUMA_cb_Masks_Save(Widget w,XtPointer data,XtPointer client_data)3910 void SUMA_cb_Masks_Save (Widget w, XtPointer data, XtPointer client_data)
3911 {
3912    static char FuncName[]={"SUMA_cb_Masks_Save"};
3913    SUMA_DRAWN_ROI *dROI=NULL;
3914    DList *list = NULL;
3915    SUMA_EngineData *ED = NULL;
3916    DListElmt *NextElm = NULL;
3917    SUMA_Boolean LocalHead = NOPE;
3918 
3919    SUMA_ENTRY;
3920 
3921    SUMA_LH("Called");
3922 
3923    if (!list) list = SUMA_CreateList();
3924    ED = SUMA_InitializeEngineListData (SE_SaveMaskFileSelection);
3925    if (!(NextElm = SUMA_RegisterEngineListCommand (  list, ED,
3926                                           SEF_vp, (void *)data,
3927                                           SES_Suma, NULL, NOPE,
3928                                           SEI_Head, NULL))) {
3929       fprintf (SUMA_STDERR,
3930          "Error %s: Failed to register command.\n", FuncName);
3931    }
3932    if (!SUMA_RegisterEngineListCommand (  list, ED,
3933                                           SEF_ip, (int *)w,
3934                                           SES_Suma, NULL, NOPE,
3935                                           SEI_In, NextElm)) {
3936       fprintf (SUMA_STDERR,
3937          "Error %s: Failed to register command.\n", FuncName);
3938    }
3939 
3940    if (!SUMA_Engine (&list)) {
3941       fprintf(SUMA_STDERR,
3942          "Error %s: SUMA_Engine call failed.\n", FuncName);
3943    }
3944 
3945    SUMA_RETURNe;
3946 }
3947 
3948 /*!
3949    \brief Loads masks into SUMA land
3950 
3951    \param dlg (SUMA_SELECTION_DIALOG_STRUCT *) struture from selection dialogue
3952 */
SUMA_LoadMultiMasks(char * filename,void * data)3953 void SUMA_LoadMultiMasks (char *filename, void *data)
3954 {
3955    static char FuncName[]={"SUMA_LoadMultiMasks"};
3956 
3957    SUMA_ENTRY;
3958 
3959    if (!filename) {
3960       SUMA_SLP_Err("Null filename");
3961       SUMA_RETURNe;
3962    }
3963 
3964    if (!SUMA_LoadMultiMasks_eng(filename, 1, 1)) {
3965       SUMA_SLP_Err("Failed loading, and processing masks");
3966       SUMA_RETURNe;
3967    }
3968 
3969    SUMA_RETURNe;
3970 }
3971 
3972 /*!
3973    Function that does the work of loading masks saved in a file
3974 */
SUMA_LoadMultiMasks_eng(char * filename,int SetupTable,int LaunchDisplay)3975 SUMA_Boolean SUMA_LoadMultiMasks_eng (char *filename,
3976                               int SetupTable,
3977                               int LaunchDisplay)
3978 {
3979    static char FuncName[]={"SUMA_LoadMultiMasks_eng"};
3980    SUMA_DSET_FORMAT form;
3981    char *fname = NULL, *att=NULL;
3982    SUMA_Boolean ans = NOPE;
3983    NI_stream ns;
3984    int ip, good, ido, an;
3985    SUMA_MaskDO *mdo=NULL;
3986    NI_group *NIcont=NULL, *ngr=NULL;
3987    NI_element *nel=NULL;
3988    DList *list = NULL;
3989    SUMA_X_SurfCont *SurfCont=NULL;
3990    SUMA_Boolean LocalHead = NOPE;
3991 
3992    SUMA_ENTRY;
3993 
3994    if (!filename) {
3995       SUMA_S_Err("Null filename");
3996       SUMA_RETURN(NOPE);
3997    }
3998 
3999    if (LocalHead) {
4000       fprintf (SUMA_STDERR,
4001                "%s: Received request to load %s.\n",
4002                FuncName, filename);
4003    }
4004 
4005    /* find out if file exists and how many values it contains */
4006    if (!SUMA_filexists(filename)) {
4007       SUMA_SLP_Err("File not found");
4008       SUMA_RETURN(NOPE);
4009    }
4010 
4011    /* take a stab at the format */
4012    form = SUMA_GuessFormatFromExtension(filename, NULL);
4013 
4014    /* Read the container group */
4015    fname = SUMA_append_replace_string("file:", filename, "", 0);
4016    if (!(ns = NI_stream_open(fname, "r"))) {
4017       SUMA_SLP_Err("Failed to open %s", fname);
4018       goto OUT;
4019    }
4020 
4021    /* read the whole thing */
4022    if (!(NIcont = NI_read_element(ns, 1))) {
4023       SUMA_SLP_Err("Failed to read element from %s", fname);
4024       goto OUT;
4025    }
4026    if (NI_element_type(NIcont) != NI_GROUP_TYPE) {
4027       SUMA_SLP_Err("Failed to NI element %s not group type", fname);
4028       goto OUT;
4029    }
4030    if (strcmp(NIcont->name, "MaskObjects")) {
4031       SUMA_SLP_Err("Unexpected NI name of %s, wanted %s",
4032                    NIcont->name, "MaskObjects" );
4033       goto OUT;
4034    }
4035 
4036    /* extract content */
4037    good = 0; ido = -1;
4038    for (ip=0; ip<NIcont->part_num; ++ip) {
4039       switch( NIcont->part_typ[ip] ){
4040         case NI_GROUP_TYPE:
4041             ngr = (NI_group *)NIcont->part[ip] ;
4042             if (!strcmp(ngr->name, "Mask")) {
4043                /* wipe out existing masks with the same idcode */
4044                SUMA_DeleteMask(NI_get_attribute(ngr,"idcode_str"));
4045                if (!(mdo = SUMA_NIMDO_to_MDO(ngr))) {
4046                   SUMA_S_Err("Failed to translate mask for %s",
4047                               ngr->name);
4048                   break;
4049                }
4050                if (!SUMA_AccessorizeMDO(mdo)) {
4051                   SUMA_S_Err("No accessorizing");
4052                   SUMA_free_MaskDO(mdo); break;
4053                }
4054                /* Now add mdo into dov */
4055                SUMA_LH("Adding DO");
4056                if (!SUMA_AddDO(SUMAg_DOv, &SUMAg_N_DOv,
4057                                (void *)mdo, MASK_type, SUMA_WORLD)) {
4058                   SUMA_S_Err("Failed in SUMA_AddDO.");
4059                   SUMA_free_MaskDO(mdo); break;
4060                }
4061                ido = SUMAg_N_DOv-1;
4062                /* register DO with viewer */
4063                SUMA_LH("Registrar");
4064                if (!SUMA_RegisterDO(ido, NULL)) {
4065                   SUMA_S_Err("Failed in SUMA_RegisterDO.");
4066                   break;
4067                }
4068                ++good;
4069             } else {
4070                SUMA_S_Warn("Don't know what to make of %s",
4071                           ngr->name);
4072             }
4073             break ;
4074          case NI_ELEMENT_TYPE:
4075             nel = (NI_element *)NIcont->part[ip] ;
4076             SUMA_S_Warn("Don't know what to make of %s",
4077                           nel->name);
4078             break;
4079          default:
4080             break;
4081       }
4082    }
4083 
4084    if (good) {
4085       SurfCont=SUMAg_CF->X->AllMaskCont;
4086       if (NI_get_attribute(NIcont, "TractLength")) {
4087          NI_GET_FLOATv(NIcont, "TractLength",
4088                        SurfCont->tract_length_mask, 2, LocalHead);
4089          NI_GET_INT(NIcont, "UseTractLength", SurfCont->UseMaskLen);
4090       }
4091       if (SurfCont->MaskEvalTable &&
4092           (att=NI_get_attribute(NIcont, "MaskEval"))) {
4093          an = SUMA_SetMaskEvalTableValueNew(0, 1, att,
4094                           1, 0, SurfCont->MaskEvalTable->num_units);
4095          if (an < 0) {
4096             SUMA_S_Err("Failed to set %s as mask expression",
4097                         att);
4098             SUMA_Set_UseMaskEval(0, 0, 1);
4099          } else {
4100             NI_GET_INT(NIcont, "UseMaskEval", SurfCont->UseMaskEval);
4101             SUMA_Set_UseMaskEval(SurfCont->UseMaskEval, 0, 1);
4102          }
4103       }
4104       if (SetupTable && SurfCont) {
4105          SUMA_InitMasksTable(SurfCont);
4106       }
4107       if (LaunchDisplay) {
4108          SUMA_NEW_MASKSTATE();
4109          /* redisplay */
4110          if (!list) list = SUMA_CreateList ();
4111          SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible,
4112                                             SES_Suma, NULL);
4113          if (!SUMA_Engine(&list)) SUMA_SLP_Err("Failed to redisplay.");
4114       }
4115    }
4116 
4117    ans = YUP;
4118 
4119    OUT:
4120    if (ns) NI_stream_close(ns); ns=NULL;
4121    SUMA_ifree(fname);
4122    NI_free(NIcont); NIcont = NULL;
4123 
4124    SUMA_RETURN(ans);
4125 }
4126 
4127 /*!
4128    \brief Loads masks into SUMA land
4129 
4130    \param dlg (SUMA_SELECTION_DIALOG_STRUCT *) struture from selection dialogue
4131 */
SUMA_SaveMultiMasks(char * filename,void * data)4132 void SUMA_SaveMultiMasks (char *filename, void *data)
4133 {
4134    static char FuncName[]={"SUMA_SaveMultiMasks"};
4135 
4136    SUMA_ENTRY;
4137 
4138    if (!filename) {
4139       SUMA_SLP_Err("Null filename");
4140       SUMA_RETURNe;
4141    }
4142 
4143    if (!SUMA_SaveMultiMasks_eng(filename)) {
4144       SUMA_SLP_Err("Failed saving masks");
4145       SUMA_RETURNe;
4146    }
4147 
4148    SUMA_RETURNe;
4149 }
4150 
4151 /*!
4152    Function that does the work of loading masks saved in a file */
SUMA_SaveMultiMasks_eng(char * filename)4153 SUMA_Boolean SUMA_SaveMultiMasks_eng (char *filename)
4154 {
4155    static char FuncName[]={"SUMA_SaveMultiMasks_eng"};
4156    SUMA_DSET_FORMAT form;
4157    SUMA_Boolean LocalHead = NOPE;
4158    DList *dl=NULL;
4159    DListElmt *el=NULL;
4160    int cnt;
4161    char *fname=NULL, *sss;
4162    SUMA_X_SurfCont *SurfCont=NULL;
4163    NI_stream ns;
4164    SUMA_MaskDO *mdo=NULL;
4165    NI_group *NIcont=NULL;
4166 
4167    SUMA_ENTRY;
4168 
4169    if (!filename) {
4170       SUMA_S_Err("Null data");
4171       SUMA_RETURN(NOPE);
4172    }
4173 
4174    if (LocalHead) {
4175       fprintf (SUMA_STDERR,
4176                "%s: Received request to save %s .\n",
4177                FuncName, filename);
4178    }
4179 
4180    /* find out if file exists and how many values it contains */
4181    fname = SUMA_Extension(filename, ".niml.mo", 0);
4182    if (SUMA_filexists(fname)) {
4183       if (SUMA_ForceUser_YesNo(SUMAg_SVv[0].X->TOPLEVEL,
4184                                  "Overwrite existing file?", SUMA_YES,
4185                                  SWP_DONT_CARE) != SUMA_YES) {
4186          SUMA_S_Note("File %s exists, user chose not to overwrite", fname);
4187          SUMA_ifree(fname);
4188          SUMA_RETURN(NOPE);
4189       }
4190    }
4191    fname = SUMA_append_replace_string("file:", fname, "", 2);
4192    if (!(ns = NI_stream_open(fname, "w"))) {
4193       SUMA_SLP_Err("Failed to open %s for writing", fname);
4194       SUMA_ifree(fname);
4195       SUMA_RETURN(NOPE);
4196    }
4197 
4198    /* Check on all masks and save them */
4199    dl = SUMA_AssembleMasksList_inDOv(SUMAg_DOv, SUMAg_N_DOv, 0);
4200    if (!dl || dlist_size(dl) == 0) {
4201       SUMA_S_Note("No masks, nothing written");
4202       SUMA_RETURN(YUP);
4203    }
4204 
4205    NIcont = NI_new_group_element();
4206    NI_rename_group(NIcont, "MaskObjects");
4207 
4208    /* Some overall attributes */
4209    SurfCont=SUMAg_CF->X->AllMaskCont;
4210 
4211    sss = SUMA_GetMaskEvalExpr();
4212    if (sss[0] != '\0') {
4213       NI_set_attribute(NIcont,"MaskEval", sss);
4214       if (SurfCont) NI_SET_INT(NIcont,"UseMaskEval",SurfCont->UseMaskEval);
4215    }
4216 
4217    if (SurfCont) {
4218       NI_SET_FLOATv(NIcont, "TractLength", SurfCont->tract_length_mask, 2);
4219       NI_SET_INT(NIcont,"UseTractLength", SurfCont->UseMaskLen);
4220    }
4221 
4222    cnt = 0; el = NULL;
4223    do {
4224       if (!el) el = dlist_head(dl);
4225       else el = dlist_next(el);
4226       mdo = (SUMA_MaskDO *)el->data;
4227       if (!SUMA_MDO_to_NIMDO(mdo, NIcont)) {
4228          SUMA_S_Err("Failed to transform mdo %s, continuing",
4229                     ADO_LABEL((SUMA_ALL_DO *)mdo));
4230       }
4231       ++cnt;
4232    } while (el != dlist_tail(dl));
4233 
4234    /* Now write the beast */
4235    NI_write_element( ns , NIcont , NI_TEXT_MODE ) ;
4236 
4237    NI_stream_close(ns); ns=NULL;
4238    SUMA_ifree(fname);
4239    NI_free(NIcont); NIcont = NULL;
4240    dlist_destroy(dl);SUMA_free(dl);
4241 
4242    SUMA_RETURN(YUP);
4243 }
4244 
4245 /*
4246    *************** Convolution functions ***************
4247    based on example in glut's convolve.c by
4248    Tom McReynolds, SGI
4249    *****************************************************
4250 */
4251 
4252 /* identity filter */
SUMA_C_identity(SUMA_C_FILTER * mat)4253 void SUMA_C_identity(SUMA_C_FILTER *mat)
4254 {
4255   int n, size;
4256   size = mat->rows * mat->cols;
4257 
4258   mat->array[0] = 1.f;
4259   for(n = 1; n < size; n++)
4260     mat->array[n] = 0.f;
4261 
4262   mat->scale = 1.f;
4263   mat->bias = 0.f;
4264 }
4265 
4266 
4267 /* create a new filter with identity filter in it */
SUMA_C_newfilter(int rows,int cols)4268 SUMA_C_FILTER * SUMA_C_newfilter(int rows, int cols)
4269 {
4270   SUMA_C_FILTER *mat;
4271 
4272   mat = (SUMA_C_FILTER *)malloc(sizeof(SUMA_C_FILTER));
4273   mat->rows = rows;
4274   mat->cols = cols;
4275   mat->array = (GLfloat *)malloc(rows * cols * sizeof(GLfloat));
4276   SUMA_C_identity(mat);
4277 
4278   return(mat);
4279 }
4280 
SUMA_C_free(SUMA_C_FILTER * mat)4281 void SUMA_C_free(SUMA_C_FILTER *mat)
4282 {
4283    if (!mat) return;
4284    if (mat->array) free(mat->array);
4285    free(mat);
4286    return;
4287 }
4288 
4289 /* doesn't re-initialize matrix */
SUMA_C_resize(SUMA_C_FILTER * mat,int rows,int cols)4290 void SUMA_C_resize(SUMA_C_FILTER *mat, int rows, int cols)
4291 {
4292   if(mat->rows != rows ||
4293      mat->cols != cols) {
4294     mat->array = (GLfloat *)realloc(mat->array, rows * cols * sizeof(GLfloat));
4295   }
4296   mat->rows = rows;
4297   mat->cols = cols;
4298 }
4299 
4300 
4301 /* box filter blur */
SUMA_C_box(SUMA_C_FILTER * mat)4302 void SUMA_C_box(SUMA_C_FILTER *mat)
4303 {
4304   int n, count;
4305   GLfloat blur;
4306 
4307   count = mat->cols * mat->rows;
4308   blur = 1.f/count;
4309   for(n = 0; n < count; n++)
4310      mat->array[n] = blur;
4311 
4312   mat->scale = 1.f;
4313   mat->bias = 0.f;
4314 }
4315 
4316 /* sobel filter */
SUMA_C_sobel(SUMA_C_FILTER * mat)4317 void SUMA_C_sobel(SUMA_C_FILTER *mat)
4318 {
4319   static GLfloat sobel[] = {-.5f, 0.f, .5f,
4320                             -1.f, 0.f, 1.f,
4321                             -.5f, 0.f, .5f};
4322 
4323   /* sobel is fixed size */
4324   SUMA_C_resize(mat, 3, 3); /* will do nothing if size is right already */
4325 
4326   memcpy(mat->array, sobel, sizeof(sobel));
4327 
4328   mat->scale = 2.f;
4329   mat->bias = 0.f;
4330 }
4331 
4332 /* laplacian filter */
SUMA_C_laplace(SUMA_C_FILTER * mat)4333 void SUMA_C_laplace(SUMA_C_FILTER *mat)
4334 {
4335   static GLfloat laplace[] = {  0.f, -.25f,   0.f,
4336                               -.25f,   1.f, -.25f,
4337                                 0.f, -.25f,   0.f};
4338 
4339   /* sobel is fixed size */
4340   SUMA_C_resize(mat, 3, 3); /* will do nothing if size is right already */
4341 
4342   memcpy(mat->array, laplace, sizeof(laplace));
4343 
4344   mat->scale = 4.f;
4345   mat->bias = .125f;
4346 }
4347 
SUMA_C_convolve(SUMA_SurfaceViewer * csv,SUMA_DO * dov,SUMA_C_FILTER * mat)4348 void SUMA_C_convolve(SUMA_SurfaceViewer *csv, SUMA_DO *dov, SUMA_C_FILTER *mat)
4349 {
4350   int i, j;
4351   int imax, jmax;
4352 
4353   imax = mat->cols;
4354   jmax = mat->rows;
4355   for(j = 0; j < jmax; j++) {
4356       for(i = 0; i < imax; i++) {
4357         glViewport(-i, -j, csv->X->aWIDTH - i, csv->X->aHEIGHT - j);
4358         SUMA_display_one(csv, dov);
4359         glAccum(GL_ACCUM, mat->array[i + j * imax]);
4360       }
4361   }
4362   if (jmax > 0 && imax > 0) {
4363    glViewport(0, 0, csv->X->aWIDTH, csv->X->aHEIGHT);
4364   }
4365 }
4366 
4367 
4368 /* *************** End Convolution utilities *************** */
4369 
4370 /*! Based on the venerable MCW_click_webhelp_CB() */
SUMA_click_webhelp_CB(Widget w,XtPointer data,XtPointer callData)4371 void SUMA_click_webhelp_CB(Widget w, XtPointer data,
4372                                      XtPointer callData)
4373 {
4374    static char FuncName[] = {"SUMA_click_webhelp_CB"};
4375    Widget whelp, winit ;
4376    int mx = 0;
4377    XmAnyCallbackStruct cbs ;
4378    XEvent ev ;
4379    char *wlabel=NULL;
4380    GUI_WIDGET_HELP *gwh=NULL;
4381    static Cursor cur = 0 ;
4382    Display *dis = XtDisplay(w) ;
4383    SUMA_Boolean LocalHead = NOPE;
4384 
4385    SUMA_ENTRY;
4386 
4387 
4388 
4389    if( cur == 0 ) cur = XCreateFontCursor( dis , XC_coffee_mug ) ;
4390 
4391 #ifdef USE_LOCATE  /* old version */
4392    whelp = XmTrackingLocate( w , cur , False ) ; /* wait for user to click */
4393 #else
4394    cbs.event = &ev ;
4395    whelp = XmTrackingEvent( w , cur , False , cbs.event ) ;
4396 #endif
4397 
4398    winit = whelp;
4399    if( whelp != NULL) {
4400       SUMA_LH("Eins on %s", XtName(whelp));
4401       if (!(gwh = SUMA_Get_Widget_Help( whelp ))) {
4402          SUMA_LH("No help on widget (%s) trying parents...",
4403                      XtName(whelp));
4404       }
4405       mx = 0;
4406       while (mx < 5 && (whelp = XtParent(whelp)) && !gwh) {
4407          SUMA_LH("Seeking fortune with %s...", XtName(whelp));
4408          gwh = SUMA_Get_Widget_Help( whelp );
4409          ++mx;
4410       }
4411       if (!gwh) {
4412          SUMA_S_Note("Could not find web help where you clicked (%s)."
4413                      "Try again in vicinity.", XtName(winit));
4414          SUMA_RETURNe;
4415       }
4416    } else {
4417       XBell( dis , 100 ) ;
4418       SUMA_RETURNe;
4419    }
4420 
4421 
4422    /* Go from name to permalink  */
4423    wlabel = SUMA_gsf(SUMA_Name_GUI_Help(gwh), WEB, NULL, NULL);
4424    whereami_browser(wlabel);
4425    SUMA_RETURNe;
4426 }
4427 
4428 
4429 
SUMA_wait_till_visible(Widget w,int maxms)4430 SUMA_Boolean SUMA_wait_till_visible(Widget w, int maxms)
4431 {
4432    static char FuncName[]={"SUMA_wait_till_visible"};
4433    int k, del=100, vis=0;
4434 
4435    SUMA_ENTRY;
4436 
4437    if (!w) SUMA_RETURN(NOPE);
4438 
4439    if (0 && !XtIsManaged(w)) {/* possible to return 0 because of asychrony */
4440       SUMA_S_Err("Widget not managed");
4441       SUMA_RETURN(NOPE);
4442    }
4443    if (!XtIsRealized(w)) {
4444       SUMA_S_Err("Widget not realized");
4445       SUMA_RETURN(NOPE);
4446    }
4447 
4448    if (MCW_widget_visible(w)) SUMA_RETURN(YUP);
4449    if (maxms < 0) maxms = 10000;
4450    k = 0;
4451    while ( !(vis=MCW_widget_visible(w)) && (k < maxms) ) {
4452       fprintf(stderr,".");
4453       if (k == 0) {
4454          /* try to hurry things along */
4455          XtPopup(w, XtGrabNone);
4456          XmUpdateDisplay(w ) ;
4457          XSync(XtDisplay(w), 0);
4458       }
4459       NI_sleep(del); k += del;
4460    }
4461    if (k>0) fprintf(stderr,"\n");
4462 
4463    SUMA_RETURN((SUMA_Boolean)vis);
4464 }
4465