#include #include #include #include #include #include #include "xpplim.h" #define MAX_N_SBOX 20 #define MAX_LEN_SBOX 25 #define FORGET_ALL 0 #define DONE_ALL 2 #define FORGET_THIS 3 #define DONE_THIS 1 #define EV_MASK (ButtonPressMask |\ KeyPressMask |\ ExposureMask |\ StructureNotifyMask) #define BUT_MASK (ButtonPressMask |\ KeyPressMask |\ ExposureMask |\ StructureNotifyMask |\ EnterWindowMask |\ LeaveWindowMask) extern Display *display; extern int DisplayWidth,DisplayHeight; extern int screen; extern Atom deleteWindowAtom; extern Window main_win,info_pop,draw_win; extern int DCURY,DCURX,CURY_OFF,DCURXs,DCURYs,CURY_OFFs,xor_flag; extern GC gc,small_gc; extern unsigned int MyBackColor,MyForeColor; extern int TipsFlag; char *get_next(),*get_first(); Window make_window(); /* This is a string box widget which handles a list of editable strings */ typedef struct { Window base,ok,cancel; Window win[MAX_N_SBOX]; char name[MAX_N_SBOX][MAX_LEN_SBOX], value[MAX_N_SBOX][MAX_LEN_SBOX]; int n,hot; int hgt,wid; int hh[MAX_N_SBOX]; } STRING_BOX; typedef struct { char **list; int n; } SCRBOX_LIST; extern int NUPAR,NEQ,NODE,NMarkov; extern char upar_names[MAXPAR][11],uvar_names[MAXODE][12]; extern char *color_names[]; SCRBOX_LIST scrbox_list[10]; /* This is a new improved pop_up widget */ typedef struct { Window base,tit; Window *w; char *title; char **entries; char **hints; int n,max; char *key; int hot; } POP_UP; typedef struct { Window base,slide,close,text; int i0; int exist,len,nlines; char **list; } TEXTWIN; typedef struct { Window base,slide; Window *w; int nw,nent,i0; int len,exist; char **list; } SCROLLBOX; TEXTWIN mytext; #define SB_PLOTTABLE 0 #define SB_VARIABLE 1 #define SB_PARAMETER 2 #define SB_PARVAR 3 #define SB_COLOR 4 #define SB_MARKER 5 #define SB_METHOD 6 set_window_title(Window win,char *string) { XTextProperty wname,iname; XStringListToTextProperty(&string,1,&wname); XStringListToTextProperty(&string,1,&iname); XSetWMProperties(display,win,&wname,&iname,NULL,0,NULL,NULL,NULL); } /* these are the standard lists that are possible */ make_scrbox_lists() { int i,n; static char *method[]={"Discrete","Euler","Mod. Euler", "Runge-Kutta","Adams","Gear","Volterra","BackEul","QualRK", "Stiff","CVode","DoPri5","DoPri8(3)","Rosenbrock","Symplectic"}; /* plottable list */ scrbox_list[0].n=NEQ+1; scrbox_list[0].list=(char **)malloc((NEQ+1)*sizeof(char *)); scrbox_list[0].list[0]=(char *)malloc(5); strcpy(scrbox_list[0].list[0],"T"); for(i=0;iexist==1){ sb->exist=0; XDestroySubwindows(display,sb->base); XDestroyWindow(display,sb->base); } } create_scroll_box(Window root,int x0,int y0,int nent, int nw,char **list,SCROLLBOX *sb) { int slen=0; int i,hgt,wid; int ww,len; int hw=DCURYs+4; for(i=0;ibase=make_window(root,x0,y0,wid,hgt,2); sb->w=(Window *)malloc(nw*sizeof(Window)); for(i=0;iw[i]=make_window(sb->base,1,hw/2+i*hw,ww,DCURYs,0); sb->i0=0; sb->nw=nw; sb->nent=nent; sb->list=list; if(sb->nwnent) sb->slide=make_window(sb->base,ww+DCURXs/2+2,2,ww+DCURXs/2+6,2+len,1); sb->len=len-4; sb->exist=1; } expose_scroll_box(Window w,SCROLLBOX sb) { int i; int flag=-1; for(i=0;inw>=sb->nent)return 0; if(w==sb->slide){ len=sb->len; if(x<2)x=2; if(x>(len+2))x=len+2; pos=((x-2)*(sb->nent-sb->nw))/len; if(pos<0)pos=0; if(pos>(sb->nent-sb->nw))pos=sb->nent-sb->nw; sb->i0=pos; redraw_scroll_box(*sb); } } select_scroll_item(Window w,SCROLLBOX sb) { int i; int item=-1; for(i=0;ihot; int id=sb->hh[ihot]; int i,xx; int maxhgt=sb->hgt; int maxw; if(id<0)return; /* shouldnt happen */ maxw=maxhgt/hw-1; if(maxw>scrbox_list[id].n)maxw=scrbox_list[id].n; xx=get_x_coord_win(sb->win[ihot]); create_scroll_box(sb->base,xx,3, scrbox_list[id].n,maxw,scrbox_list[id].list, scrb); } do_string_box(n,row,col,title,names,values,maxchar) int n,row,col,maxchar; char **names,values[][MAX_LEN_SBOX],*title; { STRING_BOX sb; int i,status; int colm,pos; SCROLLBOX scrb; scrb.exist=0; for(i=0;i0){ XDrawString(display,w,gc,l*DCURX,CURY_OFF,value,m); } /* if(flag) showchar('_',DCURX*(l+m),0,w); */ if(flag) put_cursor_at(w,DCURX*l,pos); } reset_hot(inew,sb) int inew; STRING_BOX *sb; { int i=sb->hot; sb->hot=inew; XClearWindow(display, sb->win[inew]); do_hilite_text(sb->name[inew],sb->value[inew],1,sb->win[inew], strlen(sb->value[inew]),0); XClearWindow(display, sb->win[i]); do_hilite_text(sb->name[i],sb->value[i],0,sb->win[i], strlen(sb->value[i]),0); } new_editable(sb,inew,pos,col,done,w) int inew; STRING_BOX *sb; int *pos,*col,*done; Window *w; { reset_hot(inew,sb); *pos=strlen(sb->value[inew]); *col=(*pos+strlen(sb->name[inew]))*DCURX; *done=0; *w=sb->win[inew]; } set_sbox_item(STRING_BOX *sb,int item) { int i=sb->hot; int id=sb->hh[i]; if(id<0)return; strcpy(sb->value[i],scrbox_list[id].list[item]); /* printf("setting %d to be %d in list %d \n", i,item, sb->hh[i]); */ } s_box_event_loop(sb,pos,col,scrb) STRING_BOX *sb; SCROLLBOX *scrb; int *col,*pos; { XEvent ev; int status=-1,inew; int nn=sb->n; int done=0,i,j; int item,xx; char ch; int ihot=sb->hot; Window wt; Window w=sb->win[ihot]; /* active window */ char *s; s=sb->value[ihot]; XNextEvent(display,&ev); switch(ev.type){ case ConfigureNotify: case Expose: case MapNotify: do_expose(ev); /* menus and graphs etc */ expose_sbox(*sb,ev.xany.window,*pos,*col); if(scrb->exist)expose_scroll_box(ev.xany.window,*scrb); break; case MotionNotify: if(scrb->exist) scroll_box_motion(ev,scrb); break; case ButtonPress: if(scrb->exist){ item=select_scroll_item(ev.xbutton.window,*scrb); if(item>=0){ set_sbox_item(sb,item); new_editable(sb,sb->hot,pos,col,&done,&w); destroy_scroll_box(scrb); } } if(ev.xbutton.window==sb->ok){ destroy_scroll_box(scrb); status=DONE_ALL; break; } if(ev.xbutton.window==sb->cancel){ status=FORGET_ALL; break; destroy_scroll_box(scrb); } for(i=0;iwin[i]){ XSetInputFocus(display,sb->win[i], RevertToParent,CurrentTime); if(i!=sb->hot){ destroy_scroll_box(scrb); new_editable(sb,i,pos,col,&done,&w); } else{ /* i==sb->hot */ if(ev.xbutton.xhot; if(sb->hh[j]>=0) { scroll_popup(sb,scrb); } } } break; } } break; case EnterNotify: wt=ev.xcrossing.window; if(scrb->exist)crossing_scroll_box(wt,1,*scrb); if(wt==sb->ok||wt==sb->cancel) XSetWindowBorderWidth(display,wt,2); break; case LeaveNotify: wt=ev.xcrossing.window; if(scrb->exist)crossing_scroll_box(wt,0,*scrb); if(wt==sb->ok||wt==sb->cancel) XSetWindowBorderWidth(display,wt,1); break; case KeyPress: ch=get_key_press(&ev); edit_window(w,pos,s,col,&done,ch); if(done!=0){ if(done==DONE_ALL){status=DONE_ALL;break;} inew=(sb->hot+1)%nn; new_editable(sb,inew,pos,col,&done,&w); } break; } return(status); } make_sbox_windows(sb,row,col,title,maxchar) int row,col,maxchar; char *title; STRING_BOX *sb; { int width,height; int i; int xpos,ypos,n=sb->n; int xstart,ystart; XTextProperty winname; XSizeHints size_hints; Window base; width=(maxchar+4)*col*DCURX; height=(row+4)*(DCURY+16); base=make_window(DefaultRootWindow(display),0,0,width,height,4); XStringListToTextProperty(&title,1,&winname); size_hints.flags=PPosition|PSize|PMinSize|PMaxSize; size_hints.x=0; size_hints.y=0; size_hints.width=width; size_hints.height=height; size_hints.min_width=width; size_hints.min_height=height; size_hints.max_width=width; size_hints.max_height=height; XSetWMProperties(display,base,&winname,NULL,NULL,0,&size_hints,NULL,NULL); sb->base=base; sb->hgt=height; sb->wid=width; ystart=DCURY; xstart=DCURX; for(i=0;iwin[i]=make_window(base,xpos,ypos,maxchar*DCURX,DCURY,1); } ypos=height-2*DCURY; xpos=(width-12*DCURX)/2; (sb->ok)=make_window(base,xpos,ypos,2*DCURX,DCURY,1); (sb->cancel)=make_window(base,xpos+4*DCURX,ypos,6*DCURX,DCURY,1); XRaiseWindow(display,base); } Window make_fancy_window(root,x,y,width,height,bw,fc,bc) Window root; int x,y,width,height,bw; { Window win; win=XCreateSimpleWindow(display,root,x,y,width,height, bw,fc,bc); XSelectInput(display,win,ExposureMask|KeyPressMask|ButtonPressMask| StructureNotifyMask|ButtonReleaseMask|ButtonMotionMask| LeaveWindowMask|EnterWindowMask); XMapWindow(display,win); return(win); } Window make_unmapped_window(root,x,y,width,height,bw) Window root; int x,y,width,height,bw; { Window win; win=XCreateSimpleWindow(display,root,x,y,width,height, bw,MyForeColor,MyBackColor); XSelectInput(display,win,ExposureMask|KeyPressMask|ButtonPressMask| StructureNotifyMask|ButtonReleaseMask|ButtonMotionMask| LeaveWindowMask|EnterWindowMask); return(win); } Window make_window(root,x,y,width,height,bw) Window root; int x,y,width,height,bw; { Window win; win=make_unmapped_window(root,x,y,width,height,bw); if(root==RootWindow(display,screen)) XSetWMProtocols(display, win, &deleteWindowAtom, 1); XMapWindow(display,win); return(win); } expose_resp_box(button,message,wb,wm,w) Window w,wb,wm; char *button,*message; { if(w==wb)Ftext(0,0,button,wb); if(w==wm)Ftext(0,0,message,wm); } respond_box(button,message) char *button,*message; { int l1=strlen(message); int l2=strlen(button); int width; int height; int done=0; XEvent ev; Window wmain,wb,wm; width=l1; if(l1-1&&com=0)value=key[def]; XDestroyWindow(display,w); *root=w; return(value); } draw_pop_list(w,title,list,n,max,def) Window w; char **list,*title; int n,max; int def; { int i,xi,yi; xi=2*DCURX; yi=4; set_fore(); bar(0,0,max,(DCURY+7),w); set_back(); Ftext(xi,yi,title,w); set_fore(); yi+=(DCURY+8); for(i=0;i