pplugins/pui/knob.cpp

149 lines
3.2 KiB
C++

#include <cmath>
#include <pugl/pugl.h>
#include "pui.h"
float Knob::GetNewValue(int x, int y)
{
int dx = (this->x + this->w / 2) - x;
int dy = (this->y + this->h / 2) - y;
float a = .5f - (atan2(dx, dy) * .5f / M_PI) * 1.33f;
if (a < 0) a = 0;
if (a > 1) a = 1;
return a * (max - min) + min;
}
static void DrawPartial(GLuint t1, GLuint t2, int seg, float x1, float y1, float x2, float y2, float r)
{
float xc = .5f;
float yc = .5f;
if (r >= 0 && r <= .25f) {
float t;
if (r <= .125f) {
t = .5 - tanf((.125f - r) * 2 * M_PI) * .5f;
} else {
t = .5 + tanf((r - .125f) * 2 * M_PI) * .5f;
}
float x, y;
switch (seg) {
default:
case 0: x = x1; y = 1 - t; break;
case 1: x = t; y = y1; break;
case 2: x = x1; y = t; break;
case 3: x = 1 - t; y = y1; break;
}
glBindTexture(GL_TEXTURE_2D, t2);
glBegin(GL_TRIANGLES);
glTexCoord2f(xc, yc);
glVertex2f(xc, yc);
glTexCoord2f(x1, y1);
glVertex2f(x1, y1);
glTexCoord2f(x, y);
glVertex2f(x, y);
glEnd();
glBindTexture(GL_TEXTURE_2D, t1);
glBegin(GL_TRIANGLES);
glTexCoord2f(xc, yc);
glVertex2f(xc, yc);
glTexCoord2f(x, y);
glVertex2f(x, y);
glTexCoord2f(x2, y2);
glVertex2f(x2, y2);
glEnd();
} else {
glBindTexture(GL_TEXTURE_2D, r > 0 ? t2 : t1);
glBegin(GL_TRIANGLES);
glTexCoord2f(xc, yc);
glVertex2f(xc, yc);
glTexCoord2f(x1, y1);
glVertex2f(x1, y1);
glTexCoord2f(x2, y2);
glVertex2f(x2, y2);
glEnd();
}
}
void Knob::OnPaint(const PUi *pui) const
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
float mx = (w - pui->w[TEX_KNOB]) * 0.5f + x;
float my = (h - pui->h[TEX_KNOB]) * 0.5f + y;
float hw = pui->w[TEX_KNOB] * .5f;
float hh = pui->h[TEX_KNOB] * .5f;
glPushMatrix();
glTranslatef(mx, my, 0);
glColor3f(1, 1, 1);
glScalef(pui->w[TEX_KNOB], pui->h[TEX_KNOB], 1);
GLuint t1 = pui->tex[TEX_KNOB];
GLuint t2 = pui->tex[TEX_KNOB_PRE];
float r = (this->value - this->min) / (this->max - this->min) - .5f;
r /= 1.3333f;
r += .5f;
r -= .125f;
DrawPartial(t1, t2, 0, 0, 1, 0, 0, r);
r -= .25f;
DrawPartial(t1, t2, 1, 0, 0, 1, 0, r);
r -= .25f;
DrawPartial(t1, t2, 2, 1, 0, 1, 1, r);
r -= .25f;
DrawPartial(t1, t2, 3, 1, 1, 0, 1, r);
glPopMatrix();
r = (this->value - this->min) / (this->max - this->min) - .5f;
glPushMatrix();
glTranslatef(mx + hw, my + hw, 0);
glRotatef(r * 270, 0, 0, 1);
glBindTexture(GL_TEXTURE_2D, pui->tex[TEX_KNOB_SEL]);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glTexCoord2f(0, 0);
glVertex2f(-hw, -hh);
glTexCoord2f(0, 1);
glVertex2f(-hw, hh);
glTexCoord2f(1, 1);
glVertex2f( hw, hh);
glTexCoord2f(1, 0);
glVertex2f( hw, -hh);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
char tmp[128];
snprintf(tmp, sizeof tmp, "%s: %06d", this->label, (int)(this->value * 44100));
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();
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();
}