Apply clang-format to source tree
[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,2015,2017,2019, 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 "nleg.h"
40
41 #include <cstring>
42
43 #include <algorithm>
44
45 #include "gromacs/fileio/rgb.h"
46 #include "gromacs/utility/arraysize.h"
47 #include "gromacs/utility/smalloc.h"
48
49 #include "buttons.h"
50
51 typedef struct
52 {
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 } },         { "N", &LIGHTCYAN, { 0, 0, 1 } },
60     { "NA", &LIGHTGREY, { 0.6, 0.6, 0.6 } }, { "S", &YELLOW, { 1, 1, 0 } },
61     { "C", &LIGHTGREEN, { 0, 1, 0 } },       { "CL", &VIOLET, { 1, 0, 1 } },
62     { "F", &LIGHTGREY, { 0.6, 0.6, 0.6 } },  { "Z", &LIGHTGREY, { 0.6, 0.6, 0.6 } },
63     { "P", &LIGHTBLUE, { 0.4, 0.4, 1.0 } },  { "H", &WHITE, { 0.8, 0.8, 0.8 } }
64 };
65 #define NAC asize(ac)
66
67 static int search_ac(const char* type)
68 {
69     unsigned int nb, mij, best, besti;
70
71     best  = 0;
72     besti = 0;
73     if (nullptr != type)
74     {
75         for (int i = 0; (i < NAC); i++)
76         {
77             mij = std::min(static_cast<int>(std::strlen(type)), static_cast<int>(std::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 static 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, eXLeft, eYCenter);
139     }
140     XSetForeground(x11->disp, x11->gc, x11->fg);
141 }
142
143 static bool LegWCallBack(t_x11* x11, XEvent* event, Window /*w*/, void* data)
144 {
145     t_legendwin* lw;
146
147     lw = (t_legendwin*)data;
148     switch (event->type)
149     {
150         case Expose: DrawLegend(x11, &lw->wd); break;
151         default: break;
152     }
153     return false;
154 }
155
156 t_legendwin* init_legw(t_x11* x11, Window Parent, int x, int y, int width, int height, unsigned long fg, unsigned long bg)
157 {
158     t_legendwin* lw;
159
160     snew(lw, 1);
161     InitWin(&lw->wd, x, y, width, height, 1, "Legend Window");
162     lw->wd.self = XCreateSimpleWindow(x11->disp, Parent, x, y, 1, 1, 1, fg, bg);
163     x11->RegisterCallback(x11, lw->wd.self, Parent, LegWCallBack, lw);
164     x11->SetInputMask(x11, lw->wd.self, ExposureMask);
165
166     return lw;
167 }
168
169 void map_legw(t_x11* x11, t_legendwin* lw)
170 {
171     XMapWindow(x11->disp, lw->wd.self);
172 }
173
174
175 void done_legw(t_x11* x11, t_legendwin* lw)
176 {
177     x11->UnRegisterCallback(x11, lw->wd.self);
178     sfree(lw);
179 }