#include "curves.h" #include "ui_curves.h" #include "node.h" #include "edge.h" #include #include #include #include // TODO Capability CustomCurves to be removed #define GFX_MARGIN 16 static const QColor colors[C9X_MAX_CURVES] = { QColor(0,0,127), QColor(0,127,0), QColor(127,0,0), QColor(0,127,127), QColor(127,0,127), QColor(127,127,0), QColor(127,127,127), QColor(0,0,255), QColor(0,127,255), QColor(127,0,255), QColor(0,255,0), QColor(0,255,127), QColor(127,255,0), QColor(255,0,0), QColor(255,0,127), QColor(255,127,0), }; #if 0 #ifdef __APPLE__ ui->curveEdit_1->setStyleSheet("color: #00007f;"); ui->curveEdit_2->setStyleSheet("color: #007f00;"); ui->curveEdit_3->setStyleSheet("color: #7f0000;"); ui->curveEdit_4->setStyleSheet("color: #007f7f;"); ui->curveEdit_5->setStyleSheet("color: #7f007f;"); ui->curveEdit_6->setStyleSheet("color: #7f7f00;"); ui->curveEdit_7->setStyleSheet("color: #7f7f7f;"); ui->curveEdit_8->setStyleSheet("color: #0000ff;"); ui->curveEdit_9->setStyleSheet("color: #007fff;"); ui->curveEdit_10->setStyleSheet("color: #7f00ff;"); ui->curveEdit_11->setStyleSheet("color: #00ff00;"); ui->curveEdit_12->setStyleSheet("color: #00ff7f;"); ui->curveEdit_13->setStyleSheet("color: #7fff00;"); ui->curveEdit_14->setStyleSheet("color: #ff0000;"); ui->curveEdit_15->setStyleSheet("color: #ff007f;"); ui->curveEdit_16->setStyleSheet("color: #ff7f00;"); #else ui->curveEdit_1->setStyleSheet("background-color: #00007f; color: white;"); ui->curveEdit_2->setStyleSheet("background-color: #007f00; color: white;"); ui->curveEdit_3->setStyleSheet("background-color: #7f0000; color: white;"); ui->curveEdit_4->setStyleSheet("background-color: #007f7f; color: white;"); ui->curveEdit_5->setStyleSheet("background-color: #7f007f; color: white;"); ui->curveEdit_6->setStyleSheet("background-color: #7f7f00; color: white;"); ui->curveEdit_7->setStyleSheet("background-color: #7f7f7f; color: white;"); ui->curveEdit_8->setStyleSheet("background-color: #0000ff; color: white;"); ui->curveEdit_9->setStyleSheet("background-color: #007fff; color: white;"); ui->curveEdit_10->setStyleSheet("background-color: #7f00ff; color: white;"); ui->curveEdit_11->setStyleSheet("background-color: #00ff00; color: white;"); ui->curveEdit_12->setStyleSheet("background-color: #00ff7f; color: white;"); ui->curveEdit_13->setStyleSheet("background-color: #7fff00; color: white;"); ui->curveEdit_14->setStyleSheet("background-color: #ff0000; color: white;"); ui->curveEdit_15->setStyleSheet("background-color: #ff007f; color: white;"); ui->curveEdit_16->setStyleSheet("background-color: #ff7f00; color: white;"); #endif #endif Curves::Curves(QWidget * parent, ModelData & model): ModelPanel(parent, model), ui(new Ui::Curves), currentCurve(0) { ui->setupUi(this); if (!GetEepromInterface()->getCapability(HasCvNames)) { ui->cname_LE->hide(); ui->cname_label->hide(); } QGraphicsScene *scene = new QGraphicsScene(ui->curvePreview); scene->setItemIndexMethod(QGraphicsScene::NoIndex); ui->curvePreview->setScene(scene); QIcon clearIcon; clearIcon.addFile(":/images/clear.png", QSize(), QIcon::Normal, QIcon::Off); for (int i=0; igetCapability(NumCurves); i++) { visibleCurves[i] = false; // The reset curve button QPushButton * reset = new QPushButton(this); reset->setProperty("index", i); reset->setMinimumSize(QSize(0, 0)); reset->setIcon(clearIcon); reset->setIconSize(QSize(14, 14)); connect(reset, SIGNAL(clicked()), this, SLOT(resetCurve())); ui->curvesLayout->addWidget(reset, i, 0, 1, 1); // The edit curve button QPushButton * edit = new QPushButton(this); edit->setProperty("index", i); QPalette palette; palette.setBrush(QPalette::Active, QPalette::Button, QBrush(colors[i])); palette.setBrush(QPalette::Active, QPalette::ButtonText, QBrush(Qt::white)); edit->setPalette(palette); edit->setText(tr("Curve %1").arg(i+1)); connect(edit, SIGNAL(clicked()), this, SLOT(editCurve())); ui->curvesLayout->addWidget(edit, i, 1, 1, 1); // The curve plot checkbox QCheckBox * plot = new QCheckBox(this); plot->setProperty("index", i); plot->setPalette(palette); connect(plot, SIGNAL(toggled(bool)), this, SLOT(plotCurve(bool))); ui->curvesLayout->addWidget(plot, i, 2, 1, 1); } for (int i=0; isetProperty("index", i); spny[i]->setMinimum(-100); spny[i]->setMaximum(+100); spny[i]->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); spny[i]->setAccelerated(true); connect(spny[i], SIGNAL(valueChanged(int)), this, SLOT(onPointEdited())); ui->pointsLayout->addWidget(spny[i], i, 0, 1, 1); spnx[i] = new QSpinBox(this); spnx[i]->setProperty("index", i); spnx[i]->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter); spnx[i]->setAccelerated(true); connect(spnx[i], SIGNAL(valueChanged(int)), this, SLOT(onPointEdited())); ui->pointsLayout->addWidget(spnx[i], i, 1, 1, 1); } } Curves::~Curves() { delete ui; } void Curves::editCurve() { QPushButton *button = (QPushButton *)sender(); int index = button->property("index").toInt(); setCurrentCurve(index); update(); } void Curves::resetCurve() { QPushButton *button = (QPushButton *)sender(); int index = button->property("index").toInt(); int res = QMessageBox::question(this, "companion9x", tr("Are you sure you want to reset curve %1 ?").arg(index+1), QMessageBox::Yes | QMessageBox::No); if (res == QMessageBox::Yes) { model.curves[index].clear(5); update(); emit modified(); } } void Curves::plotCurve(bool checked) { QCheckBox *chk = (QCheckBox *)sender(); int index = chk->property("index").toInt(); visibleCurves[index] = checked; updateCurve(); } void Curves::update() { lock = true; if (GetEepromInterface()->getCapability(HasCvNames)) { ui->cname_LE->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(); lock = false; } void Curves::setCurrentCurve(int index) { currentCurve = index; } void Curves::updateCurveType() { int index = (model.curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM ? 1 : 0); if (model.curves[currentCurve].count==5) index += 2; else if (model.curves[currentCurve].count==9) index += 4; else if (model.curves[currentCurve].count==17) index += 6; ui->curvetype_CB->setCurrentIndex(index); } void Curves::updateCurve() { Node * nodel = 0; Node * nodex = 0; QColor color; QGraphicsScene *scene = ui->curvePreview->scene(); scene->clear(); qreal width = scene->sceneRect().width(); qreal height = scene->sceneRect().height(); qreal centerX = scene->sceneRect().left() + width/2; //center X qreal centerY = scene->sceneRect().top() + height/2; //center Y QGraphicsSimpleTextItem *ti = scene->addSimpleText(tr("Editing curve %1").arg(currentCurve+1)); ti->setPos(3, 3); scene->addLine(centerX, GFX_MARGIN, centerX, height+GFX_MARGIN); scene->addLine(GFX_MARGIN, centerY, width+GFX_MARGIN, centerY); QPen pen; pen.setWidth(1); pen.setStyle(Qt::SolidLine); int numcurves = GetEepromInterface()->getCapability(NumCurves); for (int k=0; kaddLine(centerX + (qreal)model.curves[k].points[i].x*width/200,centerY - (qreal)model.curves[k].points[i].y*height/200,centerX + (qreal)model.curves[k].points[i+1].x*width/200,centerY - (qreal)model.curves[k].points[i+1].y*height/200, pen); else scene->addLine(GFX_MARGIN + i*width/(numpoints-1),centerY - (qreal)model.curves[k].points[i].y*height/200,GFX_MARGIN + (i+1)*width/(numpoints-1),centerY - (qreal)model.curves[k].points[i+1].y*height/200, pen); } } } int numpoints = model.curves[currentCurve].count; for (int i=0; isetProperty("index", i); nodex->setColor(colors[currentCurve]); if (model.curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) { if (i>0 && isetFixedX(false); nodex->setMinX(model.curves[currentCurve].points[i-1].x); nodex->setMaxX(model.curves[currentCurve].points[i+1].x); } else { nodex->setFixedX(true); } nodex->setPos(centerX + (qreal)model.curves[currentCurve].points[i].x*width/200,centerY - (qreal)model.curves[currentCurve].points[i].y*height/200); } else { nodex->setFixedX(true); nodex->setPos(GFX_MARGIN + i*width/(numpoints-1), centerY - (qreal)model.curves[currentCurve].points[i].y*height/200); } connect(nodex, SIGNAL(moved(int, int)), this, SLOT(onNodeMoved(int, int))); connect(nodex, SIGNAL(focus()), this, SLOT(onNodeFocus())); connect(nodex, SIGNAL(unfocus()), this, SLOT(onNodeUnfocus())); scene->addItem(nodex); if (i>0) scene->addItem(new Edge(nodel, nodex)); } } 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; } } void Curves::onNodeMoved(int x, int y) { if (!lock) { lock = true; int index = sender()->property("index").toInt(); model.curves[currentCurve].points[index].x = x; model.curves[currentCurve].points[index].y = y; spnx[index]->setValue(x); spny[index]->setValue(y); emit modified(); lock = false; } } void Curves::onNodeFocus() { int index = sender()->property("index").toInt(); spny[index]->setFocus(); } void Curves::onNodeUnfocus() { int index = sender()->property("index").toInt(); spny[index]->clearFocus(); updateCurve(); } void Curves::on_curvetype_CB_currentIndexChanged(int index) { static const int numpoint[] = {3,3,5,5,9,9,17,17}; static const CurveData::CurveType types[] = {CurveData::CURVE_TYPE_STANDARD, CurveData::CURVE_TYPE_CUSTOM, CurveData::CURVE_TYPE_STANDARD, CurveData::CURVE_TYPE_CUSTOM, CurveData::CURVE_TYPE_STANDARD, CurveData::CURVE_TYPE_CUSTOM, CurveData::CURVE_TYPE_STANDARD, CurveData::CURVE_TYPE_CUSTOM}; if (!lock) { lock = true; int numcurves = GetEepromInterface()->getCapability(NumCurves); // int currpoints = model.curves[currentCurve].count; // bool currcustom = model.curves[currentCurve].custom; int totalpoints=0; for (int i=0; igetCapability(NumCurvePoints); if (fwpoints!=0) { if (fwpoints < totalpoints) { QMessageBox::warning(this, "companion9x", tr("Not enough free points in EEPROM to store the curve.")); updateCurveType(); lock = false; return; } } model.curves[currentCurve].count = numpoint[index]; model.curves[currentCurve].type = types[index]; // TODO something better! for (int i=0; i= model.curves[currentCurve].count-1 ? +100 : -100 + (200*i)/(numpoint[index]-1)); model.curves[currentCurve].points[i].y = 0; } update(); emit modified(); lock = false; } } void Curves::on_cname_LE_editingFinished() { memset(model.curves[currentCurve].name, 0, sizeof(model.curves[currentCurve].name)); strcpy(model.curves[currentCurve].name, ui->cname_LE->text().toAscii()); emit modified(); } 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() { int index=ui->ca_ctype_CB->currentIndex(); switch (index) { 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); 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); 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); break; } } 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; } } } updateSettings(); setCurrentCurve(currentCurve); drawCurve(); } void ModelEdit::clearCurves(bool ask) { if(ask) { int res = QMessageBox::question(this,tr("Clear Curves?"),tr("Really clear all the curves?"),QMessageBox::Yes | QMessageBox::No); if(res!=QMessageBox::Yes) return; } curvesLock=true; for (int j=0; j<16; j++) { model.curves[j].count = 5; model.curves[j].custom = false; memset(model.curves[j].name, 0, sizeof(model.curves[j].name)); for (int i=0; i<17; i++) { model.curves[j].points[i].x = 0; model.curves[j].points[i].y = 0; } } for (int i=0; i<17; i++) { spnx[i]->setMinimum(-100); spnx[i]->setMaximum(100); spnx[i]->setValue(0); spny[i]->setValue(0); } currentCurve=0; curvesLock=false; ui->curvetype_CB->setCurrentIndex(2); ui->cname_LE->clear(); updateSettings(); drawCurve(); } void ModelEdit::setCurve(uint8_t c, int8_t ar[]) { int len=sizeof(ar)/sizeof(int8_t); if (GetEepromInterface()->getCapability(CustomCurves)) { if (GetEepromInterface()->getCapability(NumCurves)>c) { if (len<9) { model.curves[c].count=5; model.curves[c].custom=false; for (int i=0; i< 5; i++) { model.curves[c].points[i].y=ar[i]; } } else { model.curves[c].count=5; model.curves[c].custom=false; for (int i=0; i< 5; i++) { model.curves[c].points[i].y=ar[i]; } } } } else { if (len<9) { model.curves[c].count=5; model.curves[c].custom=false; for (int i=0; i< 5; i++) { model.curves[c].points[i].y=ar[i]; } } else { model.curves[c+8].count=5; model.curves[c+8].custom=false; for (int i=0; i< 5; i++) { model.curves[c+8].points[i].y=ar[i]; } } } } void ModelEdit::ControlCurveSignal(bool flag) { foreach(QSpinBox *sb, findChildren(QRegExp("curvePt[0-9]+"))) { sb->blockSignals(flag); } } #endif