Sorry, I forgot to attatch the code...
Tobias

#include <stdlib.h>
#include <stdio.h>

#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <X11/StringDefs.h>
#include <Xm/MainW.h>
#include <Xm/RowColumn.h>
#include <Xm/Separator.h>
#include <Xm/PushB.h>
#include <Xm/CascadeB.h>
#include <Xm/Label.h>

#include "Xbae/Matrix.h"

#define NUMBER_PRECISION 4
#define NUMBER_FORMAT "%.*g"
#define NUMBER_SIZE (NUMBER_PRECISION+6)

enum parameter_state {CHANGED=1,FIXED=2,ZEROED=4,HIDDEN=8};

struct parameter{
        char *name;
        double val;    /* The parameters value is stored here even when zeroed */
        double err;    /* The parameters error is stroed here even when fixed */
        double min;    /* lower bound of the parameter */
        double max;    /* upper bound of the parameter. if lower bound==upper bound, 
the parameter is unbounded */
        enum parameter_state state;     /* a bit pattern with a meaning of 
parameter_state */
};

struct parameter parameters[]={
        {"mN"  ,.938,0,0,0,0},
        {"mPi" ,.140,0,0,0,2},
        {"FPi" ,   1,0,0,0,4},
        {"mRho",.770,0,0,0,3},
        {"FRho", 6.2,0,0,0,0}
};

int n_parameters;

Widget create_paramatrix(Widget parent);
static void init_cells(Widget Matrix);

/************************************************************************************
* Main
*/
int main(int argc,char **argv){

        Widget toplevel,main,pane,menu,paramatrix;

        toplevel=XtInitialize(argv[0],"Short",NULL,0,&argc,argv);
        
        /* This crashes
        */
        main=XtCreateManagedWidget("Main",xmMainWindowWidgetClass,toplevel,NULL,0);
        paramatrix=create_paramatrix(main);

        /* This seems to work
        paramatrix=create_paramatrix(toplevel);
        */

        {
                int n_rows;

                n_parameters=XtNumber(parameters);

                n_rows=XbaeMatrixNumRows(paramatrix);   
                
XbaeMatrixAddRows(paramatrix,n_rows,NULL,NULL,NULL,1+n_parameters-n_rows);
                init_cells(paramatrix);
                XtManageChild(paramatrix);
        }

        XtRealizeWidget(toplevel);

        XtMainLoop();

        return(EXIT_SUCCESS);
}

/************************************************************************************
* To create menus. 
* From The X window system, programming and applications with Xt. Douglas A Young
*/

struct xs_menu_struct{
        char *name;
        XtCallbackProc func;
        XtPointer data;
        struct xs_menu_struct *sub_menu;
        int n_sub_items;
        char *sub_menu_title;
};

void  xs_create_menu_buttons(char *title,Widget menu,struct xs_menu_struct 
*menulist,int nitems){
        Arg wargs[1];
        int i;
        WidgetList buttons;
        int separators=0;
        
        buttons=(WidgetList) XtMalloc(nitems * sizeof(Widget));
        
        if(title){
                (void) XtCreateManagedWidget(title,xmLabelWidgetClass,menu,NULL,0);
                (void) 
XtCreateManagedWidget("separator",xmSeparatorWidgetClass,menu,NULL,0);
        }
        
        for(i=0;i<nitems;i++){
                if(menulist[i].name==NULL){
                        /* The item is a separator */
                        (void) 
XtCreateManagedWidget("separator",xmSeparatorWidgetClass,menu,NULL,0);
                        separators++;
                }else if(menulist[i].func){
                        /* The item is a button */
                        
buttons[i-separators]=XtCreateWidget(menulist[i].name,xmPushButtonWidgetClass,menu,NULL,0);
                        
XtAddCallback(buttons[i-separators],XmNactivateCallback,menulist[i].func,menulist[i].data);
                }else if(menulist[i].sub_menu==NULL){
                        /* The item is a label */
                        
buttons[i-separators]=XtCreateWidget(menulist[i].name,xmLabelWidgetClass,menu,NULL,0);
                }else{
                        /* The item is a cascade menu */
                        Widget sub_menu;
                        
sub_menu=XmCreatePulldownMenu(menu,menulist[i].sub_menu_title,NULL,0);
                        XtSetArg(wargs[0],XmNsubMenuId,sub_menu);
                        
buttons[i-separators]=XtCreateWidget(menulist[i].name,xmCascadeButtonWidgetClass,menu,wargs,1);
                        
xs_create_menu_buttons(menulist[i].sub_menu_title,sub_menu,menulist[i].sub_menu,menulist[i].n_sub_items);
                }
        }
        XtManageChildren(buttons,nitems-separators);
}
/************************************************************************************
* Create the Xbea matrix widget that will hold the parameters
*/

static void show_para(Widget Menu,XtPointer client_data,XtPointer call_data);
static void hide_para(Widget Menu,XtPointer client_data,XtPointer call_data);
static void click(Widget Matrix,XtPointer Menu,XEvent *event,char *dummy);

Widget create_paramatrix(Widget parent){

        Widget Matrix,paramenu;

        /* create the widget */

        {
                short widths[]={6,6,6,6,6};

                Arg wargs[10];
                int m=0;

                XtSetArg(wargs[m],XmNrows,2);m++;
                XtSetArg(wargs[m],XmNcolumns,5);m++;
                XtSetArg(wargs[m],XmNcolumnWidths,widths);m++;
                XtSetArg(wargs[m],XmNfixedRows,1);m++;
                XtSetArg(wargs[m],XmNfixedColumns,1);m++;
                XtSetArg(wargs[m],XmNgridType,XmGRID_CELL_SHADOW);m++;

                /*
                Matrix=XbaeCreateMatrix(parent,"paramatrix",wargs,m);
                */
                
Matrix=XtCreateWidget("paramatrix",xbaeMatrixWidgetClass,parent,wargs,m);
                
        }
        
        /* create the menu */

        {
                struct xs_menu_struct paramenuData[]={
                        {"Fix",NULL},
                        {"Release",NULL},
                        {NULL,NULL},
                        {"Zero",NULL},
                        {"Restore",NULL},
                        {NULL,NULL},
                        {"Hide",hide_para},
                        {"Show all",show_para}
                };
                
                paramenuData[0].data=(caddr_t) Matrix;
                paramenuData[1].data=(caddr_t) Matrix;
                paramenuData[3].data=(caddr_t) Matrix;
                paramenuData[4].data=(caddr_t) Matrix;
                paramenuData[6].data=(caddr_t) Matrix;
                paramenuData[7].data=(caddr_t) Matrix;

                paramenu=XmCreatePopupMenu(Matrix,"paramenu",NULL,0);
                
xs_create_menu_buttons("Parameter",paramenu,paramenuData,XtNumber(paramenuData));
        }

        /* add callbacks and event handlers */

        XtAddEventHandler(Matrix,ButtonPressMask,False,(XtEventHandler) 
click,paramenu);

        return Matrix;
}

static char *zeroed="Zeroed";
static char *fixed="Fixed";
static char *empty="";

static void init_cells(Widget Matrix){

        Arg wargs[10];
        int m=0;
        
        int p,n_parameters_shown=0;
        
        char* labels[]={"","Value","Error","Min","Max"};

        char *all_strings,**all_cells,***all_rows;              
        char *current_string,**current_cell,***current_row;

        all_strings=(char *) XtMalloc(4*n_parameters*NUMBER_SIZE*(sizeof 
*all_strings));
        all_cells=(char **) XtMalloc(4*(1+n_parameters)*(sizeof *all_cells));
        all_rows=(char ***) XtMalloc((1+n_parameters)*(sizeof *all_rows));
        
        current_string=all_strings;
        current_cell=all_cells;
        current_row=all_rows;

        *(current_row++)=current_cell;
        *(current_cell++)=labels[0];
        *(current_cell++)=labels[1];
        *(current_cell++)=labels[2];
        *(current_cell++)=labels[3];
        *(current_cell++)=labels[4];

        for(p=0;p<n_parameters;p++){
                if(!((parameters+p)->state & HIDDEN)){
                        n_parameters_shown++;
                        *(current_row++)=current_cell;
                        *(current_cell++)=(parameters+p)->name;
                        if((parameters+p)->state & ZEROED){
                                *(current_cell++)=zeroed;
                                *(current_cell++)=empty;
                                *(current_cell++)=empty;
                                *(current_cell++)=empty;
                        }else{
                                *(current_cell++)=current_string ; 
current_string+=sprintf(current_string,NUMBER_FORMAT,NUMBER_PRECISION,(parameters+p)->val)+1;
                                if((parameters+p)->state & FIXED){
                                        *(current_cell++)=fixed;
                                        *(current_cell++)=empty;
                                        *(current_cell++)=empty;
                                }else{
                                        *(current_cell++)=current_string ; 
current_string+=sprintf(current_string,NUMBER_FORMAT,NUMBER_PRECISION,(parameters+p)->err)+1;
                                        *(current_cell++)=current_string ; 
current_string+=sprintf(current_string,NUMBER_FORMAT,NUMBER_PRECISION,(parameters+p)->min)+1;
                                        *(current_cell++)=current_string ; 
current_string+=sprintf(current_string,NUMBER_FORMAT,NUMBER_PRECISION,(parameters+p)->max)+1;
                                }
                        }
                }
        }
        
        XtSetArg(wargs[m],XmNcells,all_rows);m++;
        XtSetValues(Matrix,wargs,m);

        for(p=0;p<n_parameters_shown;p++){
                XbaeMatrixSetRowUserData(Matrix,p+1,parameters+p);
        }
        
        free(all_strings);
        free(all_cells);
        free(all_rows);
}

/****************************************************
* Pop up menu callback functions
*/
static void hide_para(Widget Menu,XtPointer client_data,XtPointer call_data){
        int n_rows,row;
        struct parameter *row_para;
        Widget Matrix=client_data;

        n_rows=XbaeMatrixNumRows(Matrix);
        for(row=1;row<n_rows;row++){
                row_para=XbaeMatrixGetRowUserData(Matrix,row);
                if(XbaeMatrixIsRowSelected(Matrix,row)){
                        XbaeMatrixDeleteRows(Matrix,row,1);
                        row_para->state^=HIDDEN;
                        row--;
                        n_rows--;
                }
        }
}
static void show_para(Widget Menu,XtPointer client_data,XtPointer call_data){
        int n_rows,p;
        struct parameter *row_para;
        Widget Matrix=client_data;
        
        n_rows=XbaeMatrixNumRows(Matrix);
        
        for(p=0;p<n_parameters;p++){
                (parameters+p)->state|=HIDDEN;
                (parameters+p)->state^=HIDDEN;
        }
        
        if(1+n_parameters-n_rows>0){
                XbaeMatrixAddRows(Matrix,n_rows,NULL,NULL,NULL,1+n_parameters-n_rows);
                init_cells(Matrix);
        }
}
/************************************************************************************
* The click event handler selects parameters and pops up the menu
*/
static void click(Widget Matrix,XtPointer Menu,XEvent *event,char *dummy){

        Arg wargs[10];
        int popup_button,row,column;

        XtSetArg(wargs[0],XmNwhichButton,&popup_button);
        XtGetValues(Menu,wargs,1);
        
        XbaeMatrixCommitEdit(Matrix,True);

        if(event->xbutton.button == popup_button){
                /* It's the popup Menu button */
                if(XbaeMatrixGetNumSelected(Matrix)==0){
                        /* There are no selected parameters */
                        if(XbaeMatrixGetEventRowColumn(Matrix,event,&row,&column)){
                                if(row>0){
                                        XbaeMatrixSelectRow(Matrix,row);
                                }
                        }
                }
                XmMenuPosition(Menu,(XButtonPressedEvent *) event);
                XtManageChild(Menu);
        }else if(XbaeMatrixGetEventRowColumn(Matrix,event,&row,&column)){
                /* It's not the popup Menu button */
                if(row>0 && column==0){
                        if(event->xbutton.state & (4 | 1)){
                                /* shift and/or control are pressed */
                                if(XbaeMatrixIsRowSelected(Matrix,row)){
                                        XbaeMatrixDeselectRow(Matrix,row);
                                }else{
                                        XbaeMatrixSelectRow(Matrix,row);
                                }
                        }else{
                                XbaeMatrixDeselectAll(Matrix);
                                XbaeMatrixSelectRow(Matrix,row);
                        }
                }
        }
}

Reply via email to