53cb169be0ba0f943ac6e36f839459f3c7edbb80
[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,2014, 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 #include "gmxpre.h"
38
39 #include "config.h"
40
41 #include <string.h>
42
43 #include <algorithm>
44
45 #include "gromacs/legacyheaders/types/rgb.h"
46 #include "gromacs/legacyheaders/macros.h"
47 #include "gromacs/utility/smalloc.h"
48
49 #include "buttons.h"
50 #include "nleg.h"
51
52 typedef struct {
53     const char    *tp;
54     unsigned long *col;
55     t_rgb          rgb;
56 } t_atomcolor;
57
58 static t_atomcolor ac[] = {
59     { "O",  &LIGHTRED,     { 1,  0,  0   } },
60     { "N",  &LIGHTCYAN,    { 0,  0,  1   } },
61     { "NA", &LIGHTGREY,    { 0.6, 0.6, 0.6 } },
62     { "S",  &YELLOW,       { 1,  1,  0   } },
63     { "C",  &LIGHTGREEN,   { 0,  1,  0   } },
64     { "CL", &VIOLET,       { 1,  0,  1   } },
65     { "F",  &LIGHTGREY,    { 0.6, 0.6, 0.6 } },
66     { "Z",  &LIGHTGREY,    { 0.6, 0.6, 0.6 } },
67     { "P",  &LIGHTBLUE,    { 0.4, 0.4, 1.0 } },
68     { "H",  &WHITE,        { 0.8, 0.8, 0.8 } }
69 };
70 #define NAC asize(ac)
71
72 int search_ac(const char *type)
73 {
74     unsigned int i, nb, mij, best, besti;
75
76     best  = 0;
77     besti = 0;
78     if (NULL != type)
79     {
80         for (i = 0; (i < NAC); i++)
81         {
82             mij = std::min((int)strlen(type), (int)strlen(ac[i].tp));
83             for (nb = 0; (nb < mij); nb++)
84             {
85                 if (type[nb] != ac[i].tp[nb])
86                 {
87                     break;
88                 }
89             }
90             if (nb > best)
91             {
92                 best  = nb;
93                 besti = i;
94             }
95         }
96     }
97     return besti;
98 }
99
100 unsigned long Type2Color(const char *type)
101 {
102     int i;
103
104     i = search_ac(type);
105
106     return *(ac[i].col);
107 }
108
109 t_rgb *Type2RGB(const char *type)
110 {
111     int i;
112
113     i = search_ac(type);
114
115     return &(ac[i].rgb);
116 }
117
118 void DrawLegend(t_x11 *x11, t_windata *Win)
119 {
120 #define NLAB 6
121 #define COLS 3
122     static const char *lab[NLAB] = { "C", "O", "H", "S", "N", "P" };
123     int                i, i0, dh, dw, w, y, x1, x0;
124     unsigned long      cind;
125     real               h_2;
126
127     XClearWindow(x11->disp, Win->self);
128     w   = Win->width;
129     h_2 = Win->height/(2.0*NLAB/COLS);
130     dh  = h_2-2;
131     dw  = dh;
132
133     for (i = 0; (i < NLAB); i++)
134     {
135         i0   = i % (NLAB/COLS);
136         x0   = (i / (NLAB/COLS))*(Win->width/COLS)+AIR;
137         x1   = x0+2*dw+AIR;
138         cind = Type2Color(lab[i]);
139         XSetForeground(x11->disp, x11->gc, cind);
140         y = ((2*i0+1)*h_2);
141         XFillRectangle (x11->disp, Win->self, x11->gc, x0, y-dh, 2*dw, 2*dh);
142         XSetForeground(x11->disp, x11->gc, WHITE);
143         TextInRect(x11, Win->self, lab[i], x1, y-dh, w-x1, 2*dh,
144                    eXLeft, eYCenter);
145     }
146     XSetForeground(x11->disp, x11->gc, x11->fg);
147 }
148
149 static bool LegWCallBack(t_x11 *x11, XEvent *event, Window /*w*/, void *data)
150 {
151     t_legendwin *lw;
152
153     lw = (t_legendwin *)data;
154     switch (event->type)
155     {
156         case Expose:
157             DrawLegend(x11, &lw->wd);
158             break;
159         default:
160             break;
161     }
162     return false;
163 }
164
165 t_legendwin *init_legw(t_x11 *x11, Window Parent,
166                        int x, int y, int width, int height,
167                        unsigned long fg, unsigned long bg)
168 {
169     t_legendwin *lw;
170
171     snew(lw, 1);
172     InitWin(&lw->wd, x, y, width, height, 1, "Legend Window");
173     lw->wd.self = XCreateSimpleWindow(x11->disp, Parent, x, y, 1, 1, 1, fg, bg);
174     x11->RegisterCallback(x11, lw->wd.self, Parent, LegWCallBack, lw);
175     x11->SetInputMask(x11, lw->wd.self, ExposureMask);
176
177     return lw;
178 }
179
180 void map_legw(t_x11 *x11, t_legendwin *lw)
181 {
182     XMapWindow(x11->disp, lw->wd.self);
183 }
184
185
186 void done_legw(t_x11 *x11, t_legendwin *lw)
187 {
188     x11->UnRegisterCallback(x11, lw->wd.self);
189     sfree(lw);
190 }