/*****************************************************************************
Major portions of this software are copyrighted by the Medical College
of Wisconsin, 1994-2000, and are released under the Gnu General Public
License, Version 2. See the file README.Copyright for details.
******************************************************************************/
/*----------------------------------------------------------------------
* history:
*
* 2003 Dec 19 [rickr]
* - added Mean and Sigma to bottom of graph window
*----------------------------------------------------------------------
*/
#undef MAIN
#include "afni_graph.h"
#include "afni.h"
#include <X11/keysym.h> /* 24 Jan 2003 */
static int show_grapher_pixmap = 1 ;
static void fd_line( MCW_grapher *, int,int,int,int ) ;
/*------------------------------------------------------------*/
/*! Macro to call the getser function with correct prototype. */
#undef CALL_getser
#define CALL_getser(gr,aa,bb,rtyp,rval) \
do{ XtPointer (*gs)(int,int,XtPointer) = \
(XtPointer (*)(int,int,XtPointer))(gr->getser) ; \
rval = (rtyp) gs(aa,bb,gr->getaux) ; \
} while(0)
/*------------------------------------------------------------*/
/*! And to call the send_CB function with a good prototype. */
#undef CALL_sendback
#define CALL_sendback(gr,scb) \
do{ void (*sb)(MCW_grapher *,XtPointer,GRA_cbs *) = \
(void (*)(MCW_grapher *,XtPointer,GRA_cbs *))(gr->status->send_CB) ; \
if( sb != NULL ) sb(gr,gr->getaux,&scb) ; \
} while(0)
/*------------------------------------------------------------*/
/*! Create a new MCW_grapher window and structure. */
MCW_grapher * new_MCW_grapher( MCW_DC *dc , get_ptr getser , XtPointer aux )
{
int ii ;
MCW_grapher *grapher ;
static int new_xsize = -1 , new_ysize = -1 ;
char *buf , *cpt ;
Widget rc_tmp , mb_tmp , form_tmp ; /* 29 Sep 2000 */
ENTRY("new_MCW_grapher") ;
grapher = myXtNew( MCW_grapher ) ;
grapher->type = MCW_GRAPHER_TYPE ;
grapher->dc = dc ;
grapher->getser = getser ;
grapher->getaux = aux ;
grapher->parent = NULL ;
grapher->valid = 1 ;
grapher->dont_redraw = 0 ; /* 27 Jan 2004 */
grapher->timer_id = 0 ; /* 04 Dec 2003 */
grapher->never_drawn = 1 ;
grapher->button2_enabled = 0 ; /* Feb 1998 */
grapher->mirror = 0 ; /* Jul 2000 */
grapher->tschosen = 0 ; /* 31 Mar 2004 */
grapher->gx_max = 0 ;
grapher->gy_max = 0 ;
grapher->fWIDE = 0 ;
grapher->fHIGH = 0 ;
grapher->glogo_pixmap = XmUNSPECIFIED_PIXMAP ;
grapher->glogo_width = grapher->glogo_height = 0 ;
#if 0
grapher->status = (MCW_grapher_status *) getser(0,graCR_getstatus,aux) ;
#else
CALL_getser( grapher , 0,graCR_getstatus , MCW_grapher_status *,grapher->status ) ;
#endif
if( grapher->status->num_series < 1 ){
fprintf(stderr,"*** Attempt to create grapher with < 1 time points! ***\a\n") ;
myXtFree(grapher) ;
RETURN(NULL) ;
}
GRA_NULL_tuser(grapher) ; /* 22 Apr 1997 */
/** make shell that holds all **/
grapher->fdw_graph =
XtVaAppCreateShell(
"AFNI" , "AFNI" , topLevelShellWidgetClass , dc->display ,
XmNminHeight , MIN_XSIZE + GL_DLX + GR_DLX ,
XmNmaxHeight , dc->height ,
XmNminWidth , MIN_YSIZE + GT_DLY + GB_DLY ,
XmNmaxWidth , dc->width ,
XmNdeleteResponse , XmDO_NOTHING , /* deletion handled below */
XmNallowShellResize , False , /* let code resize shell */
XmNinitialResourcesPersistent , False ,
XmNkeyboardFocusPolicy , XmEXPLICIT ,
NULL ) ;
DC_yokify( grapher->fdw_graph , dc ) ; /* 14 Sep 1998 */
/** find initial size of new graphs **/
if( new_xsize < 0 ){
new_xsize = GX_MAX ;
#if 0
buf = XGetDefault(dc->display,"AFNI","graph_width") ;
#else
buf = RWC_getname(dc->display,"graph_width") ;
#endif
if( buf != NULL ){
ii = strtol( buf , &cpt , 10 ) ;
if( *cpt == '\0' || new_xsize >= MIN_XSIZE ||
new_xsize <= dc->width - GL_DLX - GR_DLX )
new_xsize = ii ;
}
new_ysize = GY_MAX ;
#if 0
buf = XGetDefault(dc->display,"AFNI","graph_height") ;
#else
buf = RWC_getname(dc->display,"graph_height") ;
#endif
if( buf != NULL ){
ii = strtol( buf , &cpt , 10 ) ;
if( *cpt == '\0' || new_ysize >= MIN_YSIZE ||
new_ysize <= dc->width - GT_DLY - GB_DLY )
new_ysize = ii ;
}
}
/** 29 Sep 2000: put in a Form to hold everything **/
form_tmp = XtVaCreateWidget(
"dialog" , xmFormWidgetClass , grapher->fdw_graph ,
XmNwidth , new_xsize + GL_DLX + GR_DLX ,
XmNheight , new_ysize + GT_DLY + GB_DLY ,
XmNborderWidth , 0 ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
/** make a drawing area to get everything **/
grapher->draw_fd =
XtVaCreateManagedWidget(
"dialog" , xmDrawingAreaWidgetClass , form_tmp ,
#if 0
XmNwidth , new_xsize + GL_DLX + GR_DLX ,
XmNheight , new_ysize + GT_DLY + GB_DLY ,
#endif
XmNtopAttachment , XmATTACH_FORM ,
XmNleftAttachment , XmATTACH_FORM ,
XmNrightAttachment , XmATTACH_FORM ,
XmNbottomAttachment , XmATTACH_FORM ,
XmNmarginWidth , 0 ,
XmNmarginHeight , 0 ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
XtInsertEventHandler( grapher->draw_fd , /* handle events in graphs */
0
| KeyPressMask /* get keystrokes */
| ButtonPressMask /* button presses */
| ExposureMask /* exposures */
| StructureNotifyMask /* resizes */
,
FALSE , /* nonmaskable events? */
GRA_drawing_EV , /* super-handler! */
(XtPointer) grapher , /* client data */
XtListTail ) ; /* last in queue */
MCW_register_help( grapher->draw_fd ,
"Button 1 in a sub-graph --> move it to center\n"
"Button 1 in the central --> move time index\n"
" sub-graph to closest point\n"
" on the graph\n"
#if 0
"Shift or Ctrl keys with --> single-step time\n"
"Button 1 in the central index up or down\n"
" sub-graph\n"
#endif
"\n"
"The red dot in the central sub-graph shows\n"
"the location of the current time index.\n"
"\n"
"Button 3 in a sub-graph --> show statistics\n"
" of time series\n"
"\n"
"To turn off the AFNI logo, click Button 1\n"
"inside the logo.\n"
"\n"
"Miscellaneous Keystrokes:\n"
"< or [ = move back in time 1 point\n"
"> or ] = move forward in time 1 point\n"
"1 = move to 1st time point\n"
"l = move to last time point\n"
"L = turn AFNI logo on/off\n"
"v/V = Video up/down in time\n"
"r/R = Video ricochet up/down in time\n"
"\n"
"See the 'Opt' menu for other keypress actions\n"
"and for other options to control graph display."
) ;
/*---------------------------*/
/*--- Button 3 popup menu ---*/
/*---------------------------*/
#ifdef BAD_BUTTON3_POPUPS /* 21 Jul 2003 */
grapher->but3_menu =
XmCreatePopupMenu( form_tmp, "menu" , NULL , 0 ) ;
#else
grapher->but3_menu =
XmCreatePopupMenu( grapher->draw_fd , "menu" , NULL , 0 ) ;
#endif
SAVEUNDERIZE(XtParent(grapher->but3_menu)) ; /* 27 Feb 2001 */
VISIBILIZE_WHEN_MAPPED(grapher->but3_menu) ;
if( !AFNI_yesenv("AFNI_DISABLE_TEAROFF") ) TEAROFFIZE(grapher->but3_menu) ;
grapher->but3_label =
XtVaCreateManagedWidget(
"dialog" , xmLabelWidgetClass , grapher->but3_menu ,
XmNalignment , XmALIGNMENT_BEGINNING ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
/*-------------------------------------*/
/*--- RowColumn to hold all buttons ---*/
/*-------------------------------------*/
grapher->option_rowcol =
XtVaCreateWidget(
"dialog" , xmRowColumnWidgetClass , form_tmp ,
XmNpacking , XmPACK_TIGHT ,
XmNorientation , XmHORIZONTAL ,
XmNmarginWidth , 0 ,
XmNmarginHeight, 0 ,
XmNspacing , 2 ,
XmNbackground , grapher->dc->ovc->pixov_brightest ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
XmNleftAttachment , XmATTACH_NONE ,
XmNtopAttachment , XmATTACH_NONE ,
XmNrightAttachment , XmATTACH_FORM ,
XmNbottomAttachment , XmATTACH_FORM ,
NULL ) ;
#if 0
allow_MCW_optmenu_popup( 0 ) ; /* 12 Dec 2001 */
#endif
/*------------------------*/
/*--- FIM Menu Buttons ---*/
/*------------------------*/
/* 29 Sep 2000: move menu buttons each onto private menubars */
rc_tmp = XtVaCreateWidget(
"dialog" , xmRowColumnWidgetClass , grapher->option_rowcol ,
XmNorientation , XmHORIZONTAL ,
XmNpacking , XmPACK_TIGHT ,
XmNmarginWidth , 0 ,
XmNmarginHeight, 0 ,
XmNspacing , 0 ,
XmNbackground , grapher->dc->ovc->pixov_brightest ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
mb_tmp = XmCreateMenuBar( rc_tmp , "dialog" , NULL,0 ) ;
XtVaSetValues( mb_tmp ,
XmNmarginWidth , 0 ,
XmNmarginHeight , 0 ,
XmNspacing , 0 ,
XmNborderWidth , 0 ,
XmNborderColor , 0 ,
XmNtraversalOn , True ,
XmNbackground , grapher->dc->ovc->pixov_brightest ,
NULL ) ;
XtManageChild( mb_tmp ) ;
grapher->fmenu = AFNI_new_fim_menu( mb_tmp , GRA_fim_CB , 1 ) ;
grapher->fmenu->parent = (XtPointer) grapher ;
XtManageChild( rc_tmp ) ;
grapher->polort = 1 ; /* 27 May 1999 */
/* macros to put double and single separator lines in a menu */
#define MENU_DLINE(wmenu) \
(void) XtVaCreateManagedWidget( \
"dialog" , xmSeparatorWidgetClass , grapher -> wmenu , \
XmNseparatorType , XmDOUBLE_LINE , NULL )
#define MENU_SLINE(wmenu) \
(void) XtVaCreateManagedWidget( \
"dialog" , xmSeparatorWidgetClass , grapher -> wmenu , \
XmNseparatorType , XmSINGLE_LINE , NULL )
/*------------------------*/
/*--- Opt Menu Buttons ---*/
/*------------------------*/
/* 29 Sep 2000: move menu buttons each onto private menubars */
rc_tmp = XtVaCreateWidget(
"dialog" , xmRowColumnWidgetClass , grapher->option_rowcol ,
XmNorientation , XmHORIZONTAL ,
XmNpacking , XmPACK_TIGHT ,
XmNmarginWidth , 0 ,
XmNmarginHeight, 0 ,
XmNspacing , 0 ,
XmNbackground , grapher->dc->ovc->pixov_brightest ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
mb_tmp = XmCreateMenuBar( rc_tmp , "dialog" , NULL,0 ) ;
XtVaSetValues( mb_tmp ,
XmNmarginWidth , 0 ,
XmNmarginHeight , 0 ,
XmNspacing , 0 ,
XmNborderWidth , 0 ,
XmNborderColor , 0 ,
XmNtraversalOn , True ,
XmNbackground , grapher->dc->ovc->pixov_brightest ,
NULL ) ;
XtManageChild( mb_tmp ) ;
grapher->opt_menu = XmCreatePulldownMenu( mb_tmp , "menu" , NULL,0 ) ;
VISIBILIZE_WHEN_MAPPED(grapher->opt_menu) ; /* 27 Sep 2000 */
if( !AFNI_yesenv("AFNI_DISABLE_TEAROFF") ) TEAROFFIZE(grapher->opt_menu) ;
grapher->opt_cbut =
XtVaCreateManagedWidget(
"dialog" , xmCascadeButtonWidgetClass , mb_tmp ,
LABEL_ARG("Opt") ,
XmNsubMenuId , grapher->opt_menu ,
XmNmarginWidth , 0 ,
XmNmarginHeight , 0 ,
XmNmarginBottom , 0 ,
XmNmarginTop , 0 ,
XmNmarginRight , 0 ,
XmNmarginLeft , 0 ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
XtManageChild( rc_tmp ) ;
MCW_register_hint( grapher->opt_cbut , "Graphing options menu" ) ;
MCW_register_help( grapher->opt_cbut ,
"******** Graph Display Options: ********\n"
"\n"
"Scale --> Change vertical scaling\n"
"Matrix --> Change number of sub-graphs\n"
"Grid --> Change number of grid lines;\n"
" also can Pin the number of\n"
" time points displayed.\n"
"Slice --> Change slice number\n"
"Colors, Etc --> Change colors of various\n"
" parts of the graph window\n"
"Baseline --> Display each sub-graph with\n"
" its minimum at the bottom of\n"
" its window (the default), OR\n"
" with the minimum of all sub-\n"
" graphs as the common baseline\n"
"Show Text? --> Instead of graphs, show the\n"
" numerical values of the data\n"
" at the current time index\n"
" in each sub-graph box\n"
"Save PNM --> Save the graph window as an\n"
" image to a PNM format file\n"
"Write Center--> Central voxel timeseries will\n"
" be written to a file with a\n"
" name like 'X_Y_Z.suffix.1D'\n"
" where X,Y,Z are voxel indexes\n"
"Tran 0D --> Choose a function to apply to\n"
" each point in each timeseries\n"
"Tran 1D --> Choose a function to apply to\n"
" the timeseries as a whole\n"
"Double Plot --> If 'Tran 1D' is active, then\n"
" plot the data timeseries AND\n"
" the transformed timeseries;\n"
" Plus/Minus -> transformed data\n"
" is added/subtracted from real\n"
" data timeseries (use this with\n"
" Dataset#2 to plot error bands)\n"
"Done --> Close this graphing window\n"
"\n"
"The keystrokes indicated in the menus will\n"
"carry out the same functions, if pressed\n"
"when the cursor focus is in the graph window.\n"
"\n"
"N.B.: keystrokes without menu items are:\n"
" < --> move time index down by 1\n"
" > --> move time index up by 1\n"
" 1 --> move to first image (time index 0)\n"
" l --> move to last image in time series\n"
" L --> turn off the AFNI logo in the corner"
) ;
/** macro to create a new opt menu button **/
#define OPT_MENU_BUT(wname,label,hhh) \
grapher -> wname = \
XtVaCreateManagedWidget( \
"dialog" , xmPushButtonWidgetClass , grapher->opt_menu , \
LABEL_ARG( label ) , \
XmNmarginHeight , 0 , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , \
NULL ) ; \
XtAddCallback( grapher -> wname , XmNactivateCallback , \
GRA_opt_CB , (XtPointer) grapher ) ; \
MCW_register_hint( grapher -> wname , hhh ) ;
/** macro to create a new opt pullright menu **/
/** 07 Jan 1999: added the mapCallback to fix position **/
#define OPT_MENU_PULLRIGHT(wmenu,wcbut,label,hhh) \
grapher -> wmenu = \
XmCreatePulldownMenu( grapher->opt_menu , "menu" , NULL , 0 ) ; \
grapher -> wcbut = \
XtVaCreateManagedWidget( \
"dialog" , xmCascadeButtonWidgetClass , grapher->opt_menu , \
LABEL_ARG( label ) , \
XmNsubMenuId , grapher -> wmenu , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , \
NULL ) ; \
MCW_register_hint( grapher -> wcbut , hhh ) ; \
XtAddCallback( grapher -> wmenu, XmNmapCallback, GRA_mapmenu_CB, NULL ) ;
/** macro to create a new button on a pullright menu **/
#define OPT_MENU_PULL_BUT(wmenu,wname,label,hhh) \
grapher -> wname = \
XtVaCreateManagedWidget( \
"dialog" , xmPushButtonWidgetClass , grapher -> wmenu , \
LABEL_ARG( label ) , \
XmNmarginHeight , 0 , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , \
NULL ) ; \
XtAddCallback( grapher -> wname , XmNactivateCallback , \
GRA_opt_CB , (XtPointer) grapher ) ; \
MCW_register_hint( grapher -> wname , hhh ) ;
#ifdef USE_OPTMENUS
/** macro to create an option menu on a pullright menu
(this menu must be fixed up later in GRA_fix_optmenus) **/
#define OPT_MENU_OPTMENU(wmenu,wname,label,cb,hhh) \
grapher -> wname = \
new_MCW_optmenu( grapher -> wmenu , label , 0,1,0,0 , \
cb , (XtPointer) grapher , NULL , NULL ) ; \
MCW_reghint_children( grapher -> wname -> wrowcol , hhh ) ;
#endif /* USE_OPTMENUS */
/*** top of menu = a label to click on that does nothing at all ***/
(void) XtVaCreateManagedWidget(
"dialog" , xmLabelWidgetClass , grapher->opt_menu ,
LABEL_ARG("--- Cancel ---") ,
XmNrecomputeSize , False ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
MENU_SLINE(opt_menu) ;
OPT_MENU_PULLRIGHT(opt_scale_menu,opt_scale_cbut ,"Scale" ,"Change vertical scale" );
OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_down_pb ,"Down [-]","Shrink graph heights" );
OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_up_pb ,"Up [+]","Increase graph heights");
OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_choose_pb,"Choose" ,"Set vertical scale" );
OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_auto_pb ,"Auto [a]","Scale automatically" );
OPT_MENU_PULLRIGHT(opt_mat_menu,opt_mat_cbut ,"Matrix" , "Change number of graphs" ) ;
OPT_MENU_PULL_BUT( opt_mat_menu,opt_mat_down_pb ,"Down [m]", "Reduce number of graphs" ) ;
OPT_MENU_PULL_BUT( opt_mat_menu,opt_mat_up_pb ,"Up [M]", "Increase number of graphs" ) ;
#ifdef USE_OPTMENUS
OPT_MENU_OPTMENU( opt_mat_menu,opt_mat_choose_av , "# " , GRA_mat_choose_CB , "Set number of graphs" ) ;
#else
OPT_MENU_PULL_BUT( opt_mat_menu,opt_mat_choose_pb ,"Choose" , "Set number of graphs" ) ;
#endif
OPT_MENU_PULLRIGHT(opt_grid_menu,opt_grid_cbut ,"Grid" , "Change vertical grid spacing" ) ;
OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_down_pb ,"Down [g]", "Reduce vertical grid spacing" ) ;
OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_up_pb ,"Up [G]", "Increase vertical grid spacing" ) ;
OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_auto_pb ,"AutoGrid", "Set grid spacing automatically" ) ;
OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_choose_pb,"Choose" , "Set vertical grid spacing" ) ;
OPT_MENU_PULL_BUT( opt_grid_menu,opt_pin_choose_pb ,"Index Pin","Fix index range of graph window" ) ; /* 17 Mar 2004 */
OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_HorZ_pb ,"HorZ [h]", "Horizontal line at Zero" ) ; /* 05 Jan 1999 */
OPT_MENU_PULLRIGHT(opt_slice_menu,opt_slice_cbut ,"Slice" , "Change slice" ) ;
OPT_MENU_PULL_BUT( opt_slice_menu,opt_slice_down_pb ,"Down [z]", "Decrement slice" ) ;
OPT_MENU_PULL_BUT( opt_slice_menu,opt_slice_up_pb ,"Up [Z]", "Increment slice" ) ;
#ifdef USE_OPTMENUS
OPT_MENU_OPTMENU( opt_slice_menu,opt_slice_choose_av , "# " , GRA_slice_choose_CB , "Set slice" ) ;
#else
OPT_MENU_PULL_BUT( opt_slice_menu,opt_slice_choose_pb ,"Choose" , "Set slice" ) ;
#endif
/***** 16 June 1997: Colors submenu *****/
{ static char * bbox_label[1] = { "Use Thick Lines" } ;
static char * pts_label[2] = { "Graph Points" , "Points+Lines" } ;
char toplabel[64] ;
XmString xstr ;
OPT_MENU_PULLRIGHT(opt_colors_menu,opt_colors_cbut,"Colors, Etc.","Change graph appearance");
if( strlen(grapher->status->namecode) > 0 ){
sprintf( toplabel , "--- %s ---" , grapher->status->namecode ) ;
xstr = XmStringCreateLtoR( toplabel , XmFONTLIST_DEFAULT_TAG ) ;
(void) XtVaCreateManagedWidget(
"dialog" , xmLabelWidgetClass , grapher->opt_colors_menu ,
XmNlabelString , xstr ,
XmNrecomputeSize , False ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
XmStringFree( xstr ) ;
MENU_DLINE(opt_colors_menu) ;
}
if( gr_setup_default ){
gr_color_default[0] = INIT_GR_boxes_color ;
gr_color_default[1] = INIT_GR_backg_color ;
gr_color_default[2] = INIT_GR_grid_color ;
gr_color_default[3] = INIT_GR_text_color ;
gr_color_default[4] = INIT_GR_data_color ;
gr_color_default[5] = INIT_GR_ideal_color ;
gr_color_default[6] = INIT_GR_ort_color ;
gr_color_default[7] = INIT_GR_ignore_color ;
gr_color_default[8] = INIT_GR_dplot_color ;
gr_thick_default[0] = INIT_GR_boxes_thick ;
gr_thick_default[1] = -1 ;
gr_thick_default[2] = INIT_GR_grid_thick ;
gr_thick_default[3] = -1 ;
gr_thick_default[4] = INIT_GR_data_thick ;
gr_thick_default[5] = INIT_GR_ideal_thick ;
gr_thick_default[6] = INIT_GR_ort_thick ;
gr_thick_default[7] = -1 ;
gr_thick_default[8] = INIT_GR_dplot_thick ;
gr_setup_default = 0 ;
}
for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
grapher->color_index[ii] = GRA_COLOR(gr_color_default[ii]) ;
grapher->thick_index[ii] = gr_thick_default[ii] ;
grapher->points_index[ii]= gr_points_default[ii] ; /* 09 Jan 1998 */
grapher->opt_color_av[ii] =
new_MCW_colormenu( grapher->opt_colors_menu ,
gr_color_label[ii] ,
grapher->dc ,
gr_color_start[ii] , grapher->dc->ovc->ncol_ov-1,
grapher->color_index[ii] ,
GRA_color_CB , (XtPointer) grapher ) ;
MCW_reghint_children( grapher->opt_color_av[ii]->wrowcol ,
gr_color_hint[ii] ) ; /* 28 Jan 2004 */
if( grapher->thick_index[ii] >= 0 ){
grapher->opt_thick_bbox[ii] =
new_MCW_bbox( grapher->opt_colors_menu ,
1 , bbox_label , MCW_BB_check , MCW_BB_noframe ,
GRA_thick_CB , (XtPointer) grapher ) ;
MCW_reghint_children( grapher->opt_thick_bbox[ii]->wrowcol ,
"Draw these lines thicker" ) ;
if( grapher->thick_index[ii] )
MCW_set_bbox( grapher->opt_thick_bbox[ii] , 1 ) ;
} else {
grapher->opt_thick_bbox[ii] = NULL ;
}
/* 09 Jan 1998: add option to draw only points in graphs */
/* 01 Aug 1998: allow points+lines to be drawn as well */
if( grapher->points_index[ii] >= 0 ){
grapher->opt_points_bbox[ii] =
new_MCW_bbox( grapher->opt_colors_menu ,
2 , pts_label , MCW_BB_radio_zero , MCW_BB_noframe ,
GRA_thick_CB , (XtPointer) grapher ) ;
MCW_reghint_children( grapher->opt_points_bbox[ii]->wrowcol ,
"Plot graph as Points only, or as Points and Lines" ) ;
if( grapher->points_index[ii] )
MCW_set_bbox( grapher->opt_points_bbox[ii] ,
1 << (grapher->points_index[ii]-1) ) ;
} else {
grapher->opt_points_bbox[ii] = NULL ;
}
MENU_DLINE( opt_colors_menu ) ;
}
/* 12 Jan 1998: control gap between graphs */
grapher->opt_ggap_av =
new_MCW_optmenu( grapher->opt_colors_menu , "Graph Gap" ,
0 , 19 , INIT_GR_ggap , 0 ,
GRA_ggap_CB , (XtPointer) grapher , NULL , NULL ) ;
AVOPT_columnize( grapher->opt_ggap_av , 4 ) ;
MCW_reghint_children( grapher->opt_ggap_av->wrowcol ,
"Space sub-graphs apart" ) ;
/* 06 Oct 2004: control 'thick' line size */
grapher->opt_gthick_av =
new_MCW_optmenu( grapher->opt_colors_menu , "'Thick' " ,
2 , 10 , INIT_GR_gthick , 0 ,
GRA_gthick_CB , (XtPointer) grapher , NULL , NULL ) ;
AVOPT_columnize( grapher->opt_gthick_av , 2 ) ;
MCW_reghint_children( grapher->opt_gthick_av->wrowcol ,
"Width of 'Thick' lines" ) ;
}
/***** end colors submenu creation *****/
#if 0
OPT_MENU_BUT(opt_color_up_pb ,"Grid Color [r]" , "Rotate grid color" ) ;
#endif
/*-- 07 Aug 2001: Baseline sub-menu creation --*/
{ char * bbox_label[3] = { "Individual [b]" ,
"Common [b]" ,
"Global [b]" } ;
XmString xstr ;
char gbuf[32] ; /* 08 Mar 2002 */
/* 08 Mar 2002: set baseline parameters from environment variables */
cpt = getenv( "AFNI_GRAPH_GLOBALBASE" ) ;
if( cpt != NULL )
grapher->global_base = strtod( cpt , NULL ) ;
else
grapher->global_base = 0.0 ;
cpt = getenv( "AFNI_GRAPH_BASELINE" ) ;
if( cpt != NULL ){
switch( *cpt ){
default: grapher->common_base = BASELINE_INDIVIDUAL ; break ;
case 'C':
case 'c': grapher->common_base = BASELINE_COMMON ; break ;
case 'G':
case 'g': grapher->common_base = BASELINE_GLOBAL ; break ;
}
} else {
grapher->common_base = BASELINE_INDIVIDUAL ;
}
/* now create menu items */
OPT_MENU_PULLRIGHT(opt_baseline_menu,opt_baseline_cbut,
"Baseline","Change sub-graphs baseline");
grapher->opt_baseline_bbox =
new_MCW_bbox( grapher->opt_baseline_menu ,
3 , bbox_label , MCW_BB_radio_one , MCW_BB_noframe ,
GRA_baseline_CB , (XtPointer)grapher ) ;
MCW_set_bbox( grapher->opt_baseline_bbox , grapher->common_base ) ;
MCW_reghint_children( grapher->opt_baseline_bbox->wrowcol ,
"Graph baseline methods" ) ;
MENU_SLINE( opt_baseline_menu ) ;
OPT_MENU_PULL_BUT( opt_baseline_menu,opt_baseline_setglobal_pb ,
"Set Global" , "Global baseline level" ) ;
MENU_SLINE( opt_baseline_menu ) ;
strcpy(gbuf,"Global:") ;
AV_fval_to_char(grapher->global_base,gbuf+7) ;
xstr = XmStringCreateLtoR(gbuf,XmFONTLIST_DEFAULT_TAG) ;
grapher->opt_baseline_global_label =
XtVaCreateManagedWidget(
"dialog" , xmLabelWidgetClass , grapher->opt_baseline_menu ,
XmNlabelString , xstr ,
XmNrecomputeSize , False ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
XmStringFree( xstr ) ;
}
/* 22 Sep 2000: Text toggle */
{ static char * bbox_label[1] = { "Show Text? [t]" } ;
grapher->opt_textgraph_bbox =
new_MCW_bbox( grapher->opt_menu ,
1 , bbox_label , MCW_BB_check , MCW_BB_noframe ,
GRA_textgraph_CB , (XtPointer)grapher ) ;
MCW_reghint_children( grapher->opt_textgraph_bbox->wrowcol ,
"Display text, not graphs" ) ;
grapher->textgraph = 0 ;
}
MENU_SLINE(opt_menu) ;
OPT_MENU_BUT(opt_save_pb ,"Save PNM [S]" , "Save graph as an image" ) ;
MENU_SLINE(opt_menu) ;
OPT_MENU_BUT(opt_write_center_pb ,"Write Center [w]" , "Write central graph as a *.1D file" ) ;
OPT_MENU_BUT(opt_write_suffix_pb ,"Set 'w' Suffix" , "Set suffix for graph writing" ) ;
/*-------------------------------------------*/
/*--- Arrowval to list 0D transformations ---*/
/*-------------------------------------------*/
#define COLSIZE AV_colsize()
if( grapher->status->transforms0D != NULL &&
grapher->status->transforms0D->num > 0 ){ /* 22 Oct 1996 */
MENU_DLINE(opt_menu) ;
grapher->transform0D_av =
new_MCW_optmenu( grapher->opt_menu ,
"Tran 0D" ,
0 , grapher->status->transforms0D->num , 0 , 0 ,
GRA_transform_CB , (XtPointer) grapher ,
GRA_transform_label , (XtPointer) grapher->status->transforms0D ) ;
if( grapher->status->transforms0D->num >= COLSIZE )
AVOPT_columnize( grapher->transform0D_av ,
(grapher->status->transforms0D->num/COLSIZE)+1 ) ;
MCW_reghint_children( grapher->transform0D_av->wrowcol ,
"Pointwise data transformations" ) ;
} else {
grapher->transform0D_av = NULL ;
}
grapher->transform0D_func = NULL ; /* no function to start with */
grapher->transform0D_index = 0 ;
/*-------------------------------------------*/
/*--- Arrowval to list 1D transformations ---*/
/*-------------------------------------------*/
if( grapher->status->transforms1D != NULL &&
grapher->status->transforms1D->num > 0 ){ /* 03 Nov 1996 */
MENU_DLINE(opt_menu) ;
grapher->transform1D_av =
new_MCW_optmenu( grapher->opt_menu ,
"Tran 1D" ,
0 , grapher->status->transforms1D->num , 0 , 0 ,
GRA_transform_CB , (XtPointer) grapher ,
GRA_transform_label , (XtPointer) grapher->status->transforms1D ) ;
if( grapher->status->transforms1D->num >= COLSIZE )
AVOPT_columnize( grapher->transform1D_av ,
(grapher->status->transforms1D->num/COLSIZE)+1 ) ;
MCW_reghint_children( grapher->transform1D_av->wrowcol ,
"Time series transformations" ) ;
/* 08 Nov 1996: dplot = double plot */
/* 07 Aug 2001: rewrite of dplot to make it have 3 states, not two */
{ char * bbox_label[3] = { "DPlot Off" ,
"Overlay" ,
"Plus/Minus" } ;
OPT_MENU_PULLRIGHT(opt_dplot_menu,opt_dplot_cbut,
"Double Plot","Graph Dataset and Tran 1D?");
grapher->opt_dplot_bbox =
new_MCW_bbox( grapher->opt_dplot_menu ,
3 , bbox_label , MCW_BB_radio_one , MCW_BB_noframe ,
GRA_dplot_change_CB , (XtPointer)grapher ) ;
MCW_set_bbox( grapher->opt_dplot_bbox , DPLOT_OFF ) ;
MCW_reghint_children( grapher->opt_dplot_bbox->wrowcol ,
"How to show 2 curves" ) ;
}
} else {
grapher->transform1D_av = NULL ;
grapher->opt_dplot_bbox = NULL ;
}
grapher->transform1D_func = NULL ; /* no function to start with */
grapher->transform1D_index = 0 ;
/*------ menu to control the x-axis drawing (09 Jan 1998) ------*/
MENU_DLINE(opt_menu) ;
OPT_MENU_PULLRIGHT( opt_xaxis_menu , opt_xaxis_cbut , "X-axis" , "Alter x-axis" ) ;
OPT_MENU_PULL_BUT( opt_xaxis_menu , opt_xaxis_pick_pb ,
"Pick x-axis" , "Set timeseries for x-axis" ) ;
OPT_MENU_PULL_BUT( opt_xaxis_menu , opt_xaxis_center_pb ,
"X-axis=center" , "X-axis = center voxel" ) ;
OPT_MENU_PULL_BUT( opt_xaxis_menu , opt_xaxis_clear_pb ,
"Clear x-axis" , "Clear x-axis timeseries" ) ;
/*------ last button on this menu ------*/
MENU_DLINE(opt_menu) ;
OPT_MENU_BUT(opt_quit_pb ,"Done [q]" , "Close window" ) ;
MCW_set_widget_bg( grapher->opt_quit_pb ,
MCW_hotcolor(grapher->opt_quit_pb) , 0 ) ;
/** done with option buttons -- manage the manager widget **/
XtManageChild( grapher->option_rowcol ) ;
#if 0
allow_MCW_optmenu_popup( 1 ) ; /* 12 Dec 2001 */
#endif
/** initialize the internal parameters **/
if(PRINT_TRACING)
{ char str[128] ;
sprintf(str,"STATUS: num_series=%d nx=%d ny=%d",
grapher->status->num_series,grapher->status->nx,grapher->status->ny ) ;
STATUS(str) ; }
grapher->fscale = 0 ;
grapher->mat = 0 ;
grapher->xpoint = -1 ;
grapher->ypoint = -1 ;
grapher->zpoint = -1 ;
#if 0
grapher->grid_color = GRID_COLOR(grapher) ;
#endif
grapher->grid_index = -1 ;
grapher->grid_fixed = 0 ; /* 02 Apr 2004 */
grapher->key_Nlock = 0 ;
grapher->xFD = 0 ;
grapher->yFD = 0 ;
grapher->time_index = 0 ;
grapher->pin_top = 0 ; /* 27 Apr 1997 */
grapher->pin_bot = 0 ; /* 17 Mar 2004 */
grapher->ggap = INIT_GR_ggap ; /* 12 Jan 1998 + 27 May 1999 */
grapher->gthick = INIT_GR_gthick ; /* 06 Oct 2004 */
grapher->cen_line = NULL ; /* coords of central graph plot */
grapher->ncen_line = 0 ;
grapher->nncen = 0 ;
grapher->cen_tsim = NULL ;
grapher->xax_tsim = NULL ; /* 09 Jan 1998 */
grapher->ave_tsim = NULL ; /* 27 Jan 2004 */
grapher->xx_text_1 =
grapher->xx_text_2 =
grapher->xx_text_2p = grapher->xx_text_3 = 1 ;
grapher->ref_ts = NULL ;
grapher->ort_ts = NULL ;
grapher->ref_ts_plotall = grapher->ort_ts_plotall = 1 ;
init_const( grapher ) ;
grapher->setshift_inc_av = NULL ;
grapher->setshift_left_av = NULL ;
grapher->setshift_right_av = NULL ;
grapher->dialog = NULL ;
grapher->setshift_inc = 0.5 ;
grapher->setshift_left = 0 ;
grapher->setshift_right = 0 ;
/** for the present, don't realize widgets (make the user do it later) **/
XtManageChild( form_tmp ) ; /* 29 Sep 2000 */
#if 0
STATUS("realizing widgets") ;
XtRealizeWidget( grapher->fdw_graph ) ;
WAIT_for_window(grapher->form_tmp) ;
XtVaSetValues( grapher->option_rowcol ,
XmNleftAttachment , XmATTACH_NONE ,
XmNtopAttachment , XmATTACH_NONE ,
XmNrightAttachment , XmATTACH_FORM ,
XmNbottomAttachment , XmATTACH_FORM ,
NULL ) ;
XMapRaised( XtDisplay(grapher->option_rowcol) ,
XtWindow(grapher->option_rowcol) ) ;
NORMAL_cursorize( grapher->fdw_graph ) ;
grapher->valid = 2 ;
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
#endif
grapher->fd_pxWind = (Pixmap) 0 ;
/*** add callback for the WM_DELETE_WINDOW protocol ***/
XmAddWMProtocolCallback(
grapher->fdw_graph , XmInternAtom(dc->display,"WM_DELETE_WINDOW",False) ,
end_fd_graph_CB , (XtPointer) grapher ) ;
RETURN(grapher) ;
}
/*----------------------------------
Exit button action
------------------------------------*/
void end_fd_graph_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
MCW_grapher * grapher = (MCW_grapher *) client_data ;
int ii ;
ENTRY("end_fd_graph_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
GRA_timer_stop( grapher ) ; /* 04 Dec 2003 */
grapher->valid = 0 ; /* can't do anything with this anymore */
if( grapher->fd_pxWind != (Pixmap) 0 ){
STATUS("freeing Pixmap") ;
XFreePixmap( grapher->dc->display , grapher->fd_pxWind ) ;
}
#ifdef USE_OPTMENUS
STATUS("destroying optmenus") ;
FREE_AV(grapher->opt_mat_choose_av) ;
FREE_AV(grapher->opt_slice_choose_av) ;
FREE_AV(grapher->fmenu->fim_ignore_choose_av) ;
FREE_AV(grapher->fmenu->fim_polort_choose_av) ;
#endif
STATUS("destroying arrowvals") ;
FREE_AV( grapher->setshift_right_av) ;
FREE_AV( grapher->setshift_left_av) ;
FREE_AV( grapher->setshift_inc_av) ;
FREE_AV( grapher->transform0D_av ) ; /* 22 Oct 1996 */
FREE_AV( grapher->transform1D_av ) ; /* 03 Nov 1996 */
FREE_AV( grapher->opt_ggap_av ) ; /* 28 Sep 1998: via Purify */
FREE_AV( grapher->opt_gthick_av ) ; /* 06 Oct 2004 */
for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ) /* 16 Jun 1997 */
FREE_AV( grapher->opt_color_av[ii] ) ;
STATUS("destroying fmenu") ;
myXtFree( grapher->fmenu->fim_editref_winaver_bbox ); /* 27 Jan 2004 */
myXtFree( grapher->fmenu->fim_opt_bbox ) ; /* Jan 1998 */
myXtFree( grapher->fmenu->fimp_opt_bbox ); /* Jan 1998 */
myXtFree( grapher->fmenu->fimp_user_bbox); /* Feb 2000 */
myXtFree( grapher->fmenu ) ;
myXtFree( grapher->cen_line ) ;
STATUS("destroying bboxes") ;
myXtFree( grapher->opt_dplot_bbox ) ; /* 08 Nov 1996 */
for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
myXtFree( grapher->opt_thick_bbox[ii] ) ; /* 16 Jun 1997 */
myXtFree( grapher->opt_points_bbox[ii] ) ; /* 09 Jan 1998 */
}
myXtFree( grapher->opt_baseline_bbox ) ; /* 07 Aug 2001 */
myXtFree( grapher->opt_textgraph_bbox ) ;
STATUS("freeing cen_tsim") ;
mri_free( grapher->cen_tsim ) ;
mri_free( grapher->xax_tsim ) ; /* 09 Jan 1998 */
mri_free( grapher->ave_tsim ) ; /* 27 Jan 2004 */
STATUS("freeing tuser") ;
GRA_CLEAR_tuser( grapher ) ; /* 22 Apr 1997 */
/* 31 Mar 2004:
On the Mac, destroying widgets after the timeseries
chooser is opened causes death for unknown reasons.
So in that case, just hide them. What the ....? */
STATUS("destroying widgets") ;
#ifdef DARWIN
if( grapher->tschosen ) XtUnrealizeWidget( grapher->fdw_graph ) ;
else XtDestroyWidget ( grapher->fdw_graph ) ;
#else
XtUnrealizeWidget( grapher->fdw_graph ) ;
#endif
STATUS("widgets now destroyed") ;
/** if AFNI has a notify callback, it will free the data **/
if( grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_destroy ;
STATUS("calling AFNI") ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
} else {
STATUS("freeing grapher") ;
myXtFree( grapher ) ; /* otherwise, we will free the data */
}
EXRETURN ;
}
/*----------------------------------
Erase pixmap to background color
------------------------------------*/
void erase_fdw( MCW_grapher *grapher )
{
ENTRY("erase_fdw") ;
if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
DC_fg_color ( grapher->dc , BG_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , 0 ) ;
XFillRectangle( grapher->dc->display ,
grapher->fd_pxWind , grapher->dc->myGC ,
0 , 0 , grapher->fWIDE , grapher->fHIGH ) ;
if( show_grapher_pixmap &&
grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP &&
grapher->glogo_height > 0 && grapher->glogo_width > 0 ){
XCopyArea( grapher->dc->display ,
grapher->glogo_pixmap , grapher->fd_pxWind , grapher->dc->myGC ,
0,0 , grapher->glogo_width,grapher->glogo_height ,
0,grapher->fHIGH - grapher->glogo_height + 1 ) ;
}
EXRETURN ;
}
/*-----------------------------------------------------*/
/* It plots line to point (x,y) for mod = 1 */
/* or moves to this point for mod = 0. */
/* All into the fd_pxWind. */
/*-----------------------------------------------------*/
void plot_fdX( MCW_grapher * grapher , int x , int y , int mod )
{
int iy = grapher->fHIGH - y;
if( mod > 0 )
XDrawLine( grapher->dc->display ,
grapher->fd_pxWind , grapher->dc->myGC ,
grapher->xFD , grapher->yFD , x , iy ) ;
grapher->xFD = x ; grapher->yFD = iy ;
return ;
}
/* ----------------------------------- */
/* Reload pixmap fd_pxWind to FDWindow */
/* ----------------------------------- */
void fd_px_store( MCW_grapher * grapher )
{
ENTRY("fd_px_store") ;
if( ! MCW_widget_visible(grapher->draw_fd) ) EXRETURN ; /* 03 Jan 1999 */
XtVaSetValues( grapher->draw_fd ,
XmNbackgroundPixmap , grapher->fd_pxWind ,
NULL ) ;
XClearWindow( grapher->dc->display , XtWindow(grapher->draw_fd) ) ;
XFlush( grapher->dc->display ) ;
EXRETURN ;
}
/*--------------------------------------------------------------
draw a small circle somewhere:
xwin,ywin = Window coordinates of center
filled = 1 or 0, if you want the circle solid or not
14 Jan 1998: 2 if for points on a filled circle
----------------------------------------------------------------*/
#define NCIR 12 /* hollow circle */
#define NBAL 21 /* filled circle */
#define NBAX 25 /* with points */
#define NBTOP NBAX /* max # of points */
static XPoint xball[] = {
{-1,-2},{ 0,-2},{ 1,-2},
{ 2,-1},{ 2, 0},{ 2, 1},
{ 1, 2},{ 0, 2},{-1, 2},
{-2, 1},{-2, 0},{-2,-1}, /* NCIR ends here */
{-1,-1},{-1, 0},{-1, 1},
{ 0,-1},{ 0, 0},{ 0, 1},
{ 1,-1},{ 1, 0},{ 1, 1}, /* NBAL ends here */
{ 0,-3},{ 0, 3},{ 3, 0},
{-3, 0} /* NBAX ends here */
} ;
/*------------------ draw into Pixmap (the graph itself) -----------------------*/
void GRA_small_circle( MCW_grapher *grapher, int xwin, int ywin, int filled )
{
int i, ncirc ;
XPoint a[NBTOP] ;
switch( filled ){
default: ncirc = NCIR ; break ;
case 1: ncirc = NBAL ; break ;
case 2: ncirc = NBAX ; break ;
}
for( i=0 ; i < ncirc ; i++ ){
a[i].x = xball[i].x + xwin ;
a[i].y = xball[i].y + ywin ;
}
XDrawPoints( grapher->dc->display, grapher->fd_pxWind,
grapher->dc->myGC, a, ncirc, CoordModeOrigin ) ;
return ;
}
/*------------------ draw into window (the graph overlay) -----------------------*/
void GRA_overlay_circle( MCW_grapher *grapher, int xwin, int ywin, int filled )
{
int i, ncirc ;
XPoint a[NBTOP] ;
switch( filled ){
default: ncirc = NCIR ; break ;
case 1: ncirc = NBAL ; break ;
case 2: ncirc = NBAX ; break ;
}
for( i=0 ; i < ncirc ; i++ ){
a[i].x = xball[i].x + xwin ;
a[i].y = xball[i].y + ywin ;
}
DC_linewidth( grapher->dc, 0 ) ;
XDrawPoints( grapher->dc->display, XtWindow(grapher->draw_fd),
grapher->dc->myGC, a, ncirc, CoordModeOrigin ) ;
return ;
}
/*---------------------------------------------------------------------------*/
void GRA_draw_circle( MCW_grapher *grapher , int xc , int yc , int rad )
{
int xb,yb ;
unsigned int ww ;
if( rad < 0 ) rad = 0 ;
xb = xc-rad ; yb = yc-rad ; ww = 2*rad ;
XDrawArc( grapher->dc->display , XtWindow(grapher->draw_fd) ,
grapher->dc->myGC , xb,yb , ww,ww , 0,360*64 ) ;
}
/*-----------------------------------------------
redraw stuff that overlays the pixmap
-------------------------------------------------*/
#define SHORT_NAME_WIDTH 384
static char * long_index_name = "index=" ;
static char * short_index_name = "#" ;
static char * long_value_name = " value=" ;
static char * short_value_name = "=" ;
static char * long_time_name = " at " ;
static char * short_time_name = "@" ;
void GRA_redraw_overlay( MCW_grapher * grapher )
{
Window win ;
Display * dis ;
int ii , xxx , jj ;
float val ;
char buf[16] , strp[128] ;
char * vbuf , *iname , *vname ;
ENTRY("GRA_redraw_overlay") ;
if( ! GRA_REALZ(grapher) ){ STATUS("ILLEGAL CALL") ; EXRETURN ; }
if( ! MCW_widget_visible(grapher->draw_fd) ) EXRETURN ; /* 03 Jan 1999 */
if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
/* erase contents of window (that aren't in the pixmap) */
dis = grapher->dc->display ;
win = XtWindow(grapher->draw_fd) ;
XClearWindow( dis , win ) ;
EXRONE(grapher) ; /* 22 Sep 2000 */
/* draw some circles over ignored data points [23 May 2005] */
if( grapher->init_ignore > 0 && !grapher->textgraph ){
DC_fg_color( grapher->dc , IGNORE_COLOR(grapher) ) ;
jj = NBOT(grapher) ; /* first point to plot */
xxx = NTOP(grapher) ; /* last */
xxx = MIN (xxx , grapher->init_ignore) ; /* point */
xxx = MIN (xxx , ii+grapher->nncen) ; /* to plot */
for( ii=jj ; ii < xxx ; ii++ )
#if 0
GRA_overlay_circle( grapher , grapher->cen_line[ii-jj].x ,
grapher->cen_line[ii-jj].y , 1 ) ;
#else
GRA_draw_circle( grapher , grapher->cen_line[ii-jj].x ,
grapher->cen_line[ii-jj].y , 4 ) ;
#endif
}
/* 22 July 1996:
draw a ball on the graph at the currently display time_index */
ii = grapher->time_index ; jj = NBOT(grapher) ;
if( ii >= jj &&
ii < NTOP(grapher) && ii-jj < grapher->nncen && !grapher->textgraph ){
DC_fg_color( grapher->dc , IDEAL_COLOR(grapher) ) ;
GRA_overlay_circle( grapher , grapher->cen_line[ii-jj].x ,
grapher->cen_line[ii-jj].y , 2 ) ;
}
/* draw text showing value at currently displayed time_index */
if( ii >= 0 && grapher->cen_tsim != NULL && ii < grapher->cen_tsim->nx ){
val = MRI_FLOAT_PTR(grapher->cen_tsim)[ii] ;
AV_fval_to_char( val , buf ) ;
vbuf = (buf[0]==' ') ? buf+1 : buf ;
if( grapher->fWIDE < SHORT_NAME_WIDTH ){
iname = short_index_name ; vname = short_value_name ;
} else {
iname = long_index_name ; vname = long_value_name ;
}
sprintf( strp , "%s%d%s%s" , iname,ii , vname,vbuf ) ;
if( grapher->cen_tsim->dx != 0.0 ){
val = grapher->cen_tsim->xo + ii * grapher->cen_tsim->dx ;
AV_fval_to_char( val , buf ) ;
vbuf = (buf[0]==' ') ? buf+1 : buf ;
ii = strlen(strp) ;
sprintf( strp+ii , "%s%s" ,
(grapher->fWIDE < SHORT_NAME_WIDTH) ? short_time_name
: long_time_name, vbuf ) ;
}
xxx = MAX( grapher->xx_text_2 ,
grapher->xorigin[grapher->xc][grapher->yc] ) ;
if( grapher->init_ignore > 0 ) xxx = MAX( xxx , grapher->xx_text_2p ) ;
DC_fg_color( grapher->dc , IDEAL_COLOR(grapher) ) ;
overlay_txt( grapher, xxx , GB_DLY-15 , strp ) ;
}
/* no more to do now */
XFlush( dis ) ;
EXRETURN ;
}
/*------------------------------------------------------------------
redraw entire graph;
code is a mask of special values:
0 = default action
PLOTCODE_AUTOSCALE = scale graphs automatically
-------------------------------------------------------------------*/
void redraw_graph( MCW_grapher *grapher , int code )
{
int x, y , www,xxx , rrr ;
int xc = grapher->xc , yc = grapher->yc ;
char strp[256] , buf[64] ;
int xd,yd,zd ;
ENTRY("redraw_graph") ;
if( ! GRA_REALZ(grapher) ){ STATUS("ILLEGAL ENTRY"); EXRETURN; }
if( grapher->fd_pxWind == (Pixmap) 0 ){ STATUS("ILLEGAL ENTRY"); EXRETURN; }
if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
/*---- draw the graphs ----*/
erase_fdw ( grapher ) ;
draw_grids ( grapher ) ;
plot_graphs( grapher , code ) ;
DC_fg_color( grapher->dc , TEXT_COLOR(grapher) ) ;
if( TPTS(grapher) < 2 ){ /* 22 Sep 2000 */
fd_txt( grapher , GL_DLX+5, 35,
"Can't draw graphs for this dataset: Num < 2" ) ;
fd_px_store( grapher ) ;
EXRETURN ;
}
/*---- draw some strings for informative purposes ----*/
DC_fg_color( grapher->dc , TEXT_COLOR(grapher) ) ;
/*** y axis labels ***/
if( !grapher->textgraph ){
AV_fval_to_char( grapher->pmax[xc][yc] , strp ) ;
www = DC_text_width(grapher->dc,strp) ;
xxx = GL_DLX - www - 2 ;
xxx = MAX(0,xxx) ;
fd_txt( grapher , xxx , GB_DLY + grapher->gy_max - MYTXT, strp) ;
AV_fval_to_char( grapher->pmax[xc][yc] - grapher->pmin[xc][yc] , buf ) ;
if( buf[0] == ' ' ) buf[0] = '+' ;
sprintf( strp , "[%s]" , buf ) ;
www = DC_text_width(grapher->dc,strp) ;
xxx = GL_DLX - www + 2 ;
xxx = MAX(0,xxx) ;
fd_txt( grapher , xxx , GB_DLY + grapher->gy_max - MYTXT - 14 , strp) ;
AV_fval_to_char( grapher->pmin[xc][yc] , strp ) ;
www = DC_text_width(grapher->dc,strp) ;
xxx = GL_DLX - www - 2 ;
xxx = MAX(0,xxx) ;
fd_txt( grapher , xxx , GB_DLY + 5, strp) ;
}
/*** bottom of the page coordinates stuff ***/
/* first column */
grapher->xx_text_1 = GL_DLX+5 ;
xd = grapher->xpoint ; yd = grapher->ypoint ; zd = grapher->zpoint ;
#ifndef DONT_MANGLE_XYZ
{ THD_ivec3 id ;
id = THD_fdind_to_3dind( grapher->getaux , TEMP_IVEC3(xd,yd,zd) ) ;
xd = id.ijk[0] ; yd = id.ijk[1] ; zd = id.ijk[2] ; }
#endif
sprintf(strp,"X: %d", xd) ;
fd_txt( grapher , GL_DLX+5 , 35, strp) ;
xxx = DC_text_width(grapher->dc,strp) ;
sprintf(strp,"Y: %d", yd) ;
fd_txt( grapher , GL_DLX+5 , 21, strp) ;
www = DC_text_width(grapher->dc,strp) ; xxx = MAX(xxx,www) ;
if( grapher->status->nz > 1 ){
sprintf(strp,"Z: %d", zd) ;
fd_txt( grapher , GL_DLX+5 , 7, strp) ;
www = DC_text_width(grapher->dc,strp) ; xxx = MAX(xxx,www) ;
}
/* second column */
grapher->xx_text_2 = xxx = xxx + GL_DLX + 15 ;
DC_linewidth( grapher->dc , 0 ) ;
fd_line( grapher , xxx-7 , 41 , xxx-7 , 5 ) ;
if( grapher->init_ignore > 0 ){ /* 23 May 2005 */
sprintf(strp,"Ignore%4d",grapher->init_ignore) ;
fd_txt( grapher , xxx , 35, strp) ;
}
sprintf(strp,"Grid:%5d", grapher->grid_spacing ) ;
rrr = DC_text_width(grapher->dc,strp) ;
if( !grapher->textgraph ){
if( grapher->fscale > 0 ){ /* 04 Feb 1998: */
AV_fval_to_char( grapher->fscale , buf ) ; /* put scale on graph, too */
www = strlen(strp) ;
sprintf(strp+www," Scale:%s pix/datum",buf) ;
} else if( grapher->fscale < 0 ){
AV_fval_to_char( -grapher->fscale , buf ) ;
www = strlen(strp) ;
sprintf(strp+www," Scale:%s datum/pix",buf) ;
}
}
fd_txt( grapher , xxx , 21, strp) ;
xxx = DC_text_width(grapher->dc,strp) ; /* 19 Dec 2003 [rickr] */
{ int bb=TBOT(grapher) , tt=TTOP(grapher)-1 ;
if( bb > 99 || tt > 99 )
sprintf(strp,"#%4d:%-4d" , bb,tt ) ;
else
sprintf(strp,"Num%3d:%-3d" , bb,tt ) ;
}
fd_line( grapher ,
grapher->xx_text_2+rrr+3 , (grapher->init_ignore > 0) ? 41 : 31 ,
grapher->xx_text_2+rrr+3 , 5 ) ;
grapher->xx_text_2p = grapher->xx_text_2+rrr+7 ; /* 23 May 2005 */
if( !grapher->textgraph ){
switch( grapher->common_base ){
default:
case BASELINE_INDIVIDUAL:
strcat(strp," Base: separate") ; break ;
case BASELINE_COMMON:
strcat(strp," Base: common") ; break ;
case BASELINE_GLOBAL:
strcat(strp," Base: global") ; break ;
}
}
fd_txt( grapher , grapher->xx_text_2 , 7, strp ) ;
/* add third column 19 Dec 2003 [rickr] */
www = DC_text_width(grapher->dc,strp) ; xxx = MAX(xxx,www) ;
grapher->xx_text_3 = grapher->xx_text_2 + xxx + 15 ;
if( !grapher->textgraph && !ISONE(grapher) ){
sprintf(strp,"Mean: %10s", MV_format_fval(grapher->tmean[xc][yc]) ) ;
fd_txt( grapher , grapher->xx_text_3 , 21, strp ) ;
sprintf(strp,"Sigma:%10s", MV_format_fval(grapher->tstd[xc][yc]) ) ;
fd_txt( grapher , grapher->xx_text_3 , 7, strp ) ;
fd_line( grapher , grapher->xx_text_3-7 , 31 , grapher->xx_text_3-7 , 5 ) ;
}
/*** flush the pixmap to the screen ***/
fd_px_store( grapher ) ;
/*** draw any overlay stuff ***/
GRA_redraw_overlay( grapher ) ;
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
/** 27 Jan 2004 **/
if( MCW_val_bbox(grapher->fmenu->fim_editref_winaver_bbox) )
GRA_winaver_setref( grapher ) ;
grapher->never_drawn = 0 ;
EXRETURN ;
}
/*------------------------------------------------
Plot text in fd_pxWind at x,y position
relative to lower left corner (!).
--------------------------------------------------*/
void fd_txt( MCW_grapher * grapher , int x , int y , char * str )
{
XDrawString( grapher->dc->display, grapher->fd_pxWind,
grapher->dc->myGC , x , grapher->fHIGH-y ,
str , strlen(str) ) ;
return ;
}
/*-----------------------------------------------*/
void overlay_txt( MCW_grapher * grapher , int x , int y , char * str )
{
XDrawString( grapher->dc->display, XtWindow(grapher->draw_fd) ,
grapher->dc->myGC , x , grapher->fHIGH-y ,
str , strlen(str) ) ;
return ;
}
/*-----------------------------------------------*/
static void fd_line( MCW_grapher *grapher , int x1,int y1, int x2,int y2 )
{
XDrawLine( grapher->dc->display , grapher->fd_pxWind ,
grapher->dc->myGC , x1,grapher->fHIGH-y1,x2,grapher->fHIGH-y2 ) ;
return ;
}
/*-----------------------------------------------*/
#define GRID_MAX 12
static int grid_ar[GRID_MAX] =
{ 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000 } ;
static void auto_grid( MCW_grapher *grapher , int npoints )
{
int ii ;
if( npoints < 2 ) return ; /* 02 Apr 2004 */
for( ii=GRID_MAX-1 ; ii > 0 ; ii-- )
if( grid_ar[ii] <= npoints/3 ) break;
grapher->grid_index = ii ;
grapher->grid_spacing = grid_ar[ii] ;
grapher->grid_fixed = 0 ; /* 02 Apr 2004 */
return ;
}
/*-----------------------------------------------*/
void init_const( MCW_grapher *grapher )
{
int ii ;
ENTRY("init_const") ;
if( !GRA_VALID(grapher) ) EXRETURN ;
if( grapher->fscale == 0 ) grapher->fscale = 1 ;
grapher->mat_max = MAT_MAX ;
grapher->mat_max = MIN( grapher->mat_max , grapher->status->nx ) ;
grapher->mat_max = MIN( grapher->mat_max , grapher->status->ny ) ;
if( grapher->mat <= 0 ) grapher->mat = INIT_GR_gmat ;
grapher->mat = MIN( grapher->mat , grapher->mat_max ) ;
if( grapher->xpoint < 0 || grapher->xpoint >= grapher->status->nx )
grapher->xpoint = grapher->status->nx / 2 ;
if( grapher->ypoint < 0 || grapher->ypoint >= grapher->status->ny )
grapher->ypoint = grapher->status->ny / 2 ;
if( grapher->zpoint < 0 || grapher->zpoint >= grapher->status->nz )
grapher->zpoint = grapher->status->nz / 2 ;
if( grapher->grid_index < 0 ) auto_grid( grapher, NPTS(grapher) ) ;
#if 0
if( grapher->grid_color < 0 )
grapher->grid_color = 1 ; /* first overlay color */
#endif
if( grapher->time_index < 0 )
grapher->time_index = 0 ;
else if( grapher->time_index >= grapher->status->num_series )
grapher->time_index = grapher->status->num_series - 1 ;
init_mat(grapher) ;
EXRETURN ;
}
/*-----------------------------------------------------------
Draw numbers instead of graphs -- 22 Sep 2000 -- RWCox
-------------------------------------------------------------*/
void text_graphs( MCW_grapher *grapher )
{
MRI_IMAGE *tsim ;
int index, ix, iy, xtemp,ytemp,ztemp , xoff,yoff ;
int iv , jv , www ;
char str[64] , *strp ;
ENTRY("text_graphs") ;
if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
DC_fg_color( grapher->dc , TEXT_COLOR(grapher) ) ;
iv = grapher->time_index ;
if( iv < 0 )
iv = 0 ;
else if( iv >= grapher->status->num_series )
iv = grapher->status->num_series - 1 ;
ztemp = grapher->zpoint * grapher->status->ny * grapher->status->nx ;
for( ix=0 ; ix < grapher->mat ; ix++ ){
xtemp = grapher->xpoint + ix - grapher->xc ;
if( xtemp < 0 ) xtemp += grapher->status->nx ;
else if( xtemp >= grapher->status->nx ) xtemp -= grapher->status->nx ;
for( iy=0 ; iy < grapher->mat ; iy++ ){
ytemp = grapher->ypoint - iy + grapher->yc ;
if( ytemp < 0 ) ytemp += grapher->status->ny ;
else if( ytemp >= grapher->status->ny ) ytemp -= grapher->status->ny ;
index = ztemp + ytemp * grapher->status->nx + xtemp ;
#if 0
tsim = (MRI_IMAGE *) grapher->getser( index , graCR_getseries ,
grapher->getaux ) ;
#else
CALL_getser( grapher , index,graCR_getseries , MRI_IMAGE *,tsim ) ;
#endif
if( tsim == NULL ) break ;
if( tsim->nx < 1 ){ mri_free(tsim); break; } /* shouldn't happen */
if( tsim->kind != MRI_float ){
MRI_IMAGE *qim = mri_to_float(tsim) ;
mri_free(tsim) ; tsim = qim ;
}
if( ix == grapher->xc && iy == grapher->yc ){
mri_free( grapher->cen_tsim ) ; /* copy time series too */
grapher->cen_tsim = mri_to_float( tsim ) ;
}
#if 0
if( grapher->transform0D_func != NULL )
# if 0
grapher->transform0D_func( tsim->nx , MRI_FLOAT_PTR(tsim) ) ;
# else
AFNI_CALL_0D_function( grapher->transform0D_func ,
tsim->nx , MRI_FLOAT_PTR(tsim) ) ;
# endif
#endif
jv = iv ; if( jv >= tsim->nx ) jv = tsim->nx - 1 ;
AV_fval_to_char( MRI_FLOAT_PTR(tsim)[jv] , str ) ;
mri_free(tsim) ;
strp = (str[0] == ' ') ? str+1 : str ;
www = DC_text_width(grapher->dc,strp) ;
fd_txt( grapher , grapher->xorigin[ix][iy] + (grapher->gx-www)/2 ,
grapher->yorigin[ix][iy] + 2 ,
strp ) ;
}
}
EXRETURN ;
}
/*-----------------------------------------------------------
Plot real graphs to pixmap
-------------------------------------------------------------*/
void plot_graphs( MCW_grapher *grapher , int code )
{
MRI_IMAGE *tsim ;
MRI_IMARR *tsimar ;
float *tsar ;
float tsbot=0.0 , ftemp , tstop ;
int i, m, index, ix, iy, xtemp,ytemp,ztemp , xoff,yoff , its,ibot,itop;
int ptop,pbot,pnum,qnum , tbot,ttop,tnum , ntmax ; /* 17 Mar 2004 */
static int *plot = NULL ; /* arrays to hold plotting coordinates */
static XPoint *a_line = NULL ;
static int nplot = 0 ;
MRI_IMARR *dplot_imar = NULL ; /* 08 Nov 1996 */
int dplot = 0 ;
MRI_IMARR *eximar ;
int iex ;
float nd_bot , nd_top , nd_dif ; /* 03 Feb 1998 */
int set_scale = ( (code & PLOTCODE_AUTOSCALE) != 0 ||
grapher->never_drawn ) ;
MRI_IMAGE *dsim ; /* 07 Aug 2001: for double plot */
float *dsar ;
#define OVI_MAX 19
int tt, use_ovi, ovi[OVI_MAX] ; /* 29 Mar 2002: for multi-plots */
ENTRY("plot_graphs") ;
if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
/* check if we draw text instead of curves */
if( grapher->status->num_series < 1 ){
EXRETURN ;
} else if( grapher->status->num_series == 1 ||
grapher->textgraph || TPTS(grapher) < 2 ){
text_graphs( grapher ) ;
EXRETURN ;
}
GRA_fixup_xaxis( grapher ) ; /* 09 Jan 1998 */
/* set colors and line widths */
DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
/* 17 Mar 2004: we will plot from pbot..ptop-1, with data from tbot..ttop-1 */
ptop = NTOP(grapher) ; pbot = NBOT(grapher) ;
if( pbot >= ptop ){
pbot = 0 ; ptop = grapher->status->num_series ;
}
ttop = TTOP(grapher) ; ttop = MIN(ttop,ptop) ; tbot = pbot ;
if( ttop <= tbot || ttop > grapher->status->num_series ){
ttop = MIN(ptop,grapher->status->num_series) ;
}
pnum = ptop-pbot ; tnum = ttop-tbot ;
if( pnum <= 1 || tnum <= 1 ) EXRETURN ; /* should never happen? */
/* set aside space for plotting, etc. */
#define NPLOT_INIT 9999 /* 29 Apr 1997 */
itop = MAX( NPLOT_INIT , grapher->status->num_series ) ;
if( nplot == 0 || nplot < itop ){
myXtFree(a_line) ; myXtFree(plot) ;
nplot = itop ;
plot = (int *) XtMalloc( sizeof(int) * itop ) ;
a_line = (XPoint *) XtMalloc( sizeof(XPoint) * itop ) ;
}
if( grapher->ncen_line < itop ){
myXtFree(grapher->cen_line) ;
grapher->cen_line = (XPoint *) XtMalloc( sizeof(XPoint) * itop ) ;
grapher->ncen_line = itop ;
}
/* set the bottom point at which to compute time series statistics */
ibot = grapher->init_ignore ;
if( ibot >= ttop-1 ) ibot = 0 ;
ibot = MAX(ibot,tbot) ; /* 17 Mar 2004 */
/** loop over matrix of graphs and get all the time series for later **/
INIT_IMARR(tsimar) ;
/** 08 Nov 1996: initialize second array for double plotting **/
/** 07 Aug 2001: modify to allow for multiple dplot cases **/
if( grapher->transform1D_func != NULL &&
MCW_val_bbox(grapher->opt_dplot_bbox) != DPLOT_OFF ){
INIT_IMARR(dplot_imar) ;
dplot = MCW_val_bbox(grapher->opt_dplot_bbox) ; /* 07 Aug 2001 */
}
GRA_CLEAR_tuser( grapher ) ; /* 22 Apr 1997 */
/* 3D index offset to correct slice number */
ztemp = grapher->zpoint * grapher->status->ny * grapher->status->nx ;
ntmax = 0 ; /* will be length of longest time series found below */
for( ix=0 ; ix < grapher->mat ; ix++ ){
/** compute the 3D index of the desired time series **/
xtemp = grapher->xpoint + ix - grapher->xc ;
if( xtemp < 0 ) xtemp += grapher->status->nx ; /* wrap */
else if( xtemp >= grapher->status->nx ) xtemp -= grapher->status->nx ;
for( iy=0 ; iy < grapher->mat ; iy++ ){
ytemp = grapher->ypoint - iy + grapher->yc ;
if( ytemp < 0 ) ytemp += grapher->status->ny; /* wrap */
else if( ytemp >= grapher->status->ny ) ytemp -= grapher->status->ny;
index = ztemp + ytemp * grapher->status->nx + xtemp ; /* 3D index in dataset */
/** get the desired time series, using the provided routine **/
#if 0
tsim = (MRI_IMAGE *) grapher->getser( index , graCR_getseries ,
grapher->getaux ) ;
#else
CALL_getser( grapher , index,graCR_getseries , MRI_IMAGE *,tsim ) ;
#endif
/* 08 Nov 1996: allow for return of NULL timeseries */
if( tsim == NULL ){
ADDTO_IMARR(tsimar,NULL) ;
if( dplot ) ADDTO_IMARR(dplot_imar,NULL) ;
continue ; /* skip to next iy */
}
ntmax = MAX( ntmax , tsim->nx ) ;
/** convert time series to floats, if need be **/
if( tsim->kind != MRI_float ){
MRI_IMAGE *qim = mri_to_float(tsim) ;
mri_free(tsim) ; tsim = qim ;
}
/* 22 Oct 1996: transform each point, if ordered */
if( grapher->transform0D_func != NULL ){
STATUS("about to perform 0D transformation") ;
#if 0
grapher->transform0D_func( tsim->nx , MRI_FLOAT_PTR(tsim) ) ;
#else
AFNI_CALL_0D_function( grapher->transform0D_func ,
tsim->nx , MRI_FLOAT_PTR(tsim) ) ;
#endif
}
/* 03 Nov 1996: 1D transformations, too */
/* 08 Nov 1996: double plotting, too */
if( grapher->transform1D_func != NULL ){
MRI_IMAGE * qim ; /* image to be transformed */
if( dplot ){ /* copy and save original */
qim = mri_to_float(tsim) ; /* if double plot is on */
ADDTO_IMARR(dplot_imar,qim) ;
}
else
qim = tsim ; /* transform original image */
STATUS("about to perform 1D transformation") ;
if( grapher->transform1D_flags & NEEDS_DSET_INDEX ){ /* 18 May 2000 */
#ifdef BE_AFNI_AWARE
FD_brick *br = (FD_brick *) grapher->getaux ;
THD_ivec3 id ;
id = THD_fdind_to_3dind( br ,
TEMP_IVEC3(xtemp,ytemp,grapher->zpoint) );
AFNI_store_dset_index(
id.ijk[0]
+id.ijk[1] * br->nxyz.ijk[0]
+id.ijk[2] * br->nxyz.ijk[0] * br->nxyz.ijk[1] , 0 ) ;
#else
AFNI_store_dset_index(-1,0) ;
#endif
}
if( ! (grapher->transform1D_flags & PROCESS_MRI_IMAGE) ){ /* older code: */
/* process image */
if( ! (grapher->transform1D_flags & RETURNS_STRING) ){ /* contents only */
#if 0
grapher->transform1D_func( qim->nx , qim->xo , qim->dx ,
MRI_FLOAT_PTR(qim) ) ;
#else
AFNI_CALL_1D_function( grapher->transform1D_func ,
qim->nx , qim->xo , qim->dx ,
MRI_FLOAT_PTR(qim) ) ;
#endif
} else {
char * quser = NULL ;
#if 0
grapher->transform1D_func( qim->nx , qim->xo , qim->dx ,
MRI_FLOAT_PTR(qim) , &quser ) ;
#else
AFNI_CALL_1D_funcstr( grapher->transform1D_func ,
qim->nx , qim->xo , qim->dx ,
MRI_FLOAT_PTR(qim) , quser ) ;
#endif
if( quser != NULL )
grapher->tuser[ix][iy] = XtNewString(quser) ;
}
} else { /* 28 Mar 2002: process MRI_IMAGE struct */
/* in place */
if( ! (grapher->transform1D_flags & RETURNS_STRING) ){
#if 0
grapher->transform1D_func( qim ) ;
#else
AFNI_CALL_1D_funcmrim( grapher->transform1D_func , qim ) ;
#endif
} else {
char *quser = NULL ;
#if 0
grapher->transform1D_func( qim , &quser ) ;
#else
AFNI_CALL_1D_funcmrimstr( grapher->transform1D_func , qim,quser ) ;
#endif
if( quser != NULL )
grapher->tuser[ix][iy] = XtNewString(quser) ;
}
}
/* At this point, qim is transformed;
if dplot is on, then it is saved in dplot_imar;
if dplot is off, then qim == tsim, and it will be saved in tsimar, below */
} /* end of transform1D */
/* put this (possibly transformed) image on the list of those to plot */
ADDTO_IMARR(tsimar,tsim) ;
}
}
/** find the average time series [27 Jan 2004] **/
if( ntmax > 1 && IMARR_COUNT(tsimar) > 0 ){
float *avar , fac ; int nax ;
STATUS("about to make average time series") ;
if( grapher->ave_tsim != NULL ) mri_free(grapher->ave_tsim) ;
grapher->ave_tsim = mri_new( ntmax , 1 , MRI_float ) ;
avar = MRI_FLOAT_PTR(grapher->ave_tsim) ; /* is full of 0's already */
for( ix=0 ; ix < IMARR_COUNT(tsimar) ; ix++ ){
tsim = IMARR_SUBIMAGE(tsimar,ix) ; if( tsim == NULL ) continue ;
tsar = MRI_FLOAT_PTR(tsim) ; if( tsar == NULL ) continue ;
nax = MIN( ntmax , tsim->nx ) ;
for( i=0 ; i < nax ; i++ ) avar[i] += tsar[i] ;
}
fac = 1.0 / IMARR_COUNT(tsimar) ;
for( i=0 ; i < grapher->ave_tsim->nx ; i++ ) avar[i] *= fac ;
if( MCW_val_bbox(grapher->fmenu->fim_editref_winaver_bbox) ){
if( grapher->ref_ts == NULL ) INIT_IMARR( grapher->ref_ts ) ;
if( IMARR_COUNT(grapher->ref_ts) == 0 ){
ADDTO_IMARR( grapher->ref_ts , grapher->ave_tsim ) ; /* create first one */
} else {
IMARR_SUBIMAGE(grapher->ref_ts,0) = grapher->ave_tsim ; /* replace first one */
}
}
} else if( grapher->ave_tsim != NULL ){
mri_free(grapher->ave_tsim) ; grapher->ave_tsim = NULL ;
}
/** find some statistics of each time series **/
STATUS("finding statistics of time series") ;
/* stuff for setting vertical scale */
if( set_scale ){
nd_bot = WAY_BIG ; nd_top = nd_dif = - WAY_BIG ; /* 03 Feb 1998 */
}
for( ix=0,its=0 ; ix < grapher->mat ; ix++ ){
for( iy=0 ; iy < grapher->mat ; iy++,its++ ){
float qbot,qtop ;
double qsum , qsumq ;
tsim = IMARR_SUBIMAGE(tsimar,its) ;
if( tsim == NULL || tsim->nx < 2 ){
grapher->tmean[ix][iy] = grapher->tbot[ix][iy] =
grapher->ttop[ix][iy] = grapher->tstd[ix][iy] = 0.0 ;
grapher->tmed[ix][iy] = grapher->tmad[ix][iy] = 0.0 ; /* 08 Mar 2001 */
grapher->sbot[ix][iy] = grapher->stop[ix][iy] = 0 ; /* 19 Mar 2004 */
continue ;
}
tsar = MRI_FLOAT_PTR(tsim) ; /* stats from ibot..itop-1 */
itop = MIN( ttop , tsim->nx ) ; /* ibot was set earlier */
if( itop-ibot < 2 ){ /* too short to deal with */
grapher->tmean[ix][iy] = grapher->tbot[ix][iy] =
grapher->ttop[ix][iy] = grapher->tstd[ix][iy] = 0.0 ;
grapher->tmed[ix][iy] = grapher->tmad[ix][iy] = 0.0 ; /* 08 Mar 2001 */
continue ; /* to next iy */
}
qbot = qtop = tsar[ibot] ;
qsum = qsumq = 0.0 ;
for( i=ibot ; i < itop ; i++ ){ /* compute stats over visible data */
qbot = MIN( qbot , tsar[i] ) ;
qtop = MAX( qtop , tsar[i] ) ;
qsum += tsar[i] ;
qsumq += tsar[i] * tsar[i] ;
}
grapher->tbot[ix][iy] = qbot ; grapher->ttop[ix][iy] = qtop ;
grapher->sbot[ix][iy] = ibot ; grapher->stop[ix][iy] = itop-1 ; /* 19 Mar 2004 */
qsum = qsum / (itop-ibot) ; grapher->tmean[ix][iy] = qsum ;
qsumq = (qsumq - (itop-ibot) * qsum * qsum) / (itop-ibot-1.0) ;
grapher->tstd[ix][iy] = (qsumq > 0.0) ? sqrt(qsumq) : 0.0 ;
qmedmad_float( itop-ibot , tsar+ibot , /* 08 Mar 2001 */
&(grapher->tmed[ix][iy]) ,
&(grapher->tmad[ix][iy]) ) ;
if( set_scale ){ /* 03 Feb 1998 */
if( tsim->ny > 1 ){
for( tt=1 ; tt < tsim->ny ; tt++ ){ /* get min/max over */
tsar += tsim->nx ; /* multiple time series */
for( i=ibot ; i < itop ; i++ ){ /* if they are present */
qbot = MIN( qbot , tsar[i] ) ;
qtop = MAX( qtop , tsar[i] ) ;
}
}
}
nd_bot = MIN( nd_bot , qbot ) ; /* vertical scale stuff */
nd_top = MAX( nd_top , qtop ) ;
nd_dif = MAX( nd_dif , (qtop-qbot) ) ;
}
}
}
/* 03 Feb 1998: set the initial vertical scale factor */
if( set_scale && nd_bot < nd_top && nd_dif > 0.0 ){
switch( grapher->common_base ){
default:
case BASELINE_INDIVIDUAL:
grapher->fscale = 0.9 * grapher->gy / nd_dif ; /* biggest range */
break ;
case BASELINE_COMMON:
grapher->fscale = 0.9 * grapher->gy / (nd_top-nd_bot) ; /* global range */
break ;
case BASELINE_GLOBAL:{
float vbot = (nd_top > grapher->global_base)
? grapher->global_base : nd_bot ;
grapher->fscale = 0.9 * grapher->gy / (nd_top-vbot) ;
}
break ;
}
if( grapher->fscale > 0.0 && grapher->fscale < 1.0 ) /* switcheroo */
grapher->fscale = -1.0 / grapher->fscale ;
if( grapher->fscale > 4.0 ) /* even value */
grapher->fscale = (int) grapher->fscale ;
else if( grapher->fscale > 1.0 )
grapher->fscale = 0.5 * ((int)(2.0*grapher->fscale)) ;
else if( grapher->fscale < -4.0 )
grapher->fscale = -((int)(1.0-grapher->fscale)) ;
else if( grapher->fscale < -1.0 )
grapher->fscale = -0.5 * ((int)(1.0-2.0*grapher->fscale)) ;
}
/** find the smallest element in all the time series, if needed **/
if( grapher->common_base == BASELINE_COMMON ){
int first = 1 ;
STATUS("finding common base") ;
for( ix=0 ; ix < tsimar->num ; ix++ ){
tsim = IMARR_SUBIMAGE(tsimar,ix) ;
if( tsim == NULL || tsim->nx < 2 ) continue ; /* skip */
tsar = MRI_FLOAT_PTR(tsim) ;
itop = MIN( ttop , tsim->nx ) ;
if( first && ibot < itop ){ tsbot = tsar[ibot] ; first = 0 ; }
for( tt=0 ; tt < tsim->ny ; tt++ ){ /* 29 Mar 2002 */
for( i=ibot ; i < itop ; i++ ) tsbot = MIN( tsbot , tsar[i] ) ;
tsar += tsim->nx ;
}
}
} else if( grapher->common_base == BASELINE_GLOBAL ){ /* 07 Aug 2001 */
tsbot = grapher->global_base ;
}
/**** loop over matrix of graphs and plot them all to the pixmap ****/
STATUS("starting time series graph loop") ;
for( ix=0,its=0 ; ix < grapher->mat ; ix++ ){
for( iy=0 ; iy < grapher->mat ; iy++,its++ ){
tsim = IMARR_SUBIMAGE(tsimar,its) ;
if( tsim == NULL || tsim->nx < 2 ) continue ; /* skip to next iy */
tsar = MRI_FLOAT_PTR(tsim) ;
itop = MIN( ttop , tsim->nx ) ;
qnum = itop - pbot ; /* number of points to plot here */
if( qnum < 2 ) continue ; /* skip to next iy */
/** find bottom value for this graph, if needed **/
if( grapher->common_base == BASELINE_INDIVIDUAL ){
tsbot = tsar[ibot] ;
for( tt=0 ; tt < tsim->ny ; tt++ ){
for( i=ibot ; i < itop ; i++ ) tsbot = MIN(tsbot,tsar[i]) ;
tsar += tsim->nx ;
}
}
grapher->pmin[ix][iy] = tsbot ; /* value at graph bottom */
/** 29 Mar 2002: decode 'color:' from tsim->name, if present **/
use_ovi = (tsim->name!=NULL) && (strncmp(tsim->name,"color: ",7)==0) ;
if( use_ovi ){
char *cpt = tsim->name+6 ; int nuse, ngood ;
for( tt=0 ; tt < OVI_MAX ; tt++ )
ovi[tt] = DATA_COLOR(grapher) ;
for( tt=0 ; tt < OVI_MAX ; tt++ ){
ngood = sscanf(cpt,"%d%n",ovi+tt,&nuse) ;
if( ngood < 1 ) break ;
cpt += nuse ; if( *cpt == '\0' ) break ;
}
}
tsar = MRI_FLOAT_PTR(tsim) ;
for( tt=0 ; tt < tsim->ny ; tt++ ){ /* 29 Mar 2002: multi-plots */
/** scale graph vertically:
fscale > 0 ==> this many pixels per unit of tsar
fscale < 0 ==> this many units of tsar per pixel **/
ftemp = grapher->fscale ;
if( ftemp == 0.0 ) ftemp = 1.0 ;
else if( ftemp < 0.0 ) ftemp = -1.0 / ftemp ;
/* scale to vertical pixels: before the ignore level */
for( i=pbot ; i < MIN(ibot,itop) ; i++ )
plot[i-pbot] = (tsar[ibot] - tsbot) * ftemp ;
/* scale after the ignore level */
for( i=ibot ; i < itop ; i++ )
plot[i-pbot] = (tsar[i] - tsbot) * ftemp ;
/* now have qnum points in plot[] */
grapher->pmax[ix][iy] = tsbot + grapher->gy / ftemp ; /* value at graph top */
/** Compute X11 line coords from pixel heights in plot[].
N.B.: X11 y is DOWN the screen, but plot[] is UP the screen **/
ftemp = grapher->gx / (pnum-1.0) ; /* x scale factor */
/* X11 box for graph:
x = xorigin[ix][iy] .. xorigin[ix][iy]+gx (L..R)
y = fHIGH-yorigin[ix][iy]-gy .. fHIGH-yorigin[ix][iy] (T..B) */
xoff = grapher->xorigin[ix][iy] ;
yoff = grapher->fHIGH - grapher->yorigin[ix][iy] ;
/* 09 Jan 1998: allow x-axis to be chosen by a
timeseries that ranges between 0 and 1 */
#define XPIX(ii) \
( (grapher->xax_tsim != NULL && (ii) < grapher->xax_tsim->nx) \
? (MRI_FLOAT_PTR(grapher->xax_tsim)[MAX((ii),ibot)] * grapher->gx) \
: (((ii)-pbot) * ftemp) )
for( i=0 ; i < qnum ; i++ ){ /* generate X11 plot lines */
a_line[i].x = xoff + XPIX(i+pbot);
a_line[i].y = yoff - plot[i] ;
}
if( use_ovi ) /* 29 Mar 2002: line color */
DC_fg_color( grapher->dc , ovi[tt%OVI_MAX] ) ;
if( DATA_POINTS(grapher) ){ /* 09 Jan 1998 */
for( i=0 ; i < qnum ; i++ )
GRA_small_circle( grapher,a_line[i].x,a_line[i].y,DATA_IS_THICK(grapher) );
}
if( DATA_LINES(grapher) ){ /* 01 Aug 1998 */
XDrawLines( grapher->dc->display ,
grapher->fd_pxWind , grapher->dc->myGC ,
a_line , qnum , CoordModeOrigin ) ;
}
/* 22 July 1996: save central graph data for later use */
if( ix == grapher->xc && iy == grapher->yc && tt == 0 ){
for( i=0 ; i < qnum ; i++ ) grapher->cen_line[i] = a_line[i] ;
grapher->nncen = qnum ;
mri_free( grapher->cen_tsim ) ; /* copy time series too */
grapher->cen_tsim = mri_to_float( tsim ) ;
}
tsar += tsim->nx ; /* 29 Mar 2002: advance to next curve */
} /* end of loop over multi-plot (tt) */
if( use_ovi )
DC_fg_color( grapher->dc , DATA_COLOR(grapher) ) ; /* reset color */
/* 08 Nov 1996: double plot? Duplicate the above drawing code! */
/* 07 Aug 2001: old method was DPLOT_OVERLAY,
new method is DPLOT_PLUSMINUS */
/* 29 Mar 2002: allow multiple time series (dsim->ny > 1) */
if( dplot ){
int dny , id , qq,qtop ;
dsim = IMARR_SUBIMAGE(dplot_imar,its) ;
if( dsim == NULL || dsim->nx < 2 ) continue ; /* skip to next iy */
dsar = MRI_FLOAT_PTR(dsim) ;
tsar = MRI_FLOAT_PTR(tsim) ; /* 25 Feb 2003: reset this */
itop = MIN( ttop , dsim->nx ); /* ibot was set long ago */
qnum = itop - pbot ; /* number of points to plot here */
if( qnum < 2 ) continue ; /* skip to next iy = next sub-graph */
if( dplot == DPLOT_PLUSMINUS ) dny = 1 ; /* 29 Mar 2002 */
else dny = dsim->ny ;
/** 29 Mar 2002: decode 'color:' from dsim->name, if present **/
use_ovi = (dsim->name!=NULL) && (strncmp(dsim->name,"color: ",7)==0) ;
if( use_ovi ){
char *cpt = dsim->name+6 ; int nuse, ngood ;
for( tt=0 ; tt < OVI_MAX ; tt++ )
ovi[tt] = DPLOT_COLOR(grapher) ;
for( tt=0 ; tt < OVI_MAX ; tt++ ){
ngood = sscanf(cpt,"%d%n",ovi+tt,&nuse) ;
if( ngood < 1 ) break ;
cpt += nuse ; if( *cpt == '\0' ) break ;
}
}
for( id=0 ; id < dny ; id++ ){ /* 29 Mar 2002: multi-plots */
ftemp = grapher->fscale ;
if( ftemp == 0.0 ) ftemp = 1.0 ;
else if( ftemp < 0.0 ) ftemp = -1.0 / ftemp ;
/* 18 Mar 2004: scan backwards from itop to reject superlarge values */
for( qtop=itop-1 ; qtop >= pbot ; qtop-- )
if( dsar[qtop] < WAY_BIG ) break ;
if( qtop <= ibot ){ dsar += dsim->nx; continue; } /* skip */
qtop++ ; qnum = qtop-pbot ;
switch( dplot ){
default:
case DPLOT_OVERLAY: /* plot curve */
for( i=pbot ; i < MIN(ibot,qtop) ; i++ )
plot[i-pbot] = (dsar[ibot] - tsbot) * ftemp ;
for( i=ibot ; i < qtop ; i++ )
plot[i-pbot] = (dsar[i] - tsbot) * ftemp ;
break ;
case DPLOT_PLUSMINUS: /* plus side */
for( i=pbot ; i < MIN(ibot,qtop) ; i++ )
plot[i-pbot] = (tsar[ibot]+dsar[ibot] - tsbot) * ftemp ;
for( i=ibot ; i < qtop ; i++ )
plot[i-pbot] = (tsar[i] +dsar[i] - tsbot) * ftemp ;
break ;
}
ftemp = grapher->gx / (pnum-1.0) ; /* cf. XPIX */
xoff = grapher->xorigin[ix][iy] ;
yoff = grapher->fHIGH - grapher->yorigin[ix][iy] ;
for( i=0 ; i < qnum ; i++ ){
a_line[i].x = xoff + XPIX(i+pbot) ; /* 09 Jan 1998 */
a_line[i].y = yoff - plot[i] ;
}
if( use_ovi ) /* 29 Mar 2002 */
DC_fg_color( grapher->dc , ovi[id%OVI_MAX] ) ;
else
DC_fg_color( grapher->dc , DPLOT_COLOR(grapher) ) ;
if( DPLOT_POINTS(grapher) ){ /* 09 Jan 1998 */
for( i=0 ; i < qnum ; i++ )
GRA_small_circle(grapher,a_line[i].x,a_line[i].y,DPLOT_IS_THICK(grapher));
}
if( DPLOT_LINES(grapher) ) { /* 01 Aug 1998 */
DC_linewidth( grapher->dc , DPLOT_THICK(grapher) ) ;
XDrawLines( grapher->dc->display ,
grapher->fd_pxWind , grapher->dc->myGC ,
a_line , qnum , CoordModeOrigin ) ;
}
/* plot minus side of plus/minus curve? */
if( dplot == DPLOT_PLUSMINUS ){ /* lots of duplicate code :-( */
ftemp = grapher->fscale ;
if( ftemp == 0.0 ) ftemp = 1.0 ;
else if( ftemp < 0.0 ) ftemp = -1.0 / ftemp ;
for( i=pbot ; i < MIN(ibot,qtop) ; i++ )
plot[i-pbot] = (tsar[ibot]-dsar[ibot] - tsbot) * ftemp ;
for( i=ibot ; i < qtop ; i++ )
plot[i-pbot] = (tsar[i] -dsar[i] - tsbot) * ftemp ;
ftemp = grapher->gx / (pnum-1.0) ;
for( i=0 ; i < qnum ; i++ ){
a_line[i].x = xoff + XPIX(i+pbot) ;
a_line[i].y = yoff - plot[i] ;
}
if( DPLOT_POINTS(grapher) ){
for( i=0 ; i < qnum ; i++ )
GRA_small_circle(grapher,a_line[i].x,a_line[i].y,DPLOT_IS_THICK(grapher));
}
if( DPLOT_LINES(grapher) ) {
DC_linewidth( grapher->dc , DPLOT_THICK(grapher) ) ;
XDrawLines( grapher->dc->display ,
grapher->fd_pxWind , grapher->dc->myGC ,
a_line , qnum , CoordModeOrigin ) ;
}
}
dsar += dsim->nx ; /* 29 Mar 2002: next curve */
} /* end of loop over multiple dplots */
DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
} /* end of dplot */
/* 05 Jan 1999: plot horizontal line through zero, if desired and needed */
if( grapher->HorZ && grapher->pmin[ix][iy] < 0.0 && grapher->pmax[ix][iy] > 0.0 ){
DC_fg_color ( grapher->dc , GRID_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , GRID_THICK(grapher) ) ;
DC_dashed_line( grapher->dc ) ;
ftemp = grapher->fscale ;
if( ftemp == 0.0 ) ftemp = 1.0 ;
else if( ftemp < 0.0 ) ftemp = -1.0 / ftemp ;
XDrawLine( grapher->dc->display , grapher->fd_pxWind , grapher->dc->myGC ,
(int) xoff , (int)(yoff + tsbot * ftemp) ,
(int)(xoff + grapher->gx) , (int)(yoff + tsbot * ftemp) ) ;
DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
DC_solid_line( grapher->dc ) ;
}
} /* end of loop over y */
} /* end of loop over x */
/** cast away the data timeseries! */
DESTROY_IMARR(tsimar) ;
if( dplot_imar != NULL ) DESTROY_IMARR(dplot_imar) ; /* 08 Nov 1996 */
/*----- Now do extra plots in center frame, if any -----*/
#define REFTS_FRAC 0.38 /* fraction of one graph that this takes up */
#define REFTS_TOP 0.98 /* top of reference graph in frame */
#define ORTTS_FRAC 0.38
#define ORTTS_TOP 0.78
/* 12 Nov 1996: include graphs of orts by looping "iex" */
for( iex=0 ; iex <= 1 ; iex++ ){
eximar = (iex==0) ? grapher->ref_ts : grapher->ort_ts ;
if( eximar != NULL && IMARR_COUNT(eximar) > 0 ){
float yscal , val , xscal , exfrac , extop ;
int nover , nvec , nx , ivec ;
int excolor , exthick ;
STATUS("plotting extra graphs") ;
exfrac = (iex==0) ? REFTS_FRAC : ORTTS_FRAC ;
extop = (iex==0) ? REFTS_TOP : ORTTS_TOP ;
excolor = (iex==0) ? IDEAL_COLOR(grapher) : ORT_COLOR(grapher) ;
exthick = (iex==0) ? IDEAL_THICK(grapher) : ORT_THICK(grapher) ;
for( its=0 ; its < IMARR_COUNT(eximar) ; its++ ){
tsim = IMARR_SUBIMAGE(eximar,its) ;
if( tsim == NULL || tsim->kind != MRI_float || tsim->nx < 2 ) continue ;
nx = tsim->nx ;
itop = MIN( ttop , nx ) ;
qnum = itop - pbot ; if( qnum < 2 ) continue ;
nvec = (grapher->ref_ts_plotall) ? (tsim->ny) : 1 ;
for( ivec=0 ; ivec < nvec ; ivec++ ){ /* plot each sub-vector */
tsar = MRI_FLOAT_PTR(tsim) + (ivec*nx) ;
tsbot = 99999999.0 ; tstop = -99999999.0 ;
nover = grapher->init_ignore ;
for( i=ibot ; i < itop ; i++ ){
val = tsar[i] ;
if( val < WAY_BIG ){ tstop = MAX(tstop,val); tsbot = MIN(tsbot,val); }
else { nover++ ; }
}
if( tstop >= WAY_BIG || tstop <= tsbot ) continue ; /* skip */
/*** scale into a_line and draw it***/
yscal = exfrac * grapher->gy / (tstop-tsbot) ;
xscal = ftemp = grapher->gx / (pnum-1.0) ;
xoff = grapher->xorigin[grapher->xc][grapher->yc] ;
yoff = grapher->fHIGH - grapher->yorigin[grapher->xc][grapher->yc]
- (extop - exfrac) * grapher->gy ;
for( i=pbot ; i < itop; i++ ){
val = (i >= ibot && tsar[i] < WAY_BIG) ? tsar[i] : tsbot ;
a_line[i-pbot].x = xoff + XPIX(i) ; /* 09 Jan 1998 */
a_line[i-pbot].y = yoff - yscal*(val-tsbot) ;
}
/* if none are over the limit, draw in one operation;
otherwise, must plot each line separately in its needed color */
if( nover == 0 ){
DC_fg_color ( grapher->dc , excolor ) ;
DC_linewidth( grapher->dc , exthick ) ;
XDrawLines( grapher->dc->display ,
grapher->fd_pxWind , grapher->dc->myGC ,
a_line , qnum , CoordModeOrigin ) ;
} else {
for( i=pbot ; i < itop-1 ; i++ ){
if( i >= ibot && tsar[i] < WAY_BIG && tsar[i+1] < WAY_BIG ){
DC_fg_color ( grapher->dc , excolor ) ;
DC_linewidth( grapher->dc , exthick ) ;
} else {
DC_fg_color( grapher->dc , IGNORE_COLOR(grapher) ) ;
if( grapher->mat < 4 &&
( i < ibot || tsar[i] >= WAY_BIG ) )
GRA_small_circle( grapher,a_line[i-pbot].x,a_line[i-pbot].y,0 );
}
XDrawLines( grapher->dc->display ,
grapher->fd_pxWind , grapher->dc->myGC ,
a_line + (i-pbot) , 2 , CoordModeOrigin ) ;
}
if( grapher->mat < 4 &&
( i < ibot || tsar[i] >= WAY_BIG ) )
GRA_small_circle( grapher,a_line[i-pbot].x,a_line[i-pbot].y,0 );
}
} /* end of loop over sub-vectors */
} /* end of loop over refs */
} /* end of if refs exist */
} /* end of loop over refs and orts */
/*---- 09 Jan 1998: plot graph showing x-axis as well ----*/
if( grapher->xax_tsim != NULL ){
float yscal , ftemp , xscal , yoff ;
int npt ;
xscal = GL_DLX / (float) grapher->gx ;
yscal = grapher->gy / (pnum-1.0) ;
yoff = grapher->fHIGH - grapher->yorigin[grapher->xc][grapher->yc] ;
ftemp = 1.0 ;
npt = ttop ;
if( npt > grapher->xax_tsim->nx ) npt = grapher->xax_tsim->nx ;
if( npt > pbot+1 ){
for( i=pbot ; i < npt ; i++ ){
a_line[i-pbot].x = XPIX(i) * xscal ;
a_line[i-pbot].y = yoff - yscal*(i-pbot) ;
}
DC_fg_color ( grapher->dc , IDEAL_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , IDEAL_THICK(grapher) ) ;
XDrawLines( grapher->dc->display , grapher->fd_pxWind , grapher->dc->myGC ,
a_line , npt-pbot , CoordModeOrigin ) ;
}
}
/***** Done!!! *****/
EXRETURN ;
}
/*------------------------------------------------------------------------
Draw frames around each sub-graph and grids inside them
12 Jan 1998: modified to allow for gaps between graphs
--------------------------------------------------------------------------*/
void draw_grids( MCW_grapher * grapher )
{
int i , mat=grapher->mat , gx=grapher->gx , gy=grapher->gy ;
int j, k, g, xo, yo, npoints , m ;
int xc = grapher->xc , yc = grapher->yc ;
float ftemp ;
ENTRY("draw_grids") ;
if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
/* draw grid lines in the chosen color */
if( GRID_COLOR(grapher) > 0 ){
DC_fg_color ( grapher->dc , GRID_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , GRID_THICK(grapher) ) ;
g = grapher->grid_spacing ;
npoints = NPTS(grapher) ; /* number time points in 1 sub-graph window */
if( npoints > 1 ){ /* this if: 22 Sep 2000 */
ftemp = gx / (npoints-1.0) ;
for( i=0 ; i < mat ; i++ ){
for( m=0 ; m < mat ; m++ ){
xo = grapher->xorigin[i][m] ; yo = grapher->yorigin[i][m] ;
for( j=1 ; j <= (npoints-1)/g ; j++ ){
k = xo + j * g * ftemp ;
plot_fdX( grapher , k , yo , 0 ) ;
plot_fdX( grapher , k , yo+gy , 1 ) ;
}
}
}
}
/* draw an interior framing box at the central square */
xo = grapher->xorigin[xc][yc] ; yo = grapher->yorigin[xc][yc] ;
g = MIN( grapher->gy/3 , grapher->gx/3 ) ; g = MIN( g , 4 ) ;
for( j=1 ; j <= g ; j++ ){
plot_fdX( grapher , xo+j , yo+j , 0 ) ;
plot_fdX( grapher , xo+j , yo+gy-j , 1 ) ;
plot_fdX( grapher , xo+gx-j , yo+gy-j , 1 ) ;
plot_fdX( grapher , xo+gx-j , yo+j , 1 ) ;
plot_fdX( grapher , xo+j , yo+j , 1 ) ;
}
}
/* draw exterior frames */
DC_fg_color ( grapher->dc , FG_COLOR(grapher) ) ;
DC_linewidth( grapher->dc , FG_THICK(grapher) ) ;
for( i=0 ; i < mat ; i++ ){
for( j=0 ; j < mat ; j++ ){
xo = grapher->xorigin[i][j] ; yo = grapher->yorigin[i][j] ;
plot_fdX( grapher , xo , yo , 0 ) ;
plot_fdX( grapher , xo+gx , yo , 1 ) ;
plot_fdX( grapher , xo+gx , yo+gy , 1 ) ;
plot_fdX( grapher , xo , yo+gy , 1 ) ;
plot_fdX( grapher , xo , yo , 1 ) ;
}
}
EXRETURN ;
}
/*------------------------------------------
Send the caller info about the new graph
--------------------------------------------*/
void send_newinfo( MCW_grapher *grapher )
{
ENTRY("send_newinfo") ;
if( GRA_VALID(grapher) && grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_newxyzm ;
cbs.xcen = grapher->xpoint ;
cbs.ycen = grapher->ypoint ;
cbs.zcen = grapher->zpoint ;
cbs.mat = grapher->mat ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
}
EXRETURN ;
}
/*---------------------------
initialize matrix stuff
-----------------------------*/
void init_mat( MCW_grapher *grapher )
{
int i, j ;
int gg ;
ENTRY("init_mat") ;
if( !GRA_VALID(grapher) ) EXRETURN ;
grapher->gx = grapher->gx_max / grapher->mat;
grapher->gy = grapher->gy_max / grapher->mat;
for (i=0;i<grapher->mat;i++) {
for (j=0;j<grapher->mat;j++) {
grapher->xorigin[i][j] = MDX1 + i * grapher->gx;
grapher->yorigin[i][j] = MDY1 + j * grapher->gy;
}
}
if( grapher->mirror && grapher->mat > 1 ){ /* Jul 2000 */
int mm = grapher->mat , m2 = mm/2 ; /* swap left and right */
for( j=0 ; j < mm ; j++ ){
for( i=0 ; i < m2 ; i++ ){
gg = grapher->xorigin[i][j] ;
grapher->xorigin[i][j] = grapher->xorigin[mm-1-i][j] ;
grapher->xorigin[mm-1-i][j] = gg ;
}
}
}
grapher->xc = grapher->mat/2;
grapher->yc = (grapher->mat-1)/2;
gg = grapher->ggap ; /* 12 Jan 1998 */
if( gg > 0 ){
gg = MIN( gg , grapher->gx / 2 ) ; /* shrink sizes of graphs */
gg = MIN( gg , grapher->gy / 2 ) ;
grapher->gx -= gg ;
grapher->gy -= gg ;
}
EXRETURN ;
}
/* ----------------------------- */ /* scale plot up and redraw */
void scale_up( MCW_grapher * grapher )
/* ----------------------------- */
{
if( !GRA_VALID(grapher) ) return ;
if (grapher->fscale > 0) grapher->fscale *= 2;
else if (grapher->fscale < -2) grapher->fscale /= 2;
else grapher->fscale = 1;
if( grapher->fscale > 1000000.0 ){
static int nn=0 ;
nn++ ; if( nn < 3 ) fprintf(stderr,"Is that you, Bellgowan? If so, stop it!\a\n") ;
}
return ;
}
/* ----------------------------- */ /* scale plot up and redraw */
void scale_down( MCW_grapher * grapher )
/* ----------------------------- */
{
if( !GRA_VALID(grapher) ) return ;
if (grapher->fscale > 1) grapher->fscale /= 2;
else if (grapher->fscale < 0) grapher->fscale *= 2;
else grapher->fscale = -2;
return ;
}
/* ----------------------------- */ /* decrease matrix and redraw */
void mat_down( MCW_grapher * grapher )
/* ----------------------------- */
{
int old;
if( !GRA_VALID(grapher) ) return ;
old = grapher->mat;
grapher->mat--;
if (grapher->mat < 1) grapher->mat = 1;
else if (grapher->mat > grapher->mat_max) grapher->mat = grapher->mat_max;
if (grapher->mat!= old) {
init_mat( grapher ) ;
redraw_graph( grapher , 0 ) ;
}
return ;
}
/* ----------------------------- */ /* increase matrix and redraw */
void mat_up( MCW_grapher * grapher )
/* ----------------------------- */
{
int old;
if( !GRA_VALID(grapher) ) return ;
old = grapher->mat;
grapher->mat++;
if (grapher->mat < 1) grapher->mat = 1;
else if (grapher->mat > grapher->mat_max) grapher->mat = grapher->mat_max;
if (grapher->mat!= old) {
init_mat(grapher) ;
redraw_graph(grapher,0) ;
}
return ;
}
/* ----------------------------- */ /* decrease grid spacing and redraw */
void grid_down( MCW_grapher * grapher )
/* ----------------------------- */
{
int old;
if( !GRA_VALID(grapher) ) return ;
old = grapher->grid_index;
grapher->grid_index--;
if (grapher->grid_index < 0) grapher->grid_index = 0;
grapher->grid_spacing = grid_ar[grapher->grid_index] ;
grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
redraw_graph(grapher,0) ;
return ;
}
/* ----------------------------- */ /* increase grid spacing and redraw */
void grid_up( MCW_grapher * grapher )
/* ----------------------------- */
{
int old;
if( !GRA_VALID(grapher) ) return ;
old = grapher->grid_index;
grapher->grid_index++;
if (grapher->grid_index >= GRID_MAX) grapher->grid_index = GRID_MAX - 1;
grapher->grid_spacing = grid_ar[grapher->grid_index] ;
grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
redraw_graph(grapher,0) ;
return ;
}
/*-----------------------------------------------------------------------
Handle all events in an grapher drawing area widget
-------------------------------------------------------------------------*/
void GRA_drawing_EV( Widget w , XtPointer client_data ,
XEvent * ev , Boolean * continue_to_dispatch )
{
MCW_grapher * grapher = (MCW_grapher *) client_data ;
ENTRY("GRA_drawing_EV") ;
if( ! GRA_REALZ(grapher) ){
if(PRINT_TRACING){
char str[256] ;
sprintf(str,"unrealized grapher! Event type = %d",(int)ev->type) ;
STATUS(str) ; }
EXRETURN ;
}
if( grapher->valid == 666 ){ /* 06 Jan 1999 */
if(PRINT_TRACING){
char str[256] ;
sprintf(str,"dying grapher! Event type = %d",(int)ev->type) ;
STATUS(str) ; }
EXRETURN ;
}
switch( ev->type ){
/*----- redraw -----*/
case Expose:{
XExposeEvent * event = (XExposeEvent *) ev ;
if(PRINT_TRACING){
char str[256] ;
sprintf(str,"Expose event with count = %d",event->count) ;
STATUS(str) ; }
/**
With the first expose, create the new pixmap.
For subsequent ones, just redraw the non-pixmap (overlay) stuff.
06 Jan 1999: check event count
**/
XSync( XtDisplay(w) , False ) ; /* 05 Feb 1999 */
if( event->count == 0 ){
if( grapher->fd_pxWind == (Pixmap) 0 ){
int width , height ;
MCW_widget_geom( grapher->draw_fd , &width , &height , NULL,NULL ) ;
GRA_new_pixmap( grapher , width , height , 1 ) ;
} else {
GRA_redraw_overlay( grapher ) ;
}
}
}
break ;
/*----- take key press -----*/
case KeyPress:{
XKeyEvent * event = (XKeyEvent *) ev ;
char buf[32] ;
KeySym ks=0 ;
int nbuf ;
STATUS("KeyPress event") ;
GRA_timer_stop( grapher ) ; /* 04 Dec 2003 */
if( grapher->fd_pxWind != (Pixmap) 0 ){
buf[0] = '\0' ;
nbuf = XLookupString( event , buf , 32 , &ks , NULL ) ;
if( nbuf == 0 ){ /* 24 Jan 2003: substitution for special keys */
switch(ks){
case XK_KP_Left:
case XK_Left: buf[0] = '<' ; break ;
case XK_KP_Right:
case XK_Right: buf[0] = '>' ; break ;
case XK_KP_Page_Up:
case XK_Page_Up: buf[0] = 'Z' ; break ;
case XK_KP_Page_Down:
case XK_Page_Down: buf[0] = 'z' ; break ;
}
}
if( buf[0] != '\0' ) GRA_handle_keypress( grapher , buf , ev ) ;
else if(PRINT_TRACING){
char str[256] ;
sprintf(str,"*** KeyPress was empty!? nbuf=%d",nbuf) ;
STATUS(str) ;
}
}
}
break ;
/*----- take button press -----*/
case ButtonPress:{
XButtonEvent *event = (XButtonEvent *) ev ;
int bx,by , width,height , but=event->button ;
int i, j, gx , gy , mat , xloc,yloc ;
unsigned int but_state ;
int xd,yd,zd ; /* 19 Mar 2004: for mangling to AFNI indexes */
STATUS("button press") ;
/* 26 Feb 2007: Buttons 4 and 5 = scroll wheel = change time point */
if( but == Button4 || but == Button5 ){
int tt = (but==Button4) ? grapher->time_index-1 : grapher->time_index+1 ;
EXRONE(grapher) ; GRA_timer_stop(grapher) ;
if( tt >= 0 && tt < grapher->status->num_series ){
if( grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_setindex; cbs.key = tt; cbs.event = NULL;
CALL_sendback( grapher , cbs ) ;
} else {
(void) drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)tt) ;
}
}
MCW_discard_events( w , ButtonPressMask ) ; EXRETURN;
}
bx = event->x ; by = event->y ; but_state = event->state ;
MCW_discard_events( w , ButtonPressMask ) ;
/* Button 1 in pixmap logo = toggle on or off */
if( but == Button1 &&
grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP &&
bx < grapher->glogo_width &&
grapher->fHIGH - by < grapher->glogo_height ){
show_grapher_pixmap = ! show_grapher_pixmap ;
if( XtIsManaged(grapher->option_rowcol) ) /* 04 Nov 1996 */
XtUnmanageChild(grapher->option_rowcol) ;
else
XtManageChild(grapher->option_rowcol) ;
redraw_graph( grapher , 0 ) ;
break ; /* break out of ButtonPress case */
}
/* compute which dataset pixel (xloc,yloc) the button press was in */
/* X11 box for graph (i,j):
x = xorigin[i][j] .. xorigin[i][j]+gx (L..R)
y = fHIGH-yorigin[i][j]-gy .. fHIGH-yorigin[i][j] (T..B) */
gx = grapher->gx ; gy = grapher->gy ; mat = grapher->mat ;
for( i=0 ; i < mat ; i++ )
if( bx > grapher->xorigin[i][0] &&
bx < grapher->xorigin[i][0] + gx ) break ; /* find in x */
if( i == mat ) break ; /* break out of ButtonPress case */
xloc = grapher->xpoint + i - grapher->xc ;
for( j=0 ; j < mat ; j++ ) /* find in y */
if( by > grapher->fHIGH - grapher->yorigin[0][j] - gy &&
by < grapher->fHIGH - grapher->yorigin[0][j] ) break ;
if( j == mat ) break ; /* break out of ButtonPress case */
yloc = grapher->ypoint - j + grapher->yc ;
/* adjust for possible wraparound */
if (xloc < 0) xloc += grapher->status->nx ;
if (xloc >= grapher->status->nx) xloc -= grapher->status->nx ;
if (yloc < 0) yloc += grapher->status->ny ;
if (yloc >= grapher->status->ny) yloc -= grapher->status->ny ;
/* Feb 1998: button 2 --> send message back to AFNI, maybe */
/* 03 Oct 2002: Shift+Button1 has the same effect */
if( but == Button2 ||
( but == Button1 && (event->state & ShiftMask) &&
!(event->state & ControlMask) ) ){
if( grapher->button2_enabled && (bx > GL_DLX) ){
GRA_cbs cbs ;
cbs.reason = graCR_button2_points ;
cbs.xcen = xloc ;
cbs.ycen = yloc ;
cbs.zcen = grapher->zpoint ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
} else {
XBell(XtDisplay(w),100) ;
}
}
/* button 1 --> move to new square as center of matrix,
if it is actually a new center, that is,
and if graphing is enabled, and if not off left edge */
if( grapher->fd_pxWind != (Pixmap) 0 &&
but == Button1 && (bx > GL_DLX) &&
( (xloc != grapher->xpoint) || (yloc != grapher->ypoint) ) ){
grapher->xpoint = xloc ;
grapher->ypoint = yloc ;
redraw_graph( grapher , 0 ) ;
send_newinfo( grapher ) ;
}
/* 22 July 1996:
button 1 in central graph of matrix causes jump to time_index */
else if( grapher->fd_pxWind != (Pixmap)0 &&
NPTS(grapher) > 1 && !grapher->textgraph &&
(but==Button1) && (bx > GL_DLX) &&
(xloc == grapher->xpoint) && yloc == grapher->ypoint &&
grapher->cen_line != NULL && grapher->nncen > 1 ){
float dist , dmin=999999.9 ;
int imin = 0 ;
/*-- 09 Jan 1998: find closest pixel in central graph --*/
for( i=0 ; i < grapher->nncen ; i++ ){
dist = abs( bx - grapher->cen_line[i].x ) /* L1 distance */
+ abs( by - grapher->cen_line[i].y ) ;
if( dist < dmin ){ dmin = dist; imin = i; if(dmin == 0) break; }
}
i = imin + NBOT(grapher) ;
if( i >= 0 && i < TTOP(grapher) ){
if( grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_setindex ;
cbs.key = i ;
cbs.event = ev ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
} else {
(void) drive_MCW_grapher( grapher,graDR_setindex,(XtPointer)i );
}
}
}
/* Button 3 --> popup statistics of this graph */
if( but == Button3 && !ISONE(grapher) && !grapher->textgraph ){
int ix , iy ;
ix = xloc - grapher->xpoint + grapher->xc ;
if( ix < 0 ) ix += grapher->status->nx ;
else if( ix >= grapher->mat ) ix -= grapher->status->nx ;
iy = grapher->ypoint - yloc + grapher->yc ;
if( iy < 0 ) iy += grapher->status->ny ;
else if( iy >= grapher->mat ) iy -= grapher->status->ny ;
if( ix >= 0 && ix < grapher->mat && iy >= 0 && iy < grapher->mat ){
XmString xstr ;
char bmin[16],bmax[16],bmean[16],bstd[16] ;
char bmed[16] , bmad[16] ; /* 08 Mar 2001 */
char *qstr , *eee ; /* 07 Mar 2002 */
int nlin , nltop=40 ; /* 07 Mar 2002 */
AV_fval_to_char( grapher->tbot[ix][iy] , bmin ) ;
AV_fval_to_char( grapher->ttop[ix][iy] , bmax ) ;
AV_fval_to_char( grapher->tmean[ix][iy] , bmean) ;
AV_fval_to_char( grapher->tstd[ix][iy] , bstd ) ;
AV_fval_to_char( grapher->tmed[ix][iy] , bmed ) ; /* 08 Mar 2001 */
AV_fval_to_char( grapher->tmad[ix][iy] , bmad ) ;
if( grapher->tuser[ix][iy] == NULL )
qstr = AFMALL(char, 912) ;
else
qstr = AFMALL(char, 912+strlen(grapher->tuser[ix][iy])) ;
/* 19 Mar 2004: mangle FD_brick indexes to AFNI indexes */
xd = xloc; yd = yloc; zd = grapher->zpoint ;
#ifndef DONT_MANGLE_XYZ
{ THD_ivec3 id ;
id = THD_fdind_to_3dind( grapher->getaux , TEMP_IVEC3(xd,yd,zd) ) ;
xd = id.ijk[0] ; yd = id.ijk[1] ; zd = id.ijk[2] ; }
#endif
sprintf( qstr, "Data Statistics\n"
"---------------\n"
"Indexes = %d:%-d\n" /* 19 Mar 2004 */
"x voxel = %d\n"
"y voxel = %d\n"
"z voxel = %d\n"
"Min =%s\n"
"Max =%s\n"
"Mean =%s\n"
"Sigma =%s\n"
"Median =%s\n" /* 08 Mar 2001 */
"MAD =%s" ,
grapher->sbot[ix][iy], grapher->stop[ix][iy], /* 19 Mar 2004 */
xd , yd , zd ,
bmin,bmax,bmean,bstd,bmed,bmad ) ;
/** 22 Apr 1997: incorporate user string for this voxel **/
if( grapher->tuser[ix][iy] != NULL ){
strcat( qstr , "\n------------------\n" ) ;
strcat( qstr , grapher->tuser[ix][iy] ) ;
}
/* 07 Mar 2002: if string is too long, popup textwin,
otherwise just open a popup window */
eee = getenv( "AFNI_GRAPH_TEXTLIMIT" ) ;
if( eee != NULL ){
nlin = strtol( eee , NULL , 10 ) ;
if( nlin > 0 ) nltop = nlin ;
}
for( nlin=1,eee=qstr ; *eee != '\0' ; eee++ )
if( *eee == '\n' ) nlin++ ;
if( nlin < nltop ){
xstr = XmStringCreateLtoR( qstr, XmFONTLIST_DEFAULT_TAG ) ;
XtVaSetValues( grapher->but3_label,XmNlabelString,xstr,NULL );
XmStringFree( xstr ) ;
XmMenuPosition( grapher->but3_menu , event ) ; /* where */
XtManageChild ( grapher->but3_menu ) ; /* popup */
} else {
(void) new_MCW_textwin(grapher->fdw_graph,qstr,TEXT_READONLY);
}
free(qstr) ;
} else {
redraw_graph(grapher,0) ; /* 11 Nov 1996 */
}
}
}
break ;
/*----- window changed size -----*/
case ConfigureNotify:{
XConfigureEvent * event = (XConfigureEvent *) ev ;
int new_width , new_height ;
STATUS("ConfigureNotify event") ;
XSync( XtDisplay(w) , False ) ;
new_width = event->width ;
new_height = event->height ;
if( new_width != grapher->fWIDE || new_height != grapher->fHIGH ){
GRA_new_pixmap( grapher , new_width , new_height , 1 ) ;
}
}
break ;
/*----- ignore all other events -----*/
default:
#ifdef AFNI_DEBUG
{char str[256]; sprintf(str,"Event code = %d\n",(int)ev->type); STATUS(str);}
#endif
break ;
} /* end of switch ev->type */
EXRETURN ;
}
/*------------------------------------------------------------------
Get a new pixmap for drawing purposes
--------------------------------------------------------------------*/
void GRA_new_pixmap( MCW_grapher * grapher ,
int new_width , int new_height , int redraw )
{
int ww,hh ;
ENTRY("GRA_new_pixmap") ;
if( ! GRA_REALZ(grapher) ) EXRETURN ;
grapher->fWIDE = new_width ;
grapher->fHIGH = new_height ;
grapher->gx_max = new_width - (GL_DLX + GR_DLX) ;
grapher->gy_max = new_height - (GT_DLY + GB_DLY) ;
if( grapher->fd_pxWind != (Pixmap) 0 ){
STATUS("freeing old Pixmap") ;
XFreePixmap( grapher->dc->display , grapher->fd_pxWind ) ;
}
STATUS("allocating new Pixmap") ;
grapher->fd_pxWind = XCreatePixmap( grapher->dc->display ,
XtWindow(grapher->draw_fd) ,
grapher->fWIDE , grapher->fHIGH,
grapher->dc->planes ) ;
MCW_widget_geom( grapher->option_rowcol , &ww , &hh , NULL,NULL ) ;
XtVaSetValues( grapher->option_rowcol ,
#ifdef WANT_AFNI_BITMAP
XmNx , grapher->fWIDE - ww - 2 ,
#else
XmNx , 2 ,
#endif
XmNy , grapher->fHIGH - hh - 2 ,
NULL ) ;
if( redraw ){
init_mat( grapher ) ;
redraw_graph( grapher , 0 ) ;
}
EXRETURN ;
}
/*----------------------------------------------------------
Deal with keypresses in a graph window
------------------------------------------------------------*/
void GRA_handle_keypress( MCW_grapher *grapher , char *buf , XEvent *ev )
{
int ii ;
ENTRY("GRA_handle_keypress") ;
if( buf[0] == '\0' ) EXRETURN ;
if(PRINT_TRACING){
char str[256] ;
sprintf(str,"buf[0]=%c (%x)",(int)buf[0],(int)buf[0]) ;
STATUS(str); }
/*** deal with the key sequence 'N <digits> <Enter>' ***/
/* first 'N' */
if( grapher->key_Nlock==0 && buf[0]=='N' ){
grapher->key_Nlock = 1 ;
HAND_cursorize( grapher->fdw_graph ) ;
HAND_cursorize( grapher->draw_fd ) ;
grapher->key_lock_sum = 0 ;
EXRETURN ;
}
/* last <Enter> */
if( grapher->key_Nlock && buf[0] == 13 ){
/* if have a number, set the graph matrix size */
if( grapher->key_lock_sum > 0 )
grapher->mat = MIN( grapher->mat_max , grapher->key_lock_sum ) ;
NORMAL_cursorize( grapher->fdw_graph ) ;
if( ISONE(grapher) )
NORMAL_cursorize( grapher->draw_fd ) ;
else
POPUP_cursorize( grapher->draw_fd ) ;
init_mat ( grapher ) ;
redraw_graph( grapher , 0 ) ;
send_newinfo( grapher ) ;
grapher->key_Nlock = grapher->key_lock_sum = 0 ;
EXRETURN ;
}
/* intermediate <digit> */
if( grapher->key_Nlock ){
if( isdigit(buf[0]) ){
ii = buf[0] - 48;
grapher->key_lock_sum = MIN( 10000, 10*grapher->key_lock_sum + ii ) ;
}
EXRETURN ;
}
/*-- other keys are single stroke commands --*/
MCW_discard_events( grapher->draw_fd , KeyPressMask ) ;
switch (buf[0]) {
case '-':
case '+':
if( buf[0] == '-' ) scale_down( grapher ) ;
else scale_up ( grapher ) ;
redraw_graph( grapher , 0 ) ;
break;
case 'a':
redraw_graph( grapher , PLOTCODE_AUTOSCALE ) ; /* 03 Feb 1998 */
break ;
case 'i':
if( !grapher->textgraph && grapher->init_ignore > 0 ){ /* 24 May 2005 */
GRA_cbs cbs ;
cbs.reason = graCR_setignore ; cbs.key = grapher->init_ignore - 1 ;
CALL_sendback( grapher , cbs ) ;
} else {
XBell(grapher->dc->display,100) ;
}
break ;
case 'I':
if( !grapher->textgraph ){ /* 24 May 2005 */
GRA_cbs cbs ;
cbs.reason = graCR_setignore ; cbs.key = grapher->init_ignore + 1 ;
CALL_sendback( grapher , cbs ) ;
} else {
XBell(grapher->dc->display,100) ;
}
break ;
case 'm':
case 'M':
if( buf[0] == 'm' ) mat_down( grapher ) ;
else mat_up ( grapher ) ;
send_newinfo( grapher ) ;
break;
case 'g':
grid_down( grapher ) ;
break;
case 'G':
grid_up( grapher ) ;
break;
case 'h': /* 05 Jan 1999 */
grapher->HorZ = ! grapher->HorZ ;
redraw_graph( grapher , 0 ) ;
break ;
case 'q':
case 'Q':
end_fd_graph_CB( NULL , (XtPointer) grapher , NULL ) ;
break ;
/* modified 07 Aug 2001 to account for more complex baseline scenario */
case 'b':{
int bbb = grapher->common_base << 1 ;
if( bbb > BASELINE_GLOBAL ) bbb = BASELINE_INDIVIDUAL ;
MCW_set_bbox( grapher->opt_baseline_bbox , bbb ) ;
grapher->common_base = bbb ;
redraw_graph( grapher , 0 ) ;
}
break ;
case 't':{ /* 22 Sep 2000 */
int bbb = ! grapher->textgraph ;
MCW_set_bbox( grapher->opt_textgraph_bbox , bbb ) ;
grapher->textgraph = bbb ;
redraw_graph( grapher , 0 ) ;
}
break ;
case 'S':
MCW_choose_string( grapher->option_rowcol ,
"Save PNM Prefix:" , NULL ,
GRA_saver_CB , (XtPointer) grapher ) ;
break ;
case 'L':
show_grapher_pixmap = ! show_grapher_pixmap ;
if( grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP )
redraw_graph( grapher , 0 ) ;
break ;
case '<': case ',': /* change time point */
case '>': case '.':
case '[': case ']':
case '1':
case 'l':
EXRONE(grapher) ; /* 22 Sep 2000 */
if( buf[0]=='<' || buf[0]==',' || buf[0]=='[' ) ii = grapher->time_index-1;
else if( buf[0]=='>' || buf[0]=='.' || buf[0]==']' ) ii = grapher->time_index+1;
else if( buf[0] == '1' ) ii = 1 ;
else if( buf[0] == 'l' ) ii = grapher->status->num_series-1;
ii = (ii+grapher->status->num_series) % grapher->status->num_series ;
if( ii >= 0 && ii < grapher->status->num_series ){
if( grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_setindex ;
cbs.key = ii;
cbs.event = NULL ;
#if 0
grapher->status->send_CB( grapher, grapher->getaux, &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
} else {
(void) drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)ii) ;
}
}
break ;
case 'v': /* 04 Dec 2003: video */
case 'V':
if( grapher->status->num_series > 1 ){
grapher->timer_func = GRA_TIMERFUNC_INDEX ;
grapher->timer_delay = (int) AFNI_numenv("AFNI_VIDEO_DELAY") ;
if( grapher->timer_delay <= 0 ) grapher->timer_delay = 1 ;
grapher->timer_param = (buf[0] == 'v') ? 1 : -1 ;
grapher->timer_id =
XtAppAddTimeOut( XtWidgetToApplicationContext(grapher->opt_quit_pb),
grapher->timer_delay , GRA_timer_CB , grapher ) ;
} else {
XBell(grapher->dc->display,100) ;
}
break ;
case 'r':
case 'R':
if( grapher->status->num_series > 1 ){
grapher->timer_func = GRA_TIMERFUNC_BOUNCE ;
grapher->timer_delay = (int) AFNI_numenv("AFNI_VIDEO_DELAY") ;
if( grapher->timer_delay <= 0 ) grapher->timer_delay = 1 ;
grapher->timer_param = (buf[0] == 'r') ? 1 : -1 ;
grapher->timer_id =
XtAppAddTimeOut( XtWidgetToApplicationContext(grapher->opt_quit_pb),
grapher->timer_delay , GRA_timer_CB , grapher ) ;
} else {
XBell(grapher->dc->display,100) ;
}
break ;
case 'z': /* change slice */
case 'Z':
if( buf[0] == 'z' ){
grapher->zpoint -- ;
if( grapher->zpoint < 0 ) grapher->zpoint = grapher->status->nz - 1 ;
} else {
grapher->zpoint ++ ;
if( grapher->zpoint >= grapher->status->nz ) grapher->zpoint = 0 ;
}
redraw_graph( grapher , 0 ) ;
send_newinfo( grapher ) ;
break ;
case 'w':{
char * wcfname ;
int ndig , ll ;
MRI_IMAGE * tsim ;
int xd,yd,zd ; /* 24 Sep 1999 */
EXRONE(grapher) ; /* 22 Sep 2000 */
ll = MAX( grapher->status->nx , grapher->status->ny ) ;
ll = MAX( grapher->status->nz , ll ) ;
ndig = (ll < 1000) ? 3 : 4 ;
ll = 3*ndig + 16 ;
if( Grapher_Stuff.wcsuffix != NULL )
ll += strlen(Grapher_Stuff.wcsuffix) ;
wcfname = (char *) XtMalloc(ll) ;
/* 24 Sep 1999: mangle the name for the output */
xd = grapher->xpoint; yd = grapher->ypoint; zd = grapher->zpoint;
#ifndef DONT_MANGLE_XYZ
{ THD_ivec3 id;
id = THD_fdind_to_3dind( grapher->getaux, TEMP_IVEC3(xd,yd,zd) );
xd = id.ijk[0]; yd = id.ijk[1]; zd = id.ijk[2]; }
#endif
if( Grapher_Stuff.wcsuffix != NULL )
sprintf(wcfname,"%0*d_%0*d_%0*d.%s.1D" ,
ndig,xd , ndig,yd , ndig,zd ,
Grapher_Stuff.wcsuffix ) ;
else
sprintf(wcfname,"%0*d_%0*d_%0*d.1D" ,
ndig,xd , ndig,yd , ndig,zd ) ;
ll = grapher->xpoint +
grapher->ypoint * grapher->status->nx +
grapher->zpoint * grapher->status->nx * grapher->status->ny ;
#if 0
tsim = (MRI_IMAGE *) grapher->getser( ll , graCR_getseries ,
grapher->getaux ) ;
#else
CALL_getser( grapher , ll,graCR_getseries , MRI_IMAGE *,tsim ) ;
#endif
if( tsim != NULL ){
mri_write_1D( wcfname , tsim ) ; /* 16 Nov 1999: replaces mri_write_ascii */
mri_free( tsim ) ;
}
myXtFree(wcfname) ;
}
break ;
/*--- At this point, have a key not handled here.
Call the creator to see if it wishes to deal with it. ---*/
default:
if( grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_keypress ;
cbs.key = buf[0] ;
cbs.event = ev ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
}
break ;
}
EXRETURN ;
}
/*--------------------------------------------------------------------------
06 Jan 1999: handle death after a timeout.
----------------------------------------------------------------------------*/
void GRA_quit_timeout_CB( XtPointer client_data , XtIntervalId * id )
{
MCW_grapher * grapher = (MCW_grapher *) client_data ;
ENTRY("GRA_quit_timeout_CB") ;
GRA_handle_keypress( grapher , "q" , NULL ) ;
EXRETURN ;
}
/*--------------------------------------------------------------------------
Handle buttons from the opt menu
----------------------------------------------------------------------------*/
void GRA_opt_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
MCW_grapher * grapher = (MCW_grapher *) client_data ;
ENTRY("GRA_opt_CB") ;
if( w == grapher->opt_scale_down_pb ){
GRA_handle_keypress( grapher , "-" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_scale_up_pb ){
GRA_handle_keypress( grapher , "+" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_scale_auto_pb ){
GRA_handle_keypress( grapher , "a" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_grid_down_pb ){
GRA_handle_keypress( grapher , "g" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_grid_up_pb ){
GRA_handle_keypress( grapher , "G" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_grid_auto_pb ){ /* 02 Apr 2004 */
auto_grid( grapher , NPTS(grapher) ) ;
redraw_graph(grapher,0) ;
EXRETURN ;
}
if( w == grapher->opt_grid_HorZ_pb ){ /* 05 Jan 1999 */
GRA_handle_keypress( grapher , "h" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_slice_down_pb ){
GRA_handle_keypress( grapher , "z" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_slice_up_pb ){
GRA_handle_keypress( grapher , "Z" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_mat_down_pb ){
GRA_handle_keypress( grapher , "m" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_mat_up_pb ){
GRA_handle_keypress( grapher , "M" , NULL ) ;
EXRETURN ;
}
#if 0
if( w == grapher->opt_color_up_pb ){
GRA_handle_keypress( grapher , "r" , NULL ) ;
EXRETURN ;
}
#endif
if( w == grapher->opt_quit_pb ){
#if 0
GRA_handle_keypress( grapher , "q" , NULL ) ;
#else
STATUS("User pressed Done button: starting timeout") ;
grapher->valid = 666 ;
(void) XtAppAddTimeOut( XtWidgetToApplicationContext(w) ,
50 , GRA_quit_timeout_CB , grapher ) ;
#endif
EXRETURN ;
}
if( w == grapher->opt_save_pb ){
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
GRA_handle_keypress( grapher , "S" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_write_center_pb ){
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
GRA_handle_keypress( grapher , "w" , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_write_suffix_pb ){
EXRONE(grapher) ; /* 22 Sep 2000 */
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
MCW_choose_string( grapher->option_rowcol ,
"'Write Center' Suffix:" , Grapher_Stuff.wcsuffix ,
GRA_wcsuffix_choose_CB , NULL ) ;
EXRETURN ;
}
if( w == grapher->opt_scale_choose_pb ){
MCW_choose_integer( grapher->option_rowcol , "Scale" ,
-9999 , 9999 , (int)(grapher->fscale) ,
GRA_scale_choose_CB , (XtPointer) grapher ) ;
EXRETURN ;
}
#ifndef USE_OPTMENUS
if( w == grapher->opt_mat_choose_pb ){
MCW_choose_integer( grapher->option_rowcol , "Matrix" ,
1 , grapher->mat_max , grapher->mat ,
GRA_mat_choose_CB , (XtPointer) grapher ) ;
EXRETURN ;
}
#endif
if( w == grapher->opt_grid_choose_pb ){
MCW_choose_integer( grapher->option_rowcol , "Grid" ,
grid_ar[0] , grid_ar[GRID_MAX-1] , grapher->grid_spacing ,
GRA_grid_choose_CB , (XtPointer) grapher ) ;
EXRETURN ;
}
if( w == grapher->opt_pin_choose_pb ){ /* 19 Mar 2004 */
char *lvec[2] = { "Bot" , "Top" } ;
int ivec[2] ;
ivec[0] = grapher->pin_bot ; ivec[1] = grapher->pin_top ;
MCW_choose_vector( grapher->option_rowcol , "Graph Pins: Bot..Top-1" ,
2 , lvec,ivec ,
GRA_pin_choose_CB , (XtPointer) grapher ) ;
EXRETURN ;
}
#ifndef USE_OPTMENUS
if( w == grapher->opt_slice_choose_pb && grapher->status->nz > 1 ){
MCW_choose_integer( grapher->option_rowcol , "Slice" ,
0 , grapher->status->nz - 1 , grapher->zpoint ,
GRA_slice_choose_CB , (XtPointer) grapher ) ;
EXRETURN ;
}
#endif
/*** 09 Jan 1998: x-axis stuff ***/
if( w == grapher->opt_xaxis_clear_pb ){
mri_free( grapher->xax_tsim ) ;
grapher->xax_tsim = NULL ;
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
redraw_graph( grapher , 0 ) ;
EXRETURN ;
}
if( w == grapher->opt_xaxis_pick_pb ){
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
if( IMARR_COUNT(GLOBAL_library.timeseries) > 0 ){
MCW_choose_timeseries( grapher->fdw_graph , "Graph x-axis" ,
GLOBAL_library.timeseries , -1 ,
GRA_pick_xaxis_CB , (XtPointer) grapher ) ;
} else {
(void) MCW_popup_message(
grapher->option_rowcol ,
"No timeseries library\nexists to pick from!" ,
MCW_USER_KILL | MCW_TIMER_KILL ) ;
}
EXRETURN ;
}
if( w == grapher->opt_xaxis_center_pb ){
EXRONE(grapher) ; /* 22 Sep 2000 */
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
if( grapher->cen_tsim != NULL ){
mri_free( grapher->xax_tsim ) ;
grapher->xax_tsim = mri_to_float( grapher->cen_tsim ) ;
redraw_graph(grapher,0) ;
} else {
XBell(XtDisplay(w),100) ;
}
EXRETURN ;
}
/** 07 Aug 2001: Set Global baseline **/
if( w == grapher->opt_baseline_setglobal_pb ){
MCW_choose_integer( grapher->option_rowcol , "Global Baseline" ,
-29999 , 29999 , (int)(grapher->global_base) ,
GRA_finalize_global_baseline_CB ,
(XtPointer) grapher ) ;
EXRETURN ;
}
/** shouldn't get to here, but who knows? **/
EXRETURN ;
}
/*----------------------------------------------------------------------*/
void GRA_fixup_xaxis( MCW_grapher * grapher ) /* 09 Jan 1998 */
{
int ii , npt , nx , ibot , nover=0 , pbot,ptop ;
float top,bot , fac ;
float * xxx ;
ENTRY("GRA_fixup_xaxis") ;
if( !GRA_VALID(grapher) || grapher->xax_tsim == NULL ) EXRETURN ;
ptop = TTOP(grapher) ; pbot = TBOT(grapher) ;
npt = ptop ; nx = grapher->xax_tsim->nx ; npt = MIN(npt,nx) ;
xxx = MRI_FLOAT_PTR(grapher->xax_tsim) ;
ibot = grapher->init_ignore ;
if( ibot >= npt-1 ) ibot = 0 ;
ibot = MAX(ibot,pbot) ;
/* find range over plotting interval (ibot..npt-1) */
top = -WAY_BIG ; bot = WAY_BIG ;
for( ii=ibot ; ii < npt ; ii++ ){
if( xxx[ii] < WAY_BIG ){
top = MAX(top,xxx[ii]) ; bot = MIN(bot,xxx[ii]) ;
} else {
nover++ ;
}
}
if( bot >= top ){
mri_free(grapher->xax_tsim) ;
grapher->xax_tsim = NULL ;
EXRETURN ;
}
/* scale all of the timeseries */
fac = 1.0 / (top-bot) ;
for( ii=0 ; ii < nx ; ii++ ){
if( xxx[ii] < WAY_BIG ) xxx[ii] = fac * (xxx[ii]-bot) ;
else xxx[ii] = 0.0 ;
}
EXRETURN ;
}
/*----------------------------------------------------------------------*/
void GRA_pick_xaxis_CB( Widget wcall , XtPointer cd , MCW_choose_cbs *cbs )
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
int its ;
MRI_IMAGE *tsim ;
ENTRY("GRA_pick_xaxis_CB") ;
if( !GRA_VALID(grapher) || cbs->reason != mcwCR_timeseries ) EXRETURN ;
GRA_timer_stop( grapher ) ;
its = cbs->ival ;
if( its >= 0 && its < IMARR_COUNT(GLOBAL_library.timeseries) ){
tsim = IMARR_SUBIMAGE(GLOBAL_library.timeseries,its) ;
mri_free( grapher->xax_tsim ) ;
grapher->xax_tsim = mri_to_float(tsim) ;
redraw_graph( grapher , 0 ) ;
}
EXRETURN ;
}
/*----------------------------------------------------------------------
Callbacks from popup choosers
------------------------------------------------------------------------*/
void GRA_wcsuffix_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
{
int ll , ii ;
ENTRY("GRA_wcsuffix_choose_CB") ;
if( cbs->reason != mcwCR_string ||
cbs->cval == NULL || (ll=strlen(cbs->cval)) == 0 ){
XBell( XtDisplay(wcaller) , 100 ) ; EXRETURN ;
}
for( ii=0 ; ii < ll ; ii++ ){
if( iscntrl(cbs->cval[ii]) ||
isspace(cbs->cval[ii]) ||
cbs->cval[ii] == '/' ){
XBell( XtDisplay(wcaller) , 100 ) ; EXRETURN ;
}
}
if( Grapher_Stuff.wcsuffix != NULL ) myXtFree(Grapher_Stuff.wcsuffix) ;
Grapher_Stuff.wcsuffix = XtNewString(cbs->cval) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
#ifdef USE_OPTMENUS
void GRA_mat_choose_CB( MCW_arrowval * cbs , XtPointer cd )
#else
void GRA_mat_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
#endif
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
ENTRY("GRA_mat_choose_CB") ;
if( ! GRA_VALID(grapher) || cbs->ival < 1 ) EXRETURN ;
grapher->mat = MIN( grapher->mat_max , cbs->ival ) ;
init_mat ( grapher ) ;
redraw_graph( grapher , 0 ) ;
send_newinfo( grapher ) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_scale_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
ENTRY("GRA_scale_choose_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
grapher->fscale = cbs->fval ;
redraw_graph( grapher , 0 ) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_grid_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
ENTRY("GRA_grid_choose_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
grapher->grid_spacing = cbs->ival ;
grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
redraw_graph(grapher,0) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_pin_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
float *vec = (float *)(cbs->cval) ;
int pb=(int)vec[0] , pt=(int)vec[1] , ii ;
ENTRY("GRA_pin_choose_CB") ;
GRA_timer_stop( grapher ) ;
if( pb >= grapher->status->num_series-2 ||
pb < 0 ||
(pt > 0 && pt-pb < 2) ){ /* stupid user */
XBell(grapher->dc->display,100) ; EXRETURN ;
}
ii = 100000*pt + pb ;
drive_MCW_grapher( grapher , graDR_setpins , (XtPointer)(ii) ) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_ggap_CB( MCW_arrowval *cbs , XtPointer cd ) /* 12 Jan 1998 */
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
int gg ;
ENTRY("GRA_ggap_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
gg = grapher->ggap ; grapher->ggap = cbs->ival ;
if( gg != grapher->ggap ){
init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
}
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_gthick_CB( MCW_arrowval *cbs , XtPointer cd ) /* 06 Oct 2004 */
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
int gg ;
ENTRY("GRA_gthick_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
gg = grapher->gthick ; grapher->gthick = cbs->ival ;
if( gg != grapher->gthick ){
init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
}
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
#ifdef USE_OPTMENUS
void GRA_slice_choose_CB( MCW_arrowval *cbs , XtPointer cd )
#else
void GRA_slice_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
#endif
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
ENTRY("GRA_slice_choose_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
grapher->zpoint = cbs->ival ;
if( grapher->zpoint >= grapher->status->nz )
grapher->zpoint = grapher->status->nz - 1 ;
redraw_graph( grapher , 0 ) ;
send_newinfo( grapher ) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
#ifdef USE_OPTMENUS
void GRA_ignore_choose_CB( MCW_arrowval * cbs , XtPointer cd )
#else
void GRA_ignore_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
#endif
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
ENTRY("GRA_ignore_choose_CB") ;
if( ! GRA_VALID(grapher) || grapher->status->send_CB == NULL ) EXRETURN ;
if( cbs->ival >= 0 && cbs->ival < TTOP(grapher)-1 ){
GRA_cbs gbs ;
gbs.reason = graCR_setignore ;
gbs.key = cbs->ival ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
#else
CALL_sendback( grapher , gbs ) ;
#endif
}
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
#ifdef USE_OPTMENUS
void GRA_polort_choose_CB( MCW_arrowval * cbs , XtPointer cd )
#else
void GRA_polort_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
#endif
{
MCW_grapher * grapher = (MCW_grapher *) cd ;
ENTRY("GRA_polort_choose_CB") ;
if( ! GRA_VALID(grapher) || grapher->status->send_CB == NULL ) EXRETURN ;
if( cbs->ival >= 0 && cbs->ival <= MAX_POLORT ){
GRA_cbs gbs ;
gbs.reason = graCR_polort ;
gbs.key = cbs->ival ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
#else
CALL_sendback( grapher , gbs ) ;
#endif
}
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_bkthr_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
{
ENTRY("GRA_bkthr_choose_CB") ;
SET_FIM_bkthr( cbs->fval ) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_refread_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
{
MCW_grapher * grapher = (MCW_grapher *) cd ;
MRI_IMAGE * flim ;
float * far ;
int ii ;
GRA_cbs gbs ;
ENTRY("GRA_refread_choose_CB") ;
if( ! GRA_VALID(grapher) ||
grapher->status->send_CB == NULL ||
cbs->reason != mcwCR_string ||
cbs->cval == NULL || strlen(cbs->cval) == 0 ) EXRETURN ;
EXRONE(grapher) ; /* 22 Sep 2000 */
flim = mri_read_1D( cbs->cval ) ; /* 16 Nov 1999: replaces mri_read_ascii */
if( flim == NULL || flim->nx < 2 ){
XBell(grapher->dc->display,100) ; mri_free(flim) ; EXRETURN ;
}
far = MRI_FLOAT_PTR(flim) ;
for( ii=0 ; ii < flim->nvox ; ii++ )
if( fabs(far[ii]) >= 33333.0 ) far[ii] = WAY_BIG ;
{ GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
gbs.reason = graCR_refequals ;
gbs.userdata = (XtPointer) flim ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
#else
CALL_sendback( grapher , gbs ) ;
#endif
mri_free(flim) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_refstore_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
{
MCW_grapher * grapher = (MCW_grapher *) cd ;
ENTRY("GRA_refstore_choose_CB") ;
if( ! GRA_VALID(grapher) ||
grapher->ref_ts == NULL ||
IMARR_COUNT(grapher->ref_ts) < 1 ||
cbs->reason != mcwCR_string ||
cbs->cval == NULL || strlen(cbs->cval) == 0 ) EXRETURN ;
EXRONE(grapher) ; /* 22 Sep 2000 */
PLUTO_register_timeseries( cbs->cval , IMARR_SUBIMAGE(grapher->ref_ts,0) ) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------------*/
void GRA_refwrite_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
{
MCW_grapher * grapher = (MCW_grapher *) cd ;
MRI_IMAGE * tsim ;
int ii , ll ;
GRA_cbs gbs ;
ENTRY("GRA_refwrite_choose_CB") ;
if( ! GRA_VALID(grapher) ||
grapher->ref_ts == NULL ||
IMARR_COUNT(grapher->ref_ts) < 1 ||
cbs->reason != mcwCR_string ||
cbs->cval == NULL || (ll=strlen(cbs->cval)) == 0 ) EXRETURN ;
EXRONE(grapher) ; /* 22 Sep 2000 */
for( ii=0 ; ii < ll ; ii++ ){
if( iscntrl(cbs->cval[ii]) || isspace(cbs->cval[ii]) ||
cbs->cval[ii] == '/' || cbs->cval[ii] == ';' ||
cbs->cval[ii] == '*' || cbs->cval[ii] == '?' ||
cbs->cval[ii] == '&' || cbs->cval[ii] == '|' ||
cbs->cval[ii] == '"' || cbs->cval[ii] == '>' ||
cbs->cval[ii] == '<' || cbs->cval[ii] == '\'' ||
cbs->cval[ii] == '[' || cbs->cval[ii] == ']' ){
XBell( XtDisplay(wcaller) , 100 ) ; EXRETURN ;
}
}
#if 0
tsim = mri_transpose( IMARR_SUBIMAGE(grapher->ref_ts,0) ) ;
mri_write_ascii( cbs->cval , tsim ) ;
mri_free( tsim ) ;
#else
mri_write_1D( cbs->cval , IMARR_SUBIMAGE(grapher->ref_ts,0) ) ; /* 16 Nov 1999 */
#endif
/* 12 Nov 1996: put this in AFNI's list of library files */
if( grapher->status->send_CB != NULL ){
mri_add_name( cbs->cval , IMARR_SUBIMAGE(grapher->ref_ts,0) ) ;
gbs.reason = graCR_timeseries_library ;
gbs.userdata = (XtPointer) IMARR_SUBIMAGE(grapher->ref_ts,0) ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
#else
CALL_sendback( grapher , gbs ) ;
#endif
}
EXRETURN ;
}
/*-----------------------------------------------------------------------
External interface to drive an MCW_grapher:
grapher = pointer to structure returned by new_MCW_grapher
drive_code = integer indicating which action to take
drive_data = data or pointer to data controlling action
(you will probably have to cast this to
XtPointer to avoid ugly warnings from the compiler)
OK drive_code drive_data should be
-- ---------- --------------------
* graDR_cursor (int) with new cursor id for the image window;
(if negative, means from cursorfont)
* graDR_realize (ignored) an unrealized viewer is re-realized
* graDR_redraw (int *) array of 4 ints: x,y,z,m
redraw the graph centered at x,y,z with matrix m
* graDR_destroy (ignored) destroy this MCW_grapher, and delete its
own XtMalloc-ed internal data structures;
after this call, you must myXtFree(grapher) to finish
the job.
* graDR_newdata (XtPointer) contains new auxiliary data for getser;
this call switches the data sequence to a
new one entirely. As with imseq, this should
be followed by a call with graDR_redraw.
* graDR_title (char *) contains new string for window title bar
* graDR_icon (Pixmap) sets the icon for this window
* graDR_addref_ts (MRI_IMAGE *) adds a reference timeseries to the list
input == NULL --> delete all references
** N.B.: The input timeseries will not be copied, just
will keep a pointer to it. Thus, the input
timeseries should not be destroyed.
* graDR_addort_ts (MRI_IMAGE *) adds an ort timeseries to the list
input == NULL --> delete all orts
* graDR_winaver (int) 0=off 1=on WinAver toggle on FIM menu
* graDR_setignore (int) set the initial ignore level for graphs
* graDR_polort (int) set the polort level for fimmery
* graDR_setindex (int) contains the new time_index;
All this does is draw some stuff.
* graDR_button2_enable (ignored) Turn button2 reporting on
* graDR_button2_disable (ignored) and off.
* graDR_fim_disable (ignored) Turn all FIM stuff off (for good)
* graDR_mirror (int) Turn mirroring on (==1) or off (==0)
* graDR_setmatrix (int) These 3 items set their corresponding
* graDR_setgrid parameters to the drive parameter.
* graDR_newlength (int) set the expected length of time series
to be some new value (e.g., the pin number)
* graDR_setpinnum [same as newlength]
* graDR_setpintop [same as newlength]
* graDR_setpinbot (int) set the bottom index for plotting
* graDR_setpins (int) set top AND bottom index for plotting;
value = 100000*top + bot
* graDR_setglobalbaseline (float *) Global baseline value
The Boolean return value is True for success, False for failure.
-------------------------------------------------------------------------*/
Boolean drive_MCW_grapher( MCW_grapher * grapher ,
int drive_code , XtPointer drive_data )
{
ENTRY("drive_MCW_grapher") ;
if( ! GRA_VALID(grapher) ) RETURN(False) ;
switch( drive_code ){
/*------- error! -------*/
default:{
fprintf(stderr,"\a\n*** drive_MCW_grapher: code=%d illegal!\n",
drive_code) ;
XBell( grapher->dc->display , 100 ) ;
RETURN( False ) ;
}
/*------ winaver [27 Jan 2004] -----*/
case graDR_winaver:{
int vvv = (int)drive_data ;
MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , vvv ) ;
RETURN( True ) ;
}
/*------ setglobalbaseline [07 Aug 2001] -----*/
case graDR_setglobalbaseline:{
float *vvv = (float *) drive_data ; /* get value */
int ii = thd_floatscan( 1 , vvv ) ; /* check value */
MCW_choose_cbs cb ;
if( ii != 0 ) RETURN( False ) ; /* this is bad */
cb.reason = mcwCR_integer ;
cb.fval = *vvv ;
GRA_finalize_global_baseline_CB(NULL,(XtPointer)grapher,&cb) ;
RETURN( True ) ;
}
/*------ setmatrix [22 Sep 2000] -----*/
case graDR_setmatrix:{
int mm = (int) drive_data ;
if( mm < 0 ) RETURN( False ) ;
grapher->mat = MIN( grapher->mat_max , mm ) ;
init_mat ( grapher ) ;
redraw_graph( grapher, PLOTCODE_AUTOSCALE ); /* 12 Oct 2000: autoscale */
send_newinfo( grapher ) ;
RETURN( True ) ;
}
/*------ setgrid [22 Sep 2000] -----*/
case graDR_setgrid:{
int mm = (int) drive_data ;
if( mm < 2 ) RETURN( False ) ;
grapher->grid_spacing = mm ;
grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
redraw_graph(grapher,0) ;
RETURN( True ) ;
}
/*------ mirroring (Jul 2000) -----*/
case graDR_mirror:{
int ii = (int) drive_data ;
if( ii != grapher->mirror ){
grapher->mirror = ii ;
init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
}
}
break ;
/*------ fim disabling -----*/
case graDR_fim_disable:{
int ii ;
XtUnmanageChild( grapher->fmenu->fim_cbut ) ;
XtUnmanageChild( grapher->opt_xaxis_cbut ) ;
for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
if( gr_unfim[ii] ){
if( grapher->opt_color_av[ii] != NULL )
XtUnmanageChild( grapher->opt_color_av[ii]->wrowcol ) ;
if( grapher->opt_thick_bbox[ii] != NULL )
XtUnmanageChild( grapher->opt_thick_bbox[ii]->wtop ) ;
if( grapher->opt_points_bbox[ii] != NULL )
XtUnmanageChild( grapher->opt_points_bbox[ii]->wtop ) ;
}
}
}
break ;
/*------ button2 stuff -----*/
case graDR_button2_enable:{
grapher->button2_enabled = 1 ;
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
RETURN( True ) ;
}
case graDR_button2_disable:{
grapher->button2_enabled = 0 ;
RETURN( True ) ;
}
/*------ set time index -----*/
case graDR_setindex:{
int new_index = (int) drive_data ;
if( new_index < 0 || new_index >= grapher->status->num_series )
RETURN( False ) ;
if( new_index != grapher->time_index ){
grapher->time_index = new_index ;
if( grapher->textgraph )
redraw_graph( grapher , 0 ) ;
else
GRA_redraw_overlay( grapher ) ;
}
RETURN( True ) ;
}
/*------ reset top of time series plotting ------*/
/* (same as graDR_setpinnum and graDR_setpintop) */
case graDR_newlength:{
int newtop=(int)drive_data ;
if( newtop < MIN_PIN ) newtop = 0 ;
if( newtop > MAX_PIN ) newtop = MAX_PIN ;
grapher->pin_top = newtop ;
if( NPTS(grapher) < 2 ) grapher->pin_bot = 0 ;
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
redraw_graph( grapher, 0 ) ;
RETURN( True ) ;
}
/*------ reset bottom of time series plotting [17 Mar 2004] -----*/
case graDR_setpinbot:{
int newbot=(int)drive_data ;
if( newbot < 0 ) newbot = 0 ;
if( newbot >= TTOP(grapher) ) newbot = 0 ;
grapher->pin_bot = newbot ;
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
redraw_graph( grapher, 0 ) ;
RETURN( True ) ;
}
/*------ reset bot and top of time series plotting [19 Mar 2004] -----*/
case graDR_setpins:{
int ii=(int)drive_data , newbot,newtop ;
if( ii <= 0 ){
newbot = newtop = 0 ;
} else {
newbot = ii % 100000 ;
newtop = ii / 100000 ;
if( newtop < MIN_PIN ) newtop = 0 ;
}
if( newtop > 0 && newtop-newbot < 2 ) newbot = 0 ;
if( newbot >= TTOP(grapher) ) newbot = 0 ;
grapher->pin_bot = newbot ;
grapher->pin_top = newtop ;
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
redraw_graph( grapher, 0 ) ;
RETURN( True ) ;
}
/*------ set ignore count -----*/
case graDR_setignore:{
int new_ignore = (int) drive_data ;
if( new_ignore >= 0 && new_ignore < TTOP(grapher)-1 ){
grapher->init_ignore = new_ignore ;
redraw_graph( grapher , PLOTCODE_AUTOSCALE ) ;
RETURN( True ) ;
} else {
RETURN( False ) ;
}
}
/*------- set polort [27 May 1999] --------*/
case graDR_polort:{
int new_polort = (int) drive_data ;
if( new_polort >= 0 ){
grapher->polort = new_polort ;
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
}
RETURN( True ) ;
}
/*----- set reference time series (currently limited to one) -----*/
case graDR_addref_ts:{
MRI_IMAGE *im = (MRI_IMAGE *) drive_data ;
if( im == NULL ){ /* no input --> kill kill kill */
STATUS("freeing reference timeseries") ;
FREE_IMARR(grapher->ref_ts) ;
grapher->ref_ts = NULL ;
} else{
if( grapher->ref_ts == NULL ) INIT_IMARR( grapher->ref_ts ) ;
if( IMARR_COUNT(grapher->ref_ts) == 0 ){
STATUS("adding reference timeseries") ;
ADDTO_IMARR( grapher->ref_ts , im ) ; /* create first one */
} else {
STATUS("replacing reference timeseries") ;
IMARR_SUBIMAGE(grapher->ref_ts,0) = im ; /* replace first one */
}
}
redraw_graph( grapher , 0 ) ;
RETURN( True ) ;
}
/*----- set ort time series (currently limited to one) -----*/
case graDR_addort_ts:{
MRI_IMAGE *im = (MRI_IMAGE *) drive_data ;
if( im == NULL ){ /* no input --> kill kill kill */
STATUS("freeing ort timeseries") ;
FREE_IMARR(grapher->ort_ts) ;
grapher->ort_ts = NULL ;
} else{
if( grapher->ort_ts == NULL ) INIT_IMARR( grapher->ort_ts ) ;
if( IMARR_COUNT(grapher->ort_ts) == 0 ){
STATUS("adding ort timeseries") ;
ADDTO_IMARR( grapher->ort_ts , im ) ; /* create first one */
} else {
STATUS("replacing ort timeseries") ;
IMARR_SUBIMAGE(grapher->ort_ts,0) = im ; /* replace first one */
}
}
redraw_graph( grapher , 0 ) ;
RETURN( True ) ;
}
/*------ set icon pixmap -----*/
case graDR_icon:{
int xret , yret ;
unsigned int wret,hret,bret,dret ;
Window rret ;
XtVaSetValues( grapher->fdw_graph , XmNiconPixmap , (Pixmap) drive_data , NULL ) ;
grapher->glogo_pixmap = (Pixmap) drive_data ;
/* get geometry for later use */
if( grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP ){
(void) XGetGeometry( grapher->dc->display , grapher->glogo_pixmap ,
&rret , &xret , &yret , &wret , &hret , &bret , &dret ) ;
grapher->glogo_width = wret ;
grapher->glogo_height = hret ;
} else {
grapher->glogo_width = 0 ;
grapher->glogo_height = 0 ;
}
RETURN( True ) ;
}
/*------- title --------*/
case graDR_title:{
char * title = (char *) drive_data ;
if( title == NULL || strlen(title) == 0 ) RETURN( False ) ;
XtVaSetValues( grapher->fdw_graph , XmNtitle , title , NULL ) ;
RETURN( True ) ;
}
/*------- death! -------*/
case graDR_destroy:{
end_fd_graph_CB( NULL , (XtPointer) grapher , NULL ) ;
RETURN( True ) ;
}
/*------- unrealize! -------*/
case graDR_unrealize:{
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
if( GRA_REALZ(grapher) ) XtUnrealizeWidget( grapher->fdw_graph ) ;
grapher->valid = 1 ;
if( grapher->fd_pxWind != (Pixmap) 0 )
XFreePixmap( grapher->dc->display , grapher->fd_pxWind ) ;
RETURN( True ) ;
}
/*------- realize! -------*/
case graDR_realize:{
if( ! GRA_REALZ(grapher) ){
int width , height ;
grapher->valid = 2 ;
XtRealizeWidget( grapher->fdw_graph ) ;
WAIT_for_window(grapher->fdw_graph) ;
/* 29 Sep 2000: next 2 lines of code are for the Form change */
XtVaSetValues( grapher->option_rowcol ,
XmNleftAttachment , XmATTACH_NONE ,
XmNtopAttachment , XmATTACH_NONE ,
XmNrightAttachment , XmATTACH_FORM ,
XmNbottomAttachment , XmATTACH_FORM ,
NULL ) ;
XMapRaised( XtDisplay(grapher->option_rowcol) ,
XtWindow(grapher->option_rowcol) ) ;
NORMAL_cursorize( grapher->fdw_graph ) ;
if( ISONE(grapher) )
NORMAL_cursorize( grapher->draw_fd ) ; /* 07 Dec 2001 */
else
POPUP_cursorize( grapher->draw_fd ) ;
MCW_widget_geom( grapher->draw_fd , &width , &height , NULL,NULL ) ;
GRA_new_pixmap( grapher , width , height , 0 ) ;
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
AFNI_sleep(1) ; /* 08 Mar 2002: for good luck */
}
RETURN( True ) ;
}
/*------- new cursor for image -------*/
case graDR_cursor:{
int cur = (int) drive_data ;
MCW_alter_widget_cursor( grapher->fdw_graph , cur , "yellow" , "blue" ) ;
RETURN( True ) ;
}
/*------- new data sequence!!! -------*/
case graDR_newdata:{
int npold = grapher->status->num_series ; /* 22 Sep 2000 */
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
grapher->getaux = drive_data ;
#if 0
grapher->status = (MCW_grapher_status *)
grapher->getser(0,graCR_getstatus,drive_data) ;
#else
CALL_getser( grapher , 0,graCR_getstatus , MCW_grapher_status *,grapher->status ) ;
#endif
init_const( grapher ) ;
/* mustn't allow bottom of plotting range to be beyond top of data! */
if( grapher->pin_bot >= grapher->status->num_series-1 ) grapher->pin_bot = 0 ;
if( npold < 2 || !grapher->grid_fixed ){ /* 22 Sep 2000 */
auto_grid( grapher , NPTS(grapher) ) ;
}
#ifdef USE_OPTMENUS
GRA_fix_optmenus( grapher ) ;
#endif
if( ISONE(grapher) ) /* 07 Dec 2001 */
NORMAL_cursorize( grapher->draw_fd ) ;
else
POPUP_cursorize( grapher->draw_fd ) ;
RETURN( True ) ;
}
/*------- redraw -------*/
case graDR_redraw:{
int *xym = (int *) drive_data ;
STATUS("graDR_redraw") ;
if( xym != NULL ){
if( xym[0] >= 0 ) grapher->xpoint = xym[0] ;
if( xym[1] >= 0 ) grapher->ypoint = xym[1] ;
if( xym[2] >= 0 ) grapher->zpoint = xym[2] ;
if( xym[3] > 0 ) grapher->mat = xym[3] ;
init_mat(grapher) ;
}
redraw_graph( grapher , 0 ) ;
RETURN( True ) ;
}
} /* end of switch on drive_code */
RETURN( False ) ; /* should never be reached! */
}
/*------------------------------------------------------------------
Callback for all FIM menu buttons
--------------------------------------------------------------------*/
void GRA_fim_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
FIM_menu * fm = (FIM_menu *) client_data ;
MCW_grapher * grapher = (MCW_grapher *) fm->parent ;
GRA_cbs cbs ;
ENTRY("GRA_fim_CB") ;
if( ! GRA_VALID(grapher) || grapher->status->send_CB == NULL ) EXRETURN ;
EXRONE(grapher) ; /* 22 Sep 2000 */
/*--- carry out action, depending on which widget called me ---*/
/*** Pick reference ***/
if( w == grapher->fmenu->fim_pickref_pb ){
cbs.reason = graCR_pickref ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
grapher->tschosen = 1 ; /* 31 Mar 2004 */
}
/*** Pick ort ***/
else if( w == grapher->fmenu->fim_pickort_pb ){
cbs.reason = graCR_pickort ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
grapher->tschosen = 1 ; /* 31 Mar 2004 */
}
/*** Clear FIM ***/
else if( w == grapher->fmenu->fim_editref_clear_pb ){
cbs.reason = graCR_clearfim ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
}
/*** Clear Ort ***/
else if( w == grapher->fmenu->fim_editort_clear_pb ){
cbs.reason = graCR_clearort ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
}
/*** set ref to central time series ***/
else if( w == grapher->fmenu->fim_editref_equals_pb ||
w == grapher->fmenu->fim_editref_add_pb ){
int ll ;
MRI_IMAGE * tsim ;
ll = grapher->xpoint +
grapher->ypoint * grapher->status->nx +
grapher->zpoint * grapher->status->nx * grapher->status->ny ;
#if 0
tsim = (MRI_IMAGE *) grapher->getser( ll , graCR_getseries ,
grapher->getaux ) ;
#else
CALL_getser( grapher , ll,graCR_getseries , MRI_IMAGE *,tsim ) ;
#endif
if( tsim != NULL ){
{ GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
cbs.reason = (w == grapher->fmenu->fim_editref_equals_pb)
? graCR_refequals : graCR_refadd ;
cbs.userdata = (XtPointer) tsim ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
mri_free( tsim ) ;
}
}
/*** read or write or smooth ***/
else if( w == grapher->fmenu->fim_editref_read_pb ){
MCW_choose_string( grapher->option_rowcol ,
"Ideal Input Filename:" , NULL ,
GRA_refread_choose_CB , (XtPointer) grapher ) ;
}
else if( w == grapher->fmenu->fim_editref_write_pb ){
if( grapher->ref_ts != NULL && IMARR_COUNT(grapher->ref_ts) > 0 ){
MCW_choose_string( grapher->option_rowcol ,
"Ideal Output Filename:" , NULL ,
GRA_refwrite_choose_CB , (XtPointer) grapher ) ;
} else {
XBell( grapher->dc->display , 100 ) ;
}
}
else if( w == grapher->fmenu->fim_editref_store_pb ){
if( grapher->ref_ts != NULL && IMARR_COUNT(grapher->ref_ts) > 0 ){
MCW_choose_string( grapher->option_rowcol ,
"Label to Store Ideal:" , NULL ,
GRA_refstore_choose_CB , (XtPointer) grapher ) ;
} else {
XBell( grapher->dc->display , 100 ) ;
}
}
else if( w == grapher->fmenu->fim_editref_smooth_pb ){
cbs.reason = graCR_refsmooth ;
if( grapher->ref_ts != NULL && IMARR_COUNT(grapher->ref_ts) > 0 ){
{ GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
} else {
XBell( grapher->dc->display , 100 ) ;
}
}
/*** Set shifts ***/
else if( w == grapher->fmenu->fim_editref_setshift_pb ){
GRA_setshift_startup( grapher ) ;
}
/*** Execute FIM ***/
else if( w == grapher->fmenu->fim_execute_pb ){
int val = MCW_val_bbox(grapher->fmenu->fim_opt_bbox) ;
cbs.reason = graCR_dofim ;
switch(val){
default: cbs.key = FIM_ALPHA_MASK | FIM_CORR_MASK ; break ;
case 2: cbs.key = FIM_PERC_MASK | FIM_CORR_MASK ; break ;
case 4: cbs.key = FIM_PAVE_MASK | FIM_CORR_MASK ; break ;
case 3: cbs.key = FIM_PTOP_MASK | FIM_CORR_MASK ; break ;
}
cbs.mat = 0 ; /* Feb 2000 */
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
}
else if( w == grapher->fmenu->fim_execfimp_pb ){
cbs.reason = graCR_dofim ;
cbs.key = MCW_val_bbox(grapher->fmenu->fimp_opt_bbox) ;
cbs.mat = MCW_val_bbox(grapher->fmenu->fimp_user_bbox) ; /* Feb 2000 */
GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
if( cbs.key || cbs.mat )
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
else
XBell( grapher->dc->display , 100 ) ;
}
/*** 04 Jan 2000: modify the FIM+ button settings ***/
else if( w == grapher->fmenu->fimp_setdefault_pb ){
char * ff = my_getenv( "AFNI_FIM_MASK" ) ; int mm=0 ;
if( ff != NULL ) mm = strtol(ff,NULL,10) ;
if( mm <= 0 ) mm = FIM_DEFAULT_MASK ;
MCW_set_bbox( grapher->fmenu->fimp_opt_bbox , mm ) ;
}
else if( w == grapher->fmenu->fimp_setall_pb ){
int mm = (2 << FIM_NUM_OPTS) - 1 ;
MCW_set_bbox( grapher->fmenu->fimp_opt_bbox , mm ) ;
}
else if( w == grapher->fmenu->fimp_unsetall_pb ){
MCW_set_bbox( grapher->fmenu->fimp_opt_bbox , 0 ) ;
}
/*** FIM plotting buttons ***/
else if( w == grapher->fmenu->fim_plot_firstref_pb ){
if( grapher->ref_ts_plotall != 0 ){
grapher->ref_ts_plotall = 0 ;
redraw_graph( grapher , 0 ) ;
}
}
else if( w == grapher->fmenu->fim_plot_allrefs_pb ){
if( grapher->ref_ts_plotall == 0 ){
grapher->ref_ts_plotall = 1 ;
redraw_graph( grapher , 0 ) ;
}
}
/*** Ignore stuff ***/
else if( w == grapher->fmenu->fim_ignore_down_pb && grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_setignore ;
cbs.key = grapher->init_ignore - 1 ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
}
else if( w == grapher->fmenu->fim_ignore_up_pb && grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_setignore ;
cbs.key = grapher->init_ignore + 1 ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
}
else if( w == grapher->fmenu->fim_ignore_choose_pb && grapher->status->send_CB != NULL ){
#ifdef USE_OPTMENUS
GRA_ignore_choose_CB( grapher->fmenu->fim_ignore_choose_av , grapher ) ;
#else
MCW_choose_integer( grapher->option_rowcol , "Initial Ignore" ,
0 , grapher->status->num_series-1 , grapher->init_ignore ,
GRA_ignore_choose_CB , (XtPointer) grapher ) ;
#endif
}
/* 27 May 1999: set polort */
else if( w == grapher->fmenu->fim_polort_choose_pb && grapher->status->send_CB != NULL ){
#ifdef USE_OPTMENUS
GRA_polort_choose_CB( grapher->fmenu->fim_polort_choose_av , grapher ) ;
#else
MCW_choose_integer( grapher->option_rowcol , "Polort Order" ,
0 , MAX_POLORT , grapher->polort ,
GRA_polort_choose_CB , (XtPointer) grapher ) ;
#endif
}
/* 02 Jun 1999: set FIM bkg threshold */
else if( w == grapher->fmenu->fim_bkthr_choose_pb ){
MCW_choose_integer( grapher->option_rowcol , "Bkg Thresh %" ,
0 , 99 , (int)(100*FIM_THR) ,
GRA_bkthr_choose_CB , (XtPointer) grapher ) ;
}
/*** Unimplemented Button ***/
else {
XBell( grapher->dc->display , 100 ) ;
}
/*--- Done!!! ---*/
EXRETURN ;
}
/*-----------------------------------------------------------------------*/
#define SETSHIFT_quit_label "Quit"
#define SETSHIFT_apply_label "Apply"
#define SETSHIFT_done_label "Set"
#define SETSHIFT_quit_help "Press to close\nthis control box"
#define SETSHIFT_apply_help "Press to apply this choice\nand keep this control box"
#define SETSHIFT_done_help "Press to apply this choice\nand close this control box"
#define NUM_SETSHIFT_ACT 3
static MCW_action_item SETSHIFT_act[NUM_SETSHIFT_ACT] = {
{ SETSHIFT_quit_label , GRA_setshift_action_CB, NULL, SETSHIFT_quit_help ,"Close window" , 0 },
{ SETSHIFT_apply_label , GRA_setshift_action_CB, NULL, SETSHIFT_apply_help,"Apply choice and keep window" , 0 },
{ SETSHIFT_done_label , GRA_setshift_action_CB, NULL, SETSHIFT_done_help ,"Apply choice and close window", 1 }
} ;
#define SETSHIFT_QUIT 0
#define SETSHIFT_APPLY 1
#define SETSHIFT_DONE 2
/*-----------------------------------------------------------------------*/
void GRA_setshift_startup( MCW_grapher * grapher )
{
int ib , xx,yy ;
Widget wrc ;
ENTRY("GRA_setshift_startup") ;
if( ! GRA_REALZ(grapher) || grapher->dialog != NULL ) EXRETURN ;
MCW_widget_geom( grapher->fdw_graph , NULL,NULL,&xx,&yy ) ; /* geometry of shell */
grapher->dialog = XtVaCreatePopupShell(
"menu" , xmDialogShellWidgetClass , grapher->fdw_graph ,
XmNx , xx+15 ,
XmNy , yy+15 ,
XmNtitle , "Shifts" ,
XmNdeleteResponse , XmDO_NOTHING ,
XmNinitialResourcesPersistent , False ,
XmNvisual , grapher->dc->visual , /* 14 Sep 1998 */
XmNcolormap , grapher->dc->colormap ,
XmNdepth , grapher->dc->depth ,
XmNscreen , grapher->dc->screen ,
XmNbackground , 0 ,
XmNborderColor , 0 ,
XmNkeyboardFocusPolicy , XmEXPLICIT ,
NULL ) ;
if( MCW_isitmwm(grapher->fdw_graph) ){
XtVaSetValues( grapher->dialog ,
XmNmwmDecorations , MWM_DECOR_BORDER ,
XmNmwmFunctions , MWM_FUNC_MOVE
| MWM_FUNC_CLOSE ,
NULL ) ;
}
XmAddWMProtocolCallback( /* make "Close" window menu work */
grapher->dialog ,
XmInternAtom( grapher->dc->display , "WM_DELETE_WINDOW" , False ) ,
GRA_setshift_action_CB , grapher ) ;
wrc = XtVaCreateWidget( /* RowColumn to hold all */
"dialog" , xmRowColumnWidgetClass , grapher->dialog ,
XmNpacking , XmPACK_TIGHT ,
XmNorientation , XmVERTICAL ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
(void) XtVaCreateManagedWidget(
"dialog" , xmLabelWidgetClass , wrc ,
LABEL_ARG("-- Shift Controls --") ,
XmNalignment , XmALIGNMENT_CENTER ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
(void) XtVaCreateManagedWidget(
"dialog" , xmSeparatorWidgetClass , wrc ,
XmNseparatorType , XmSHADOW_ETCHED_IN ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
grapher->setshift_inc_av = new_MCW_arrowval(
wrc , "Increment " , MCW_AV_downup ,
1 , 1000 , (int)(100.0*grapher->setshift_inc) ,
MCW_AV_edittext , 2 ,
NULL , NULL , NULL , NULL ) ;
grapher->setshift_left_av = new_MCW_arrowval(
wrc , "Steps Left " , MCW_AV_downup ,
0 , 29 , grapher->setshift_left ,
MCW_AV_edittext , 0 ,
NULL , NULL , NULL , NULL ) ;
grapher->setshift_right_av = new_MCW_arrowval(
wrc , "Steps Right" , MCW_AV_downup ,
0 , 29 , grapher->setshift_right ,
MCW_AV_edittext , 0 ,
NULL , NULL , NULL , NULL ) ;
grapher->setshift_inc_av->allow_wrap = 1 ; /* allow wrap at limits of values */
grapher->setshift_left_av->allow_wrap = 1 ;
grapher->setshift_right_av->allow_wrap = 1 ;
grapher->setshift_inc_av->fastdelay = 250 ; /* slow down arrow repeat action */
grapher->setshift_left_av->fastdelay = 250 ;
grapher->setshift_right_av->fastdelay = 250 ;
MCW_reghelp_children( grapher->setshift_inc_av->wrowcol ,
"This controls the step size\n"
"used to create the shifted\n"
"time series -- for example,\n"
"0.2 means a shift of 1/5\n"
"of a time series stepsize."
) ;
MCW_reghint_children( grapher->setshift_inc_av->wrowcol ,
"Size of shift" ) ;
MCW_reghelp_children( grapher->setshift_left_av->wrowcol ,
"This controls the number\n"
"of left shifts used to\n"
"create the desired multi-\n"
"vector time series.\n\n"
"N.B.: Steps Left plus\n"
" Steps Right should\n"
" be positive!"
) ;
MCW_reghint_children( grapher->setshift_left_av->wrowcol ,
"Number of steps left" ) ;
MCW_reghelp_children( grapher->setshift_right_av->wrowcol ,
"This controls the number\n"
"of right shifts used to\n"
"create the desired multi-\n"
"vector time series.\n\n"
"N.B.: Steps Left plus\n"
" Steps Right should\n"
" be positive!"
) ;
MCW_reghint_children( grapher->setshift_right_av->wrowcol ,
"Number of steps right" ) ;
for( ib=0 ; ib < NUM_SETSHIFT_ACT ; ib++ )
SETSHIFT_act[ib].data = (XtPointer) grapher ;
(void) MCW_action_area( wrc , SETSHIFT_act , NUM_SETSHIFT_ACT ) ;
XtManageChild( wrc ) ;
XtPopup( grapher->dialog , XtGrabNone ) ; RWC_sleep(1);
RWC_visibilize_widget( grapher->dialog ) ; /* 09 Nov 1999 */
NORMAL_cursorize( grapher->dialog ) ;
EXRETURN ;
}
/*-----------------------------------------------------------------------*/
void GRA_setshift_action_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
MCW_grapher * grapher = (MCW_grapher *) client_data ;
XmAnyCallbackStruct * cbs = (XmAnyCallbackStruct *) call_data ;
char * wname ;
int ib , close_window ;
ENTRY("GRA_setshift_action_CB") ;
if( !GRA_REALZ(grapher) || grapher->dialog==NULL ) EXRETURN ;
wname = XtName(w) ;
for( ib=0 ; ib < NUM_SETSHIFT_ACT ; ib++ ) /* button index, if any */
if( strcmp(wname,SETSHIFT_act[ib].label) == 0 ) break ;
close_window = (ib == SETSHIFT_DONE ||
ib == SETSHIFT_QUIT || ib == NUM_SETSHIFT_ACT) ;
if( close_window ){
RWC_XtPopdown( grapher->dialog ) ;
XSync( XtDisplay(w) , False ) ;
XmUpdateDisplay( w ) ;
}
switch( ib ){
case SETSHIFT_APPLY:
case SETSHIFT_DONE:{
grapher->setshift_inc = grapher->setshift_inc_av->fval ;
grapher->setshift_left = grapher->setshift_left_av->ival ;
grapher->setshift_right = grapher->setshift_right_av->ival ;
GRA_doshift( grapher ) ;
}
break ;
}
if( close_window ){ /* close the window */
XtDestroyWidget( grapher->dialog ) ;
grapher->dialog = NULL ;
FREE_AV( grapher->setshift_right_av ) ;
FREE_AV( grapher->setshift_left_av ) ;
FREE_AV( grapher->setshift_inc_av ) ;
}
EXRETURN ;
}
/*-----------------------------------------------------------------------*/
void GRA_doshift( MCW_grapher * grapher )
{
MRI_IMAGE * tsim , * newim , * tim ;
float * tsar , * nar , * tar ;
int ii,ivec , nx , newny , nleft,nright ;
float shinc ;
GRA_cbs gbs ;
ENTRY("GRA_doshift") ;
if( !GRA_VALID(grapher) ) EXRETURN ;
if( grapher->status->send_CB == NULL ||
grapher->setshift_inc <= 0.0 ||
grapher->setshift_left + grapher->setshift_right <= 0 ||
grapher->ref_ts == NULL ||
IMARR_COUNT(grapher->ref_ts) == 0 ){
XBell( grapher->dc->display , 100 ) ; EXRETURN ;
}
tsim = IMARR_SUBIMAGE(grapher->ref_ts,0) ; /* current ref */
tsar = MRI_FLOAT_PTR(tsim) ;
nx = tsim->nx ;
shinc = grapher->setshift_inc ;
nleft = grapher->setshift_left ;
nright = grapher->setshift_right ;
newny = 1 + nleft + nright ;
newim = mri_new( nx , newny , MRI_float ) ;
nar = MRI_FLOAT_PTR(newim) ;
for( ii=0 ; ii < nx ; ii++ )
nar[ii] = (ii < grapher->init_ignore) ? WAY_BIG : tsar[ii] ;
for( ivec=1 ; ivec <= nleft ; ivec++ ){
tim = mri_shift_1D( newim , -ivec * shinc ) ;
tar = MRI_FLOAT_PTR(tim) ;
for( ii=0 ; ii < nx ; ii++ ) nar[ii+ivec*nx] = tar[ii] ;
mri_free(tim) ;
}
for( ivec=1 ; ivec <= nright ; ivec++ ){
tim = mri_shift_1D( newim , ivec * shinc ) ;
tar = MRI_FLOAT_PTR(tim) ;
for( ii=0 ; ii < nx ; ii++ ) nar[ii+(ivec+nleft)*nx] = tar[ii] ;
mri_free(tim) ;
}
{ GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
gbs.reason = graCR_refequals ;
gbs.userdata = (XtPointer) newim ;
#if 0
grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
#else
CALL_sendback( grapher , gbs ) ;
#endif
mri_free( newim ) ;
EXRETURN ;
}
/*---------------------------------------------------------------------
Returns a bunch of widgets in a structure.
The parent widget is intended to be a menu bar.
-----------------------------------------------------------------------*/
FIM_menu * AFNI_new_fim_menu( Widget parent, XtCallbackProc cbfunc, int graphable )
{
FIM_menu *fmenu ;
Widget qbut_menu = NULL ;
ENTRY("AFNI_new_fim_menu") ;
fmenu = myXtNew(FIM_menu) ;
fmenu->cbfunc = cbfunc ;
/*------------------------*/
/*--- FIM Menu Buttons ---*/
/*------------------------*/
fmenu->fim_menu = XmCreatePulldownMenu( parent , "menu" , NULL,0 ) ;
VISIBILIZE_WHEN_MAPPED(fmenu->fim_menu) ; /* 27 Sep 2000 */
if( !AFNI_yesenv("AFNI_DISABLE_TEAROFF") ) TEAROFFIZE(fmenu->fim_menu) ;
fmenu->fim_cbut =
XtVaCreateManagedWidget(
"dialog" , xmCascadeButtonWidgetClass , parent ,
LABEL_ARG("FIM") ,
XmNsubMenuId , fmenu->fim_menu ,
XmNmarginWidth , 0 ,
XmNmarginHeight , 0 ,
XmNmarginBottom , 0 ,
XmNmarginTop , 0 ,
XmNmarginRight , 0 ,
XmNmarginLeft , 0 ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
if( graphable ){
MCW_register_hint( fmenu->fim_cbut , "Functional Imaging menu" ) ;
MCW_register_help( fmenu->fim_cbut ,
"******* Functional Imaging Controls: *******\n"
"\n"
"Ideal Vector Operations:\n"
" Pick Ideal --> Choose from a list\n"
" Pick Ort --> Choose from a list\n"
" Edit: = Center --> Use voxel timeseries\n"
" += Center --> Average with voxel\n"
" Smooth --> A 3 point filter\n"
" Shift --> Time-shifted copies\n"
" Clear --> Turn ideal off\n"
" WinAver --> Average of sub-graphs\n"
" Read --> Input from external file\n"
" Write --> Output to external file\n"
" Store --> Save in internal list\n"
" Ignore: Set how many points to ignore\n"
" at beginning of time series\n"
" [ Applies both to graphing ]\n"
" [ and to FIM computations. ]\n"
"\n"
"FIM Plots:\n"
" Can choose to graph only first vector in\n"
" ideal family, or all of them superimposed.\n"
"\n"
"Refresh Freq --> Choose number of time steps\n"
" between redisplay of the functional overlay\n"
" during FIM computations (0 == no redisplay).\n"
"Compute FIM --> Use the recursive method to\n"
" compute the correlation of each voxel time\n"
" series with each ideal vector; uses the best\n"
" correlation as the 'correct' waveform for\n"
" each voxel, individually. Time points that\n"
" have an ideal vector value >= 33333 will be\n"
" ignored in the computations, as will those\n"
" at the beginning specified in the Opt menu\n"
" 'Ignore' function."
) ;
} else {
MCW_register_hint( fmenu->fim_cbut , "Functional Imaging menu" ) ;
MCW_register_help( fmenu->fim_cbut ,
"******* Functional Imaging Controls: *******\n"
"\n"
"Pick Dataset --> Choose time-dependent dataset\n"
" from a list. If there is only one possible\n"
" choice, it will be selected for you without\n"
" displaying the list.\n"
"\n"
"Pick Ideal --> Choose time series from a list.\n"
"Pick Ort --> Choose time series from a list.\n"
"\n"
"Ignore --> Set how many points to ignore at the\n"
" beginning of time series.\n"
" [ Applies both to graphing and FIM-ing. ]\n"
"\n"
"Refresh Freq --> Choose number of time steps\n"
" between redisplay of the functional overlay\n"
" during FIM computations (0 == no redisplay).\n"
"\n"
"Compute FIM --> Use the recursive method to\n"
" compute the correlation of each voxel time\n"
" series with each ideal vector; uses the best\n"
" correlation as the 'correct' waveform for\n"
" each voxel, individually. Time points that\n"
" have an ideal vector value >= 33333 will be\n"
" ignored in the computations, as will those\n"
" at the beginning specified in the Opt menu\n"
" 'Ignore' function."
) ;
}
/* macros to put double and single separator lines in a menu */
#undef MENU_DLINE
#define MENU_DLINE(wmenu) \
(void) XtVaCreateManagedWidget( \
"dialog" , xmSeparatorWidgetClass , fmenu -> wmenu , \
XmNseparatorType , XmDOUBLE_LINE , NULL )
#undef MENU_SLINE
#define MENU_SLINE(wmenu) \
(void) XtVaCreateManagedWidget( \
"dialog" , xmSeparatorWidgetClass , fmenu -> wmenu , \
XmNseparatorType , XmSINGLE_LINE , NULL )
/* macro to create a new FIM menu button */
#define FIM_MENU_BUT(wname,label,hhh) \
fmenu -> wname = \
XtVaCreateManagedWidget( \
"dialog" , xmPushButtonWidgetClass , fmenu->fim_menu , \
LABEL_ARG( label ) , \
XmNmarginHeight , 0 , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , \
NULL ) ; \
XtAddCallback( fmenu -> wname , XmNactivateCallback , \
cbfunc , (XtPointer) fmenu ) ; \
MCW_register_hint( fmenu -> wname , hhh ) ;
/** macro to create a new fim pullright menu **/
/** 07 Jan 1999: added the mapCallback to fix position **/
#define FIM_MENU_PULLRIGHT(wmenu,wcbut,label,hhh) \
fmenu -> wmenu = \
XmCreatePulldownMenu( fmenu->fim_menu , "menu" , NULL , 0 ) ; \
fmenu -> wcbut = \
XtVaCreateManagedWidget( \
"dialog" , xmCascadeButtonWidgetClass , fmenu->fim_menu , \
LABEL_ARG( label ) , \
XmNsubMenuId , fmenu -> wmenu , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , \
NULL ) ; \
MCW_register_hint( fmenu -> wcbut , hhh ) ; \
XtAddCallback( fmenu -> wmenu, XmNmapCallback, GRA_mapmenu_CB, NULL ) ;
/** macro to create a new button on a pullright menu **/
#define FIM_MENU_PULL_BUT(wmenu,wname,label,hhh) \
fmenu -> wname = \
XtVaCreateManagedWidget( \
"dialog" , xmPushButtonWidgetClass , fmenu -> wmenu , \
LABEL_ARG( label ) , \
XmNmarginHeight , 0 , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , \
NULL ) ; \
XtAddCallback( fmenu -> wname , XmNactivateCallback , \
cbfunc , (XtPointer) fmenu ) ; \
MCW_register_hint( fmenu -> wname , hhh ) ;
#define EMPTY_BUT(wname) fmenu -> wname = NULL
/** 15 Dec 1997: a pullright menu with a single button **/
#define FIM_MENU_QBUT(wname,label,qlab,hhh) \
do { Widget ccc ; \
qbut_menu = XmCreatePulldownMenu(fmenu->fim_menu,"menu",NULL,0); \
ccc = XtVaCreateManagedWidget( "dialog" , \
xmCascadeButtonWidgetClass , fmenu->fim_menu , \
LABEL_ARG( label ) , \
XmNsubMenuId , qbut_menu , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , NULL ) ; \
fmenu -> wname = XtVaCreateManagedWidget( "dialog" , \
xmPushButtonWidgetClass , qbut_menu , \
LABEL_ARG( qlab ) , \
XmNmarginHeight , 0 , \
XmNtraversalOn , True , \
XmNinitialResourcesPersistent , False , NULL ) ; \
MCW_register_hint( fmenu -> wname , hhh ) ; \
XtAddCallback( fmenu -> wname , XmNactivateCallback , \
cbfunc , (XtPointer) fmenu ) ; \
XtAddCallback( qbut_menu, XmNmapCallback, GRA_mapmenu_CB, NULL ) ; \
} while(0)
/*** top of menu = a label to click on that does nothing at all ***/
(void) XtVaCreateManagedWidget(
"dialog" , xmLabelWidgetClass , fmenu->fim_menu ,
LABEL_ARG("--- Cancel ---") ,
XmNrecomputeSize , False ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
MENU_SLINE(fim_menu) ;
if( graphable ){
EMPTY_BUT(fim_pickdset_pb) ;
} else {
FIM_MENU_BUT( fim_pickdset_pb , "Pick Dataset" , "Choose Dataset to Graph" ) ;
}
FIM_MENU_BUT( fim_pickref_pb , "Pick Ideal" , "Pick Ideal Timeseries to Graph" ) ;
FIM_MENU_BUT( fim_pickort_pb , "Pick Ort" , "Pick Ort Timeseries to Graph" ) ;
if( graphable ){
char *bbox_label[1] = { "Ideal=WinAver" } ;
MENU_SLINE(fim_menu) ;
FIM_MENU_PULLRIGHT(fim_editref_menu,fim_editref_cbut ,"Edit Ideal" , "Modify Ideal Timeseries" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_equals_pb ,"Ideal = Center", "Set to Center Sub-graph" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_add_pb ,"Ideal+= Center", "Add in Center Sub-graph" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_smooth_pb ,"Smooth Ideal" , "Lowpass Filter Ideal" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_setshift_pb,"Shift Ideal" , "Time Shift Ideal" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_clear_pb ,"Clear Ideal" , "Turn Ideal Off" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editort_clear_pb ,"Clear Ort" , "Turn Ort Off" ) ;
fmenu->fim_editref_winaver_bbox /* 27 Jan 2004 */
= new_MCW_bbox( fmenu->fim_editref_menu ,
1 , bbox_label , MCW_BB_check , MCW_BB_noframe ,
GRA_winaver_CB , (XtPointer)fmenu ) ;
MCW_reghint_children( fmenu->fim_editref_winaver_bbox->wrowcol ,
"Ideal = Average of all Graphs in Window" ) ;
#ifdef USE_OPTMENUS
fmenu->fim_polort_choose_av =
new_MCW_optmenu( fmenu->fim_editref_menu , "Polort " , 0,MAX_POLORT,1,0 ,
GRA_fmenu_av_CB , (XtPointer) fmenu , NULL , NULL ) ;
fmenu->fim_polort_choose_pb = fmenu->fim_polort_choose_av->wrowcol ;
MCW_reghint_children( fmenu->fim_polort_choose_av->wrowcol , "Order of Polynomial Baseline for FIM" ) ;
#else
FIM_MENU_PULL_BUT( fim_editref_menu,fim_polort_choose_pb ,"Polort?", "Order of Polynomial Baseline for FIM") ;
#endif
FIM_MENU_PULL_BUT( fim_editref_menu,fim_bkthr_choose_pb ,"Bkg Thresh" , "Choose Background Threshold for FIM") ;
MENU_SLINE (fim_editref_menu) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_read_pb ,"Read Ideal" , "Read from .1D file" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_write_pb ,"Write Ideal", "Write to .1D file" ) ;
FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_store_pb ,"Store Ideal", "Save in internal list of timeseries" ) ;
} else {
EMPTY_BUT(fim_editref_cbut) ;
EMPTY_BUT(fim_editref_equals_pb) ;
EMPTY_BUT(fim_editref_add_pb) ;
EMPTY_BUT(fim_editref_smooth_pb) ;
EMPTY_BUT(fim_editref_setshift_pb) ;
EMPTY_BUT(fim_editref_clear_pb) ;
EMPTY_BUT(fim_editref_read_pb) ;
EMPTY_BUT(fim_editref_write_pb) ;
EMPTY_BUT(fim_editref_store_pb) ;
EMPTY_BUT(fim_editort_clear_pb) ;
EMPTY_BUT(fim_polort_choose_pb) ;
fmenu->fim_editref_winaver_bbox = NULL ; /* 27 Jan 2004 */
}
FIM_MENU_PULLRIGHT(fim_ignore_menu,fim_ignore_cbut ,"Ignore", "Number of initial timepoints to ignore" ) ;
FIM_MENU_PULL_BUT( fim_ignore_menu,fim_ignore_down_pb ,"Down" , "Ignore fewer points" ) ;
FIM_MENU_PULL_BUT( fim_ignore_menu,fim_ignore_up_pb ,"Up" , "Ignore more points" ) ;
#ifdef USE_OPTMENUS
fmenu->fim_ignore_choose_av =
new_MCW_optmenu( fmenu->fim_ignore_menu , "# " , 0,2,0,0 ,
GRA_fmenu_av_CB , (XtPointer) fmenu , NULL , NULL ) ;
fmenu->fim_ignore_choose_pb = fmenu->fim_ignore_choose_av->wrowcol ;
MCW_reghint_children( fmenu->fim_ignore_choose_av->wrowcol , "Pick number of ignored points" ) ;
#else
FIM_MENU_PULL_BUT( fim_ignore_menu,fim_ignore_choose_pb ,"Choose" , "Pick number of ignored points") ;
#endif
if( graphable ){
FIM_MENU_PULLRIGHT(fim_plot_menu,fim_plot_cbut ,"FIM Plots" , "Number of Ideals to plot" ) ;
FIM_MENU_PULL_BUT( fim_plot_menu,fim_plot_firstref_pb ,"First Ideal" , "Only plot 1 Ideal" ) ;
FIM_MENU_PULL_BUT( fim_plot_menu,fim_plot_allrefs_pb ,"All Ideals" , "Plot all Ideals" ) ;
} else {
EMPTY_BUT(fim_plot_cbut) ;
EMPTY_BUT(fim_plot_firstref_pb) ;
EMPTY_BUT(fim_plot_allrefs_pb) ;
}
MENU_DLINE(fim_menu) ;
FIM_MENU_QBUT( fim_execute_pb , "Compute FIM" , "-> fico" , "Correlation Analysis" ) ;
MCW_set_widget_bg( fmenu->fim_execute_pb ,
MCW_hotcolor(fmenu->fim_execute_pb) , 0 ) ;
{ static char * blab[] = {"Fit Coef", "% Change", "% From Ave", "% From Top"};
(void) XtVaCreateManagedWidget(
"dialog" , xmSeparatorWidgetClass , qbut_menu ,
XmNseparatorType , XmSINGLE_LINE , NULL ) ;
fmenu->fim_opt_bbox = new_MCW_bbox( qbut_menu , 4 , blab ,
MCW_BB_radio_one , MCW_BB_noframe ,
NULL , NULL ) ;
MCW_reghint_children( fmenu->fim_opt_bbox->wrowcol , "What to Compute" ) ;
}
MENU_DLINE(fim_menu) ;
FIM_MENU_QBUT( fim_execfimp_pb , "Compute FIM+" , "-> fbuc" , "Extended Correlation Analysis" ) ;
MCW_set_widget_bg( fmenu->fim_execfimp_pb ,
MCW_hotcolor(fmenu->fim_execfimp_pb) , 0 ) ;
(void) XtVaCreateManagedWidget(
"dialog" , xmSeparatorWidgetClass , qbut_menu ,
XmNseparatorType , XmSINGLE_LINE , NULL ) ;
fmenu->fimp_opt_bbox = new_MCW_bbox( qbut_menu, FIM_NUM_OPTS, fim_opt_labels,
MCW_BB_check , MCW_BB_noframe ,
NULL , NULL ) ;
MCW_reghint_children( fmenu->fimp_opt_bbox->wrowcol , "What to Compute" ) ;
{ char * ff = my_getenv( "AFNI_FIM_MASK" ) ; int mm=0 ;
if( ff != NULL ) mm = strtol(ff,NULL,10) ;
if( mm <= 0 ) mm = FIM_DEFAULT_MASK ;
MCW_set_bbox( fmenu->fimp_opt_bbox , mm ) ;
}
/* 04 Jan 2000: add some more buttons */
(void) XtVaCreateManagedWidget(
"dialog" , xmSeparatorWidgetClass , qbut_menu ,
XmNseparatorType , XmSINGLE_LINE , NULL ) ;
fmenu->fimp_setdefault_pb =
XtVaCreateManagedWidget( "dialog" , xmPushButtonWidgetClass , qbut_menu ,
LABEL_ARG( "Set Defaults" ) ,
XmNmarginHeight , 0 ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
XtAddCallback( fmenu->fimp_setdefault_pb ,
XmNactivateCallback , cbfunc , (XtPointer) fmenu ) ;
MCW_register_hint( fmenu->fimp_setdefault_pb , "Default computing options" ) ;
fmenu->fimp_setall_pb =
XtVaCreateManagedWidget( "dialog" , xmPushButtonWidgetClass , qbut_menu ,
LABEL_ARG( "Set All" ) ,
XmNmarginHeight , 0 ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
XtAddCallback( fmenu->fimp_setall_pb ,
XmNactivateCallback , cbfunc , (XtPointer) fmenu ) ;
MCW_register_hint( fmenu->fimp_setall_pb , "Set all computing options on" ) ;
fmenu->fimp_unsetall_pb =
XtVaCreateManagedWidget( "dialog" , xmPushButtonWidgetClass , qbut_menu ,
LABEL_ARG( "Unset All" ) ,
XmNmarginHeight , 0 ,
XmNtraversalOn , True ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
XtAddCallback( fmenu->fimp_unsetall_pb ,
XmNactivateCallback , cbfunc , (XtPointer) fmenu ) ;
MCW_register_hint( fmenu->fimp_unsetall_pb , "Set all computing options off" ) ;
/* 01 Feb 2000: add user-contributed options (if any) */
fmenu->fimp_user_bbox = NULL ; /* default = no menu */
if( GLOBAL_library.registered_fim.num > 0 ){
(void) XtVaCreateManagedWidget(
"dialog" , xmSeparatorWidgetClass , qbut_menu ,
XmNseparatorType , XmDOUBLE_LINE , NULL ) ;
(void) XtVaCreateManagedWidget(
"dialog" , xmLabelWidgetClass , qbut_menu ,
LABEL_ARG("--Extra Funcs--") ,
XmNrecomputeSize , False ,
XmNinitialResourcesPersistent , False ,
NULL ) ;
fmenu->fimp_user_bbox = new_MCW_bbox( qbut_menu,
GLOBAL_library.registered_fim.num ,
GLOBAL_library.registered_fim.labels ,
MCW_BB_check , MCW_BB_noframe ,
NULL , NULL ) ;
MCW_reghint_children( fmenu->fimp_user_bbox->wrowcol , "Other correlation functions" ) ;
}
RETURN(fmenu) ;
}
/*-----------------------------------------------------------------------------
Routines to handle point transformations of a timeseries (22 Oct 1996)
-------------------------------------------------------------------------------*/
char * GRA_transform_label( MCW_arrowval * av , XtPointer cd )
{
MCW_function_list * xforms = (MCW_function_list *) cd ;
if( av == NULL || xforms == NULL ||
av->ival <= 0 || av->ival > xforms->num ) return "-none-" ;
return xforms->labels[av->ival - 1] ; /* label for each function */
}
/*-----------------------------------------------------------------------------*/
/*! Will be called from both the 1D and 0D menus. */
void GRA_transform_CB( MCW_arrowval * av , XtPointer cd )
{
MCW_grapher * grapher = (MCW_grapher *) cd ;
ENTRY("GRA_transform_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
/** set the 0D transform function pointer **/
if( av == grapher->transform0D_av && av != NULL ){
if( grapher->status->transforms0D == NULL || av->ival <= 0 ||
av->ival > grapher->status->transforms0D->num ){
grapher->transform0D_func = NULL ; /* no transform */
grapher->transform0D_index = 0 ;
} else {
grapher->transform0D_func = grapher->status->transforms0D->funcs[av->ival-1];
grapher->transform0D_index = av->ival ;
grapher->transform0D_flags = grapher->status->transforms0D->flags[av->ival-1];
/* 21 Jul 2003: call the init function, if present */
if( grapher->status->transforms0D->func_init[av->ival-1] != NULL )
grapher->status->transforms0D->func_init[av->ival-1]() ;
}
}
/** set the 1D transform function pointer **/
if( av == grapher->transform1D_av && av != NULL ){
if( grapher->status->transforms1D == NULL || av->ival <= 0 ||
av->ival > grapher->status->transforms1D->num ){
grapher->transform1D_func = NULL ; /* no transform */
grapher->transform1D_index = 0 ;
} else {
grapher->transform1D_func = grapher->status->transforms1D->funcs[av->ival-1];
grapher->transform1D_index = av->ival ;
grapher->transform1D_flags = grapher->status->transforms1D->flags[av->ival-1];
/* 21 Jul 2003: call the init function, if present */
if( grapher->status->transforms1D->func_init[av->ival-1] != NULL )
grapher->status->transforms1D->func_init[av->ival-1]() ;
}
}
redraw_graph( grapher , 0 ) ;
EXRETURN ;
}
/*----------------------------------------------------------------------------
22 Sep 2000: for textgraph toggle
------------------------------------------------------------------------------*/
void GRA_textgraph_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
MCW_grapher *grapher = (MCW_grapher *) client_data ;
int bbb ;
ENTRY("GRA_textgraph_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
bbb = MCW_val_bbox( grapher->opt_textgraph_bbox ) ;
if( bbb != grapher->textgraph ){
grapher->textgraph = bbb ;
redraw_graph( grapher , 0 ) ;
}
EXRETURN ;
}
/*----------------------------------------------------------------------------
22 Sep 2000: for new baseline toggle
------------------------------------------------------------------------------*/
void GRA_baseline_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
MCW_grapher *grapher = (MCW_grapher *) client_data ;
int bbb ;
ENTRY("GRA_baseline_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
bbb = MCW_val_bbox( grapher->opt_baseline_bbox ) ;
if( bbb != grapher->common_base ){
grapher->common_base = bbb ;
redraw_graph( grapher , 0 ) ;
}
EXRETURN ;
}
/*----------------------------------------------------------------------------
Set the global baseline value
------------------------------------------------------------------------------*/
void GRA_finalize_global_baseline_CB( Widget w,
XtPointer cd , MCW_choose_cbs *cbs )
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
XmString xstr ;
char str[32] ;
ENTRY("GRA_finalize_global_baseline_CB") ;
if( !GRA_VALID(grapher) ) EXRETURN ;
grapher->global_base = cbs->fval ;
if( grapher->common_base == BASELINE_GLOBAL ) redraw_graph(grapher,0) ;
strcpy(str,"Global:") ;
AV_fval_to_char(grapher->global_base,str+7) ;
xstr = XmStringCreateLtoR( str,XmFONTLIST_DEFAULT_TAG ) ;
XtVaSetValues( grapher->opt_baseline_global_label ,
XmNlabelString,xstr ,
NULL ) ;
XmStringFree(xstr) ;
EXRETURN ;
}
/*----------------------------------------------------------------------------*/
/*** user presses Ideal=WinAver toggle [27 Jan 2004] ***/
void GRA_winaver_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
FIM_menu *fm = (FIM_menu *)client_data ;
MCW_grapher *grapher = (MCW_grapher *)fm->parent ;
if( MCW_val_bbox(grapher->fmenu->fim_editref_winaver_bbox) ){
GRA_cbs cbs ;
cbs.reason = graCR_winaver ;
CALL_sendback( grapher , cbs ) ;
redraw_graph( grapher , 0 ) ;
}
}
/*----------------------------------------------------------------------------*/
void GRA_winavertimer_CB( XtPointer cd , XtIntervalId *id )
{
MCW_grapher *grapher = (MCW_grapher *)cd ;
GRA_cbs cbs ;
if( !GRA_REALZ(grapher) || grapher->ave_tsim == NULL ) return ;
cbs.reason = graCR_refequals ;
cbs.userdata = (XtPointer)grapher->ave_tsim ;
grapher->dont_redraw = 1 ;
CALL_sendback( grapher , cbs ) ;
grapher->dont_redraw = 0 ;
return ;
}
/*----------------------------------------------------------------------------*/
/*** set ref to average time series [27 Jan 2004] ***/
void GRA_winaver_setref( MCW_grapher *grapher )
{
GRA_cbs cbs ;
ENTRY("GRA_winaver_setref") ;
if( !GRA_REALZ(grapher) || grapher->ave_tsim == NULL ){
STATUS("nothing to do") ; EXRETURN ;
}
(void)XtAppAddTimeOut( XtWidgetToApplicationContext(grapher->opt_quit_pb) ,
1 , GRA_winavertimer_CB , grapher ) ;
EXRETURN ;
}
/*----------------------------------------------------------------------------
08 Nov 1996: for "double plots" -- just redraw everything
------------------------------------------------------------------------------*/
void GRA_dplot_change_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
MCW_grapher *grapher = (MCW_grapher *) client_data ;
ENTRY("GRA_dplot_change_CB") ;
if( ! GRA_REALZ(grapher) ) EXRETURN ;
redraw_graph( grapher , 0 ) ;
EXRETURN ;
}
#ifdef USE_OPTMENUS
/*---------------------------------------------------------------------------
Fix the optmenus for the grapher; used when the dataset changes
and so the upper limits on the selectors must change too
-----------------------------------------------------------------------------*/
void GRA_fix_optmenus( MCW_grapher *grapher )
{
int igtop ;
ENTRY("GRA_fix_optmenus") ;
if( ! GRA_REALZ(grapher) ) EXRETURN ;
/** matrix selection **/
if( grapher->opt_mat_choose_av->imax != grapher->mat_max )
refit_MCW_optmenu( grapher->opt_mat_choose_av ,
1 , grapher->mat_max , grapher->mat , 0 ,
NULL , NULL ) ;
else
AV_assign_ival( grapher->opt_mat_choose_av , grapher->mat ) ;
/** slice selection **/
if( grapher->opt_slice_choose_av->imax != grapher->status->nz-1 )
refit_MCW_optmenu( grapher->opt_slice_choose_av ,
0, grapher->status->nz - 1, grapher->zpoint, 0,
NULL , NULL ) ;
else
AV_assign_ival( grapher->opt_slice_choose_av , grapher->zpoint ) ;
/** fim ignoration **/
igtop = MIN( grapher->status->num_series-2 , 99 ) ;
igtop = MAX( igtop , 1 ) ;
if( grapher->fmenu->fim_ignore_choose_av->imax != igtop )
refit_MCW_optmenu( grapher->fmenu->fim_ignore_choose_av ,
0 , igtop , grapher->init_ignore, 0,
NULL , NULL ) ;
else
AV_assign_ival( grapher->fmenu->fim_ignore_choose_av , grapher->init_ignore ) ;
/** 27 May 1999: fim polort **/
AV_assign_ival( grapher->fmenu->fim_polort_choose_av , grapher->polort ) ;
EXRETURN ;
}
/*--------------------------------------------------------------------------*/
void GRA_fmenu_av_CB( MCW_arrowval* av , XtPointer cd )
{
FIM_menu *fmenu = (FIM_menu *) cd ;
ENTRY("GRA_fmenu_av_CB") ;
fmenu->cbfunc( av->wrowcol , cd , NULL ) ;
EXRETURN ;
}
#endif /* USE_OPTMENUS */
/*--------------------------------------------------------------------------
Selection of a color submenu item
----------------------------------------------------------------------------*/
void GRA_color_CB( MCW_arrowval *av , XtPointer cd )
{
MCW_grapher *grapher = (MCW_grapher *) cd ;
int ii , jj ;
ENTRY("GRA_color_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ )
if( av == grapher->opt_color_av[ii] ) break ;
if( ii < NUM_COLOR_ITEMS ){
jj = grapher->color_index[ii] ;
grapher->color_index[ii] = av->ival ;
if( jj != grapher->color_index[ii] ) redraw_graph( grapher , 0 ) ;
}
EXRETURN ;
}
/*--------------------------------------------------------------------------*/
void GRA_thick_CB( Widget w , XtPointer cd , XtPointer call_data )
{
MCW_grapher * grapher = (MCW_grapher *) cd ;
int ii , jj ;
ENTRY("GRA_thick_CB") ;
if( ! GRA_VALID(grapher) ) EXRETURN ;
for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ )
if( grapher->opt_thick_bbox[ii] != NULL &&
w == grapher->opt_thick_bbox[ii]->wbut[0] ) break ;
if( ii < NUM_COLOR_ITEMS ){
jj = grapher->thick_index[ii] ;
grapher->thick_index[ii] = MCW_val_bbox( grapher->opt_thick_bbox[ii] ) ;
if( jj != grapher->thick_index[ii] ) redraw_graph( grapher , 0 ) ;
EXRETURN ;
}
/* 09 Jan 1998 */
for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ )
if( grapher->opt_points_bbox[ii] != NULL &&
( w == grapher->opt_points_bbox[ii]->wbut[0] ||
w == grapher->opt_points_bbox[ii]->wbut[1] ) ) break ;
if( ii < NUM_COLOR_ITEMS ){
jj = grapher->points_index[ii] ;
grapher->points_index[ii] = MCW_val_bbox( grapher->opt_points_bbox[ii] ) ;
if( jj != grapher->points_index[ii] ) redraw_graph( grapher , 0 ) ;
EXRETURN ;
}
EXRETURN ; /* should not be reached */
}
/*--------------------------------------------------------------------------
Save the background pixmap to a PNM file
----------------------------------------------------------------------------*/
void GRA_saver_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
{
int ll , ii ;
MCW_grapher * grapher = (MCW_grapher *) cd ;
char * fname , * ppnm ;
ENTRY("GRA_saver_CB") ;
if( ! GRA_REALZ(grapher) ) EXRETURN ;
if( cbs->reason != mcwCR_string ||
cbs->cval == NULL || (ll=strlen(cbs->cval)) == 0 ){
XBell( XtDisplay(wcaller) , 100 ) ; EXRETURN ;
}
fname = (char *) malloc( sizeof(char) * (ll+8) ) ;
strcpy( fname , cbs->cval ) ;
for( ii=0 ; ii < ll ; ii++ )
if( iscntrl(fname[ii]) || isspace(fname[ii]) ) break ;
if( ii < ll || ll < 2 || ll > 240 ){
XBell( XtDisplay(wcaller) , 100 ) ;
free( fname ) ; EXRETURN ;
}
ppnm = strstr( fname , ".ppm" ) ;
if( ppnm == NULL ) ppnm = strstr( fname , ".pnm" ) ;
if( ppnm == NULL ) ppnm = strstr( fname , ".jpg" ) ;
if( ppnm == NULL ) strcat(fname,".ppm") ;
GRA_file_pixmap( grapher , fname ) ;
POPDOWN_string_chooser ;
free(fname) ; EXRETURN ;
}
/*--------------------------------------------------------------------------*/
void GRA_file_pixmap( MCW_grapher *grapher , char *fname )
{
XImage *xim ;
XGCValues gcv ;
MRI_IMAGE *tim ;
int ii ;
ENTRY("GRA_file_pixmap") ;
if( ! GRA_REALZ(grapher) ) EXRETURN ;
if( grapher->fd_pxWind == (Pixmap) 0 ) EXRETURN ;
ii = XGetGCValues( grapher->dc->display ,
grapher->dc->myGC , GCPlaneMask , &gcv ) ;
if( ii == 0 ) EXRETURN ;
xim = XGetImage( grapher->dc->display , grapher->fd_pxWind ,
0 , 0 , grapher->fWIDE , grapher->fHIGH ,
gcv.plane_mask , ZPixmap ) ;
if( xim == NULL ) EXRETURN ;
tim = XImage_to_mri( grapher->dc , xim , 0 ) ;
if( tim == NULL ){ MCW_kill_XImage( xim ) ; EXRETURN ; }
INFO_message("Writing grapher image to '%s'",fname) ;
mri_write_pnm( fname , tim ) ;
mri_free( tim ) ;
MCW_kill_XImage( xim ) ; /* 10 Mar 1999 */
EXRETURN ;
}
/*-----------------------------------------------------------------------------
07 Jan 1999: change location of newly popped up menu
-------------------------------------------------------------------------------*/
void GRA_mapmenu_CB( Widget w , XtPointer client_data , XtPointer call_data )
{
int ww,hh,xx,yy ;
int pw,ph,px,py ;
ENTRY("GRA_mapmenu_CB") ;
if( AFNI_yesenv("AFNI_DONT_MOVE_MENUS") ) EXRETURN ; /* 08 Aug 2001 */
MCW_widget_geom( w , &ww,&hh , &xx,&yy ) ;
MCW_widget_geom( XtParent(XtParent(w)) , &pw,&ph , &px,&py ) ;
#if 1
if(PRINT_TRACING){
char str[256] ;
sprintf(str,"menu: width=%d height=%d x=%d y=%d",ww,hh,xx,yy); STATUS(str);
sprintf(str,"parent: width=%d height=%d x=%d y=%d",pw,ph,px,py); STATUS(str); }
#endif
pw = pw >> 3 ;
if( ! ( xx > px+7*pw || xx+ww < px+pw ) ){
xx = px - ww ; if( xx < 0 ) xx = 0 ;
#if 1
if(PRINT_TRACING){
char str[256]; sprintf(str,"moving menu to x=%d",xx); STATUS(str); }
#endif
XtVaSetValues( w , XmNx , xx , NULL ) ;
}
RWC_xineramize( XtDisplay(w) , xx,yy,ww,hh , &xx,&yy ) ; /* 27 Sep 2000 */
XtVaSetValues( w , XmNx,xx , XmNy,yy , NULL ) ;
EXRETURN ;
}
/*----------------------------------------------------------------------------*/
/*! Do something every so often. */
void GRA_timer_CB( XtPointer cd , XtIntervalId *id ) /* 03 Dec 2003 */
{
MCW_grapher *grapher = (MCW_grapher *)cd ;
int redo = 0 ;
ENTRY("GRA_timer_CB") ;
if( !GRA_REALZ(grapher) || grapher->timer_id == 0 ) EXRETURN ;
switch( grapher->timer_func ){
case GRA_TIMERFUNC_INDEX:{
int nn = grapher->time_index , nt=grapher->status->num_series ;
if( nt > 1 && grapher->timer_param != 0 ){
nn = (nn+grapher->timer_param+nt) % nt ;
redo = 1 ;
if( grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_setindex ;
cbs.key = nn ;
cbs.event = NULL ;
#if 0
grapher->status->send_CB( grapher, grapher->getaux, &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
} else {
(void) drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)nn) ;
}
}
}
break ;
case GRA_TIMERFUNC_BOUNCE:{
int nn = grapher->time_index , nt=grapher->status->num_series ;
if( nt > 1 && grapher->timer_param != 0 ){
nn = nn + grapher->timer_param ;
if( nn < 0 ){
nn = -nn; grapher->timer_param = -grapher->timer_param;
} else if( nn >= nt ){
nn = 2*(nt-1)-nn; grapher->timer_param = -grapher->timer_param;
}
redo = 1 ;
if( grapher->status->send_CB != NULL ){
GRA_cbs cbs ;
cbs.reason = graCR_setindex ;
cbs.key = nn ;
cbs.event = NULL ;
#if 0
grapher->status->send_CB( grapher, grapher->getaux, &cbs ) ;
#else
CALL_sendback( grapher , cbs ) ;
#endif
} else {
(void) drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)nn) ;
}
}
}
break ;
}
if( redo ) grapher->timer_id = XtAppAddTimeOut(
XtWidgetToApplicationContext(grapher->opt_quit_pb) ,
grapher->timer_delay , GRA_timer_CB , grapher ) ;
else grapher->timer_id = 0 ;
EXRETURN ;
}
/*--------------------------------------------------------------------------*/
void GRA_timer_stop( MCW_grapher *grapher )
{
if( grapher->timer_id > 0 ){
XtRemoveTimeOut(grapher->timer_id); grapher->timer_id = 0;
}
}
syntax highlighted by Code2HTML, v. 0.9.1