mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-04 20:04:21 +08:00
353 lines
9.2 KiB
C++
353 lines
9.2 KiB
C++
|
|
/*
|
|
A* -------------------------------------------------------------------
|
|
B* This file contains source code for the PyMOL computer program
|
|
C* copyright 1998-2002 by Warren Lyford Delano of DeLano Scientific.
|
|
D* -------------------------------------------------------------------
|
|
E* It is unlawful to modify or remove this copyright notice.
|
|
F* -------------------------------------------------------------------
|
|
G* Please see the accompanying LICENSE file for further information.
|
|
H* -------------------------------------------------------------------
|
|
I* Additional authors of this source file include:
|
|
-*
|
|
-*
|
|
-*
|
|
Z* -------------------------------------------------------------------
|
|
*/
|
|
#include"os_gl.h"
|
|
#include"Base.h"
|
|
#include"Block.h"
|
|
#include"Ortho.h"
|
|
#include"ScrollBar.h"
|
|
#include"CGO.h"
|
|
|
|
bool ScrollBar::isMaxed() const
|
|
{
|
|
if(m_ValueMax > 0.0F) {
|
|
return m_Value == m_ValueMax;
|
|
} else
|
|
return false;
|
|
}
|
|
|
|
void ScrollBar::update()
|
|
{
|
|
int range;
|
|
|
|
if(m_HorV) {
|
|
range = (rect.right - rect.left);
|
|
} else {
|
|
range = (rect.top - rect.bottom);
|
|
}
|
|
m_ExactBarSize = (range * m_DisplaySize) / static_cast<float>(m_ListSize);
|
|
m_BarSize = static_cast<int> (0.499F + m_ExactBarSize);
|
|
if(m_BarSize < 4)
|
|
m_BarSize = DIP2PIXEL(4);
|
|
m_BarRange = range - m_BarSize;
|
|
if(m_BarRange < 2)
|
|
m_BarRange = 2;
|
|
m_ValueMax = static_cast<float>(m_ListSize - m_DisplaySize);
|
|
if(m_ValueMax < 1)
|
|
m_ValueMax = 1;
|
|
m_Value = std::clamp(m_Value, 0.0f, m_ValueMax);
|
|
}
|
|
|
|
void ScrollBar::fill(CGO* orthoCGO)
|
|
{
|
|
if (orthoCGO)
|
|
CGOColorv(orthoCGO, BackColor);
|
|
#ifndef PURE_OPENGL_ES_2
|
|
else
|
|
glColor3fv(BackColor);
|
|
#endif
|
|
Block::fill(orthoCGO);
|
|
}
|
|
|
|
void ScrollBar::drawImpl(bool bFill, CGO* orthoCGO)
|
|
{
|
|
int top, left, bottom, right;
|
|
|
|
if (bFill)
|
|
fill(orthoCGO);
|
|
|
|
update();
|
|
|
|
float value = std::min(m_Value, m_ValueMax);
|
|
|
|
if(m_HorV) {
|
|
top = rect.top - 1;
|
|
bottom = rect.bottom + 1;
|
|
left = (int) (0.499F + rect.left + (m_BarRange * value) / m_ValueMax);
|
|
right = left + m_BarSize;
|
|
m_BarMin = left;
|
|
m_BarMax = right;
|
|
} else {
|
|
top = (int) (0.499F + rect.top - (m_BarRange * value) / m_ValueMax);
|
|
bottom = top - m_BarSize;
|
|
left = rect.left + 1;
|
|
right = rect.right - 1;
|
|
m_BarMin = top;
|
|
m_BarMax = bottom;
|
|
}
|
|
|
|
if(m_G->HaveGUI && m_G->ValidContext) {
|
|
|
|
if (orthoCGO){
|
|
CGOColor(orthoCGO, 0.8F, 0.8F, 0.8F);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right, top, 0.f);
|
|
CGOVertex(orthoCGO, right, bottom + 1, 0.f);
|
|
CGOVertex(orthoCGO, left, top, 0.f);
|
|
CGOVertex(orthoCGO, left, bottom + 1, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
} else {
|
|
glColor3f(0.8F, 0.8F, 0.8F);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right, top);
|
|
glVertex2i(right, bottom + 1);
|
|
glVertex2i(left, bottom + 1);
|
|
glVertex2i(left, top);
|
|
glEnd();
|
|
}
|
|
|
|
if (orthoCGO){
|
|
CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, right, bottom, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, bottom, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
} else {
|
|
glColor3f(0.3F, 0.3F, 0.3F);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right, top - 1);
|
|
glVertex2i(right, bottom);
|
|
glVertex2i(left + 1, bottom);
|
|
glVertex2i(left + 1, top - 1);
|
|
glEnd();
|
|
}
|
|
|
|
if (orthoCGO){
|
|
CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right, bottom + 1, 0.f);
|
|
CGOVertex(orthoCGO, right, bottom, 0.f);
|
|
CGOVertex(orthoCGO, left, bottom + 1, 0.f);
|
|
CGOVertex(orthoCGO, left, bottom, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
} else {
|
|
glColor3f(0.3F, 0.3F, 0.3F);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right, bottom + 1);
|
|
glVertex2i(right, bottom);
|
|
glVertex2i(left, bottom);
|
|
glVertex2i(left, bottom + 1);
|
|
glEnd();
|
|
}
|
|
|
|
if (orthoCGO){
|
|
CGOColorv(orthoCGO, m_BarColor);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right - 1, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, right - 1, bottom + 1, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, bottom + 1, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
} else {
|
|
glColor3fv(m_BarColor);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right - 1, top - 1);
|
|
glVertex2i(right - 1, bottom + 1);
|
|
glVertex2i(left + 1, bottom + 1);
|
|
glVertex2i(left + 1, top - 1);
|
|
glEnd();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ScrollBar::drawHandle(float alpha, CGO* orthoCGO)
|
|
{
|
|
float value;
|
|
int top, left, bottom, right;
|
|
|
|
value = std::min(m_Value, m_ValueMax);
|
|
|
|
if(m_HorV) {
|
|
top = rect.top - 1;
|
|
bottom = rect.bottom + 1;
|
|
left = (int) (0.499F + rect.left + (m_BarRange * value) / m_ValueMax);
|
|
right = left + m_BarSize;
|
|
} else {
|
|
top = (int) (0.499F + rect.top - (m_BarRange * value) / m_ValueMax);
|
|
bottom = top - m_BarSize;
|
|
left = rect.left + 1;
|
|
right = rect.right - 1;
|
|
}
|
|
|
|
if(m_G->HaveGUI && m_G->ValidContext) {
|
|
|
|
glEnable(GL_BLEND);
|
|
if (orthoCGO){
|
|
CGOAlpha(orthoCGO, alpha);
|
|
CGOColor(orthoCGO, 0.8F, 0.8F, 0.8F);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right, top, 0.f);
|
|
CGOVertex(orthoCGO, right, bottom + 1, 0.f);
|
|
CGOVertex(orthoCGO, left, top, 0.f);
|
|
CGOVertex(orthoCGO, left, bottom + 1, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
CGOAlpha(orthoCGO, 1.f);
|
|
} else {
|
|
glColor4f(0.8F, 0.8F, 0.8F, alpha);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right, top);
|
|
glVertex2i(right, bottom + 1);
|
|
glVertex2i(left, bottom + 1);
|
|
glVertex2i(left, top);
|
|
glEnd();
|
|
}
|
|
|
|
if (orthoCGO){
|
|
CGOAlpha(orthoCGO, alpha);
|
|
CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, right, bottom, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, bottom, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
CGOAlpha(orthoCGO, 1.f);
|
|
} else {
|
|
glColor4f(0.3F, 0.3F, 0.3F, alpha);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right, top - 1);
|
|
glVertex2i(right, bottom);
|
|
glVertex2i(left + 1, bottom);
|
|
glVertex2i(left + 1, top - 1);
|
|
glEnd();
|
|
}
|
|
|
|
if (orthoCGO){
|
|
CGOAlpha(orthoCGO, alpha);
|
|
CGOColor(orthoCGO, 0.3F, 0.3F, 0.3F);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right, bottom + 1, 0.f);
|
|
CGOVertex(orthoCGO, right, bottom, 0.f);
|
|
CGOVertex(orthoCGO, left, bottom, 0.f);
|
|
CGOVertex(orthoCGO, left, bottom + 1, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
CGOAlpha(orthoCGO, 1.f);
|
|
} else {
|
|
glColor4f(0.3F, 0.3F, 0.3F, alpha);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right, bottom + 1);
|
|
glVertex2i(right, bottom);
|
|
glVertex2i(left, bottom);
|
|
glVertex2i(left, bottom + 1);
|
|
glEnd();
|
|
}
|
|
|
|
if (orthoCGO){
|
|
CGOAlpha(orthoCGO, alpha);
|
|
CGOColor(orthoCGO, m_BarColor[0], m_BarColor[1], m_BarColor[2]);
|
|
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
|
|
CGOVertex(orthoCGO, right - 1, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, right - 1, bottom + 1, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, top - 1, 0.f);
|
|
CGOVertex(orthoCGO, left + 1, bottom + 1, 0.f);
|
|
CGOEnd(orthoCGO);
|
|
CGOAlpha(orthoCGO, 1.f);
|
|
} else {
|
|
glColor4f(m_BarColor[0], m_BarColor[1], m_BarColor[2], alpha);
|
|
glBegin(GL_POLYGON);
|
|
glVertex2i(right - 1, top - 1);
|
|
glVertex2i(right - 1, bottom + 1);
|
|
glVertex2i(left + 1, bottom + 1);
|
|
glVertex2i(left + 1, top - 1);
|
|
glEnd();
|
|
}
|
|
glDisable(GL_BLEND);
|
|
}
|
|
}
|
|
|
|
int ScrollBar::click(int button, int x, int y, int mod)
|
|
{
|
|
int grab = 0;
|
|
|
|
if(button == P_GLUT_MIDDLE_BUTTON) {
|
|
if(m_HorV) {
|
|
if(x < m_BarMin || x > m_BarMax)
|
|
setValue((m_ListSize * (x - rect.left)) /
|
|
(rect.right - rect.left) - m_DisplaySize * 0.5F);
|
|
grab = x;
|
|
} else {
|
|
if(y > m_BarMin || y < m_BarMax)
|
|
setValue((m_ListSize * (y - rect.top)) /
|
|
(rect.bottom - rect.top) - m_DisplaySize * 0.5F);
|
|
grab = y;
|
|
}
|
|
} else {
|
|
if(m_HorV) {
|
|
if(x > m_BarMax) {
|
|
m_Value += m_DisplaySize;
|
|
} else if(x < m_BarMin) {
|
|
m_Value -= m_DisplaySize;
|
|
} else {
|
|
grab = x;
|
|
}
|
|
} else {
|
|
if(y > m_BarMin) {
|
|
m_Value -= m_DisplaySize;
|
|
} else if(y < m_BarMax) {
|
|
m_Value += m_DisplaySize;
|
|
} else {
|
|
grab = y;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(grab) {
|
|
OrthoGrab(m_G, this);
|
|
m_StartPos = grab;
|
|
m_StartValue = m_Value;
|
|
}
|
|
|
|
OrthoDirty(m_G);
|
|
return 0;
|
|
}
|
|
|
|
int ScrollBar::drag(int x, int y, int mod)
|
|
{
|
|
int displ;
|
|
if(m_HorV)
|
|
displ = m_StartPos - x;
|
|
else
|
|
displ = y - m_StartPos;
|
|
setValue(m_StartValue - (m_ValueMax * displ) / m_BarRange);
|
|
OrthoDirty(m_G);
|
|
return true;
|
|
}
|
|
|
|
int ScrollBar::release(int button, int x, int y, int mod)
|
|
{
|
|
OrthoUngrab(m_G);
|
|
OrthoDirty(m_G);
|
|
return 0;
|
|
}
|
|
|
|
void ScrollBar::setLimits(int list_size, int display_size)
|
|
{
|
|
m_ListSize = list_size;
|
|
m_DisplaySize = display_size;
|
|
update();
|
|
}
|
|
|
|
void ScrollBar::setBox(int top, int left, int bottom, int right)
|
|
{
|
|
rect.top = top;
|
|
rect.left = left;
|
|
rect.bottom = bottom;
|
|
rect.right = right;
|
|
}
|
|
|