diff --git a/pui/knob.cpp b/pui/knob.cpp index 6cde78b..33fee73 100644 --- a/pui/knob.cpp +++ b/pui/knob.cpp @@ -1,53 +1,148 @@ +#include #include #include "pui.h" float Knob::GetNewValue(int x, int y) { - int p = 20; - if (false) { - int x2 = this->x + p; - int w2 = this->w - p - p; - if (x <= x2) return min; - if (x >= x2 + w2) return max; - return (x - x2) * (max - min) / w2 + min; + 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 { - int y2 = this->y + p; - int h2 = this->h - p - p; - if (y <= y2) return max; - if (y >= y2 + h2) return min; - return (y2 + h2 - y) * (max - min) / h2 + min; + 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 { -// float m = (value - min) / (max - min); - -// printf("%d\n", tex[TEX_TROUGH1]); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); - int t = TEX_KNOB; - int w2 = pui->w[t]; - int h2 = pui->h[t]; - int mx, my; - mx = (w - w2) * 0.5f + x; - my = (h - h2) * 0.5f + y; + float mx = (w - pui->w[TEX_KNOB]) * 0.5f + x; + float my = (h - pui->h[TEX_KNOB]) * 0.5f + y; - glBindTexture(GL_TEXTURE_2D, pui->tex[t]); + 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, 0.0); - glVertex2f( mx, my); - glTexCoord2f(0.0, 1.0); - glVertex2f( mx, h2 + my); - glTexCoord2f(1.0, 1.0); - glVertex2f(w2 + mx, h2 + my); - glTexCoord2f(1.0, 0.0); - glVertex2f(w2 + mx, my); + 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(); + }