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