source: tags/initial/GDE/LOOPTOOL/Window.c

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 14.7 KB
Line 
1#include <stdio.h>
2#include <errno.h>
3#include <xview/xview.h>
4#include <xview/canvas.h>
5#include <xview/cursor.h>
6#include <xview/scrollbar.h>
7#include <xview/panel.h>
8#include <string.h>
9#include <malloc.h>
10#include <math.h>
11#include "loop.h"
12#include "globals.h"
13#include <xview/cms.h>
14
15
16Xv_singlecolor Default_Colors[16]= {
17        {0,128,0},
18        {255,192,0},
19        {255,0,255},
20        {225,0,0},
21        {0,192,192},
22        {0,192,0},
23        {0,0,255},
24        {128,0,255},
25        {0,0,0},
26        {36,36,36},
27        {72,72,72},
28        {109,109,109},
29        {145,145,145},
30        {182,182,182},
31        {218,218,218},
32        {255,255,255}
33};
34
35int COLOR;
36
37/*Window.c
38*       Written by Steven Smith, Copyright 1989, U of Illinois
39*       Microbiology/CGPA.
40*/
41
42/*
43*       WindowSetup: Set up windows, menus, dialogs etc.  No
44*       parameters passed in, only globals passed out.  Current
45*       palette set to 8 simple colors.
46*/
47
48WindowSetup()
49{
50        extern EditProc(),FileProc(),StyleProc(),EventHandler(),SetDepth();
51        extern SetFile(),ShoCon(),xv_pf_open();
52        extern void ReDraw();
53        Cms colmap;
54
55        Panel menubar,fdlg,pdlg;
56        int i,j;
57
58        unsigned char red[8],green[8],blue[8];
59
60/*
61*       Open font for screen operations.
62*/
63        page=xv_create(NULL,FRAME,     
64                FRAME_LABEL,    "LoopTool",
65                WIN_INHERIT_COLORS,TRUE,
66                0);
67
68/*
69*       Dialogs...
70*/
71        file_dialog=xv_create(page,FRAME,0);
72        print_dialog=xv_create(page,FRAME,0);
73
74        fdlg=xv_create(file_dialog,PANEL,
75                XV_HEIGHT,150,
76                XV_WIDTH, 200,
77                PANEL_LAYOUT,PANEL_HORIZONTAL,
78                0);
79
80
81        xv_create(fdlg,PANEL_BUTTON,
82                PANEL_LABEL_STRING,"Ok",
83                PANEL_NOTIFY_PROC,SetFile,
84                0);
85
86        xv_create(fdlg,PANEL_TEXT,
87                PANEL_LABEL_STRING,"Data File:",
88                PANEL_VALUE,"",
89                PANEL_NOTIFY_PROC,SetFile, 
90                0);
91
92
93/*
94*       Set menu items.
95*/
96        File=xv_create(NULL,MENU,
97                MENU_NOTIFY_PROC,FileProc,
98                MENU_STRINGS,"Save","Print","Quit",0,0);
99
100        Edit=xv_create(NULL,MENU,
101                MENU_NOTIFY_PROC,EditProc,
102                MENU_STRINGS,"Clear constraint",
103                "Show Constraints", "Distance Constraint",
104                "Position Constraint",
105                "Invert Helix","Stack Helix" ,0,0);
106
107/*
108        Style=xv_create(NULL,MENU,
109                MENU_NOTIFY_PROC,StyleProc,
110                MENU_STRINGS,"Font","Size","Grey level","Label",0,0);
111*/
112
113        menubar=xv_create(page,PANEL,
114                XV_HEIGHT,50,
115                0);
116
117/*
118*       Menu items.
119*/
120        xv_create(menubar,PANEL_BUTTON,
121                PANEL_LABEL_STRING,"File",
122                PANEL_ITEM_MENU,File,
123                0);
124
125        xv_create(menubar,PANEL_BUTTON,
126                PANEL_LABEL_STRING,"Edit",
127                PANEL_ITEM_MENU,Edit,
128                0);
129
130/*
131        xv_create(menubar,PANEL_BUTTON,
132                PANEL_LABEL_STRING,"Style",
133                PANEL_ITEM_MENU,Style,
134                0);
135*/
136
137        xv_create(menubar,PANEL_SLIDER,
138                PANEL_LABEL_STRING,"View Depth:",
139                PANEL_VALUE,100,
140                PANEL_MIN_VALUE,0,
141                PANEL_MAX_VALUE,100,
142                PANEL_SLIDER_WIDTH,60,
143                PANEL_SHOW_RANGE,TRUE,
144                PANEL_SHOW_VALUE,TRUE,
145                PANEL_NOTIFY_PROC,SetDepth,
146                0);
147
148        window_fit_height(menubar);
149
150/*
151*       Pagecan is the canvas used for the primary display.
152*/     
153        pagecan=xv_create(page,CANVAS,
154                WIN_INHERIT_COLORS,TRUE,
155                WIN_DYNAMIC_VISUAL,TRUE,
156                WIN_BELOW,menubar,
157/*
158                CANVAS_WIDTH,WINDOW_SIZE,
159                CANVAS_HEIGHT,WINDOW_SIZE,
160*/
161                OPENWIN_AUTO_CLEAR,TRUE,
162                CANVAS_AUTO_SHRINK,TRUE,
163                CANVAS_AUTO_EXPAND,TRUE,
164                CANVAS_REPAINT_PROC,ReDraw,
165                0);
166
167/*
168        xv_create(pagecan,SCROLLBAR,
169                SCROLLBAR_DIRECTION,SCROLLBAR_VERTICAL,
170                SCROLLBAR_SPLITTABLE,TRUE,
171                SCROLLBAR_OVERSCROLL,0,
172                0);
173
174        xv_create(pagecan,SCROLLBAR,
175                SCROLLBAR_DIRECTION,SCROLLBAR_HORIZONTAL,
176                SCROLLBAR_SPLITTABLE,TRUE,
177                SCROLLBAR_OVERSCROLL,0,
178                0);
179*/
180
181        xv_set(canvas_paint_window(pagecan),
182                WIN_EVENT_PROC,EventHandler,
183                WIN_CONSUME_EVENTS,
184                        WIN_MOUSE_BUTTONS,
185                        WIN_RESIZE,
186                        LOC_DRAG,
187                        LOC_WINENTER,
188                        WIN_ASCII_EVENTS,
189                        WIN_META_EVENTS,
190                        0,
191                0);
192
193/*
194* Set palette
195*/
196
197        if( xv_get(page,WIN_DEPTH)>4)
198        {
199                colmap = (Cms)xv_find(page,CMS,
200                        CMS_NAME,"GDE Palette",
201                        XV_AUTO_CREATE,FALSE,
202                        0);
203                         
204
205               if(colmap == NULL)
206                        colmap = (Cms)xv_create(NULL,CMS,
207                        CMS_TYPE,XV_DYNAMIC_CMS,
208                        CMS_SIZE,16,
209                        CMS_COLORS,Default_Colors,
210                        0);
211
212               xv_set(canvas_paint_window(pagecan),
213                WIN_CMS_NAME,"GDE Palette",
214                WIN_CMS, colmap,
215                WIN_FOREGROUND_COLOR,8, 
216                WIN_BACKGROUND_COLOR,15,
217                WIN_INHERIT_COLORS,FALSE,
218                0);
219                COLOR = TRUE;
220        }
221        else
222                COLOR = FALSE;
223
224        window_fit_width(page);
225
226        fdlg=xv_create(file_dialog,PANEL, 
227                XV_WIDTH,300,
228                XV_HEIGHT,200,
229                PANEL_LAYOUT,PANEL_HORIZONTAL,
230                0);
231
232        pdlg=xv_create(print_dialog,PANEL, 
233                XV_WIDTH,300, 
234                XV_HEIGHT,200,
235                PANEL_LAYOUT,PANEL_HORIZONTAL, 
236                0);
237
238        window_main_loop(page);
239        return;
240}
241
242
243
244/*
245*       ReDraw:  Redrawing procedure.  Two primary states are handled.
246*       If modified is false, then the bases are laid using their current
247*       coordinates.  If modified is true, then the structure is recalculated.
248*/
249
250void ReDraw(canvas,pw,repaint_area)
251        Canvas canvas;
252        Pixwin *pw;
253        Rectlist *repaint_area;
254{
255        extern DrawPair();
256        Rect rect;
257        int nucpos,i,size,ccw,imax;
258        LoopStak lstack[10000];
259        extern PromptSeq(),BuildLoopStk(),Translate();
260        extern ReadSeqSet(),gprint(),Arc();
261        errno = 0;
262
263/*
264*       if no file was defined...
265*/
266        if(infile==NULL)
267        {
268                PromptFile();
269                ReadSeqSet(&dataset);
270        }
271/*
272*       if no sequence was picked...
273*/
274
275        if (seqnum== -1)
276        {
277                PromptSeq(infile,&dataset,&seqnum);
278                Translate(&dataset,seqnum,&baselist,&seqlen);
279                if(tempfile)
280                        ImposeTemp();
281        }
282/*
283*       if the constraints have been modified, then recalculate.
284*/
285        if(modified)
286        {
287/*
288*       set all base positions to an unknown state.
289*/
290                modified=FALSE;
291                for(nucpos=1;nucpos<seqlen-1;nucpos++)
292                        baselist[nucpos].known=FALSE;
293
294/*
295*       except for the first and last.
296*/
297                baselist[0].known=TRUE;
298                baselist[seqlen-1].known=TRUE;
299                if(baselist[0].posnum>0)
300                        PosConFix(baselist[0]);
301
302/*
303*       for all bases...
304*/
305                for(nucpos=0;nucpos<seqlen-1;nucpos++)
306                {
307                        redo=FALSE;
308/*
309*       If the current base is unknown,back up and flag that it was
310*       not known.
311*/
312                        for(;baselist[nucpos].known==FALSE;nucpos--)
313                        {
314                                redo=TRUE;
315                        }
316
317/*
318*       If the next base is not known, then begin a loop.
319*/
320                        if(baselist[nucpos+1].known==FALSE)
321                        {
322                                size=BuildLoopStk(lstack,nucpos,baselist,&ccw,
323                                &imax);
324/*
325*       If the loop is more than two bases, then lay the arc out.
326*/
327                                if(size>2)
328                                        Arc(lstack,size,baselist,ccw,imax);
329                        }
330                }
331/*
332*        Find min and max positions.
333*/
334
335                xmax = -99999.99;
336                ymax = -99999.99;
337                xmin = 99999.99;
338                ymin = 99999.99;
339               
340                for(nucpos=0;nucpos<seqlen;nucpos++)
341                {
342                        xmax=Max(xmax,baselist[nucpos].x);
343                        xmin=Min(xmin,baselist[nucpos].x);
344                        ymax=Max(ymax,baselist[nucpos].y);
345                        ymin=Min(ymin,baselist[nucpos].y);
346                }
347/*
348*       Scale all points so that ther fall on the page.
349*/
350                WINDOW_SIZE = Min(xv_get(canvas_paint_window(pagecan),XV_HEIGHT),
351                xv_get(canvas_paint_window(pagecan),XV_WIDTH));
352                xscale=(double)(xv_get(canvas_paint_window(pagecan),XV_WIDTH)-30) / (xmax-xmin);
353                yscale=(double)(xv_get(canvas_paint_window(pagecan),XV_HEIGHT)-30) / (ymax-ymin);
354
355                if(xscale<yscale)
356                        yscale=xscale;
357                else
358                        xscale=yscale;
359
360                xoffset=(-xmin)*xscale+20;
361                yoffset=(-ymin)*yscale+20;
362
363/*
364*       Clear the page..
365*/
366                if(COLOR)
367                        pw_writebackground(canvas_paint_window(pagecan),0,0,
368                        xv_get(canvas_paint_window(pagecan),XV_WIDTH),
369                        xv_get(canvas_paint_window(pagecan),XV_HEIGHT),
370                        PIX_SRC | (15 <<5));
371                else
372                        pw_writebackground(canvas_paint_window(pagecan),0,0,
373                        xv_get(canvas_paint_window(pagecan),XV_WIDTH),
374                        xv_get(canvas_paint_window(pagecan),XV_HEIGHT),
375                        PIX_SRC );
376        }
377        WINDOW_SIZE = Min(xv_get(canvas_paint_window(pagecan),XV_HEIGHT),
378        xv_get(canvas_paint_window(pagecan),XV_WIDTH));
379        rect_construct(&rect,0,0,xv_get(canvas_paint_window(pagecan),XV_WIDTH),xv_get(canvas_paint_window(pagecan),XV_HEIGHT));
380/*
381*       Write all bases and symbols on the page.
382*/
383        for(nucpos=0;nucpos<seqlen;nucpos++)
384        {
385                if(baselist[nucpos].depth <ddepth)
386                {
387                        gprint(baselist[nucpos],pw);
388                        if(baselist[nucpos].pair > nucpos)
389                                DrawPair(baselist[nucpos],
390                                baselist[baselist[nucpos].pair],pw);
391                        if(baselist[nucpos].label != NULL)
392                                PlaceLabel(baselist[nucpos].label,nucpos,pw);
393                }
394               
395        }
396        if(sho_con)
397                ShoCon();
398        return;
399}
400
401
402PromptSeq(infile,dset,seqnum)
403FILE *infile;
404DataSet *dset;
405int *seqnum;
406{
407        *seqnum=0;
408}
409
410
411/*
412*       BuildLoopStack:  Build a stack of bases that make a subloop of
413*       the structure.  Unknown bases are pushed on the stack until a known
414*       base is encountered.  Base to base distances are also pushed upon
415*       the stack for the arc subroutine.
416*/
417BuildLoopStk(stk,nuc,blist,ccw,imax)
418LoopStak stk[];
419int nuc,*imax;
420Base *blist;
421int *ccw;
422{
423        int stkp,current,cw_cnt=0,ccw_cnt=0;
424        double dist,dmax=0.0;
425        Base *here,*there;
426
427/*
428*       Push the first base on...
429*/
430        stk[stkp=0].nucnum=nuc;
431        stk[stkp++].dist=0.0;
432       
433
434        current=NextBase(nuc,blist,&dist);
435        for(;blist[current].known == FALSE;
436                current=NextBase(current,blist,&dist))
437        {
438                if(dist>dmax)
439                {
440                        dmax=dist;
441                        *imax=stkp;
442                }
443                if(blist[current].dir == CCW) ccw_cnt++;
444                else
445                        cw_cnt++;
446                stk[stkp].nucnum=current;
447                stk[stkp++].dist=dist;
448        }
449        if(dist>dmax)
450        {
451                dmax=dist;
452                *imax=stkp;
453        }
454        stk[stkp].nucnum=current;
455        stk[stkp++].dist=dist;
456        here = &(blist[nuc]);
457        there = &(blist[current]);
458        stk[0].dist = distance(here->x,here->y,there->x,there->y);
459/*
460*       Is this a clockwise loop, or a counter clockwise loop.
461*/
462        *ccw = ((ccw_cnt >= cw_cnt)? TRUE:FALSE);
463        return(stkp);
464}
465
466
467
468NextBase(cur,blist,dist)
469int cur;
470Base blist[];
471double *dist;
472{
473        double Spacing();
474        Base here;
475        int next,pair,forw;
476
477        here=blist[cur];
478        pair=here.pair;
479        forw=here.dforw.pair;
480
481        if(redo == TRUE)
482        {
483                next = ++cur;
484                redo = FALSE;
485                *dist = BASE_TO_BASE_DIST;
486        }
487        else if(pair > cur && forw > cur)
488        {
489                if(blist[pair].known && blist[forw].known)
490                {
491                        next= ++cur;
492                        *dist=BASE_TO_BASE_DIST;
493                }
494                else if(here.known == FALSE)
495                {
496                        if(pair>forw)
497                        {
498                                next = pair;
499                                *dist=Spacing(here.nuc,blist[next].nuc);
500                        }
501                        else
502                        {
503                                next = forw;
504                                *dist = here.dforw.dist;
505                        }
506                }
507                else
508                {
509                        if(pair<=forw) 
510                        {       
511                                next = pair; 
512                                *dist=Spacing(here.nuc,blist[next].nuc); 
513                        } 
514                        else 
515                        {       
516                                next = forw;
517                                *dist = here.dforw.dist; 
518                        } 
519                } 
520        }
521
522        else if(forw != -1)
523        {
524                next=here.dforw.pair;
525                *dist=here.dforw.dist;
526        }
527
528        else if(pair > cur && here.known == FALSE)
529        {
530                next=pair;
531                *dist=Spacing(here.nuc,blist[next].nuc);
532        }
533
534        else
535        {
536                next= ++cur;
537                *dist=BASE_TO_BASE_DIST;
538        }
539
540        return(next);
541}
542
543
544
545Arc(stk,siz,blist,ccw,imax)
546LoopStak stk[];
547int siz,imax;
548Base *blist;
549int ccw;
550{
551        double x1,y1,x2,y2,xc,yc,a,d,c,dx,dy;
552        double dist,dtry,temp,temp1,temp2;
553        double th[1000];
554        double rho,phi,theta2,theta,dsqrd;
555        int sw_flag=FALSE;
556        double r,rmax,rmin,slen=0.0;
557        register i,j,upflag = TRUE;
558
559        x1 = blist[stk[0].nucnum].x;
560        y1 = blist[stk[0].nucnum].y;
561        x2 = blist[stk[siz-1].nucnum].x;
562        y2 = blist[stk[siz-1].nucnum].y;
563
564        dist=distance(x1,y1,x2,y2);
565        dsqrd = sqr(dist);
566
567        rmin=0.0;
568        for(i=1;i<siz;i++)
569                slen+=stk[i].dist;
570        if(slen <= dist)
571        {
572                dx=(x2-x1)/(double)(siz-1);
573                dy=(y2-y1)/(double)(siz-1);
574                for(i=1;i<siz-1;i++)
575                {
576                        blist[stk[i].nucnum].x=x1+dx*(double)i;
577                        blist[stk[i].nucnum].y=y1+dy*(double)i;
578                        blist[stk[i].nucnum].known=TRUE;
579                        if(blist[stk[i].nucnum].posnum != -1)
580                                PosConFix(blist[stk[i].nucnum]);
581                }
582        }
583        else
584        {
585                if(stk[imax].dist > dist)
586                {
587                        temp=dist;
588                        dist=stk[imax].dist;
589                        stk[imax].dist = temp;
590                        sw_flag = TRUE;
591                        dsqrd = dist*dist;
592                }
593                rmax=4.118252;
594                rmin=0.0;
595/*
596                for(i=1;i<siz;i++)
597                        rmin=Max(rmin,stk[i].dist * .5);
598*/
599                r = 0.0;
600                for(;fabs((rmax + rmin)*.5 - r)>.0001;)
601                {
602                        r=(rmin+rmax) * .5;
603                        c=1.0/r;
604                        theta=0.0;
605                        for(i=1;i<siz;i++)
606                        {
607                                temp = stk[i].dist*.5*c;
608                                if(temp>1.0)
609                                        theta = TWO_PI *100.0;
610                                else
611                                {
612                                        th[i]=2.0*asin(temp);
613                                        theta+=th[i];
614                                }
615                        }
616                        if(theta > TWO_PI)
617                        {
618                                rmin=r;
619                                if(upflag)
620                                        rmax = r*2.0;
621                        }
622                        else
623                        {
624                                temp1=r-r*cos(theta);
625                                temp2=r*sin(theta);
626                                dtry=sqr(temp1)+sqr(temp2);
627
628                                if(dtry-dsqrd>.01)
629                                {
630                                        rmax=r;
631                                        upflag = FALSE;
632                                }
633                                else if(dtry-dsqrd< -.01)
634                                {
635                                        rmin=r;
636                                        if(upflag)
637                                                rmax = r*2.0;
638                                }
639                                else
640                                {
641                                        rmin=r;
642                                        rmax=r;
643                                }
644                                if(r>10000.0)
645                                {
646                                        rmin=r;
647                                        rmax=r;
648                                }
649                        }
650                }
651                if(sw_flag == TRUE)
652                {
653                        dist=stk[imax].dist;
654                        temp=th[imax];
655                        th[imax] = (TWO_PI-theta);
656                        theta = (TWO_PI-temp);
657                }
658                rho=atan2(y2-y1,x2-x1);
659
660                a=sqrt(fabs(r*r-dist*dist*.25));
661                if(theta<PI_val && sw_flag == FALSE)
662                        a = -a;
663
664                if (ccw)
665                        phi=rho-PI_o2  + PI_val;
666                else
667                        phi=rho-PI_o2;
668
669
670                xc=(x1+x2)*.5+a*cos(phi);
671                yc=(y1+y2)*.5+a*sin(phi);
672
673                if(ccw)
674                        theta2=phi+theta*.5;
675                else
676                        theta2=phi-theta*.5;
677
678
679                for(i=1;i<siz-1;i++)
680                {
681                        if(ccw)
682                                theta2-=th[i];
683                        else
684                                theta2+=th[i];
685
686                        blist[stk[i].nucnum].x=xc+r*cos(theta2);
687                        blist[stk[i].nucnum].y=yc+r*sin(theta2);
688                        blist[stk[i].nucnum].known=TRUE;
689                        if(blist[stk[i].nucnum].posnum != -1)
690                                PosConFix(blist[stk[i].nucnum]);
691                }       
692        }
693}
694
695PromptFile(){}
696
697gprint(base,pw)
698Base base;
699Pixwin *pw;
700{
701        int xp,yp;
702        int color;
703        char dummy[132];
704
705
706        xp=(int)(base.x * xscale +xoffset);
707        yp=(int)(base.y * yscale + yoffset);
708
709        if(base.attr & HILITE)
710        {
711                pw_char(pw,xp,yp,PIX_NOT(PIX_SRC),NULL,base.nuc);
712        }
713        else
714        {
715                switch(base.nuc | 32)
716                {
717                        case 'a':
718                                color=3;
719                                break;
720                        case 'g':
721                                color = 8;
722                                break;
723                        case 'c':
724                                color = 6;
725                                break;
726                        case 'u':
727                                color = 5;
728                                break;
729                        case 't':
730                                color = 5;
731                                break;
732                        default:
733                                color = 12;
734                                break;
735                };
736                if(COLOR)
737                        pw_char(pw,xp,yp,PIX_SRC | (color <<5),NULL,base.nuc);
738                else
739                        pw_char(pw,xp,yp,PIX_SRC ,NULL,base.nuc);
740        }
741}
742
743double Spacing(a,b)
744char a,b;
745{
746        a |= 32;
747        b |= 32;
748
749        if( a=='a' && b=='u' || a=='u' && b=='a' ||
750        a=='a' && b=='t' || a=='t' && b=='a')
751                return (1.8);
752
753        if( a=='g' && b=='c' || a=='c' && b=='g')
754                return (1.8);
755
756        if( a=='g' && b=='u' || a=='u' && b=='g' ||
757        a=='g' && b=='t' || a=='t' && b=='g')
758                return (1.8);
759
760        return(2.4);
761
762}
763
764SetFile(){ return 0;}
Note: See TracBrowser for help on using the repository browser.