From 1875785cf8afd7bc58215ba6f442a2e5ad7cfa85 Mon Sep 17 00:00:00 2001 From: bsongis Date: Sun, 30 Mar 2014 23:13:07 +0200 Subject: [PATCH] Curve Wizard is completely rewritten --- companion/src/modeledit/curvedialog.ui | 217 ----------- companion/src/modeledit/curves.cpp | 402 +++++++++---------- companion/src/modeledit/curves.h | 14 + companion/src/modeledit/curves.ui | 519 ++++++++++++++++--------- companion/src/modeledit/expodialog.cpp | 2 +- 5 files changed, 538 insertions(+), 616 deletions(-) delete mode 100644 companion/src/modeledit/curvedialog.ui diff --git a/companion/src/modeledit/curvedialog.ui b/companion/src/modeledit/curvedialog.ui deleted file mode 100644 index f8ccccba3..000000000 --- a/companion/src/modeledit/curvedialog.ui +++ /dev/null @@ -1,217 +0,0 @@ - - - Dialog - - - - 0 - 0 - 400 - 300 - - - - Dialog - - - - - - - - Curve type - - - - - - - - 0 - 0 - - - - -100 - - - 100 - - - - - - - Coefficient - - - - - - - - Both - - - - - x>0 - - - - - x<0 - - - - - - - - Y at X=0 - - - - - - - - 0 - 0 - - - - -100 - - - 100 - - - - - - - - 0 - 0 - - - - -100 - - - 100 - - - - - - - Side - - - - - - - Y at X=-100 - - - - - - - - 0 - 0 - - - - -100 - - - 100 - - - - - - - Y at X=100 - - - - - - - - Linear - - - - - Single Expo - - - - - Symmetrical f(x)=-f(-x) - - - - - Symmetrical f(x)=f(-x) - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/companion/src/modeledit/curves.cpp b/companion/src/modeledit/curves.cpp index 5d388c6db..34d1d5d93 100644 --- a/companion/src/modeledit/curves.cpp +++ b/companion/src/modeledit/curves.cpp @@ -10,6 +10,88 @@ #define GFX_MARGIN 16 +#define CURVE_COEFF_ENABLE 1 +#define CURVE_YMID_ENABLE 2 +#define CURVE_YMIN_ENABLE 4 + +float curveLinear(float x, float coeff, float yMin, float yMid, float yMax) +{ + float a = (yMax-yMin) / 200.0; + return yMin + a * (x+100.0); +} + +float c9xexpou(float point, float coeff) +{ + float x = point*1024.0/100.0; + float k = coeff*256.0/100.0; + return ((k*x*x*x/(1024*1024) + x*(256-k) + 128) / 256) / 1024.0 * 100; +} + +float curveExpo(float x, float coeff, float yMin, float yMid, float yMax) +{ + float a = (yMax-yMin) / 100.0; + + x += 100.0; + x /= 2.0; + + if (coeff >= 0) { + return round(c9xexpou(x, coeff)*a + yMin); + } + else { + coeff = -coeff; + x = 100 - x; + return round((100.0 - c9xexpou(x, coeff))*a + yMin); + } +} + +float curveSymmetricalY(float x, float coeff, float yMin, float yMid, float yMax) +{ + bool invert; + if (x<0) { + x = -x; + invert = 1; + } + else { + invert = 0; + } + + float y; + if (coeff >= 0) { + y = round(c9xexpou(x, coeff) * (yMax/100.0)); + } + else { + coeff = -coeff; + x = 100.0 - x; + y = round((100.0-c9xexpou(x, coeff)) * (yMax/100.0)); + } + + if (invert) { + y = -y; + } + + return y; +} + +float curveSymmetricalX(float x, float coeff, float yMin, float yMid, float yMax) +{ + float a = (yMax-yMid) / 100.0; + + if (x<0) + x = -x; + + float y; + if (coeff >= 0) { + y = round(c9xexpou(x, coeff) * a + yMid); + } + else { + coeff = -coeff; + x = 100-x; + y = round((100.0-c9xexpou(x, coeff)) * a + yMid); + } + + return y; +} + #if 0 #ifdef __APPLE__ ui->curveEdit_1->setStyleSheet("color: #00007f;"); @@ -126,6 +208,11 @@ Curves::Curves(QWidget * parent, ModelData & model): } } + addTemplate(tr("Linear"), CURVE_YMIN_ENABLE, curveLinear); + addTemplate(tr("Single Expo"), CURVE_COEFF_ENABLE | CURVE_YMIN_ENABLE, curveExpo); + addTemplate(tr("Symmetrical f(x)=-f(-x)"), CURVE_COEFF_ENABLE, curveSymmetricalY); + addTemplate(tr("Symmetrical f(x)=f(-x)"), CURVE_COEFF_ENABLE | CURVE_YMID_ENABLE, curveSymmetricalX); + lock = false; } @@ -170,41 +257,16 @@ void Curves::update() ui->curveName->setText(model.curves[currentCurve].name); } - int count = model.curves[currentCurve].count; - for (int i=0; ishow(); - spny[i]->setValue(model.curves[currentCurve].points[i].y); - if (model.curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) { - spnx[i]->show(); - if (i==0 || i==model.curves[currentCurve].count-1) { - spnx[i]->setDisabled(true); - spnx[i]->setMaximum(+100); - spnx[i]->setMinimum(-100); - } - else { - spnx[i]->setMaximum(model.curves[currentCurve].points[i+1].x); - spnx[i]->setMinimum(model.curves[currentCurve].points[i-1].x); - } - spnx[i]->setValue(model.curves[currentCurve].points[i].x); - } - else { - spnx[i]->hide(); - } - } - for (int i=count; ihide(); - spnx[i]->hide(); - } - updateCurveType(); updateCurve(); + updateCurvePoints(); lock = false; } void Curves::setCurrentCurve(int index) { - currentCurve = index; + currentCurve = index; } void Curves::updateCurveType() @@ -234,6 +296,8 @@ void Curves::updateCurveType() void Curves::updateCurve() { + lock = true; + Node * nodel = 0; Node * nodex = 0; QColor color; @@ -298,18 +362,51 @@ void Curves::updateCurve() scene->addItem(nodex); if (i>0) scene->addItem(new Edge(nodel, nodex)); } + + lock = false; +} + +void Curves::updateCurvePoints() +{ + lock = true; + + int count = model.curves[currentCurve].count; + for (int i=0; ishow(); + spny[i]->setValue(model.curves[currentCurve].points[i].y); + if (model.curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) { + spnx[i]->show(); + if (i==0 || i==model.curves[currentCurve].count-1) { + spnx[i]->setDisabled(true); + spnx[i]->setMaximum(+100); + spnx[i]->setMinimum(-100); + } + else { + spnx[i]->setMaximum(model.curves[currentCurve].points[i+1].x); + spnx[i]->setMinimum(model.curves[currentCurve].points[i-1].x); + } + spnx[i]->setValue(model.curves[currentCurve].points[i].x); + } + else { + spnx[i]->hide(); + } + } + for (int i=count; ihide(); + spnx[i]->hide(); + } + + lock = false; } void Curves::onPointEdited() { if (!lock) { - lock = true; int index = sender()->property("index").toInt(); model.curves[currentCurve].points[index].x = spnx[index]->value(); model.curves[currentCurve].points[index].y = spny[index]->value(); updateCurve(); emit modified(); - lock = false; } } @@ -371,7 +468,7 @@ void Curves::on_curvePoints_currentIndexChanged(int index) // TODO something better + reuse! for (int i=0; i= model.curves[currentCurve].count-1 ? +100 : -100 + (200*i)/(numpoints-1)); + model.curves[currentCurve].points[i].x = (i >= numpoints-1 ? +100 : -100 + (200*i)/(numpoints-1)); model.curves[currentCurve].points[i].y = 0; } @@ -394,7 +491,7 @@ void Curves::on_curveCustom_currentIndexChanged(int index) // TODO something better + reuse! for (int i=0; i= model.curves[currentCurve].count-1 ? +100 : -100 + (200*i)/(numpoints-1)); + model.curves[currentCurve].points[i].x = (i >= numpoints-1 ? +100 : -100 + (200*i)/(numpoints-1)); model.curves[currentCurve].points[i].y = 0; } @@ -425,213 +522,72 @@ void Curves::resizeEvent(QResizeEvent *event) QRect qr = ui->curvePreview->contentsRect(); ui->curvePreview->scene()->setSceneRect(GFX_MARGIN, GFX_MARGIN, qr.width()-GFX_MARGIN*2, qr.height()-GFX_MARGIN*2); updateCurve(); - ModelPanel::resizeEvent(event); } -#if 0 -void ModelEdit::on_ca_ctype_CB_currentIndexChanged() +void Curves::on_curveType_currentIndexChanged() { - int index=ui->ca_ctype_CB->currentIndex(); - switch (index) { + int index = ui->curveType->currentIndex(); + unsigned int flags = templates[index].flags; + ui->curveCoeffLabel->setVisible(flags & CURVE_COEFF_ENABLE); + ui->curveCoeff->setVisible(flags & CURVE_COEFF_ENABLE); + ui->yMax->setValue(100); + ui->yMidLabel->setVisible(flags & CURVE_YMID_ENABLE); + ui->yMid->setVisible(flags & CURVE_YMID_ENABLE); + ui->yMid->setValue(0); + ui->yMinLabel->setVisible(flags & CURVE_YMIN_ENABLE); + ui->yMin->setVisible(flags & CURVE_YMIN_ENABLE); + ui->yMin->setValue(-100); +} + +void Curves::addTemplate(QString name, unsigned int flags, curveFunction function) +{ + CurveCreatorTemplate tmpl; + tmpl.name = name; + tmpl.flags = flags; + tmpl.function = function; + templates.append(tmpl); + ui->curveType->addItem(name); +} + +void Curves::on_curveApply_clicked() +{ + int index = ui->curveType->currentIndex(); + int numpoints = model.curves[currentCurve].count; + + for (int i=0; icurveSide->currentIndex()) { case 0: - ui->ca_coeff_SB->hide(); - ui->ca_coeff_label->hide(); - ui->ca_ymid_SB->hide(); - ui->ca_ymid_label->hide(); - ui->ca_ymin_SB->show(); - ui->ca_ymin_label->show(); - ui->ca_ymin_SB->setValue(-100); - ui->ca_ymax_SB->setValue(100); + apply = true; break; case 1: - ui->ca_coeff_SB->show(); - ui->ca_coeff_label->show(); - ui->ca_ymid_SB->hide(); - ui->ca_ymid_label->hide(); - ui->ca_ymin_SB->show(); - ui->ca_ymin_label->show(); - ui->ca_ymin_SB->setValue(-100); - ui->ca_ymax_SB->setValue(100); + if (x>=0) + apply = true; break; case 2: - ui->ca_coeff_SB->show(); - ui->ca_coeff_label->show(); - ui->ca_ymid_SB->hide(); - ui->ca_ymid_label->hide(); - ui->ca_ymin_SB->hide(); - ui->ca_ymin_label->hide(); - ui->ca_ymax_SB->setValue(100); - break; - case 3: - ui->ca_coeff_SB->show(); - ui->ca_coeff_label->show(); - ui->ca_ymid_SB->show(); - ui->ca_ymid_label->show(); - ui->ca_ymin_SB->hide(); - ui->ca_ymin_label->hide(); - ui->ca_ymid_SB->setValue(0); - ui->ca_ymax_SB->setValue(100); + if (x<0) + apply = true; break; } -} -float c9xexpou(float point, float coeff) -{ - float x=point*1024.0/100.0; - float k=coeff*256.0/100.0; - return ((k*x*x*x/(1024*1024) + x*(256-k) + 128) / 256)/1024.0*100; -} - -void ModelEdit::on_ca_apply_PB_clicked() -{ - int index=ui->ca_ctype_CB->currentIndex(); - float x; - int y; - int invert=0; - float a; - if (index==0) { - a=(ui->ca_ymax_SB->value()-ui->ca_ymin_SB->value())/200.0; - int numpoints=model.curves[currentCurve].count; - for (int i=0; ica_ymin_SB->value()+a*x; - switch (ui->ca_side_CB->currentIndex()) { - case 0: - model.curves[currentCurve].points[i].y=y; - break; - case 1: - if (x>=100) { - model.curves[currentCurve].points[i].y=y; - } - break; - case 2: - if (x<100) { - model.curves[currentCurve].points[i].y=y; - } - break; - } - } - } else if (index==1) { - int numpoints=model.curves[currentCurve].count; - for (int i=0; ica_coeff_SB->value(); - if (a>=0) { - y=round(c9xexpou(x,a)*(ui->ca_ymax_SB->value()-ui->ca_ymin_SB->value())/100.0+ui->ca_ymin_SB->value()); - } else { - a=-a; - x=100-x; - y=round((100.0-c9xexpou(x,a))*(ui->ca_ymax_SB->value()-ui->ca_ymin_SB->value())/100.0+ui->ca_ymin_SB->value()); - } - switch (ui->ca_side_CB->currentIndex()) { - case 0: - model.curves[currentCurve].points[i].y=y; - break; - case 1: - if (x>=50) { - model.curves[currentCurve].points[i].y=y; - } - break; - case 2: - if (x<50) { - model.curves[currentCurve].points[i].y=y; - } - break; - } - } - } else if (index==2) { - int numpoints=model.curves[currentCurve].count; - for (int i=0; ica_coeff_SB->value(); - if (x<0) { - x=-x; - invert=1; - } else { - invert=0; - } - if (a>=0) { - y=round(c9xexpou(x,a)*(ui->ca_ymax_SB->value()/100.0)); - } else { - a=-a; - x=100-x; - y=round((100.0-c9xexpou(x,a))*(ui->ca_ymax_SB->value()/100.0)); - } - switch (ui->ca_side_CB->currentIndex()) { - case 0: - if (invert==1) { - model.curves[currentCurve].points[i].y=-y; - } else { - model.curves[currentCurve].points[i].y=y; - } - break; - case 1: - if (invert==0) { - model.curves[currentCurve].points[i].y=y; - } - break; - case 2: - if (invert==1) { - model.curves[currentCurve].points[i].y=-y; - } - break; - } - } - } else if (index==3) { - int numpoints=model.curves[currentCurve].count; - for (int i=0; i=0); - a=ui->ca_coeff_SB->value(); - if (x<0) { - x=-x; - } - if (a>=0) { - y=round(c9xexpou(x,a)*((ui->ca_ymax_SB->value()-ui->ca_ymid_SB->value())/100.0)+ui->ca_ymid_SB->value()); - } else { - a=-a; - x=100-x; - y=round((100.0-c9xexpou(x,a))*((ui->ca_ymax_SB->value()-ui->ca_ymid_SB->value())/100.0)+ui->ca_ymid_SB->value()); - } - switch (ui->ca_side_CB->currentIndex()) { - case 0: - model.curves[currentCurve].points[i].y=y; - break; - case 1: - if (pos) { - model.curves[currentCurve].points[i].y=y; - } - break; - case 2: - if (!pos) { - model.curves[currentCurve].points[i].y=y; - } - break; - } - } + if (apply) { + model.curves[currentCurve].points[i].y = templates[index].function(x, ui->curveCoeff->value(), ui->yMin->value(), ui->yMid->value(), ui->yMax->value()); } - updateSettings(); - setCurrentCurve(currentCurve); - drawCurve(); + } + + updateCurve(); + updateCurvePoints(); + emit modified(); } +#if 0 void ModelEdit::clearCurves(bool ask) { if (ask) { diff --git a/companion/src/modeledit/curves.h b/companion/src/modeledit/curves.h index e8915cf65..69e0bd0f8 100644 --- a/companion/src/modeledit/curves.h +++ b/companion/src/modeledit/curves.h @@ -8,6 +8,14 @@ namespace Ui { class Curves; } +typedef float (*curveFunction) (float x, float coeff, float yMin, float yMid, float yMax); + +struct CurveCreatorTemplate { + QString name; + unsigned int flags; + curveFunction function; +}; + class Curves : public ModelPanel { Q_OBJECT @@ -30,9 +38,12 @@ class Curves : public ModelPanel void onNodeMoved(int x, int y); void onNodeFocus(); void onNodeUnfocus(); + void on_curveType_currentIndexChanged(); + void on_curveApply_clicked(); protected: virtual void resizeEvent(QResizeEvent *event); + void addTemplate(QString name, unsigned int flags, curveFunction function); private: Ui::Curves *ui; @@ -40,10 +51,13 @@ class Curves : public ModelPanel bool visibleCurves[C9X_MAX_CURVES]; QSpinBox * spnx[C9X_MAX_POINTS]; QSpinBox * spny[C9X_MAX_POINTS]; + QVector templates; void setCurrentCurve(int index); void updateCurve(); void updateCurveType(); + void updateCurvePoints(); bool allowCurveType(int points, CurveData::CurveType type); + void setPointY(int i, int x, int y); }; diff --git a/companion/src/modeledit/curves.ui b/companion/src/modeledit/curves.ui index 7c81cfc6b..7c08f5a3f 100644 --- a/companion/src/modeledit/curves.ui +++ b/companion/src/modeledit/curves.ui @@ -1,175 +1,344 @@ - - - Curves - - - - 0 - 0 - 521 - 542 - - - - Form - - - - - - - - - - - - - 0 - - - - - - - - - Standard - - - - - Custom - - - - - - - - - Lines - - - - - Smooth - - - - - - - - - - Curve type - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Curve name - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 6 - - - - - - - - 0 - 0 - - - - - 400 - 400 - - - - Qt::AlignCenter - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - 0 - - - 2 - - - 0 - - - 0 - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - + + + Curves + + + + 0 + 0 + 718 + 539 + + + + Form + + + + + + + + + 10 + + + + + + 0 + 0 + + + + + 400 + 400 + + + + Qt::AlignCenter + + + + + + + + + Curve name + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 + + + + + + + + + Standard + + + + + Custom + + + + + + + + + Lines + + + + + Smooth + + + + + + + + + + 6 + + + + + + + Curve type + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + 0 + + + 2 + + + 0 + + + 0 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 50 + false + + + + false + + + Curve Creator + + + + + + Y at X=0 + + + + + + + + 0 + 0 + + + + -100 + + + 100 + + + + + + + Y at X=100 + + + + + + + + 0 + 0 + + + + -100 + + + 100 + + + + + + + + Both + + + + + x>0 + + + + + x<0 + + + + + + + + + 0 + 0 + + + + -100 + + + 100 + + + + + + + Apply + + + + + + + Side + + + + + + + + 0 + 0 + + + + -100 + + + 100 + + + + + + + + + + Curve type + + + + + + + Y at X=-100 + + + + + + + Coefficient + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + diff --git a/companion/src/modeledit/expodialog.cpp b/companion/src/modeledit/expodialog.cpp index 6dff103c2..eb1557b6c 100644 --- a/companion/src/modeledit/expodialog.cpp +++ b/companion/src/modeledit/expodialog.cpp @@ -1,6 +1,5 @@ #include "expodialog.h" #include "ui_expodialog.h" -#include "eeprominterface.h" #include "helpers.h" ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, int stickMode, char * inputName) : @@ -94,6 +93,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, i } if (GetEepromInterface()->getCapability(VirtualInputs)) connect(ui->inputName, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); + QTimer::singleShot(0, this, SLOT(shrink())); }