Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

pbar.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "pbar.h"
00008 #include "xim.h"    /* for display of the colorscale in "big" mode */
00009 #include <ctype.h>
00010 
00011 static void PBAR_button_EV( Widget w, XtPointer cd, XEvent *ev, Boolean *ctd ) ;
00012 static void PBAR_bigmap_finalize( Widget w, XtPointer cd, MCW_choose_cbs *cbs );
00013 static void PBAR_big_menu_CB( Widget , XtPointer , XtPointer ) ;
00014 
00015 static int      bigmap_num=0 ;    /* 31 Jan 2003 */
00016 static char   **bigmap_name ;
00017 static rgbyte **bigmap ;
00018 
00019 static MCW_DC *myfirst_dc = NULL ;  /* 04 Feb 2003 */
00020 
00021 #undef  PBAR_callback
00022 #define PBAR_callback(pb,vv)                                            \
00023  do{ void (*pf)(MCW_pbar *,XtPointer,int) =                             \
00024       (void (*)(MCW_pbar *,XtPointer,int))(pb->pb_CB) ;                 \
00025      if( pf != NULL ) pf( pb, (XtPointer)(pb->pb_data), (int)(vv) );    \
00026  } while(0)
00027 
00028 /*----------------------------------------------------------------------
00029    Make a new paned-window color+threshold selection bar:
00030 
00031      parent  = parent Widget
00032      dc      = pointer to MCW_DC for display info
00033      npane   = initial number of panes
00034      pheight = initial height (in pixels) of each pane
00035      pmin    = min value (bottom of lowest pane)
00036      pmax    = max value (top of highest pane)
00037      cbfunc  = function to call when a change is made
00038 
00039                  void cbfunc( MCW_pbar * pbar , XtPointer cbdata , int reason )
00040 
00041      cbdata  = data for this call
00042      reason  = pbCR_COLOR --> color changed
00043                pbCR_VALUE --> value changed
00044 
00045   WARNING: this code is a mess!  Especially the parts dealing
00046            with resizing, where the geometry management of the
00047            Motif widgets must be allowed for.
00048 ------------------------------------------------------------------------*/
00049 
00050 MCW_pbar * new_MCW_pbar( Widget parent , MCW_DC * dc ,
00051                          int npane , int pheight , float pmin , float pmax ,
00052                          gen_func * cbfunc , XtPointer cbdata )
00053 
00054 {
00055    MCW_pbar * pbar ;
00056    int i , np , jm , lcol , ic , ph ;
00057    Widget frm ;
00058 
00059 ENTRY("new_MCW_pbar") ;
00060 
00061    /* sanity check */
00062 
00063    if( npane   < NPANE_MIN        || npane > NPANE_MAX ||
00064        pheight < PANE_MIN_HEIGHT  || pmin == pmax         ) RETURN( NULL );
00065 
00066    /* new pbar */
00067 
00068    lcol = dc->ovc->ncol_ov - 1 ;  /* last color available */
00069 
00070    pbar = myXtNew( MCW_pbar ) ;
00071 
00072    pbar->top = XtVaCreateWidget( "pbar" , xmBulletinBoardWidgetClass , parent ,
00073                                      XmNmarginHeight , 0 ,
00074                                      XmNmarginWidth , 0 ,
00075                                      XmNheight , npane*pheight+(npane-1)*PANE_SPACING ,
00076                                      XmNresizePolicy , XmRESIZE_ANY ,
00077                                      XmNtraversalOn , False ,
00078                                      XmNinitialResourcesPersistent , False ,
00079                                   NULL ) ;
00080 
00081    frm = XtVaCreateManagedWidget( "pbar" , xmFrameWidgetClass , pbar->top ,
00082                                      XmNshadowType , XmSHADOW_ETCHED_IN ,
00083                                   NULL ) ;
00084 
00085    pbar->panew = XtVaCreateWidget( "pbar" , xmPanedWindowWidgetClass , frm ,
00086                                       XmNsashWidth , PANE_WIDTH-2*PANE_SPACING,
00087                                       XmNsashIndent , PANE_SPACING ,
00088                                       XmNsashHeight , (npane<NPANE_NOSASH) ? SASH_HYES
00089                                                                            : SASH_HNO ,
00090                                       XmNmarginHeight , 0 ,
00091                                       XmNmarginWidth , 0 ,
00092                                       XmNspacing , PANE_SPACING ,
00093                                       XmNx , 0 , XmNy , 0 ,
00094                                       XmNtraversalOn, False ,
00095                                       XmNinitialResourcesPersistent , False ,
00096                               NULL ) ;
00097 
00098    if( check_pixmap == XmUNSPECIFIED_PIXMAP )
00099       check_pixmap = XCreatePixmapFromBitmapData(
00100                         XtDisplay(parent) , RootWindowOfScreen(XtScreen(parent)) ,
00101                         check_bits , check_width , check_height ,
00102 #if 0
00103                         1,0,
00104 #else
00105                         dc->ovc->pixov_brightest , dc->ovc->pixov_darkest ,
00106 #endif
00107                         DefaultDepthOfScreen(XtScreen(parent)) ) ;
00108 
00109    /** make the panes **/
00110 
00111    pbar->pane_hsum[0] = 0 ;  /* Dec 1997 */
00112 
00113    for( i=0 ; i < NPANE_MAX ; i++ ){
00114       ph = (i<npane) ? pheight : PANE_MIN_HEIGHT ;  /* Dec 1997 */
00115       pbar->pane_hsum[i+1] = pbar->pane_hsum[i] + ph ;
00116 
00117       pbar->panes[i] = XtVaCreateWidget(
00118                           "pbar" , xmDrawnButtonWidgetClass , pbar->panew ,
00119                               XmNpaneMinimum , PANE_MIN_HEIGHT ,
00120                               XmNallowResize , True ,
00121                               XmNheight , ph ,
00122                               XmNwidth , PANE_WIDTH,
00123                               XmNborderWidth , 0 ,
00124                               XmNmarginWidth , 0 ,
00125                               XmNmarginHeight , 0 ,
00126                               XmNhighlightThickness , 0 ,
00127                               XmNpushButtonEnabled , True ,
00128                               XmNshadowThickness , 1 ,
00129                               XmNuserData , (XtPointer) pbar ,
00130                               XmNtraversalOn , False,
00131                               XmNinitialResourcesPersistent , False ,
00132                             NULL ) ;
00133 
00134       if( i < npane ) XtManageChild( pbar->panes[i] ) ;
00135 
00136       XtAddCallback( pbar->panes[i] , XmNactivateCallback , PBAR_click_CB , dc ) ;
00137       XtAddCallback( pbar->panes[i] , XmNresizeCallback , PBAR_resize_CB , pbar ) ;
00138 
00139       pbar->ov_index[i] = ic = MIN( lcol , i+1 ) ;
00140       MCW_set_widget_bg( pbar->panes[i] , NULL , dc->ovc->pix_ov[ic] ) ;
00141    }
00142    XtManageChild( pbar->panew ) ;
00143 
00144    pbar->panes_sum    = pheight * npane ;
00145    pbar->num_panes    = npane ;
00146    pbar->panew_height = pbar->panes_sum + (npane-1)*PANE_SPACING ;
00147 
00148    pbar->pb_CB     = cbfunc ;
00149    pbar->pb_data   = cbdata ;
00150    pbar->dc        = dc ;
00151    pbar->renew_all = 0 ;
00152 
00153    /** make the labels **/
00154 
00155    for( i=0 ; i <= NPANE_MAX ; i++ ){
00156       int yy ;
00157       char buf[16] ;
00158 
00159       pbar->pval[i] = pmax - i * (pmax-pmin)/npane ;
00160       PBAR_labelize( pbar->pval[i] , buf ) ;
00161 
00162       if( i < npane ){
00163          yy = i * (pheight+PANE_SPACING) ;
00164          if( i > 0 ) yy -= PANE_LOFF ;
00165       } else {
00166 #if 1
00167          yy = pbar->panew_height - PANE_LOFF + PANE_SPACING ;
00168 #else
00169          yy = pbar->panew_height - 2 * PANE_LOFF + PANE_SPACING ;
00170 #endif
00171       }
00172 
00173       pbar->labels[i] =  XtVaCreateWidget(
00174                             " XXXXX" , xmLabelWidgetClass , pbar->top ,
00175                                XmNrecomputeSize , False ,
00176                                XmNx , PANE_WIDTH+PANE_SPACING+4 ,
00177                                XmNy , yy ,
00178                                XmNborderWidth , 0 ,
00179                                XmNmarginWidth , 0 ,
00180                                XmNmarginHeight , 0 ,
00181                                XmNalignment , XmALIGNMENT_BEGINNING ,
00182                                XmNhighlightThickness , 0 ,
00183                                XmNshadowThickness , 0 ,
00184                              NULL ) ;
00185 
00186       if( KEEP_LABEL(i,npane) ){
00187          XtManageChild( pbar->labels[i] ) ;
00188          MCW_set_widget_label( pbar->labels[i] , buf ) ;
00189       }
00190    }
00191    /*-- add _save & mode stuff --*/
00192 
00193    for( np=NPANE_MIN ; np <= NPANE_MAX ; np++ ){
00194       for( i=0 ; i <= np ; i++ )
00195          for( jm=0 ; jm < PANE_MAXMODE ; jm++ )
00196             pbar->pval_save[np][i][jm] = pmax - i * (pmax-pmin)/np ;
00197 
00198       for( i=0 ; i < np ; i++ )
00199          for( jm=0 ; jm < PANE_MAXMODE ; jm++ )
00200             pbar->ovin_save[np][i][jm] = MIN(lcol,i+1) ;
00201    }
00202    pbar->update_me    = 0 ;
00203    pbar->mode         = 0 ;
00204    pbar->hide_changes = 0 ;
00205    pbar->keep_pval    = 0 ;  /* Dec 1997 */
00206 
00207    for( jm=0 ; jm < PANE_MAXMODE ; jm++ )
00208       pbar->npan_save[jm] = pbar->num_panes ;
00209 
00210    /*-- 31 Jan 2003: create palettes to choose between for "big" mode --*/
00211 
00212    if( myfirst_dc == NULL ) myfirst_dc = dc ;  /* 04 Feb 2003 */
00213 
00214    PBAR_add_bigmap(NULL,NULL) ;
00215 
00216    /*-- 30 Jan 2003: setup the "big" mode for 128 colors --*/
00217 
00218    pbar->bigmode      = 0 ;
00219    pbar->bigflip      = 0 ;
00220    pbar->bigrota      = 0 ;
00221    pbar->bigset       = 0 ;
00222    pbar->bigmap_index = 0 ;
00223    pbar->bigbot  = -1.0 ; pbar->bigtop = 1.0 ;
00224    pbar->bigxim  = NULL ;
00225    for( i=0 ; i < NPANE_BIG ; i++ )
00226      pbar->bigcolor[i] = bigmap[0][i] ;
00227    pbar->bigname = bigmap_name[0] ;
00228 
00229    XtAddCallback( pbar->panes[0], XmNexposeCallback, PBAR_bigexpose_CB, pbar ) ;
00230 
00231    XtInsertEventHandler( pbar->panes[0] ,
00232                          ButtonPressMask ,      /* get button presses */
00233                          FALSE ,                /* nonmaskable events? */
00234                          PBAR_button_EV ,       /* event handler */
00235                          (XtPointer) pbar ,     /* client data */
00236                          XtListTail ) ;         /* last in queue */
00237 
00238    /* 11 Feb 2003: create a popup menu for doing stuff */
00239 
00240    pbar->bigfac  = 0.0 ;
00241 #ifdef BAD_BUTTON3_POPUPS   /* 21 Jul 2003 */
00242    pbar->big_menu = XmCreatePopupMenu( pbar->top      , "menu" , NULL , 0 ) ;
00243 #else
00244    pbar->big_menu = XmCreatePopupMenu( pbar->panes[0] , "menu" , NULL , 0 ) ;
00245 #endif
00246 
00247    SAVEUNDERIZE(XtParent(pbar->big_menu)) ;
00248    VISIBILIZE_WHEN_MAPPED(pbar->big_menu) ;
00249 
00250    pbar->big_label = XtVaCreateManagedWidget(
00251                      "menu" , xmLabelWidgetClass , pbar->big_menu ,
00252                         XmNinitialResourcesPersistent , False ,
00253                      NULL ) ;
00254 
00255    (void) XtVaCreateManagedWidget( "menu",
00256                                     xmSeparatorWidgetClass, pbar->big_menu ,
00257                                        XmNseparatorType , XmSINGLE_LINE ,
00258                                     NULL ) ;
00259 
00260    pbar->big_choose_pb = XtVaCreateManagedWidget(
00261                            "menu" , xmPushButtonWidgetClass , pbar->big_menu ,
00262                              LABEL_ARG("Choose Colorscale") ,
00263                              XmNtraversalOn , False ,
00264                              XmNinitialResourcesPersistent , False ,
00265                           NULL ) ;
00266    XtAddCallback( pbar->big_choose_pb, XmNactivateCallback, PBAR_big_menu_CB , pbar ) ;
00267 
00268    /*-- go home --*/
00269 
00270    XtManageChild( pbar->top ) ;
00271    RETURN( pbar );
00272 }
00273 
00274 /*-------------------------------------------------------------------*/
00275 /*! Read pbar bigmaps ordered by environment */
00276 
00277 static void PBAR_enviro_bigmaps( MCW_DC *dc )
00278 {
00279    static int first=1 ;
00280    char nnn[32] , *eh , *en , *fn , bn[2000] ;
00281    int ii ;
00282 
00283 ENTRY("PBAR_enviro_bigmaps") ;
00284 
00285    if( !first || dc == NULL ) EXRETURN ;
00286    first = 0 ;
00287 
00288    eh = getenv("HOME") ;
00289    for( ii=1 ; ii <= 99 ; ii++ ){
00290      sprintf(nnn,"AFNI_COLORSCALE_%02d",ii) ;
00291      en = getenv(nnn) ;              /** 21 Apr 2005: check alternatives **/
00292      if( en == NULL            ){sprintf(nnn,"AFNI_COLOR_SCALE_%02d",ii); en=getenv(nnn);}
00293      if( en == NULL && ii <= 9 ){sprintf(nnn,"AFNI_COLORSCALE_O%1d" ,ii); en=getenv(nnn);}
00294      if( en == NULL && ii <= 9 ){sprintf(nnn,"AFNI_COLORSCALE_%1d"  ,ii); en=getenv(nnn);}
00295      if( en != NULL ){
00296        if( THD_is_file(en) ){
00297          fn = en ;
00298        } else if( eh != NULL ){
00299          sprintf(bn,"%.999s/%.999s",eh,en) ; fn = bn ;
00300        } else {
00301          continue ;  /* skip this name */
00302        }
00303        PBAR_read_bigmap( fn , dc ) ;
00304      }
00305    }
00306    EXRETURN ;
00307 }
00308 
00309 /*-----------------------------------------------------------------------*/
00310 /*! Add a color map for "big" mode.
00311 -------------------------------------------------------------------------*/
00312 
00313 void PBAR_add_bigmap( char *name , rgbyte *cmap )
00314 {
00315    int ii , nn , kk ;
00316 
00317 ENTRY("PBAR_add_bigmap") ;
00318 
00319    /* if needed, setup initial colorscale tables */
00320 
00321 #define NBIGMAP_INIT 7                           /* # of initial colorscales */
00322 #define NBIG_GAP     6
00323 #define NBIG_MBOT    (NPANE_BIG/2-NBIG_GAP)
00324 #define NBIG_MTOP    (NPANE_BIG/2+NBIG_GAP)
00325 #define AJJ_RED        0.0
00326 #define AJJ_YEL       60.0
00327 #define AJJ_GRN      120.0
00328 #define AJJ_CYN      180.0
00329 #define AJJ_BLU      240.0
00330 #define AJJ_PUR      300.0
00331    if( bigmap_num == 0 ){
00332      bigmap_num     = NBIGMAP_INIT ;
00333      bigmap_name    = (char **) malloc(sizeof(char *)*NBIGMAP_INIT) ;
00334      bigmap_name[0] = strdup("Spectrum:red_to_blue") ;
00335      bigmap_name[1] = strdup("Spectrum:red_to_blue+gap") ;
00336      bigmap_name[2] = strdup("Spectrum:yellow_to_cyan") ;
00337      bigmap_name[3] = strdup("Spectrum:yellow_to_cyan+gap") ;
00338      bigmap_name[4] = strdup("Spectrum:yellow_to_red") ;
00339      bigmap_name[5] = strdup("Color_circle_AJJ") ;
00340      bigmap_name[6] = strdup("Color_circle_ZSS") ;
00341      bigmap         = (rgbyte **) malloc(sizeof(rgbyte *)*NBIGMAP_INIT) ;
00342      bigmap[0]      = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00343      bigmap[1]      = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00344      bigmap[2]      = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00345      bigmap[3]      = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00346      bigmap[4]      = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00347      bigmap[5]      = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00348      bigmap[6]      = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00349      for( ii=0 ; ii < NPANE_BIG ; ii++ ){
00350        bigmap[0][ii] = DC_spectrum_AJJ(      ii*((AJJ_BLU+8.0)/(NPANE_BIG-1.0))-4.0,0.8);
00351        bigmap[4][ii] = DC_spectrum_AJJ( 60.0-ii*(AJJ_YEL/(NPANE_BIG-1.0))          ,0.7);
00352        bigmap[5][ii] = DC_spectrum_AJJ(      ii*(360.0  /(NPANE_BIG-1.0))          ,0.8);
00353        bigmap[6][ii] = DC_spectrum_ZSS(360.0-ii*(360.0  /(NPANE_BIG-1.0))          ,1.0);
00354        if( ii < NBIG_MBOT ){
00355          bigmap[1][ii] = DC_spectrum_AJJ(         ii*(AJJ_YEL/(NBIG_MBOT-1.0)) , 0.8 );
00356          bigmap[2][ii] = DC_spectrum_AJJ( AJJ_YEL-ii*(AJJ_YEL/(NBIG_MBOT-1.0)) , 0.8 );
00357          bigmap[3][ii] = bigmap[2][ii] ;
00358        } else if( ii > NBIG_MTOP ){
00359          bigmap[1][ii] = DC_spectrum_AJJ( AJJ_CYN+(ii-NBIG_MTOP-1)*(60.0/(NPANE_BIG-NBIG_MTOP-2.0)),0.8);
00360          bigmap[2][ii] = DC_spectrum_AJJ( AJJ_BLU-(ii-NBIG_MTOP-1)*(60.0/(NPANE_BIG-NBIG_MTOP-2.0)),0.8);
00361          bigmap[3][ii] = bigmap[2][ii] ;
00362        } else {
00363          bigmap[1][ii].r = bigmap[1][ii].g = bigmap[1][ii].b = 0 ;
00364          bigmap[2][ii]   = DC_spectrum_AJJ( 360.0-(ii-NBIG_MBOT+1)*(120.0/(NBIG_MTOP-NBIG_MBOT+2.0)),0.8) ;
00365          bigmap[3][ii].r = bigmap[3][ii].g = bigmap[3][ii].b = 0 ;
00366        }
00367      }
00368      PBAR_enviro_bigmaps( myfirst_dc ) ;
00369    }
00370 
00371    if( name == NULL || *name == '\0' || cmap == NULL ) EXRETURN ;
00372 
00373    /* 07 Feb 2003: see if name is a duplicate;
00374                    if so, replace the old colorscale */
00375 
00376    for( nn=0 ; nn < bigmap_num ; nn++ )
00377      if( strcmp(name,bigmap_name[nn]) == 0 ) break ;
00378 
00379    if( nn == bigmap_num ){   /* is NOT a replacement */
00380      kk          = nn+1 ;    /* so make room for it */
00381      bigmap_num  = kk ;
00382      bigmap_name = (char **) realloc(bigmap_name,sizeof(char *)*kk);
00383      bigmap      = (rgbyte **) realloc(bigmap,sizeof(rgbyte *)*kk);
00384      bigmap[nn]  = (rgbyte *) malloc(sizeof(rgbyte)*NPANE_BIG) ;
00385 
00386    } else {                  /* is a replacment */
00387      free(bigmap_name[nn]) ; /* so just free old name string */
00388    }
00389 
00390    bigmap_name[nn] = strdup(name) ;
00391 
00392    for( ii=0 ; ii < NPANE_BIG ; ii++ ) bigmap[nn][ii] = cmap[ii] ;
00393 
00394    POPDOWN_strlist_chooser ; EXRETURN ;
00395 }
00396 
00397 /*-----------------------------------------------------------------------*/
00398 
00399 void PBAR_make_bigmap( char *name,
00400                        int neq, float *val, rgbyte *col, MCW_DC *dc )
00401 {
00402    int ii,jj ;
00403    float fr,fg,top,bot,del,vv ;
00404    rgbyte map[NPANE_BIG] ;
00405 
00406 ENTRY("PBAR_make_bigmap") ;
00407 
00408    if( neq < 2 || val == NULL || col == NULL || dc == NULL ){
00409      STATUS("bad inputs") ; EXRETURN ;
00410    }
00411 
00412    /* bubble sort val,col pairs */
00413 
00414    do{
00415     for( jj=ii=0 ; ii < neq-1 ; ii++ ){
00416      if( val[ii+1] > val[ii] ){
00417        fr     = val[ii] ; val[ii] = val[ii+1] ; val[ii+1] = fr     ;
00418        map[0] = col[ii] ; col[ii] = col[ii+1] ; col[ii+1] = map[0] ;
00419        jj = 1 ;
00420      }
00421     }
00422    } while(jj) ;
00423 
00424    top = val[0] ; bot = val[neq-1] ; if( bot >= top ) EXRETURN ;
00425    del = (top-bot)/(NPANE_BIG-1) ;
00426 
00427    for( jj=ii=0 ; ii < NPANE_BIG ; ii++ ){
00428      vv = top - ii*del ;
00429      for( ; jj < neq-1 ; jj++ )
00430        if( vv <= val[jj] && vv >= val[jj+1] ) break ;
00431      if( vv >= val[jj] ){
00432        map[ii] = col[jj] ;
00433      } else if( vv <= val[jj+1] ){
00434        map[ii] = col[jj+1] ;
00435      } else {
00436        fr = (vv-val[jj+1])/(val[jj]-val[jj+1]) ;
00437        fg = 1.0-fr ;
00438        map[ii].r = (byte)(fr*col[jj].r + fg*col[jj+1].r + 0.5) ;
00439        map[ii].g = (byte)(fr*col[jj].g + fg*col[jj+1].g + 0.5) ;
00440        map[ii].b = (byte)(fr*col[jj].b + fg*col[jj+1].b + 0.5) ;
00441      }
00442    }
00443 
00444    PBAR_add_bigmap( name, map ) ; EXRETURN ;
00445 }
00446 
00447 /*-----------------------------------------------------------------------*/
00448 #define NSBUF 128
00449 
00450 int PBAR_define_bigmap( char *cmd )
00451 {
00452   int ii , neq=0 , nonum=0 ;
00453   char name[NSBUF], eqn[NSBUF] , rhs[NSBUF] ;
00454   float  val[NPANE_BIG] , fr,fg,fb ;
00455   rgbyte col[NPANE_BIG] ;
00456 
00457 ENTRY("PBAR_define_bigmap") ;
00458 
00459   if( myfirst_dc == NULL ) RETURN(-1) ;
00460 
00461   name[0] = '\0' ; ii = 0 ;
00462   sscanf(cmd,"%127s%n",name,&ii) ;
00463   if( *name == '\0' || ii == 0 ) RETURN(-1) ;
00464   cmd += ii ;
00465 
00466   /* get lines of form "value=colordef" */
00467 
00468   while( neq < NPANE_BIG ){
00469     eqn[0] = '\0' ; ii = 0 ;
00470     sscanf(cmd,"%127s%n",eqn,&ii) ;
00471     if( *eqn == '\0' || ii == 0 ) break ;   /* exit loop */
00472     cmd += ii ;
00473     if( neq == 0 && (isalpha(eqn[0]) || eqn[0]=='#') ) nonum = 1 ;
00474     rhs[0] = '\0' ; ii = 0 ;
00475     if( !nonum ) sscanf(eqn,"%f=%s%n",val+neq,rhs,&ii) ;
00476     else         sscanf(eqn,"%s%n"           ,rhs,&ii) ;
00477     if( *rhs == '\0' || ii == 0 ) RETURN(-1);               /* bad */
00478     ii = DC_parse_color( myfirst_dc , rhs, &fr,&fg,&fb ) ;
00479     if( ii ) RETURN(-1);                                    /* bad */
00480     col[neq].r = (byte)(255.0*fr+0.5) ;
00481     col[neq].g = (byte)(255.0*fg+0.5) ;
00482     col[neq].b = (byte)(255.0*fb+0.5) ; neq++ ;
00483   }
00484 
00485   if( nonum )                    /* supply numbers, if missing */
00486     for( ii=0 ; ii < neq ; ii++ ) val[ii] = neq-ii ;
00487 
00488   PBAR_make_bigmap( name , neq, val, col, myfirst_dc ); RETURN(0);
00489 }
00490 
00491 /*-----------------------------------------------------------------------*/
00492 
00493 void PBAR_read_bigmap( char *fname , MCW_DC *dc )
00494 {
00495   int ii , neq=0 , nonum=0 , yeseq=0 ;
00496   char name[NSBUF], lhs[NSBUF],rhs[NSBUF],mid[NSBUF],line[2*NSBUF] , *cpt ;
00497   float  val[NPANE_BIG] , fr,fg,fb , top,bot,del,vv ;
00498   rgbyte col[NPANE_BIG] ;
00499   FILE *fp ;
00500 
00501 ENTRY("PBAR_read_bigmap") ;
00502 
00503   if( fname == NULL || *fname == '\0' || dc == NULL ) EXRETURN ;
00504 
00505   STATUS(fname) ;
00506   fp = fopen(fname,"r"); if( fp == NULL ){
00507     STATUS("can't open file") ; EXRETURN;
00508   }
00509 
00510   /* get name */
00511 
00512   do{
00513     cpt = fgets( line , 2*NSBUF , fp ) ;
00514     if( cpt == NULL ){ STATUS("can't read title line"); fclose(fp); EXRETURN; }
00515     name[0] = '\0' ;
00516     sscanf(line,"%127s",name) ;
00517   } while( name[0]=='\0' || name[0]=='!' || (name[0]=='/' && name[1]=='/') ) ;
00518 
00519   /* get lines of form "value = colordef" */
00520 
00521   while( neq < NPANE_BIG ){
00522     cpt = fgets( line , 2*NSBUF , fp ) ;
00523     if( cpt == NULL ){ STATUS("!!end of file"); break; } /* exit while loop */
00524     lhs[0] = mid[0] = rhs[0] = '\0' ;
00525     sscanf(line,"%127s %127s %127s",lhs,mid,rhs) ;
00526     if( lhs[0]=='\0' || lhs[0]=='!' || (lhs[0]=='/' && lhs[1]=='/') ) continue;
00527     STATUS(line) ;
00528 
00529          if( neq == 0 && (isalpha(lhs[0]) || lhs[0]=='#') ) nonum = 1 ;
00530     else if( neq == 0 && strchr(lhs,'=') != NULL          ) yeseq = 1 ;
00531 
00532     if( yeseq ){
00533       val[neq] = strtod(lhs,&cpt) ;
00534       if( *cpt != '\0' ) cpt++ ;     /* skip ending character */
00535     } else if( !nonum ){
00536       val[neq] = strtod(lhs,&cpt) ;
00537       if( val[neq] == 0.0 && *cpt != '\0' ){
00538         STATUS("!!bad number") ;
00539         fprintf(stderr,"** %s: %s is a bad number\n",fname,lhs); continue;
00540       }
00541       cpt = (mid[0] == '=') ? rhs : mid ;  /* color is string #2 or #3 */
00542     } else {
00543       cpt = lhs ;                          /* no number => lhs is the color */
00544     }
00545     if( *cpt == '\0' ){ STATUS("no color string?"); continue; } /* not good */
00546 
00547     ii = DC_parse_color( dc , cpt , &fr,&fg,&fb ) ;
00548     if( ii ){
00549       STATUS("!!bad color") ;
00550       fprintf(stderr,"** %s: %s is bad colorname\n",fname,rhs); continue;
00551     }
00552     col[neq].r = (byte)(255.0*fr+0.5) ;
00553     col[neq].g = (byte)(255.0*fg+0.5) ;
00554     col[neq].b = (byte)(255.0*fb+0.5) ; neq++ ;
00555   } /* end of loop over color lines */
00556   fclose(fp) ;
00557 
00558   if( nonum ){                    /* supply numbers, if missing */
00559     for( ii=0 ; ii < neq ; ii++ )
00560       val[ii] = neq-ii ;
00561   }
00562 
00563   PBAR_make_bigmap( name , neq, val, col, dc ) ; EXRETURN ;
00564 }
00565 
00566 /*-----------------------------------------------------------------------*/
00567 /*! Button 3 event handler for pane #0 of a pbar, used only when
00568     in "big" mode, to select a color map.
00569 -------------------------------------------------------------------------*/
00570 
00571 static void PBAR_button_EV( Widget w, XtPointer cd, XEvent *ev, Boolean *ctd )
00572 {
00573    MCW_pbar *pbar = (MCW_pbar *) cd ;
00574    XButtonEvent *bev = (XButtonEvent *) ev ;
00575    int hh , ii , rr,gg,bb ;
00576    float yy ;
00577 
00578 ENTRY("PBAR_button_EV") ;
00579 
00580 #if 0
00581    if( bev->button == Button2 )
00582      XUngrabPointer( bev->display , CurrentTime ) ;
00583 #endif
00584 
00585    if( pbar == NULL || !pbar->bigmode ) EXRETURN ;
00586 
00587    /* get current position, value, and color */
00588 
00589    MCW_widget_geom( pbar->panes[0] , NULL,&hh , NULL,NULL ) ;
00590    ii = (int)( ((NPANE_BIG-1.0)*bev->y)/(hh-1) + 0.5 ) ;      /* color index */
00591    rr = (int)pbar->bigcolor[ii].r ;                           /* color */
00592    gg = (int)pbar->bigcolor[ii].g ;
00593    bb = (int)pbar->bigcolor[ii].b ;
00594 
00595    yy = ii/(NPANE_BIG-1.0) ;
00596    yy = (yy * pbar->bigbot + (1.0-yy) * pbar->bigtop) ;
00597    if( pbar->bigfac != 0.0 ) yy *= pbar->bigfac ;             /* value */
00598 
00599    switch( bev->button ){
00600 
00601      case Button3:{                  /* 11 Feb 2003: popup a menu */
00602        char str[256] ;               /* but first, put informative label on it */
00603        sprintf(str,
00604                "value = %s\nRGB=(%03d,%03d,%03d)" ,
00605                AV_uformat_fval(yy) , rr,gg,bb      ) ;
00606        MCW_set_widget_label( pbar->big_label , str ) ;
00607 
00608        XmMenuPosition( pbar->big_menu , bev ) ; /* where */
00609        XtManageChild ( pbar->big_menu ) ;       /* popup */
00610      }
00611      break ;
00612 
00613 #if 0
00614      case Button2:{
00615        ii = (int)( ((NPANE_BIG-1.0)*bev->y)/(hh-1) + 0.5 ) ;
00616        fprintf(stderr,"Color[%03d]: R=%03d G=%03d B=%03d #%02x%02x%02x\n",
00617                ii , (int)pbar->bigcolor[ii].r          ,
00618                     (int)pbar->bigcolor[ii].g          ,
00619                     (int)pbar->bigcolor[ii].b          ,
00620                     (unsigned int)pbar->bigcolor[ii].r ,
00621                     (unsigned int)pbar->bigcolor[ii].g ,
00622                     (unsigned int)pbar->bigcolor[ii].b  ) ;
00623      }
00624      break ;
00625 #endif
00626 
00627    }
00628    EXRETURN ;
00629 }
00630 
00631 /*--------------------------------------------------------------------*/
00632 
00633 static void PBAR_big_menu_CB( Widget w , XtPointer cd , XtPointer qd )
00634 {
00635    MCW_pbar *pbar = (MCW_pbar *) cd ;
00636 
00637 ENTRY("PBAR_big_menu_CB") ;
00638 
00639    if( pbar == NULL || !pbar->bigmode ) EXRETURN ;
00640 
00641    if( w == pbar->big_choose_pb ){
00642      MCW_choose_strlist( w , "Choose Colorscale" ,
00643                          bigmap_num ,
00644                          pbar->bigmap_index ,
00645                          bigmap_name ,
00646                          PBAR_bigmap_finalize , cd ) ;
00647    }
00648 
00649    EXRETURN ;
00650 }
00651 
00652 /*--------------------------------------------------------------------*/
00653 
00654 static void PBAR_bigmap_finalize( Widget w, XtPointer cd, MCW_choose_cbs *cbs )
00655 {
00656    MCW_pbar *pbar = (MCW_pbar *) cd ;
00657    int ii , ind=cbs->ival ;
00658 
00659 ENTRY("PBAR_bigmap_finalize") ;
00660 
00661    if( ind < 0 || ind >= bigmap_num || !pbar->bigmode ){
00662      XBell( pbar->dc->display,100); POPDOWN_strlist_chooser; EXRETURN;
00663    }
00664 
00665    pbar->bigflip      = 0 ;                 /* 07 Feb 2004 */
00666    pbar->bigrota      = 0 ;
00667    pbar->bigname      = bigmap_name[ind] ;  /* 22 Oct 2003 */
00668    pbar->bigmap_index = ind ;
00669    for( ii=0 ; ii < NPANE_BIG ; ii++ )
00670      pbar->bigcolor[ii] = bigmap[ind][ii] ;
00671 
00672    MCW_kill_XImage(pbar->bigxim) ; pbar->bigxim = NULL ;
00673    PBAR_bigexpose_CB(NULL,pbar,NULL) ;
00674    if( XtIsRealized(pbar->panes[0]) )
00675      PBAR_callback(pbar,pbCR_COLOR) ;
00676 
00677    EXRETURN ;
00678 }
00679 
00680 /*--------------------------------------------------------------------*/
00681 
00682 void PBAR_set_bigmap( MCW_pbar *pbar , char *bnam )  /* 03 Feb 2003 */
00683 {
00684    int ii ;
00685 
00686 ENTRY("PBAR_set_bigmap") ;
00687 
00688    if( pbar == NULL || bnam == NULL || *bnam == '\0' ) EXRETURN ;
00689    for( ii=0 ; ii < bigmap_num ; ii++ )
00690      if( strcmp(bnam,bigmap_name[ii]) == 0 ) break ;
00691    if( ii < bigmap_num ){
00692      MCW_choose_cbs cbs ;
00693      cbs.ival = ii ;
00694      PBAR_bigmap_finalize( NULL , pbar , &cbs ) ;
00695    }
00696    EXRETURN ;
00697 }
00698 
00699 /*--------------------------------------------------------------------*/
00700 
00701 char * PBAR_get_bigmap( MCW_pbar *pbar )    /* 03 Feb 2003 */
00702 {
00703    return bigmap_name[pbar->bigmap_index] ;
00704 }
00705 
00706 /*--------------------------------------------------------------------*/
00707 /*! Actually redisplay pane #0 in "big" mode.
00708 ----------------------------------------------------------------------*/
00709 
00710 void PBAR_bigexpose_CB( Widget w , XtPointer cd , XtPointer cb )
00711 {
00712    MCW_pbar *pbar = (MCW_pbar *) cd ;
00713 
00714 ENTRY("PBAR_bigexpose_CB") ;
00715 
00716    if( pbar == NULL || !pbar->bigmode ) EXRETURN ;
00717 
00718    /* make an image of what we want to see */
00719 
00720    if( pbar->bigxim == NULL ){
00721      int ww,hh , ii , jj , kk ;
00722      MRI_IMAGE *cim ;
00723      XImage    *xim ;
00724      byte      *car , r,g,b ;
00725 
00726      MCW_widget_geom( pbar->panes[0] , &ww,&hh , NULL,NULL ) ;
00727      cim = mri_new( ww,NPANE_BIG , MRI_rgb ) ;
00728      car = MRI_RGB_PTR(cim) ;
00729      for( kk=ii=0 ; ii < NPANE_BIG ; ii++ ){
00730        r=pbar->bigcolor[ii].r; g= pbar->bigcolor[ii].g; b=pbar->bigcolor[ii].b;
00731        if( r > 0 || g > 0 || b > 0 ){
00732          for( jj=0 ; jj < ww ; jj++ ){
00733            car[kk++] = r; car[kk++] = g; car[kk++] = b;
00734          }
00735        } else {                                            /* 06 Feb 2003 */
00736          for( jj=0 ; jj < ww ; jj++ ){
00737            car[kk++]=128; car[kk++]=128; car[kk++]=128;
00738          }
00739        }
00740      }
00741      xim = mri_to_XImage( pbar->dc , cim ) ;
00742      pbar->bigxim = resize_XImage( pbar->dc , xim , ww,hh ) ;
00743      MCW_kill_XImage(xim) ; mri_free(cim) ;
00744    }
00745 
00746    /* actually show the image to the window pane */
00747 
00748    if( XtIsRealized(pbar->panes[0]) )
00749      XPutImage( pbar->dc->display , XtWindow(pbar->panes[0]) ,
00750                 pbar->dc->origGC , pbar->bigxim , 0,0,0,0 ,
00751                 pbar->bigxim->width , pbar->bigxim->height ) ;
00752 
00753    EXRETURN ;
00754 }
00755 
00756 /*--------------------------------------------------------------------*/
00757 /*! Set "big" mode in the pbar -- 30 Jan 2003 - RWCox.
00758 ----------------------------------------------------------------------*/
00759 
00760 void PBAR_set_bigmode( MCW_pbar *pbar, int bmode, float bot,float top )
00761 {
00762 ENTRY("PBAR_set_bigmode") ;
00763    if( bmode && bot < top ){ pbar->bigbot = bot; pbar->bigtop = top; }
00764    pbar->bigmode   = bmode ;
00765    pbar->update_me = 1 ;
00766    update_MCW_pbar( pbar ) ;
00767    EXRETURN ;
00768 }
00769 
00770 /*--------------------------------------------------------------------*/
00771 
00772 static void PBAR_show_bigmode( MCW_pbar *pbar )  /* 30 Jan 2003 */
00773 {
00774    int ii , yy ;
00775    char buf[16] ;
00776 
00777 ENTRY("PBAR_show_bigmode") ;
00778 
00779    if( pbar == NULL || !pbar->bigmode ) EXRETURN ;
00780 
00781    if( !pbar->bigset ){   /* set up big mode */
00782 
00783      if( pbar->hide_changes ) XtUnmapWidget( pbar->top ) ;
00784 
00785      /* turn off all but 1 pane and all but 2 labels */
00786 
00787      XtManageChild( pbar->labels[0] ) ;
00788      XtManageChild( pbar->labels[1] ) ;
00789      for( ii=2 ; ii <= NPANE_MAX ; ii++ )
00790        XtUnmanageChild( pbar->labels[ii] ) ;
00791      XtManageChild( pbar->panes[0] ) ;
00792      for( ii=1 ; ii < NPANE_MAX ; ii++ )
00793        XtUnmanageChild( pbar->panes[ii] ) ;
00794      XtVaSetValues( pbar->panes[0] , XmNheight,pbar->panew_height , NULL ) ;
00795      XtVaSetValues( pbar->panew    , XmNheight,pbar->panew_height , NULL ) ;
00796      XtVaSetValues( pbar->top      , XmNheight,pbar->panew_height , NULL ) ;
00797 
00798      if( pbar->hide_changes ) XtMapWidget( pbar->top ) ;
00799 
00800      MCW_widget_geom( pbar->panes[0] , NULL,NULL,NULL , &yy ) ;
00801      XtVaSetValues( pbar->labels[0] , XmNy , yy , NULL ) ;
00802      PBAR_labelize( pbar->bigtop , buf ) ;
00803      MCW_set_widget_label( pbar->labels[0] , buf ) ;
00804 
00805      yy = pbar->panew_height - PANE_LOFF + PANE_SPACING ;
00806      XtVaSetValues( pbar->labels[1] , XmNy , yy , NULL ) ;
00807      PBAR_labelize( pbar->bigbot , buf ) ;
00808      MCW_set_widget_label( pbar->labels[1] , buf ) ;
00809 
00810      pbar->bigset = 1 ;
00811    }
00812 
00813    /* show the thing */
00814 
00815    PBAR_bigexpose_CB( NULL , pbar , NULL ) ;
00816    EXRETURN ;
00817 }
00818 
00819 /*--------------------------------------------------------------------
00820    make a label for the edge out of the floating value
00821 ----------------------------------------------------------------------*/
00822 
00823 void PBAR_labelize( float val , char * buf )
00824 {
00825    float aval = fabs(val) ;
00826    char prefix[4] ;
00827 
00828    if( val == 0.0  ){ strcpy(buf," 0") ; return ; }
00829 
00830    if( val > 0.0 ) strcpy(prefix," ") ;
00831    else            strcpy(prefix,"-") ;
00832 
00833         if( aval <= 9.994 ) sprintf(buf,"%s%4.2f",prefix,aval) ;
00834    else if( aval <= 99.94 ) sprintf(buf,"%s%4.1f",prefix,aval) ;
00835    else                     sprintf(buf,"%s%4f"  ,prefix,aval) ;
00836    return ;
00837 }
00838 
00839 /*--------------------------------------------------------------------*/
00840 
00841 void PBAR_flip( MCW_pbar *pbar )  /* 07 Feb 2004 */
00842 {
00843    rgbyte tc ; int ip ;
00844 
00845 ENTRY("PBAR_flip") ;
00846 
00847    if( pbar == NULL || !pbar->bigmode ) EXRETURN ;
00848 
00849    for( ip=0 ; ip < NPANE_BIG/2 ; ip++ ){
00850      tc = pbar->bigcolor[ip] ;
00851      pbar->bigcolor[ip] = pbar->bigcolor[NPANE_BIG-1-ip] ;
00852      pbar->bigcolor[NPANE_BIG-1-ip] = tc ;
00853    }
00854    MCW_kill_XImage(pbar->bigxim) ; pbar->bigxim = NULL ;
00855    PBAR_bigexpose_CB( NULL , pbar , NULL ) ;
00856    pbar->bigflip = ! pbar->bigflip ;
00857    EXRETURN ;
00858 }
00859 
00860 /*--------------------------------------------------------------------
00861   pbar pane was clicked --> set its color
00862 ----------------------------------------------------------------------*/
00863 
00864 void PBAR_click_CB( Widget w , XtPointer cd , XtPointer cb )
00865 {
00866    MCW_DC * dc = (MCW_DC *) cd ;
00867    MCW_pbar * pbar = NULL ;
00868    int ip ;
00869 
00870 ENTRY("PBAR_click_CB") ;
00871 
00872    XtVaGetValues( w , XmNuserData , &pbar , NULL ) ;
00873    if( pbar == NULL ) EXRETURN ;
00874 
00875    if( pbar->bigmode ){   /* 30 Jan 2003: reverse color spectrum */
00876      PBAR_flip( pbar ) ;
00877      PBAR_callback(pbar,pbCR_COLOR) ;
00878      EXRETURN ;
00879    }
00880 
00881    for( ip=0 ; ip < pbar->num_panes ; ip++ ) if( pbar->panes[ip] == w ) break ;
00882    if( ip == pbar->num_panes ) EXRETURN ;
00883 
00884    MCW_choose_ovcolor( w , dc , pbar->ov_index[ip] , PBAR_set_CB , dc ) ;
00885    EXRETURN ;
00886 }
00887 
00888 /*--------------------------------------------------------------------*/
00889 
00890 void PBAR_set_panecolor( MCW_pbar *pbar , int ip , int ovc ) /* 17 Jan 2003 */
00891 {
00892 ENTRY("PBAR_set_panecolor") ;
00893    if( pbar == NULL || pbar->bigmode ) EXRETURN ;  /* 30 Jan 2003 */
00894    if( ovc > 0 ){
00895       XtVaSetValues( pbar->panes[ip] ,
00896                         XmNbackgroundPixmap , XmUNSPECIFIED_PIXMAP ,
00897                      NULL ) ;
00898       MCW_set_widget_bg( pbar->panes[ip] , NULL , pbar->dc->ovc->pix_ov[ovc] ) ;
00899    } else {
00900       XtVaSetValues( pbar->panes[ip] ,
00901                         XmNbackgroundPixmap , check_pixmap ,
00902                      NULL ) ;
00903    }
00904    EXRETURN ;
00905 }
00906 
00907 /*--------------------------------------------------------------------
00908   actual place where color of pane is changed, and user is callbacked
00909 ----------------------------------------------------------------------*/
00910 
00911 void PBAR_set_CB( Widget w , XtPointer cd , MCW_choose_cbs * cbs )
00912 {
00913    MCW_DC * dc = (MCW_DC *) cd ;
00914    MCW_pbar * pbar = NULL ;
00915    int ip , jm ;
00916 
00917 ENTRY("PBAR_set_CB") ;
00918 
00919    if( cbs->ival > 0 && cbs->ival < dc->ovc->ncol_ov ){
00920       XtVaSetValues( w , XmNbackgroundPixmap , XmUNSPECIFIED_PIXMAP , NULL ) ;
00921       MCW_set_widget_bg( w , NULL , dc->ovc->pix_ov[cbs->ival] ) ;
00922    } else {
00923       XtVaSetValues( w , XmNbackgroundPixmap , check_pixmap , NULL ) ;
00924    }
00925 
00926    XtVaGetValues( w , XmNuserData , &pbar , NULL ) ;
00927    if( pbar == NULL ) EXRETURN ;
00928    if( pbar->bigmode ) EXRETURN ;  /* 30 Jan 2003 */
00929 
00930    for( ip=0 ; ip < pbar->num_panes ; ip++ ) if( pbar->panes[ip] == w ) break ;
00931    if( ip == pbar->num_panes ) EXRETURN ;
00932 
00933    jm = pbar->mode ;
00934    pbar->ovin_save[pbar->num_panes][ip][jm] =
00935                          pbar->ov_index[ip] = cbs->ival ;
00936 
00937    PBAR_callback(pbar,pbCR_COLOR) ;
00938    EXRETURN ;
00939 }
00940 
00941 /*--------------------------------------------------------------------------
00942    Rotate the colors in a pbar by n locations (+ or -) -- 30 Mar 2001
00943 ----------------------------------------------------------------------------*/
00944 
00945 void rotate_MCW_pbar( MCW_pbar * pbar , int n )
00946 {
00947    int ip , iov[NPANE_MAX] , np , kov , jm ;
00948    Widget w ;
00949    MCW_DC * dc ;
00950 
00951 ENTRY("rotate_MCW_pbar") ;
00952 
00953    if( pbar == NULL || n == 0 ) EXRETURN ;
00954 
00955    if( pbar->bigmode ){             /* 30 Jan 2003: rotate the spectrum */
00956      rgbyte oldcolor[NPANE_BIG] ;
00957 
00958      MCW_kill_XImage(pbar->bigxim) ; pbar->bigxim = NULL ;
00959      memcpy(oldcolor,pbar->bigcolor,sizeof(rgbyte)*NPANE_BIG) ;
00960 
00961      while( n < 0 ) n += NPANE_BIG ;  /* make n positive */
00962      for( ip=0 ; ip < NPANE_BIG ; ip++ )
00963        pbar->bigcolor[ip] = oldcolor[(ip+n)%NPANE_BIG] ;
00964 
00965      PBAR_bigexpose_CB( NULL , pbar , NULL ) ;
00966 
00967      pbar->bigrota += (pbar->bigflip) ? -n : n ;  /* 07 Feb 2004 */
00968 
00969    } else {                         /* the older way */
00970      dc = pbar->dc ;
00971      np = pbar->num_panes ;
00972      jm = pbar->mode ;
00973      while( n < 0 ) n += np ;  /* make n positive */
00974      for( ip=0 ; ip < np ; ip++ ) iov[ip] = pbar->ov_index[ip] ;
00975 
00976      for( ip=0 ; ip < np ; ip++ ){
00977         kov = iov[ (ip+n)%np ] ;  /* new overlay index for ip-th pane */
00978         w   = pbar->panes[ip] ;
00979         if( kov > 0 && kov < dc->ovc->ncol_ov ){
00980            XtVaSetValues( w , XmNbackgroundPixmap , XmUNSPECIFIED_PIXMAP , NULL ) ;
00981            MCW_set_widget_bg( w , NULL , dc->ovc->pix_ov[kov] ) ;
00982         } else {
00983            XtVaSetValues( w , XmNbackgroundPixmap , check_pixmap , NULL ) ;
00984         }
00985         pbar->ovin_save[pbar->num_panes][ip][jm] =
00986                               pbar->ov_index[ip] = kov ;
00987      }
00988    }
00989 
00990    PBAR_callback(pbar,pbCR_COLOR) ;
00991 
00992    EXRETURN ;
00993 }
00994 
00995 /*--------------------------------------------------------------------
00996   callback when a pane is resized:
00997     - if the panes don't all add up to the right height, then
00998       this isn't the last callback in the sequence, and we should
00999       wait for that one to occur
01000 -----------------------------------------------------------------------*/
01001 
01002 void PBAR_resize_CB( Widget w , XtPointer cd , XtPointer cb )
01003 {
01004    MCW_pbar * pbar = (MCW_pbar *) cd ;
01005    int i , sum , hh[NPANE_MAX] , yy , ip=-1 , jm ;
01006    char buf[16] ;
01007    float pmin , pmax , val ;
01008    int alter_all = pbar->renew_all ;
01009 
01010 ENTRY("PBAR_resize_CB") ;
01011 
01012    if( pbar == NULL || pbar->renew_all < 0 ) EXRETURN ;  /* skip it */
01013    if( pbar->bigmode ) EXRETURN ;  /* 30 Jan 2003 */
01014 
01015    jm  = pbar->mode ;
01016    sum = 0 ;
01017    for( i=0 ; i < pbar->num_panes ; i++ ){
01018      MCW_widget_geom( pbar->panes[i] , NULL , &(hh[i]) , NULL,NULL ) ;
01019 #ifdef PBAR_DEBUG
01020 printf("resize: read pane # %d height=%d\n",i,hh[i]) ; fflush(stdout) ;
01021 #endif
01022      sum += hh[i] ;
01023      if( w == pbar->panes[i] ) ip = i ;
01024    }
01025 
01026    if( sum != pbar->panes_sum ){
01027       if( ip != pbar->num_panes - 1 ) EXRETURN ;
01028       pbar->panes_sum = sum ;
01029       MCW_widget_geom( pbar->panew , NULL,&(pbar->panew_height),NULL,NULL) ;
01030 #if 0
01031       XtVaSetValues( pbar->top , XmNheight , pbar->panew_height , NULL ) ;
01032 #endif
01033       alter_all = 1 ;
01034    }
01035 
01036    sum  = 0 ;
01037    pmax = pbar->pval[0] ;
01038    pmin = pbar->pval[pbar->num_panes] ;
01039 
01040    for( i=0 ; i <= pbar->num_panes ; i++ ){
01041 
01042 #if 0  /* the pre Dec 1997 way */
01043       val = pmax - sum * (pmax-pmin) / pbar->panes_sum ;
01044       if( alter_all || val != pbar->pval[i] ){
01045 #else
01046       if( alter_all || (i>0 && pbar->pane_hsum[i] != sum) ){
01047 #endif
01048 
01049          if( ! pbar->keep_pval ){  /* Dec 1997 */
01050             val = pmax - sum * (pmax-pmin) / pbar->panes_sum ;
01051             pbar->pval_save[pbar->num_panes][i][jm] =         /* reset this */
01052                                       pbar->pval[i] = val ;   /* threshold  */
01053                                                               /* to match pane size */
01054          }
01055 
01056          if( KEEP_LABEL(i,pbar->num_panes) ){
01057             if( i < pbar->num_panes ){
01058                MCW_widget_geom( pbar->panes[i] , NULL,NULL,NULL , &yy ) ;
01059                if( i > 0 ) yy -= PANE_LOFF ;
01060             } else {
01061 #if 1
01062                yy = pbar->panew_height - PANE_LOFF + PANE_SPACING ;
01063 #else
01064                yy = pbar->panew_height - 2 * PANE_LOFF + PANE_SPACING ;
01065 #endif
01066             }
01067 
01068             XtVaSetValues( pbar->labels[i] , XmNy , yy , NULL ) ;
01069             PBAR_labelize( pbar->pval[i] , buf ) ;
01070             MCW_set_widget_label( pbar->labels[i] , buf ) ;
01071          }
01072 
01073       }
01074       if( i < pbar->num_panes ) sum += hh[i] ;
01075    }
01076 
01077    pbar->pane_hsum[0] = 0 ;
01078    for( i=0 ; i < pbar->num_panes ; i++ )
01079       pbar->pane_hsum[i+1] = pbar->pane_hsum[i] + hh[i] ;
01080 
01081    PBAR_callback(pbar,pbCR_VALUE) ;
01082 
01083    pbar->renew_all = 0 ;
01084    EXRETURN ;
01085 }
01086 
01087 /*-------------------------------------------------------------------------
01088   user want to programatically alter the pbar:
01089     number of panes, and/or new array of values
01090 ---------------------------------------------------------------------------*/
01091 
01092 void update_MCW_pbar( MCW_pbar * pbar )
01093 {
01094 ENTRY("update_MCW_pbar") ;
01095    if( pbar == NULL ) EXRETURN ;
01096    if( pbar->update_me ){
01097      if( pbar->bigmode ) PBAR_show_bigmode( pbar ) ;         /* 30 Jan 2003 */
01098      else                alter_MCW_pbar( pbar , 0 , NULL ) ;
01099    }
01100    pbar->update_me = 0 ;
01101    EXRETURN ;
01102 }
01103 
01104 void alter_MCW_pbar( MCW_pbar * pbar , int new_npane , float * new_pval )
01105 {
01106    int i , npane , npane_old , sum , hh , ovc , jm ;
01107    float pmin , pmax , pval[NPANE_MAX+1] , fhh , rhh ;
01108    int was_bigset ;
01109 
01110    /* sanity check */
01111 
01112 ENTRY("alter_MCW_pbar") ;
01113 
01114    if( pbar == NULL || new_npane > NPANE_MAX ||
01115        ( new_npane < NPANE_MIN && new_npane != 0 ) ) EXRETURN ;
01116 
01117    if( pbar->bigmode ) EXRETURN ;   /* 30 Jan 2003 */
01118    was_bigset   = pbar->bigset ;
01119    pbar->bigset = 0 ;
01120 
01121    /* count of panes, old and new */
01122 
01123    jm              = pbar->mode ;
01124    npane           = (new_npane > 0) ? new_npane : pbar->num_panes ;
01125    npane_old       = pbar->num_panes ;
01126    pbar->num_panes = pbar->npan_save[jm] = npane ;
01127 
01128    if( was_bigset ) npane_old = 1 ;
01129 
01130    /*-- get new value array --*/
01131 
01132    if( new_pval == NULL ){
01133      for( i=0 ; i <= npane ; i++ ) pval[i] = pbar->pval_save[npane][i][jm] ;
01134    } else {
01135      for( i=0 ; i <= npane ; i++ ) pval[i] = new_pval[i] ;
01136    }
01137    pmax = pval[0] ;
01138    pmin = pval[npane] ;
01139 
01140    /*--- make new panes or destroy old ones ---*/
01141 
01142    if( pbar->hide_changes ) XtUnmapWidget( pbar->top ) ;
01143 
01144    /* set new pane colors */
01145 
01146    for( i=0 ; i < npane ; i++ ){
01147       ovc = pbar->ov_index[i] = pbar->ovin_save[npane][i][jm] ;
01148 
01149       if( ovc > 0 ){
01150          XtVaSetValues( pbar->panes[i] ,
01151                            XmNbackgroundPixmap , XmUNSPECIFIED_PIXMAP ,
01152                         NULL ) ;
01153          MCW_set_widget_bg( pbar->panes[i] , NULL , pbar->dc->ovc->pix_ov[ovc] ) ;
01154       } else {
01155          XtVaSetValues( pbar->panes[i] ,
01156                            XmNbackgroundPixmap , check_pixmap ,
01157                         NULL ) ;
01158       }
01159    }
01160 
01161 #ifdef PBAR_DEBUG
01162 printf("\n"); fflush(stdout) ;
01163 #endif
01164 
01165    pbar->renew_all = -1 ;  /* skip updates for the moment */
01166    for( i=0 ; i < NPANE_MAX ; i++ )
01167       XtVaSetValues( pbar->panes[i] , XmNheight , PANE_MIN_HEIGHT , NULL ) ;
01168 
01169    for( i=0 ; i <= NPANE_MAX ; i++ )
01170       if( KEEP_LABEL(i,npane) ) XtManageChild  ( pbar->labels[i] ) ;
01171       else                      XtUnmanageChild( pbar->labels[i] ) ;
01172 
01173    if( npane > npane_old ){
01174       for( i=npane_old ; i < npane ; i++ ){
01175 #ifdef PBAR_DEBUG
01176 printf("manage pane %d\n",i) ; fflush(stdout) ;
01177 #endif
01178 
01179          XtManageChild( pbar->panes[i] ) ;
01180 
01181       }
01182    } else if( npane < npane_old ){
01183       for( i=npane_old-1 ; i >= npane ; i-- ){
01184 #ifdef PBAR_DEBUG
01185 printf("unmanage pane %d\n",i) ; fflush(stdout) ;
01186 #endif
01187          XtUnmanageChild( pbar->panes[i] ) ;
01188       }
01189    }
01190 
01191    /* set new pane heights */
01192 
01193    pbar->panes_sum = pbar->panew_height - (npane-1)*PANE_SPACING ;
01194    for( i=0 ; i <= npane ; i++ ) pbar->pval[i] = pval[i] ;
01195 
01196    sum = pbar->panes_sum ;
01197    rhh = 0.0 ;
01198    for( i=0 ; i < npane-1 ; i++ ){
01199       fhh  = pbar->panes_sum * (pval[i]-pval[i+1]) / (pmax-pmin) ;
01200       hh   = (int) (rhh+fhh+0.45) ;
01201       rhh  = fhh - hh ;
01202       sum -= hh ;
01203 #ifdef PBAR_DEBUG
01204 printf("set pane %d to height %d (top=%g bot=%g float=%g rem=%g sum=%d)\n",
01205        i,hh,pval[i],pval[i+1],fhh,rhh,sum) ; fflush(stdout) ;
01206 #endif
01207       XtVaSetValues( pbar->panes[i] , XmNheight , hh , NULL ) ;
01208    }
01209 #ifdef PBAR_DEBUG
01210 printf("set pane %d to height %d\n",npane-1,sum) ; fflush(stdout) ;
01211 #endif
01212    XtVaSetValues( pbar->panes[npane-1] , XmNheight , sum , NULL ) ;
01213 
01214    XtVaSetValues( pbar->panew ,
01215                      XmNheight , pbar->panew_height ,
01216                      XmNsashHeight , (npane<NPANE_NOSASH) ? SASH_HYES
01217                                                           : SASH_HNO ,
01218                   NULL ) ;
01219 
01220    XtVaSetValues( pbar->top , XmNheight , pbar->panew_height , NULL ) ;
01221 
01222    if( pbar->hide_changes ) XtMapWidget( pbar->top ) ;
01223 
01224    pbar->renew_all = 1 ;
01225    pbar->keep_pval = 1 ;  /* Dec 1997 */
01226    PBAR_resize_CB( pbar->panes[pbar->num_panes-1] , (XtPointer) pbar , NULL ) ;
01227 
01228    if( pbar->keep_pval ){                  /* Dec 1997 */
01229       for( i=0 ; i <= npane ; i++ )
01230          pbar->pval_save[pbar->num_panes][i][jm] =
01231                                    pbar->pval[i] = pval[i] ;
01232    }
01233    pbar->keep_pval = 0 ;
01234 
01235 #ifdef PBAR_DEBUG
01236  { int hh,ww,xx,yy , i ;
01237 
01238    XmUpdateDisplay(pbar->top) ;
01239 
01240    MCW_widget_geom(pbar->top , &ww,&hh,&xx,&yy ) ;
01241    printf("pbar->top  :  w=%d h=%d x=%d y=%d\n",ww,hh,xx,yy) ; fflush(stdout) ;
01242 
01243    MCW_widget_geom(pbar->panew , &ww,&hh,&xx,&yy ) ;
01244    printf("pbar->panew: w=%d h=%d x=%d y=%d\n",ww,hh,xx,yy) ; fflush(stdout) ;
01245 
01246    for( i=0 ; i < pbar->num_panes ; i++ ){
01247       MCW_widget_geom(pbar->panes[i] , &ww,&hh,&xx,&yy ) ;
01248       printf("pane # %d: w=%d h=%d x=%d y=%d\n",i,ww,hh,xx,yy) ; fflush(stdout) ;
01249    }
01250  }
01251 #endif
01252 
01253    EXRETURN ;
01254 }
01255 
01256 /*-------------------------------------------------------------------------
01257    Make an image of the pbar (sans handles)
01258    -- RWCox - 15 Jun 2000
01259 ---------------------------------------------------------------------------*/
01260 
01261 MRI_IMAGE * MCW_pbar_to_mri( MCW_pbar * pbar , int nx , int ny )
01262 {
01263    MRI_IMAGE * im ;
01264    int   ii,npix,kk,ll,jj , sum,hh ;
01265    float pmin,pmax , rhh,fhh , hfrac ;
01266    byte rr,gg,bb , *bar ;
01267 
01268 ENTRY("MCW_pbar_to_mri") ;
01269 
01270    /* check for decent inputs */
01271 
01272    if( pbar == NULL ) RETURN(NULL) ;
01273    if( nx < 1 ) nx = 1 ;
01274 
01275    if( pbar->bigmode ){    /* 30 Jan 2003: save spectrum */
01276      XImage *xim ;
01277      if( pbar->bigxim == NULL ){
01278        PBAR_bigexpose_CB(NULL,pbar,NULL) ;
01279        if( pbar->bigxim == NULL ) RETURN(NULL) ;
01280      }
01281      if( ny < NPANE_BIG ) ny = NPANE_BIG ;
01282      xim = resize_XImage( pbar->dc , pbar->bigxim , nx,ny ) ;
01283      im  = XImage_to_mri( pbar->dc , xim , X2M_USE_CMAP|X2M_FORCE_RGB ) ;
01284      MCW_kill_XImage( xim ) ;
01285      RETURN(im) ;
01286    }
01287 
01288    /** the old way: make the image by brute force **/
01289 
01290    if( ny < 4*pbar->num_panes ) ny = 4*pbar->num_panes ;
01291 
01292    im  = mri_new( nx , ny , MRI_rgb ) ;
01293    bar = MRI_RGB_PTR(im) ;
01294 
01295    pmax = pbar->pval[0] ;
01296    pmin = pbar->pval[pbar->num_panes] ;
01297 
01298    hfrac = ny / (pmax-pmin) ;
01299    rhh  = 0.0 ;
01300    sum  = ny ;
01301 
01302    /* do each pane */
01303 
01304    for( kk=0 ; kk < pbar->num_panes-1 ; kk++ ){
01305       fhh  = hfrac * (pbar->pval[kk]-pbar->pval[kk+1]) ; /* wannabe height */
01306       hh   = (int) (rhh+fhh+0.45) ;                      /* actual height */
01307       rhh  = fhh - hh ;                                  /* remainder */
01308       sum -= hh ;                                        /* # pixels left */
01309 
01310       if( pbar->ov_index[kk] > 0 ){                      /* solid color */
01311          rr = DCOV_REDBYTE  (pbar->dc,pbar->ov_index[kk]) ;
01312          gg = DCOV_GREENBYTE(pbar->dc,pbar->ov_index[kk]) ;
01313          bb = DCOV_BLUEBYTE (pbar->dc,pbar->ov_index[kk]) ;
01314 
01315          npix = hh*nx ;
01316          for( ii=0 ; ii < npix ; ii++ ){
01317            *bar++ = rr ; *bar++ = gg ; *bar++ = bb ;
01318          }
01319       } else {                                           /* check pattern */
01320          byte bwj , bwi ;
01321          bwj = 255 ;
01322          for( jj=0 ; jj < hh ; jj++ ){
01323             bwi = bwj ;
01324             for( ii=0 ; ii < nx ; ii++ ){
01325               *bar++ = bwi ; *bar++ = bwi ; *bar++ = bwi ; bwi = ~bwi ;
01326             }
01327             bwj = ~bwj ;
01328          }
01329       }
01330    }
01331 
01332    /* last pane */
01333 
01334    kk = pbar->num_panes-1 ;
01335 
01336    if( pbar->ov_index[kk] > 0 ){                      /* solid color */
01337       rr = DCOV_REDBYTE  (pbar->dc,pbar->ov_index[kk]) ;
01338       gg = DCOV_GREENBYTE(pbar->dc,pbar->ov_index[kk]) ;
01339       bb = DCOV_BLUEBYTE (pbar->dc,pbar->ov_index[kk]) ;
01340 
01341       npix = sum*nx ;
01342       for( ii=0 ; ii < npix ; ii++ ){
01343         *bar++ = rr ; *bar++ = gg ; *bar++ = bb ;
01344       }
01345    } else {                                           /* check pattern */
01346       byte bwj , bwi ;
01347       bwj = 255 ;
01348       for( jj=0 ; jj < hh ; jj++ ){
01349          bwi = bwj ;
01350          for( ii=0 ; ii < nx ; ii++ ){
01351            *bar++ = bwi ; *bar++ = bwi ; *bar++ = bwi ; bwi = ~bwi ;
01352          }
01353          bwj = ~bwj ;
01354       }
01355    }
01356 
01357    RETURN(im) ;
01358 }
 

Powered by Plone

This site conforms to the following standards: