X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/c7f552fd8888da2f0d8cfb228fe0f28d3df3a12c..b4b6f2ea75b9f0f3ca918f5b84016610bf7a4d4f:/interpretor/faust-0.9.47mr3/architecture/gui/faustqt.h diff --git a/interpretor/faust-0.9.47mr3/architecture/gui/faustqt.h b/interpretor/faust-0.9.47mr3/architecture/gui/faustqt.h deleted file mode 100644 index 46aab5b..0000000 --- a/interpretor/faust-0.9.47mr3/architecture/gui/faustqt.h +++ /dev/null @@ -1,1753 +0,0 @@ -/************************************************************************ - ************************************************************************ - FAUST Architecture File - Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale - --------------------------------------------------------------------- - This Architecture section is free software; you can redistribute it - and/or modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 3 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; If not, see . - - ************************************************************************ - ************************************************************************/ -#ifndef __faustqt__ -#define __faustqt__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "GUI.h" - -//---------------------------------- - -// for compatibility -#define minValue minimum -#define maxValue maximum - - -using namespace std; - - -//==============================BEGIN QSYNTHKNOB===================================== -// -// qsynthknob and qsynthDialVokiStyle borrowed from qsynth-0.3.3 by Rui Nuno Capela -// This widget is based on a design by Thorsten Wilms, -// implemented by Chris Cannam in Rosegarden, -// adapted for QSynth by Pedro Lopez-Cabanillas, -// improved for Qt4 by David Garcia Garzon. -// - -#define DIAL_MIN (0.25 * M_PI) -#define DIAL_MAX (1.75 * M_PI) -#define DIAL_RANGE (DIAL_MAX - DIAL_MIN) - -class qsynthDialVokiStyle : public QCommonStyle -{ -public: - qsynthDialVokiStyle() {}; - virtual ~qsynthDialVokiStyle() {}; - - virtual void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget = 0) const - { - if (cc != QStyle::CC_Dial) - { - QCommonStyle::drawComplexControl(cc, opt, p, widget); - return; - } - - const QStyleOptionSlider *dial = qstyleoption_cast(opt); - if (dial == NULL) - return; - - double angle = DIAL_MIN // offset - + (DIAL_RANGE * - (double(dial->sliderValue - dial->minimum) / - (double(dial->maximum - dial->minimum)))); - int degrees = int(angle * 180.0 / M_PI); - int side = dial->rect.width() < dial->rect.height() ? dial->rect.width() : dial->rect.height(); - int xcenter = dial->rect.width() / 2; - int ycenter = dial->rect.height() / 2; - int notchWidth = 1 + side / 400; - int pointerWidth = 2 + side / 30; - int scaleShadowWidth = 1 + side / 100; - int knobBorderWidth = 0; - int ns = dial->tickInterval; - int numTicks = 1 + (dial->maximum + ns - dial->minimum) / ns; - int indent = int(0.15 * side) + 2; - int knobWidth = side - 2 * indent; - int shineFocus = knobWidth / 4; - int shineCenter = knobWidth / 5; - int shineExtension = shineCenter * 4; - int shadowShift = shineCenter * 2; - int meterWidth = side - 2 * scaleShadowWidth; - - QPalette pal = opt->palette; - QColor knobColor = pal.mid().color(); - QColor borderColor = knobColor.light(); - QColor meterColor = (dial->state & State_Enabled) ? - QColor("orange") : pal.mid().color(); - // pal.highlight().color() : pal.mid().color(); - QColor background = pal.window().color(); - - p->save(); - p->setRenderHint(QPainter::Antialiasing, true); - - // The bright metering bit... - - QConicalGradient meterShadow(xcenter, ycenter, -90); - meterShadow.setColorAt(0, meterColor.dark()); - meterShadow.setColorAt(0.5, meterColor); - meterShadow.setColorAt(1.0, meterColor.light().light()); - p->setBrush(meterShadow); - p->setPen(Qt::transparent); - p->drawPie(xcenter - meterWidth / 2, ycenter - meterWidth / 2, - meterWidth, meterWidth, (180 + 45) * 16, -(degrees - 45) * 16); - - // Knob projected shadow - QRadialGradient projectionGradient( - xcenter + shineCenter, ycenter + shineCenter, - shineExtension, xcenter + shadowShift, ycenter + shadowShift); - projectionGradient.setColorAt(0, QColor( 0, 0, 0, 100)); - projectionGradient.setColorAt(1, QColor(200, 0, 0, 10)); - QBrush shadowBrush(projectionGradient); - p->setBrush(shadowBrush); - p->drawEllipse(xcenter - shadowShift, ycenter - shadowShift, - knobWidth, knobWidth); - - // Knob body and face... - - QPen pen; - pen.setColor(knobColor); - pen.setWidth(knobBorderWidth); - p->setPen(pen); - - QRadialGradient gradient( - xcenter - shineCenter, ycenter - shineCenter, - shineExtension, xcenter - shineFocus, ycenter - shineFocus); - gradient.setColorAt(0.2, knobColor.light().light()); - gradient.setColorAt(0.5, knobColor); - gradient.setColorAt(1.0, knobColor.dark(150)); - QBrush knobBrush(gradient); - p->setBrush(knobBrush); - p->drawEllipse(xcenter - knobWidth / 2, ycenter - knobWidth / 2, - knobWidth, knobWidth); - - // Tick notches... - - p->setBrush(Qt::NoBrush); - - if (dial->subControls & QStyle::SC_DialTickmarks) - { - pen.setColor(pal.dark().color()); - pen.setWidth(notchWidth); - p->setPen(pen); - double hyp = double(side - scaleShadowWidth) / 2.0; - double len = hyp / 4; - for (int i = 0; i < numTicks; ++i) { - int div = numTicks; - if (div > 1) --div; - bool internal = (i != 0 && i != numTicks - 1); - double angle = DIAL_MIN - + (DIAL_MAX - DIAL_MIN) * i / div; - double dir = (internal ? -1 : len); - double sinAngle = sin(angle); - double cosAngle = cos(angle); - double x0 = xcenter - (hyp - len) * sinAngle; - double y0 = ycenter + (hyp - len) * cosAngle; - double x1 = xcenter - (hyp + dir) * sinAngle; - double y1 = ycenter + (hyp + dir) * cosAngle; - p->drawLine(QLineF(x0, y0, x1, y1)); - } - } - - // Shadowing... - - // Knob shadow... - if (knobBorderWidth > 0) { - QLinearGradient inShadow(xcenter - side / 4, ycenter - side / 4, - xcenter + side / 4, ycenter + side / 4); - inShadow.setColorAt(0.0, borderColor.light()); - inShadow.setColorAt(1.0, borderColor.dark()); - p->setPen(QPen(QBrush(inShadow), knobBorderWidth * 7 / 8)); - p->drawEllipse(xcenter - side / 2 + indent, - ycenter - side / 2 + indent, - side - 2 * indent, side - 2 * indent); - } - - // Scale shadow... - QLinearGradient outShadow(xcenter - side / 3, ycenter - side / 3, - xcenter + side / 3, ycenter + side / 3); - outShadow.setColorAt(0.0, background.dark().dark()); - outShadow.setColorAt(1.0, background.light().light()); - p->setPen(QPen(QBrush(outShadow), scaleShadowWidth)); - p->drawArc(xcenter - side / 2 + scaleShadowWidth / 2, - ycenter - side / 2 + scaleShadowWidth / 2, - side - scaleShadowWidth, side - scaleShadowWidth, -45 * 16, 270 * 16); - - // Pointer notch... - - double hyp = double(side) / 2.0; - double len = hyp - indent - 1; - - double x = xcenter - len * sin(angle); - double y = ycenter + len * cos(angle); - - QColor pointerColor = pal.dark().color(); - pen.setColor((dial->state & State_Enabled) ? pointerColor.dark(140) : pointerColor); - pen.setWidth(pointerWidth + 2); - p->setPen(pen); - p->drawLine(QLineF(xcenter, ycenter, x, y)); - pen.setColor((dial->state & State_Enabled) ? pointerColor.light() : pointerColor.light(140)); - pen.setWidth(pointerWidth); - p->setPen(pen); - p->drawLine(QLineF(xcenter - 1, ycenter - 1, x - 1, y - 1)); - - // done - p->restore(); - } - -}; -// -//===============================END QSYNTHKNOB====================================== - - -//==============================BEGIN DISPLAYS=================================== -// -// This section constains displays, passive QT widgets that displays values in -// different ways, in particular bargraphs -// - -/** - * An abstract widget that display a value in a range - */ -class AbstractDisplay : public QWidget -{ - protected : - float fMin; - float fMax; - float fValue; - - public: - - AbstractDisplay (float lo, float hi) : fMin(lo), fMax(hi), fValue(lo) - { - } - - /** - * set the range of displayed values - */ - virtual void setRange(float lo, float hi) - { - fMin = lo; - fMax = hi; - } - - /** - * set the value to be displayed - */ - virtual void setValue(float v) - { - if (v < fMin) v = fMin; - else if (v > fMax) v = fMax; - - if (v != fValue) { - fValue = v; - update(); - } - } -}; - - -/** - * Displays dB values using a scale of colors - */ -class dbAbstractDisplay : public AbstractDisplay -{ - protected : - - float fScaleMin; - float fScaleMax; - vector fLevel; - vector fBrush; - - - /** - * Convert a dB value into a scale between 0 and 1 (following IEC standard ?) - */ - float dB2Scale ( float dB ) const - { - float fScale = 1.0f; - - /*if (dB < -70.0f) - fScale = 0.0f; - else*/ if (dB < -60.0f) - fScale = (dB + 70.0f) * 0.0025f; - else if (dB < -50.0f) - fScale = (dB + 60.0f) * 0.005f + 0.025f; - else if (dB < -40.0) - fScale = (dB + 50.0f) * 0.0075f + 0.075f; - else if (dB < -30.0f) - fScale = (dB + 40.0f) * 0.015f + 0.15f; - else if (dB < -20.0f) - fScale = (dB + 30.0f) * 0.02f + 0.3f; - else if (dB < -0.001f || dB > 0.001f) /* if (dB < 0.0f) */ - fScale = (dB + 20.0f) * 0.025f + 0.5f; - - return fScale; - } - - - /** - * Create the scale of colors used to paint the bargraph in relation to the levels - * The parameter x indicates the direction of the gradient. x=1 means an horizontal - * gradient typically used by a vertical bargraph, and x=0 a vertical gradient. - */ - void initLevelsColors(int x) - { - int alpha = 200; - { // level until -10 dB - QColor c(40, 160, 40, alpha); - QLinearGradient g(0,0,x,1-x); - g.setCoordinateMode(QGradient::ObjectBoundingMode); - g.setColorAt(0.0, c.lighter()); - g.setColorAt(0.2, c); - g.setColorAt(0.8, c); - g.setColorAt(0.9, c.darker(120)); - - fLevel.push_back(-10); - fBrush.push_back(QBrush(g)); - } - - { // level until -6 dB - QColor c(160, 220, 20, alpha); - QLinearGradient g(0,0,x,1-x); - g.setCoordinateMode(QGradient::ObjectBoundingMode); - g.setColorAt(0.0, c.lighter()); - g.setColorAt(0.2, c); - g.setColorAt(0.8, c); - g.setColorAt(0.9, c.darker(120)); - - fLevel.push_back(-6); - fBrush.push_back(QBrush(g)); - } - - { // level until -3 dB - QColor c(220, 220, 20, alpha); - QLinearGradient g(0,0,x,1-x); - g.setCoordinateMode(QGradient::ObjectBoundingMode); - g.setColorAt(0.0, c.lighter()); - g.setColorAt(0.2, c); - g.setColorAt(0.8, c); - g.setColorAt(0.9, c.darker(120)); - - fLevel.push_back(-3); - fBrush.push_back(QBrush(g)); - } - - { // level until -0 dB - QColor c(240, 160, 20, alpha); - QLinearGradient g(0,0,x,1-x); - g.setCoordinateMode(QGradient::ObjectBoundingMode); - g.setColorAt(0.0, c.lighter()); - g.setColorAt(0.2, c); - g.setColorAt(0.8, c); - g.setColorAt(0.9, c.darker(120)); - - fLevel.push_back(0); - fBrush.push_back(QBrush(g)); - } - - { // until 10 dB (and over because last one) - QColor c(240, 0, 20, alpha); // ColorOver - QLinearGradient g(0,0,x,1-x); - g.setCoordinateMode(QGradient::ObjectBoundingMode); - g.setColorAt(0.0, c.lighter()); - g.setColorAt(0.2, c); - g.setColorAt(0.8, c); - g.setColorAt(0.9, c.darker(120)); - - fLevel.push_back(+10); - fBrush.push_back(QBrush(g)); - } - - } - - public: - - dbAbstractDisplay(float lo, float hi) : AbstractDisplay(lo,hi) - { - } - - /** - * set the range of displayed values - */ - virtual void setRange(float lo, float hi) - { - AbstractDisplay::setRange(lo, hi); - fScaleMin = dB2Scale(fMin); - fScaleMax = dB2Scale(fMax); - } -}; - - -/** - * Small rectangular LED display which color changes with the level in dB - */ -class dbLED : public dbAbstractDisplay -{ - protected: - - /** - * Draw the LED using a color depending of its value in dB - */ - virtual void paintEvent ( QPaintEvent *) - { - QPainter painter(this); - painter.drawRect(rect()); - - if (fValue <= fLevel[0]) { - - // interpolate the first color on the alpha channel - QColor c(40, 160, 40) ; - float a = (fValue-fMin)/(fLevel[0]-fMin); - c.setAlphaF(a); - painter.fillRect(rect(), c); - - } else { - - // find the minimal level > value - int l = fLevel.size()-1; while (fValue < fLevel[l] && l > 0) l--; - painter.fillRect(rect(), fBrush[l]); - } - } - - public: - - dbLED(float lo, float hi) : dbAbstractDisplay(lo,hi) - { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - initLevelsColors(1); - } - - virtual QSize sizeHint () const - { - return QSize(16, 8); - } -}; -/** - * Small rectangular LED display which intensity (alpha channel) changes according to the value - */ -class LED : public AbstractDisplay -{ - QColor fColor; - - protected: - - /** - * Draw the LED using a transparency depending of its value - */ - virtual void paintEvent ( QPaintEvent *) - { - QPainter painter(this); - painter.drawRect(rect()); - // interpolate the first color on the alpha channel - QColor c = fColor ; - float a = (fValue-fMin)/(fMax-fMin); - c.setAlphaF(a); - painter.fillRect(rect(), c); - } - - public: - - LED(float lo, float hi) : AbstractDisplay(lo,hi), fColor("yellow") - { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - } - - virtual QSize sizeHint () const - { - return QSize(16, 8); - } -}; - - - -/** - * A simple bargraph that detect automatically its direction - */ -class linBargraph : public AbstractDisplay -{ - protected : - QBrush fBrush; - - /** - * No scale implemented yet - */ - void paintScale(QPainter* painter) const - { - painter->drawRect(0,0,width(),height()); - } - - /** - * The length of the rectangle is proportional to the value - */ - void paintContent (QPainter* painter) const - { - int w = width(); - int h = height(); - float v = (fValue-fMin)/(fMax-fMin); - - if (h>w) { - // draw vertical rectangle - painter->fillRect(0,(1-v)*h,w, v*h, fBrush); - } else { - // draw horizontal rectangle - painter->fillRect(0, 0, h, v*w, fBrush); - } - - } - - virtual void paintEvent ( QPaintEvent *) - { - QPainter painter(this); - paintContent(&painter); - paintScale(&painter); - } - - public: - - linBargraph(float lo, float hi) : AbstractDisplay(lo,hi) - { - // compute the brush that will be used to - // paint the value - QColor c(0xffa500); // orange - int x = int(height() < width()); // gradient direction - QLinearGradient g(0,0,x,1-x); - g.setCoordinateMode(QGradient::ObjectBoundingMode); - g.setColorAt(0.0, c.lighter()); - g.setColorAt(0.2, c); - g.setColorAt(0.8, c); - g.setColorAt(0.9, c.darker(120)); - fBrush = QBrush(g); - } -}; - - -/** - * A simple vertical bargraph - */ -class linVerticalBargraph : public linBargraph -{ - public: - - linVerticalBargraph(float lo, float hi) : linBargraph(lo,hi) - { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - } - - virtual QSize sizeHint () const - { - return QSize(16, 128); - } -}; - - - -/** - * A simple horizontal bargraph - */ -class linHorizontalBargraph : public linBargraph -{ - public: - - linHorizontalBargraph(float lo, float hi) : linBargraph(lo,hi) - { - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - } - - virtual QSize sizeHint () const - { - return QSize(128, 16); - } -}; - - - - -/** - * A dB Bargraph with a scale of colors - */ -class dbBargraph : public dbAbstractDisplay -{ - QBrush fBackColor; - - protected : - - // These two abstract methods are implemented - // according to the vertical or horizontal direction - // in dbVerticalBargraph and dbHorizontalBargraph - virtual void paintMark(QPainter* painter, float v) const = 0; - virtual int paintSegment (QPainter* painter, int pos, float v, const QBrush& b) const = 0; - - /** - * Draw the logarithmic scale - */ - void paintScale(QPainter* painter) const - { - painter->fillRect(0,0,width(),height(), fBackColor); - painter->save(); - painter->setPen(QColor(0x6699aa)); //0xffa500)); - for (float v = -10; v > fMin; v -= 10) paintMark(painter, v); - for (float v = -6; v < fMax; v += 3) paintMark(painter, v); - painter->restore(); - } - - - /** - * Draw the content using colored segments - */ - void paintContent (QPainter* painter) const - { - int l = fLevel.size(); - - float p = -1; // fake value indicates to start from border - int n = 0; - // paint all the full segments < fValue - for (n=0; (n < l) && (fValue > fLevel[n]); n++) { - p = paintSegment(painter, p, fLevel[n], fBrush[n]); - } - // paint the last segment - if (n == l) n = n-1; - p=paintSegment(painter, p, fValue, fBrush[n]); - - painter->drawRect(0,0,width(),height()); - } - - - virtual void paintEvent ( QPaintEvent *) - { - QPainter painter(this); - paintScale(&painter); - paintContent(&painter); - } - - public: - - dbBargraph(float lo, float hi) : dbAbstractDisplay(lo,hi) - { - - QFont f = this->font(); - f.setPointSize(6); - this->setFont(f); - - fBackColor = QBrush(QColor(20,20,20)); - } -}; - - -/** - * Vertical dB Bargraph - */ -class dbVerticalBargraph : public dbBargraph -{ - protected: - /** - * Convert a dB value into a vertical position - */ - float dB2y (float dB) const - { - float s0 = fScaleMin; - float s1 = fScaleMax; - float sx = dB2Scale(dB); - int h = height(); - - return h - h*(s0-sx)/(s0-s1); - } - - /** - * Paint a vertical graduation mark - */ - virtual void paintMark(QPainter* painter, float v) const - { - int n = 10; - int y = dB2y(v); - QRect r(0,y-n,width()-1,2*n); - if (v > 0.0) { - painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v).prepend('+')); - } else { - painter->drawText(r, Qt::AlignRight|Qt::AlignVCenter, QString::number(v)); - } - } - - /** - * Paint a color segment - */ - virtual int paintSegment (QPainter* painter, int pos, float v, const QBrush& b) const - { - if (pos == -1) pos = height(); - float y = dB2y(v); - painter->fillRect(0, y, width(), pos-y+1, b); - return y; - } - - - public: - - dbVerticalBargraph(float lo, float hi) : dbBargraph(lo,hi) - { - setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - initLevelsColors(1); - } - - virtual QSize sizeHint () const - { - return QSize(18, 256); - } -}; - -/** - * Horizontal dB Bargraph - */ -class dbHorizontalBargraph : public dbBargraph -{ - - protected: - - /** - * Convert a dB value into an horizontal position - */ - float dB2x (float dB) const - { - float s0 = fScaleMin; - float s1 = fScaleMax; - float sx = dB2Scale(dB); - int w = width(); - - return w - w*(s1-sx)/(s1-s0); - } - - /** - * Paint an horizontal graduation mark - */ - void paintMark(QPainter* painter, float v) const - { - int n = 10; - int x = dB2x(v); - QRect r(x-n,0,2*n, height()); - painter->drawText(r, Qt::AlignHCenter|Qt::AlignVCenter, QString::number(v)); - } - - /** - * Paint a horizontal color segment - */ - int paintSegment (QPainter* painter, int pos, float v, const QBrush& b) const - { - if (pos == -1) pos = 0; - float x = dB2x(v); - painter->fillRect(pos, 0, x-pos, height(), b); - return x; - } - - - public: - - dbHorizontalBargraph(float lo, float hi) : dbBargraph(lo,hi) - { - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - initLevelsColors(0); - } - - virtual QSize sizeHint () const - { - return QSize(256, 18); - } - -}; - -// -//===============================END DISPLAYS==================================== - -//============================= BEGIN GROUP LABEL METADATA=========================== -// Unlike widget's label, metadata inside group's label are not extracted directly by -// the Faust compiler. Therefore they must be extracted within the architecture file -//----------------------------------------------------------------------------------- -// - -/** - * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string - * (but not those in the middle of the string) - */ -static string rmWhiteSpaces(const string& s) -{ - size_t i = s.find_first_not_of(" \t"); - size_t j = s.find_last_not_of(" \t"); - if ( (i != string::npos) && (j != string::npos) ) { - return s.substr(i, 1+j-i); - } else { - return ""; - } -} - -/** - * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata(unit=dB) - */ -static void extractMetadata(const string& fulllabel, string& label, map& metadata) -{ - enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue}; - int state = kLabel; int deep = 0; - string key, value; - - for (unsigned int i=0; i < fulllabel.size(); i++) { - char c = fulllabel[i]; - switch (state) { - case kLabel : - assert (deep == 0); - switch (c) { - case '\\' : state = kEscape1; break; - case '[' : state = kKey; deep++; break; - default : label += c; - } - break; - - case kEscape1 : - label += c; - state = kLabel; - break; - - case kEscape2 : - key += c; - state = kKey; - break; - - case kEscape3 : - value += c; - state = kValue; - break; - - case kKey : - assert (deep > 0); - switch (c) { - case '\\' : state = kEscape2; - break; - - case '[' : deep++; - key += c; - break; - - case ':' : if (deep == 1) { - state = kValue; - } else { - key += c; - } - break; - case ']' : deep--; - if (deep < 1) { - metadata[rmWhiteSpaces(key)] = ""; - state = kLabel; - key=""; - value=""; - } else { - key += c; - } - break; - default : key += c; - } - break; - - case kValue : - assert (deep > 0); - switch (c) { - case '\\' : state = kEscape3; - break; - - case '[' : deep++; - value += c; - break; - - case ']' : deep--; - if (deep < 1) { - metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value); - state = kLabel; - key=""; - value=""; - } else { - value += c; - } - break; - default : value += c; - } - break; - - default : - cerr << "ERROR unrecognized state " << state << endl; - } - } - label = rmWhiteSpaces(label); -} -// -//============================= END GROUP LABEL METADATA=========================== - - -/****************************************************************************** -******************************************************************************* - - IMPLEMENTATION OF GUI ITEMS - (QT 4.3 for FAUST) - -******************************************************************************* -*******************************************************************************/ - - -class uiButton : public QObject, public uiItem -{ - Q_OBJECT - - public : - QAbstractButton* fButton; - - uiButton (GUI* ui, float* zone, QAbstractButton* b) : uiItem(ui, zone), fButton(b) {} - - - virtual void reflectZone() - { - float v = *fZone; - fCache = v; - fButton->setDown( v > 0.0 ); - } - - public slots : - void pressed() { modifyZone(1.0); } - void released() { modifyZone(0.0); } -}; - - -class uiCheckButton : public QObject, public uiItem -{ - Q_OBJECT - - public : - QCheckBox* fCheckBox; - - uiCheckButton (GUI* ui, float* zone, QCheckBox* b) : uiItem(ui, zone), fCheckBox(b) {} - - virtual void reflectZone() - { - float v = *fZone; - fCache = v; - fCheckBox->setCheckState( (v < 0.5) ? Qt::Unchecked : Qt::Checked ); - } - - public slots : - void setState(int v) { modifyZone(float(v>0)); } -}; - - -class uiSlider : public QObject, public uiItem -{ - Q_OBJECT - - int faust2qt(float x) { return int(0.5 + (x-fMin)/fStep); } - float qt2faust (int v) { return fMin + v*fStep; } - int optimalTick() { - float x=fStep; - while((fMax-fMin)/x > 50) x*=10; - while((fMax-fMin)/x < 10) x/=2; - return faust2qt(fMin+x); - } - - public : - QSlider* fSlider; - float fCur; - float fMin; - float fMax; - float fStep; - - uiSlider (GUI* ui, float* zone, QSlider* slider, float cur, float lo, float hi, float step) - : uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step) - { - fSlider->setMinimum(0); - fSlider->setMaximum(faust2qt(fMax)); - fSlider->setValue(faust2qt(fCur)); - fSlider->setTickInterval(optimalTick()); - *fZone = fCur; - } - - virtual void reflectZone() - { - float v = *fZone; - fCache = v; - fSlider->setValue(faust2qt(v)); - } - - public slots : - void setValue(int v) { modifyZone(qt2faust(v)); } -}; - - -class uiKnob : public QObject, public uiItem -{ - Q_OBJECT - - int faust2qt(float x) { return int(0.5 + (x-fMin)/fStep); } - float qt2faust (int v) { return fMin + v*fStep; } - int optimalTick() { - float x=fStep; - while((fMax-fMin)/x > 50) x*=10; - while((fMax-fMin)/x < 10) x/=2; - return faust2qt(fMin+x); - } - - public : - QAbstractSlider* fSlider; - float fCur; - float fMin; - float fMax; - float fStep; - - uiKnob (GUI* ui, float* zone, QAbstractSlider* slider, float cur, float lo, float hi, float step) - : uiItem(ui, zone), fSlider(slider), fCur(cur), fMin(lo), fMax(hi), fStep(step) - { - fSlider->setMinimum(0); - fSlider->setMaximum(faust2qt(fMax)); - fSlider->setValue(faust2qt(fCur)); - //fSlider->setTickInterval(optimalTick()); - *fZone = fCur; - } - - virtual void reflectZone() - { - float v = *fZone; - fCache = v; - fSlider->setValue(faust2qt(v)); - } - - public slots : - void setValue(int v) { modifyZone(qt2faust(v)); } -}; - - -class uiBargraph : public QObject, public uiItem -{ - Q_OBJECT - - int faust2qt(float x) { return int(0.5 + (x-fMin)/(fMax-fMin)*fStep); } - - public : - QProgressBar* fBar; - float fMin; - float fMax; - int fStep; - - uiBargraph (GUI* ui, float* zone, QProgressBar* bar, float lo, float hi) - : uiItem(ui, zone), fBar(bar), fMin(lo), fMax(hi), fStep(1024) - { - fBar->setRange(0, fStep); - fBar->setValue(0); - *fZone = 0; - } - - virtual void reflectZone() - { - float v = *fZone; - fCache = v; - int x = faust2qt(v); - //std::cout << "update *" << fBar << " = " << x << std::endl; - fBar->setValue(x); - } -}; - - -class uiBargraph2 : public QObject, public uiItem -{ - Q_OBJECT - - public : - AbstractDisplay* fBar; - - uiBargraph2 (GUI* ui, float* zone, AbstractDisplay* bar, float lo, float hi) - : uiItem(ui, zone), fBar(bar) - { - fBar->setRange(lo, hi); - fBar->setValue(lo); - *fZone = lo; - } - - virtual void reflectZone() - { - float v = *fZone; - fCache = v; - fBar->setValue(v); - } -}; - - - -class uiNumEntry : public QObject, public uiItem -{ - Q_OBJECT - - public : - QDoubleSpinBox* fNumEntry; - float fCur; - float fMin; - float fMax; - float fStep; - int fDecimals; - - uiNumEntry (GUI* ui, float* zone, QDoubleSpinBox* numEntry, float cur, float lo, float hi, float step) - : uiItem(ui, zone), fNumEntry(numEntry), fCur(cur), fMin(lo), fMax(hi), fStep(step) - { - fDecimals = (fStep >= 1.0) ? 0 : int(0.5+log10(1.0/fStep)); - - fNumEntry->setMinimum(fMin); - fNumEntry->setMaximum(fMax); - fNumEntry->setSingleStep(fStep); - fNumEntry->setDecimals(fDecimals); - fNumEntry->setValue(fCur); - *fZone = fCur; - } - - - virtual void reflectZone() - { - float v = *fZone; - fCache = v; - fNumEntry->setValue(v); - } - - public slots : - void setValue(double v) { - modifyZone(float(v)); - } -}; - - - - -/****************************************************************************** -******************************************************************************* - - IMPLEMENTATION OF THE USER INTERFACE - (QT 4.3 for FAUST) - -******************************************************************************* -*******************************************************************************/ - - -class QTGUI : public QObject, public GUI -{ - Q_OBJECT - QApplication fAppl; - QTimer* fTimer; - QStyle* fStyle; - string gGroupTooltip; - stack fGroupStack; - - map fGuiSize; // map widget zone with widget size coef - map fTooltip; // map widget zone with tooltip strings - map fUnit; // map widget zone to unit string (i.e. "dB") - set fKnobSet; // set of widget zone to be knobs - set fLedSet; // set of widget zone to be LEDs - - - /** - * Format tooltip string by replacing some white spaces by - * return characters so that line width doesn't exceed n. - * Limitation : long words exceeding n are not cut - */ - virtual string formatTooltip(int n, const string& tt) - { - string ss = tt; // ss string we are going to format - int lws = 0; // last white space encountered - int lri = 0; // last return inserted - for (int i=0; i< (int)tt.size(); i++) { - if (tt[i] == ' ') lws = i; - if (((i-lri) >= n) && (lws > lri)) { - // insert return here - ss[lws] = '\n'; - lri = lws; - } - } - return ss; - } - - - /** - * Analyses the widget zone metadata declarations and takes - * appropriate actions - */ - virtual void declare(float* zone, const char* key, const char* value) - { - if (zone == 0) { - // special zone 0 means group metadata - if (strcmp(key,"tooltip")==0) { - // only group tooltip are currently implemented - gGroupTooltip = formatTooltip(30, value); - } - } else { - if (strcmp(key,"size")==0) { - fGuiSize[zone]=atof(value); - } - else if (strcmp(key,"tooltip")==0) { - fTooltip[zone] = formatTooltip(30, value) ; - } - else if (strcmp(key,"unit")==0) { - fUnit[zone] = value ; - } - else if (strcmp(key,"style")==0) { - // else if ((strcmp(key,"style")==0) || (strcmp(key,"type")==0)) { - if (strcmp(value,"knob") == 0) { - fKnobSet.insert(zone); - } else if (strcmp(value,"led") == 0) { - fLedSet.insert(zone); - } - } - } - } - - bool isTabContext() - { - return fGroupStack.empty() || ((!fGroupStack.empty()) && (dynamic_cast(fGroupStack.top()) != 0)); - } - - void insert(const char* label, QWidget* widget) - { - if (fStyle) widget->setStyle(fStyle); - if (!fGroupStack.empty()) { - QWidget* mother = fGroupStack.top(); - QTabWidget* tab = dynamic_cast(mother); - if (tab) { - tab->addTab(widget,label); - } else { - widget->setParent(mother); - mother->layout()->addWidget(widget); - } - } - } - - /** - * Analyses a full label and activates the relevant options. returns a simplified - * label (without options) and an amount of stack adjustement (in case additional - * containers were pushed on the stack). - */ - - int checkLabelOptions(QWidget* widget, const string& fullLabel, string& simplifiedLabel) - { - map metadata; - extractMetadata(fullLabel, simplifiedLabel, metadata); - - if (metadata.count("tooltip")) { - widget->setToolTip(metadata["tooltip"].c_str()); - } - if (metadata["option"] == "detachable") { - //openHandleBox(simplifiedLabel.c_str()); - return 1; - } - - // no adjustement of the stack needed - return 0; - } - - /** - * Check if a tooltip is associated to a zone and add it to the corresponding widget - */ - void checkForTooltip(float* zone, QWidget* widget) - { - if (fTooltip.count(zone)) { - widget->setToolTip(fTooltip[zone].c_str()); - } - } - - /** - * Check if a knob is required - */ - bool isKnob(float* zone) - { - return fKnobSet.count(zone) > 0; - } - - void openBox(const char* fulllabel, QLayout* layout) - { - map metadata; - string label; - extractMetadata(fulllabel, label, metadata); - layout->setMargin(5); - QWidget* box; - - if (isTabContext()) { - box = new QWidget(); - // set background color - QPalette pal = box->palette(); - pal.setColor(box->backgroundRole(), QColor::fromRgb(150, 150, 150) ); - box->setPalette(pal); - - } else if (label.size()>0) { - QGroupBox* group = new QGroupBox(); - group->setTitle(label.c_str()); - box = group; - } else { - // no label here we use simple widget - layout->setMargin(0); - box = new QWidget(); - } - - box->setLayout(layout); -/* if (metadata.count("tooltip")) { - box->setToolTip(metadata["tooltip"].c_str()); - }*/ - if (gGroupTooltip != string()) { - box->setToolTip(gGroupTooltip.c_str()); - gGroupTooltip = string(); - } - insert(label.c_str(), box); - fGroupStack.push(box); - } - - void openTab(const char* label) - { - QTabWidget* group = new QTabWidget(); - if (fStyle) group->setStyle(fStyle); - insert(label, group); - fGroupStack.push(group); - } - - - public slots : - void update() { - //std::cout << '.' << std::endl; - updateAllZones(); - } - - public: - - QTGUI(int argc, char* argv[], QStyle* style = 0) : fAppl(argc, argv), fTimer(0), fStyle(style){ - //fGroupStack.push(new QMainWindow()); - } - - virtual ~QTGUI() {} - - virtual void run() - { - if (fTimer == 0) { - fTimer = new QTimer(this); - QObject::connect(fTimer, SIGNAL(timeout()), this, SLOT(update())); - fTimer->start(100); - } -#if 1 - fAppl.setStyleSheet( - -// BUTTONS - "QPushButton {" - "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1," - "stop: 0 #B0B0B0, stop: 1 #404040);" - "border: 2px solid grey;" - "border-radius: 6px;" - "margin-top: 1ex;" - "}" - - "QPushButton:hover {" - "border: 2px solid orange;" - "}" - - "QPushButton:pressed {" - //"border: 1px solid orange;" - "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," - "stop: 0 #404040, stop: 1 #B0B0B0);" - "}" -// GROUPS - "QGroupBox {" - "background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1," - "stop: 0 #A0A0A0, stop: 1 #202020);" - "border: 2px solid gray;" - "border-radius: 5px;" - "margin-top: 1ex;" - "font-size:7pt;" - "font-weight:bold;" - //"color: dark grey;" - "color: white;" - "}" - - "QGroupBox::title {" - "subcontrol-origin: margin;" - "subcontrol-position: top center;" /* position at the top center */ - "padding: 0 5px;" - "}" -// SLIDERS - // horizontal sliders - "QSlider::groove:vertical {" - "background: red;" - "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */ - "left: 13px; right: 13px;" - "}" - - "QSlider::handle:vertical {" - "height: 40px;" - "width: 30px;" - "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," - "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);" - "margin: 0 -5px; /* expand outside the groove */" - "border-radius: 5px;" - "}" - - "QSlider::add-page:vertical {" - "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," - "stop: 0 yellow, stop : 0.5 orange);" - "}" - - "QSlider::sub-page:vertical {" - "background: grey;" - "}" - - // horizontal sliders - - "QSlider::groove:horizontal {" - "background: red;" - "position: absolute;" /* absolutely position 4px from the left and right of the widget. setting margins on the widget should work too... */ - "top: 14px; bottom: 14px;" - "}" - - "QSlider::handle:horizontal {" - "width: 40px;" - "background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0," - "stop: 0 #AAAAAA, stop : 0.05 #0A0A0A, stop: 0.3 #101010, stop : 0.90 #AAAAAA, stop: 0.91 #000000);" - "margin: -5px 0; /* expand outside the groove */" - "border-radius: 5px;" - "}" - - "QSlider::sub-page:horizontal {" - "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," - "stop: 0 yellow, stop : 0.5 orange);" - "}" - - "QSlider::add-page:horizontal {" - "background: grey;" - "}" - -// TABS - //TabWidget and TabBar - "QTabWidget::pane {" /* The tab widget frame */ - //"border-top: 2px solid #C2C7CB;" - "border-top: 2px solid orange;" - "background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," - "stop: 0 #A0A0A0, stop: 1 #202020);" - "}" - - "QTabWidget::tab-bar {" - "left: 5px;" /* move to the right by 5px */ - "}" - - /* Style the tab using the tab sub-control. Note that - it reads QTabBar _not_ QTabWidget */ - "QTabBar::tab {" - "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," - "stop: 0 #909090, stop: 0.4 #888888," - "stop: 0.5 #808080, stop: 1.0 #909090);" - "border: 2px solid #808080;" - //"border-bottom-color: #C2C7CB;" /* same as the pane color */ - "border-bottom-color: orange;" /* same as the pane color */ - "border-top-left-radius: 4px;" - "border-top-right-radius: 4px;" - "min-width: 8ex;" - "padding: 2px;" - "}" - - "QTabBar::tab:selected, QTabBar::tab:hover {" - "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," - "stop: 0 #D0D0D0, stop: 0.4 #A0A0A0," - "stop: 0.5 #808080, stop: 1.0 #A0A0A0);" - //"stop: 0.5 #A0A0A0, stop: 1.0 #C0C0C0);" - //"stop: 0 #fafafa, stop: 0.4 #f4f4f4," - //"stop: 0.5 #e7e7e7, stop: 1.0 #fafafa);" - //"border-bottom-color: orange;" /* same as the pane color */ - "}" - - "QTabBar::tab:selected {" - "border-color: orange;" - "border-bottom-color: #A0A0A0;" /* same as pane color */ - "}" - - "QTabBar::tab:!selected {" - " margin-top: 2px;" /* make non-selected tabs look smaller */ - "}" - ); -#endif - fAppl.exec(); - stop(); - - } - - - // ------------------------- Groups ----------------------------------- - - virtual void openHorizontalBox(const char* label) { - openBox(label, new QHBoxLayout()); - } - - virtual void openVerticalBox(const char* label) { - openBox(label, new QVBoxLayout()); - } - - virtual void openFrameBox(const char* ) { } - virtual void openTabBox(const char* label) { - openTab(label); - } - - virtual void closeBox() - { - QWidget* group = fGroupStack.top(); - fGroupStack.pop(); - if (fGroupStack.empty()) { group->show(); } - } - - // ------------------------- active widgets ----------------------------------- - - virtual void addButton(const char* label , float* zone) - { - QAbstractButton* w = new QPushButton(label); - uiButton* c = new uiButton(this, zone, w); - - insert(label, w); - QObject::connect(w, SIGNAL(pressed()), c, SLOT(pressed())); - QObject::connect(w, SIGNAL(released()), c, SLOT(released())); - checkForTooltip(zone, w); - } - - virtual void addToggleButton(const char* , float* ) - {} - - virtual void addCheckButton(const char* label , float* zone) - { - QCheckBox* w = new QCheckBox(label); - uiCheckButton* c = new uiCheckButton(this, zone, w); - - insert(label, w); - QObject::connect(w, SIGNAL(stateChanged(int)), c, SLOT(setState(int))); - checkForTooltip(zone, w); - } - - virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) - { - if (isKnob(zone)) { - addVerticalKnob(label, zone, init, min, max, step); - return; - } - //insert(label, new QDoubleSpinBox()); - if (label && label[0]) openVerticalBox(label); - QDoubleSpinBox* w = new QDoubleSpinBox(); - uiNumEntry* c = new uiNumEntry(this, zone, w, init, min, max, step); - insert(label, w); - w->setSuffix(fUnit[zone].c_str()); - QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double))); - if (label && label[0]) closeBox(); - checkForTooltip(zone, w); - } - - // special num entry without buttons - virtual void addNumDisplay(const char* label, float* zone, float init, float min, float max, float step) - { - //insert(label, new QDoubleSpinBox()); - if (label && label[0]) openVerticalBox(label); - QDoubleSpinBox* w = new QDoubleSpinBox(); - w->setAlignment(Qt::AlignHCenter); -#if 1 - w->setStyleSheet( - "QDoubleSpinBox {" - "border: 2px solid orange;" - "border-radius: 5px;" - "}" - ); -#endif - uiNumEntry* c = new uiNumEntry(this, zone, w, init, min, max, step); - insert(label, w); - w->setButtonSymbols(QAbstractSpinBox::NoButtons); - w->setSuffix(fUnit[zone].c_str()); - QObject::connect(w, SIGNAL(valueChanged(double)), c, SLOT(setValue(double))); - if (label && label[0]) closeBox(); - checkForTooltip(zone, w); - } - - - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // KNOBS - // - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - - virtual void addVerticalKnob(const char* label , float* zone, float init, float min, float max, float step) - { - openVerticalBox(label); - QAbstractSlider* w = new QDial(); //qsynthKnob(); - uiKnob* c = new uiKnob(this, zone, w, init, min, max, step); - insert(label, w); - w->setStyle(new qsynthDialVokiStyle()); - QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); - addNumDisplay(0, zone, init, min, max, step); - - // compute the size of the knob+display - int width = int(64*pow(2,fGuiSize[zone])); - int height = int(100*pow(2,fGuiSize[zone])); - fGroupStack.top()->setMinimumSize(width,height); - fGroupStack.top()->setMaximumSize(width,height); - - closeBox(); - checkForTooltip(zone, w); - } - - virtual void addHorizontalKnob(const char* label , float* zone, float init, float min, float max, float step) - { - openHorizontalBox(label); - QAbstractSlider* w = new QDial(); //new qsynthKnob(); - uiKnob* c = new uiKnob(this, zone, w, init, min, max, step); - insert(label, w); - w->setStyle(new qsynthDialVokiStyle()); - QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); - addNumDisplay(0, zone, init, min, max, step); - closeBox(); - checkForTooltip(zone, w); - } - - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - // - // SLIDERS - // - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - - virtual void addVerticalSlider(const char* label , float* zone, float init, float min, float max, float step) - { - if (isKnob(zone)) { - addVerticalKnob(label, zone, init, min, max, step); - return; - } - openVerticalBox(label); - QSlider* w = new QSlider(Qt::Vertical); - w->setMinimumHeight(160); - w->setMinimumWidth(34); - //w->setTickPosition(QSlider::TicksBothSides); - uiSlider* c = new uiSlider(this, zone, w, init, min, max, step); - insert(label, w); - QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); - addNumDisplay(0, zone, init, min, max, step); - closeBox(); - checkForTooltip(zone, w); - } - - virtual void addHorizontalSlider(const char* label , float* zone, float init, float min, float max, float step) - { - if (isKnob(zone)) { - addHorizontalKnob(label, zone, init, min, max, step); - return; - } - openHorizontalBox(label); - QSlider* w = new QSlider(Qt::Horizontal); - w->setMinimumHeight(34); - w->setMinimumWidth(160); - //w->setTickPosition(QSlider::TicksBothSides); - uiSlider* c = new uiSlider(this, zone, w, init, min, max, step); - insert(label, w); - QObject::connect(w, SIGNAL(valueChanged(int)), c, SLOT(setValue(int))); - addNumDisplay(0, zone, init, min, max, step); - closeBox(); - checkForTooltip(zone, w); - } - - // ------------------------- passive widgets ----------------------------------- - - virtual void addNumDisplay(const char*, float*, int) - {} - - virtual void addTextDisplay(const char*, float*, const char* [], float, float) - {} - - virtual void addHorizontalBargraph(const char* label , float* zone, float min, float max) - { - AbstractDisplay* bargraph; - openVerticalBox(label); - bool db = (fUnit[zone] == "dB"); - - if (fLedSet.count(zone)) { - if (db) { - bargraph = new dbLED(min, max); - } else { - bargraph = new LED(min,max); - } - } else { - if (db) { - bargraph = new dbHorizontalBargraph(min, max); - } else { - bargraph = new linHorizontalBargraph(min, max); - } - } - - new uiBargraph2(this, zone, bargraph, min, max); - insert(label, bargraph); - closeBox(); - checkForTooltip(zone, bargraph); - } - - virtual void addVerticalBargraph(const char* label , float* zone, float min, float max) - { - AbstractDisplay* bargraph; - openVerticalBox(label); - bool db = (fUnit[zone] == "dB"); - - if (fLedSet.count(zone)) { - if (db) { - bargraph = new dbLED(min, max); - } else { - bargraph = new LED(min,max); - } - } else { - if (db) { - bargraph = new dbVerticalBargraph(min, max); - } else { - bargraph = new linVerticalBargraph(min, max); - } - } - new uiBargraph2(this, zone, bargraph, min, max); - insert(label, bargraph); - closeBox(); - checkForTooltip(zone, bargraph); - } - -}; - -#endif