187 lines
5.0 KiB
C++
187 lines
5.0 KiB
C++
/*
|
|
Copyright 2013 Peter Nelson
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
#include <pugl/pugl.h>
|
|
#include "pui.h"
|
|
|
|
static const int trough_cut = 20;
|
|
static const int pad = 20;
|
|
|
|
static const float slider_coords[][4] = {
|
|
{ 0, 0, .25f, .5f }, /// Small vertical slider
|
|
{ .5f, .25f, .75f, .75f }, /// Large vertical slider
|
|
{ .75f, 0, 1, .1875f }, /// Vertical trough top
|
|
{ .75f, .1875f, 1, .5625f }, /// Vertical trough
|
|
{ .75f, .5625f, 1, .75f }, /// Vertical trough bottom
|
|
|
|
{ .25f, 0, .75f, .25f }, /// Small horizontal slider
|
|
{ 0, .5f, .5f, .75f }, /// Large horizontal slider
|
|
{ 0, .75f, .1875f, 1 }, /// Horizontal trough left
|
|
{ .1875f, .75f, .5625f, 1 }, /// Horizontal trough
|
|
{ .5625f, .75f, .75f, 1 }, /// Horizontal trough right
|
|
};
|
|
|
|
enum SliderPart {
|
|
SP_VSMALL,
|
|
SP_VLARGE,
|
|
SP_VTOP,
|
|
SP_VTROUGH,
|
|
SP_VBOTTOM,
|
|
|
|
SP_HSMALL,
|
|
SP_HLARGE,
|
|
SP_HLEFT,
|
|
SP_HTROUGH,
|
|
SP_HRIGHT,
|
|
};
|
|
|
|
HSlider::HSlider(bool big, int h)
|
|
{
|
|
this->h = h;
|
|
this->big = big;
|
|
}
|
|
|
|
VSlider::VSlider(bool big, int w)
|
|
{
|
|
this->w = w;
|
|
this->big = big;
|
|
}
|
|
|
|
float HSlider::GetNewValue(int x, int y)
|
|
{
|
|
int x2 = this->x + pad;
|
|
int w2 = this->w - pad - pad;
|
|
if (x <= x2) return min;
|
|
if (x >= x2 + w2) return max;
|
|
return (x - x2) * (max - min) / w2 + min;
|
|
}
|
|
|
|
static void slider_rect(SliderPart part, int x1, int y1, int x2, int y2)
|
|
{
|
|
const float *p = slider_coords[part];
|
|
glTexCoord2f(p[0], p[1]);
|
|
glVertex2f(x1, y1);
|
|
glTexCoord2f(p[0], p[3]);
|
|
glVertex2f(x1, y2);
|
|
glTexCoord2f(p[2], p[3]);
|
|
glVertex2f(x2, y2);
|
|
glTexCoord2f(p[2], p[1]);
|
|
glVertex2f(x2, y1);
|
|
}
|
|
|
|
void HSlider::OnPaint(const PUi *pui) const
|
|
{
|
|
float m = (value - min) / (max - min);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
GLuint t = TEX_SLIDERS;
|
|
int trough_h = pui->h[t] * .25f;
|
|
int my = (h - trough_h) * 0.5f + y;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, pui->tex[t]);
|
|
glBegin(GL_QUADS);
|
|
glColor3f(1.0, 1.0, 1.0);
|
|
slider_rect(SP_HLEFT, x, my, x + trough_cut, my + trough_h);
|
|
slider_rect(SP_HTROUGH, x + trough_cut, my, x + w - trough_cut, my + trough_h);
|
|
slider_rect(SP_HRIGHT, x + w - trough_cut, my, x + w, my + trough_h);
|
|
glEnd();
|
|
|
|
float slider_w = pui->w[t] * .5f;
|
|
float slider_h = pui->h[t] * .25f;
|
|
int x3 = this->x + pad;
|
|
int w3 = this->w - pad - pad;
|
|
my = (h - slider_h) * 0.5f + y;
|
|
int mx = x3 + w3 * m - slider_w * 0.5f;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, pui->tex[t]);
|
|
glBegin(GL_QUADS);
|
|
if (this->colour.a) glColor4f(colour.r, colour.g, colour.b, colour.a);
|
|
slider_rect(big ? SP_HLARGE : SP_HSMALL, mx, my, mx + slider_w, my + slider_h);
|
|
glEnd();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
|
|
float VSlider::GetNewValue(int x, int y)
|
|
{
|
|
int y2 = this->y + pad;
|
|
int h2 = this->h - pad - pad;
|
|
if (y <= y2) return max;
|
|
if (y >= y2 + h2) return min;
|
|
return (y2 + h2 - y) * (max - min) / h2 + min;
|
|
}
|
|
|
|
void VSlider::OnPaint(const PUi *pui) const
|
|
{
|
|
float m = (value - min) / (max - min);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
GLuint t = TEX_SLIDERS;
|
|
int trough_w = pui->w[t] * .25f;
|
|
int mx = (w - trough_w) * 0.5f + x;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, pui->tex[t]);
|
|
glBegin(GL_QUADS);
|
|
glColor3f(1.0, 1.0, 1.0);
|
|
slider_rect(SP_VTOP, mx, y, mx + trough_w, y + trough_cut);
|
|
slider_rect(SP_VTROUGH, mx, y + trough_cut, mx + trough_w, y + h - trough_cut);
|
|
slider_rect(SP_VBOTTOM, mx, y + h - trough_cut, mx + trough_w, y + h);
|
|
glEnd();
|
|
|
|
float slider_w = pui->w[t] * .25f;
|
|
float slider_h = pui->h[t] * .5f;
|
|
int y3 = this->y + pad;
|
|
int h3 = this->h - pad - pad;
|
|
mx = (w - slider_w) * 0.5f + x;
|
|
int my = y3 + h3 - h3 * m - slider_h * 0.5f;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, pui->tex[t]);
|
|
glBegin(GL_QUADS);
|
|
if (this->colour.a) glColor4f(colour.r, colour.g, colour.b, colour.a);
|
|
slider_rect(big ? SP_VLARGE : SP_VSMALL, mx, my, mx + slider_w, my + slider_h);
|
|
glEnd();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
char tmp[128];
|
|
snprintf(tmp, sizeof tmp, "%s", this->label);
|
|
|
|
FTBBox box = pui->font->BBox(tmp);
|
|
FTPoint p = box.Upper() - box.Lower();
|
|
float cx = p.X();
|
|
float cy = p.Y();
|
|
|
|
float ox = -.5f;
|
|
float oy = 0;
|
|
|
|
glPushMatrix();
|
|
// glColor4f(colour.r, colour.g, colour.b, colour.a);
|
|
glTranslatef(x + w * 0.5f, y - 4, 0);
|
|
glScalef(.5f, -.5f, 1);
|
|
glTranslatef(cx * ox, -cy * oy, 0);
|
|
glColor4f(0, 0, 0, 1);
|
|
pui->font->Render(tmp);
|
|
glTranslatef(0, 2, 0);
|
|
glColor4f(1, 1, 1, 1);
|
|
pui->font->Render(tmp);
|
|
glPopMatrix();
|
|
|
|
Widget::OnPaint(pui);
|
|
}
|
|
|