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);
}
}
}
}