1 
2 /*
3 A* -------------------------------------------------------------------
4 B* This file contains source code for the PyMOL computer program
5 C* copyright 1998-2002 by Warren Lyford Delano of DeLano Scientific.
6 D* -------------------------------------------------------------------
7 E* It is unlawful to modify or remove this copyright notice.
8 F* -------------------------------------------------------------------
9 G* Please see the accompanying LICENSE file for further information.
10 H* -------------------------------------------------------------------
11 I* Additional authors of this source file include:
12 -*
13 -*
14 -*
15 Z* -------------------------------------------------------------------
16 */
17 #include"os_gl.h"
18 #include"Base.h"
19 #include"Block.h"
20 #include"OOMac.h"
21 #include"Ortho.h"
22 #include"ScrollBar.h"
23 #include"CGO.h"
24 
isMaxed() const25 bool ScrollBar::isMaxed() const
26 {
27   if(m_ValueMax > 0.0F) {
28     return m_Value == m_ValueMax;
29   } else
30     return false;
31 }
32 
update()33 void ScrollBar::update()
34 {
35   int range;
36 
37   if(m_HorV) {
38     range = (rect.right - rect.left);
39   } else {
40     range = (rect.top - rect.bottom);
41   }
42   m_ExactBarSize = (range * m_DisplaySize) / static_cast<float>(m_ListSize);
43   m_BarSize = static_cast<int> (0.499F + m_ExactBarSize);
44   if(m_BarSize < 4)
45     m_BarSize = DIP2PIXEL(4);
46   m_BarRange = range - m_BarSize;
47   if(m_BarRange < 2)
48     m_BarRange = 2;
49   m_ValueMax = static_cast<float>(m_ListSize - m_DisplaySize);
50   if(m_ValueMax < 1)
51     m_ValueMax = 1;
52   m_Value = pymol::clamp(m_Value, 0.0f, m_ValueMax);
53 }
54 
fill(CGO * orthoCGO)55 void ScrollBar::fill(CGO* orthoCGO)
56 {
57   if (orthoCGO)
58     CGOColorv(orthoCGO, BackColor);
59 #ifndef PURE_OPENGL_ES_2
60   else
61     glColor3fv(BackColor);
62 #endif
63   Block::fill(orthoCGO);
64 }
65 
drawImpl(bool bFill,CGO * orthoCGO)66 void ScrollBar::drawImpl(bool bFill, CGO* orthoCGO)
67 {
68   int top, left, bottom, right;
69 
70   if (bFill)
71     fill(orthoCGO);
72 
73   update();
74 
75   float value = std::min(m_Value, m_ValueMax);
76 
77   if(m_HorV) {
78     top = rect.top - 1;
79     bottom = rect.bottom + 1;
80     left = (int) (0.499F + rect.left + (m_BarRange * value) / m_ValueMax);
81     right = left + m_BarSize;
82     m_BarMin = left;
83     m_BarMax = right;
84   } else {
85     top = (int) (0.499F + rect.top - (m_BarRange * value) / m_ValueMax);
86     bottom = top - m_BarSize;
87     left = rect.left + 1;
88     right = rect.right - 1;
89     m_BarMin = top;
90     m_BarMax = bottom;
91   }
92 
93   if(m_G->HaveGUI && m_G->ValidContext) {
94 
95     if (orthoCGO){
96       CGOColor(orthoCGO, 0.8F, 0.8F, 0.8F);
97       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
98       CGOVertex(orthoCGO, right, top, 0.f);
99       CGOVertex(orthoCGO, right, bottom + 1, 0.f);
100       CGOVertex(orthoCGO, left, top, 0.f);
101       CGOVertex(orthoCGO, left, bottom + 1, 0.f);
102       CGOEnd(orthoCGO);
103     } else {
104       glColor3f(0.8F, 0.8F, 0.8F);
105       glBegin(GL_POLYGON);
106       glVertex2i(right, top);
107       glVertex2i(right, bottom + 1);
108       glVertex2i(left, bottom + 1);
109       glVertex2i(left, top);
110       glEnd();
111     }
112 
113     if (orthoCGO){
114       CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
115       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
116       CGOVertex(orthoCGO, right, top - 1, 0.f);
117       CGOVertex(orthoCGO, right, bottom, 0.f);
118       CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
119       CGOVertex(orthoCGO, left + 1, bottom, 0.f);
120       CGOEnd(orthoCGO);
121     } else {
122       glColor3f(0.3F, 0.3F, 0.3F);
123       glBegin(GL_POLYGON);
124       glVertex2i(right, top - 1);
125       glVertex2i(right, bottom);
126       glVertex2i(left + 1, bottom);
127       glVertex2i(left + 1, top - 1);
128       glEnd();
129     }
130 
131     if (orthoCGO){
132       CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
133       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
134       CGOVertex(orthoCGO, right, bottom + 1, 0.f);
135       CGOVertex(orthoCGO, right, bottom, 0.f);
136       CGOVertex(orthoCGO, left, bottom + 1, 0.f);
137       CGOVertex(orthoCGO, left, bottom, 0.f);
138       CGOEnd(orthoCGO);
139     } else {
140       glColor3f(0.3F, 0.3F, 0.3F);
141       glBegin(GL_POLYGON);
142       glVertex2i(right, bottom + 1);
143       glVertex2i(right, bottom);
144       glVertex2i(left, bottom);
145       glVertex2i(left, bottom + 1);
146       glEnd();
147     }
148 
149     if (orthoCGO){
150       CGOColorv(orthoCGO, m_BarColor);
151       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
152       CGOVertex(orthoCGO, right - 1, top - 1, 0.f);
153       CGOVertex(orthoCGO, right - 1, bottom + 1, 0.f);
154       CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
155       CGOVertex(orthoCGO, left + 1, bottom + 1, 0.f);
156       CGOEnd(orthoCGO);
157     } else {
158       glColor3fv(m_BarColor);
159       glBegin(GL_POLYGON);
160       glVertex2i(right - 1, top - 1);
161       glVertex2i(right - 1, bottom + 1);
162       glVertex2i(left + 1, bottom + 1);
163       glVertex2i(left + 1, top - 1);
164       glEnd();
165     }
166   }
167 }
168 
drawHandle(float alpha,CGO * orthoCGO)169 void ScrollBar::drawHandle(float alpha, CGO* orthoCGO)
170 {
171   float value;
172   int top, left, bottom, right;
173 
174   value = std::min(m_Value, m_ValueMax);
175 
176   if(m_HorV) {
177     top = rect.top - 1;
178     bottom = rect.bottom + 1;
179     left = (int) (0.499F + rect.left + (m_BarRange * value) / m_ValueMax);
180     right = left + m_BarSize;
181   } else {
182     top = (int) (0.499F + rect.top - (m_BarRange * value) / m_ValueMax);
183     bottom = top - m_BarSize;
184     left = rect.left + 1;
185     right = rect.right - 1;
186   }
187 
188   if(m_G->HaveGUI && m_G->ValidContext) {
189 
190     glEnable(GL_BLEND);
191     if (orthoCGO){
192       CGOAlpha(orthoCGO, alpha);
193       CGOColor(orthoCGO, 0.8F, 0.8F, 0.8F);
194       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
195       CGOVertex(orthoCGO, right, top, 0.f);
196       CGOVertex(orthoCGO, right, bottom + 1, 0.f);
197       CGOVertex(orthoCGO, left, top, 0.f);
198       CGOVertex(orthoCGO, left, bottom + 1, 0.f);
199       CGOEnd(orthoCGO);
200       CGOAlpha(orthoCGO, 1.f);
201     } else {
202       glColor4f(0.8F, 0.8F, 0.8F, alpha);
203       glBegin(GL_POLYGON);
204       glVertex2i(right, top);
205       glVertex2i(right, bottom + 1);
206       glVertex2i(left, bottom + 1);
207       glVertex2i(left, top);
208       glEnd();
209     }
210 
211     if (orthoCGO){
212       CGOAlpha(orthoCGO, alpha);
213       CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
214       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
215       CGOVertex(orthoCGO, right, top - 1, 0.f);
216       CGOVertex(orthoCGO, right, bottom, 0.f);
217       CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
218       CGOVertex(orthoCGO, left + 1, bottom, 0.f);
219       CGOEnd(orthoCGO);
220       CGOAlpha(orthoCGO, 1.f);
221     } else {
222       glColor4f(0.3F, 0.3F, 0.3F, alpha);
223       glBegin(GL_POLYGON);
224       glVertex2i(right, top - 1);
225       glVertex2i(right, bottom);
226       glVertex2i(left + 1, bottom);
227       glVertex2i(left + 1, top - 1);
228       glEnd();
229     }
230 
231     if (orthoCGO){
232       CGOAlpha(orthoCGO, alpha);
233       CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
234       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
235       CGOVertex(orthoCGO, right, bottom + 1, 0.f);
236       CGOVertex(orthoCGO, right, bottom, 0.f);
237       CGOVertex(orthoCGO, left, bottom, 0.f);
238       CGOVertex(orthoCGO, left, bottom + 1, 0.f);
239       CGOEnd(orthoCGO);
240       CGOAlpha(orthoCGO, 1.f);
241     } else {
242       glColor4f(0.3F, 0.3F, 0.3F, alpha);
243       glBegin(GL_POLYGON);
244       glVertex2i(right, bottom + 1);
245       glVertex2i(right, bottom);
246       glVertex2i(left, bottom);
247       glVertex2i(left, bottom + 1);
248       glEnd();
249     }
250 
251     if (orthoCGO){
252       CGOAlpha(orthoCGO, alpha);
253       CGOColor(orthoCGO, m_BarColor[0], m_BarColor[1], m_BarColor[2]);
254       CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
255       CGOVertex(orthoCGO, right - 1, top - 1, 0.f);
256       CGOVertex(orthoCGO, right - 1, bottom + 1, 0.f);
257       CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
258       CGOVertex(orthoCGO, left + 1, bottom + 1, 0.f);
259       CGOEnd(orthoCGO);
260       CGOAlpha(orthoCGO, 1.f);
261     } else {
262       glColor4f(m_BarColor[0], m_BarColor[1], m_BarColor[2], alpha);
263       glBegin(GL_POLYGON);
264       glVertex2i(right - 1, top - 1);
265       glVertex2i(right - 1, bottom + 1);
266       glVertex2i(left + 1, bottom + 1);
267       glVertex2i(left + 1, top - 1);
268       glEnd();
269     }
270     glDisable(GL_BLEND);
271   }
272 }
273 
click(int button,int x,int y,int mod)274 int ScrollBar::click(int button, int x, int y, int mod)
275 {
276   int grab = 0;
277 
278   if(button == P_GLUT_MIDDLE_BUTTON) {
279     if(m_HorV) {
280       if(x < m_BarMin || x > m_BarMax)
281         setValue((m_ListSize * (x - rect.left)) /
282             (rect.right - rect.left) - m_DisplaySize * 0.5F);
283       grab = x;
284     } else {
285       if(y > m_BarMin || y < m_BarMax)
286         setValue((m_ListSize * (y - rect.top)) /
287             (rect.bottom - rect.top) - m_DisplaySize * 0.5F);
288       grab = y;
289     }
290   } else {
291     if(m_HorV) {
292       if(x > m_BarMax) {
293         m_Value += m_DisplaySize;
294       } else if(x < m_BarMin) {
295         m_Value -= m_DisplaySize;
296       } else {
297         grab = x;
298       }
299     } else {
300       if(y > m_BarMin) {
301         m_Value -= m_DisplaySize;
302       } else if(y < m_BarMax) {
303         m_Value += m_DisplaySize;
304       } else {
305         grab = y;
306       }
307     }
308   }
309 
310   if(grab) {
311     OrthoGrab(m_G, this);
312     m_StartPos = grab;
313     m_StartValue = m_Value;
314   }
315 
316   OrthoDirty(m_G);
317   return 0;
318 }
319 
drag(int x,int y,int mod)320 int ScrollBar::drag(int x, int y, int mod)
321 {
322   int displ;
323   if(m_HorV)
324     displ = m_StartPos - x;
325   else
326     displ = y - m_StartPos;
327   setValue(m_StartValue - (m_ValueMax * displ) / m_BarRange);
328   OrthoDirty(m_G);
329   return true;
330 }
331 
release(int button,int x,int y,int mod)332 int ScrollBar::release(int button, int x, int y, int mod)
333 {
334   OrthoUngrab(m_G);
335   OrthoDirty(m_G);
336   return 0;
337 }
338 
setLimits(int list_size,int display_size)339 void ScrollBar::setLimits(int list_size, int display_size)
340 {
341   m_ListSize = list_size;
342   m_DisplaySize = display_size;
343   update();
344 }
345 
setBox(int top,int left,int bottom,int right)346 void ScrollBar::setBox(int top, int left, int bottom, int right)
347 {
348   rect.top = top;
349   rect.left = left;
350   rect.bottom = bottom;
351   rect.right = right;
352 }
353 
354