#include #include #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(); Widget::OnPaint(pui); }