Merge release-4-6 into master
[alexxy/gromacs.git] / src / programs / view / nleg.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2013, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  *
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  *
30  * For more info, check our website at http://www.gromacs.org
31  *
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <ctype.h>
40 #include <string.h>
41 #include <smalloc.h>
42 #include <macros.h>
43 #include "buttons.h"
44 #include "nleg.h"
45 #include "writeps.h"
46
47 typedef struct {
48     const char    *tp;
49     unsigned long *col;
50     t_rgb          rgb;
51 } t_atomcolor;
52
53 static t_atomcolor ac[] = {
54     { "O",  &LIGHTRED,     { 1,  0,  0   } },
55     { "N",  &LIGHTCYAN,    { 0,  0,  1   } },
56     { "NA", &LIGHTGREY,    { 0.6, 0.6, 0.6 } },
57     { "S",  &YELLOW,       { 1,  1,  0   } },
58     { "C",  &LIGHTGREEN,   { 0,  1,  0   } },
59     { "CL", &VIOLET,       { 1,  0,  1   } },
60     { "F",  &LIGHTGREY,    { 0.6, 0.6, 0.6 } },
61     { "Z",  &LIGHTGREY,    { 0.6, 0.6, 0.6 } },
62     { "P",  &LIGHTBLUE,    { 0.4, 0.4, 1.0 } },
63     { "H",  &WHITE,        { 0.8, 0.8, 0.8 } }
64 };
65 #define NAC asize(ac)
66
67 int search_ac(const char *type)
68 {
69     unsigned int i, nb, mij, best, besti;
70
71     best  = 0;
72     besti = 0;
73     if (NULL != type)
74     {
75         for (i = 0; (i < NAC); i++)
76         {
77             mij = std::min((int)strlen(type), (int)strlen(ac[i].tp));
78             for (nb = 0; (nb < mij); nb++)
79             {
80                 if (type[nb] != ac[i].tp[nb])
81                 {
82                     break;
83                 }
84             }
85             if (nb > best)
86             {
87                 best  = nb;
88                 besti = i;
89             }
90         }
91     }
92     return besti;
93 }
94
95 unsigned long Type2Color(const char *type)
96 {
97     int i;
98
99     i = search_ac(type);
100
101     return *(ac[i].col);
102 }
103
104 t_rgb *Type2RGB(const char *type)
105 {
106     int i;
107
108     i = search_ac(type);
109
110     return &(ac[i].rgb);
111 }
112
113 void DrawLegend(t_x11 *x11, t_windata *Win)
114 {
115 #define NLAB 6
116 #define COLS 3
117     static const char *lab[NLAB] = { "C", "O", "H", "S", "N", "P" };
118     int                i, i0, dh, dw, w, y, x1, x0;
119     unsigned long      cind;
120     real               h_2;
121
122     XClearWindow(x11->disp, Win->self);
123     w   = Win->width;
124     h_2 = Win->height/(2.0*NLAB/COLS);
125     dh  = h_2-2;
126     dw  = dh;
127
128     for (i = 0; (i < NLAB); i++)
129     {
130         i0   = i % (NLAB/COLS);
131         x0   = (i / (NLAB/COLS))*(Win->width/COLS)+AIR;
132         x1   = x0+2*dw+AIR;
133         cind = Type2Color(lab[i]);
134         XSetForeground(x11->disp, x11->gc, cind);
135         y = ((2*i0+1)*h_2);
136         XFillRectangle (x11->disp, Win->self, x11->gc, x0, y-dh, 2*dw, 2*dh);
137         XSetForeground(x11->disp, x11->gc, WHITE);
138         TextInRect(x11, Win->self, lab[i], x1, y-dh, w-x1, 2*dh,
139                    eXLeft, eYCenter);
140     }
141     XSetForeground(x11->disp, x11->gc, x11->fg);
142 }
143
144 static bool LegWCallBack(t_x11 *x11, XEvent *event, Window w, void *data)
145 {
146     t_legendwin *lw;
147
148     lw = (t_legendwin *)data;
149     switch (event->type)
150     {
151         case Expose:
152             DrawLegend(x11, &lw->wd);
153             break;
154         default:
155             break;
156     }
157     return false;
158 }
159
160 t_legendwin *init_legw(t_x11 *x11, Window Parent,
161                        int x, int y, int width, int height,
162                        unsigned long fg, unsigned long bg)
163 {
164     t_legendwin *lw;
165
166     snew(lw, 1);
167     InitWin(&lw->wd, x, y, width, height, 1, "Legend Window");
168     lw->wd.self = XCreateSimpleWindow(x11->disp, Parent, x, y, 1, 1, 1, fg, bg);
169     x11->RegisterCallback(x11, lw->wd.self, Parent, LegWCallBack, lw);
170     x11->SetInputMask(x11, lw->wd.self, ExposureMask);
171
172     return lw;
173 }
174
175 void map_legw(t_x11 *x11, t_legendwin *lw)
176 {
177     XMapWindow(x11->disp, lw->wd.self);
178 }
179
180
181 void done_legw(t_x11 *x11, t_legendwin *lw)
182 {
183     x11->UnRegisterCallback(x11, lw->wd.self);
184     sfree(lw);
185 }