| Chris@60 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@60 | 2 | 
| Chris@60 | 3 /* | 
| Chris@60 | 4     Sonic Visualiser | 
| Chris@60 | 5     An audio file viewer and annotation editor. | 
| Chris@60 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| Chris@182 | 7     This file copyright 2006 Chris Cannam and QMUL. | 
| Chris@60 | 8 | 
| Chris@60 | 9     This program is free software; you can redistribute it and/or | 
| Chris@60 | 10     modify it under the terms of the GNU General Public License as | 
| Chris@60 | 11     published by the Free Software Foundation; either version 2 of the | 
| Chris@60 | 12     License, or (at your option) any later version.  See the file | 
| Chris@60 | 13     COPYING included with this distribution for more information. | 
| Chris@60 | 14 */ | 
| Chris@60 | 15 | 
| Chris@60 | 16 #include "PluginParameterBox.h" | 
| Chris@60 | 17 | 
| Chris@60 | 18 #include "AudioDial.h" | 
| Chris@60 | 19 | 
| Chris@71 | 20 #include "plugin/PluginXml.h" | 
| Chris@342 | 21 #include "plugin/RealTimePluginInstance.h" // for PortHint stuff | 
| Chris@71 | 22 | 
| Chris@167 | 23 #include "base/RangeMapper.h" | 
| Chris@167 | 24 | 
| Chris@60 | 25 #include <QDoubleSpinBox> | 
| Chris@60 | 26 #include <QGridLayout> | 
| Chris@63 | 27 #include <QComboBox> | 
| Chris@63 | 28 #include <QCheckBox> | 
| Chris@60 | 29 #include <QLayout> | 
| Chris@60 | 30 #include <QLabel> | 
| Chris@60 | 31 | 
| Chris@60 | 32 #include <iostream> | 
| Chris@60 | 33 #include <string> | 
| Chris@1596 | 34 #include <memory> | 
| Chris@60 | 35 | 
| Chris@78 | 36 #include <cmath> | 
| Chris@78 | 37 | 
| Chris@1581 | 38 PluginParameterBox::PluginParameterBox(std::shared_ptr<Vamp::PluginBase> plugin, | 
| Chris@1581 | 39                                        QWidget *parent) : | 
| Chris@62 | 40     QFrame(parent), | 
| Chris@293 | 41     m_plugin(plugin), | 
| Chris@1408 | 42     m_programCombo(nullptr) | 
| Chris@60 | 43 { | 
| Chris@60 | 44     m_layout = new QGridLayout; | 
| Chris@60 | 45     setLayout(m_layout); | 
| Chris@60 | 46     populate(); | 
| Chris@60 | 47 } | 
| Chris@60 | 48 | 
| Chris@60 | 49 PluginParameterBox::~PluginParameterBox() | 
| Chris@60 | 50 { | 
| Chris@60 | 51 } | 
| Chris@60 | 52 | 
| Chris@60 | 53 void | 
| Chris@60 | 54 PluginParameterBox::populate() | 
| Chris@60 | 55 { | 
| Chris@71 | 56     Vamp::PluginBase::ParameterList params = m_plugin->getParameterDescriptors(); | 
| Chris@293 | 57     m_programs = m_plugin->getPrograms(); | 
| Chris@60 | 58 | 
| Chris@60 | 59     m_params.clear(); | 
| Chris@60 | 60 | 
| Chris@293 | 61     if (params.empty() && m_programs.empty()) { | 
| Chris@62 | 62         m_layout->addWidget | 
| Chris@62 | 63             (new QLabel(tr("This plugin has no adjustable parameters.")), | 
| Chris@62 | 64              0, 0); | 
| Chris@62 | 65     } | 
| Chris@62 | 66 | 
| Chris@63 | 67     int offset = 0; | 
| Chris@63 | 68 | 
| Chris@293 | 69     if (!m_programs.empty()) { | 
| Chris@63 | 70 | 
| Chris@63 | 71         std::string currentProgram = m_plugin->getCurrentProgram(); | 
| Chris@63 | 72 | 
| Chris@293 | 73         m_programCombo = new QComboBox; | 
| Chris@293 | 74         m_programCombo->setMaxVisibleItems | 
| Chris@908 | 75             (int(m_programs.size() < 25 ? m_programs.size() : 20)); | 
| Chris@63 | 76 | 
| Chris@908 | 77         for (int i = 0; in_range_for(m_programs, i); ++i) { | 
| Chris@293 | 78             m_programCombo->addItem(m_programs[i].c_str()); | 
| Chris@293 | 79             if (m_programs[i] == currentProgram) { | 
| Chris@908 | 80                 m_programCombo->setCurrentIndex(int(i)); | 
| Chris@63 | 81             } | 
| Chris@63 | 82         } | 
| Chris@63 | 83 | 
| Chris@63 | 84         m_layout->addWidget(new QLabel(tr("Program")), 0, 0); | 
| Chris@293 | 85         m_layout->addWidget(m_programCombo, 0, 1, 1, 2); | 
| Chris@63 | 86 | 
| Chris@293 | 87         connect(m_programCombo, SIGNAL(currentIndexChanged(const QString &)), | 
| Chris@63 | 88                 this, SLOT(programComboChanged(const QString &))); | 
| Chris@63 | 89 | 
| Chris@63 | 90         offset = 1; | 
| Chris@63 | 91     } | 
| Chris@63 | 92 | 
| Chris@908 | 93     for (int i = 0; in_range_for(params, i); ++i) { | 
| Chris@60 | 94 | 
| Chris@207 | 95         QString identifier = params[i].identifier.c_str(); | 
| Chris@60 | 96         QString name = params[i].name.c_str(); | 
| Chris@60 | 97         QString unit = params[i].unit.c_str(); | 
| Chris@60 | 98 | 
| Chris@60 | 99         float min = params[i].minValue; | 
| Chris@60 | 100         float max = params[i].maxValue; | 
| Chris@60 | 101         float deft = params[i].defaultValue; | 
| Chris@207 | 102         float value = m_plugin->getParameter(params[i].identifier); | 
| Chris@60 | 103 | 
| Chris@342 | 104         int hint = PortHint::NoHint; | 
| Chris@1581 | 105         auto rtpi = std::dynamic_pointer_cast<RealTimePluginInstance> | 
| Chris@342 | 106             (m_plugin); | 
| Chris@342 | 107         if (rtpi) { | 
| Chris@342 | 108             hint = rtpi->getParameterDisplayHint(i); | 
| Chris@342 | 109         } | 
| Chris@342 | 110 | 
| Chris@60 | 111         float qtz = 0.0; | 
| Chris@60 | 112         if (params[i].isQuantized) qtz = params[i].quantizeStep; | 
| Chris@60 | 113 | 
| Chris@682 | 114 //        cerr << "PluginParameterBox: hint = " << hint << ", min = " << min << ", max = " | 
| Chris@682 | 115 //                  << max << ", qtz = " << qtz << endl; | 
| Chris@342 | 116 | 
| Chris@74 | 117         std::vector<std::string> valueNames = params[i].valueNames; | 
| Chris@74 | 118 | 
| Chris@60 | 119         // construct an integer range | 
| Chris@60 | 120 | 
| Chris@60 | 121         int imin = 0, imax = 100; | 
| Chris@60 | 122 | 
| Chris@342 | 123         if (!(hint & PortHint::Logarithmic)) { | 
| Chris@342 | 124             if (qtz > 0.0) { | 
| Chris@908 | 125                 imax = int(lrintf((max - min) / qtz)); | 
| Chris@1348 | 126                 if (imax <= imin) { | 
| Chris@1348 | 127                     imax = 100; | 
| Chris@1348 | 128                     qtz = (max - min) / 100.f; | 
| Chris@1348 | 129                 } | 
| Chris@342 | 130             } else { | 
| Chris@908 | 131                 qtz = (max - min) / 100.f; | 
| Chris@342 | 132             } | 
| Chris@60 | 133         } | 
| Chris@60 | 134 | 
| Chris@60 | 135         //!!! would be nice to ensure the default value corresponds to | 
| Chris@60 | 136         // an integer! | 
| Chris@60 | 137 | 
| Chris@207 | 138         QLabel *label = new QLabel(name); | 
| Chris@208 | 139         if (params[i].description != "") { | 
| Chris@828 | 140             label->setToolTip(QString("<qt>%1</qt>") | 
| Chris@828 | 141                               .arg(params[i].description.c_str()) | 
| Chris@828 | 142                               .replace("\n", "<br>")); | 
| Chris@208 | 143         } | 
| Chris@63 | 144         m_layout->addWidget(label, i + offset, 0); | 
| Chris@60 | 145 | 
| Chris@60 | 146         ParamRec rec; | 
| Chris@60 | 147         rec.param = params[i]; | 
| Chris@1408 | 148         rec.dial = nullptr; | 
| Chris@1408 | 149         rec.spin = nullptr; | 
| Chris@1408 | 150         rec.check = nullptr; | 
| Chris@1408 | 151         rec.combo = nullptr; | 
| Chris@63 | 152 | 
| Chris@74 | 153         if (params[i].isQuantized && !valueNames.empty()) { | 
| Chris@74 | 154 | 
| Chris@74 | 155             QComboBox *combobox = new QComboBox; | 
| Chris@207 | 156             combobox->setObjectName(identifier); | 
| Chris@74 | 157             for (unsigned int j = 0; j < valueNames.size(); ++j) { | 
| Chris@74 | 158                 combobox->addItem(valueNames[j].c_str()); | 
| Chris@249 | 159                 if ((unsigned int)(lrintf(fabsf((value - min) / qtz))) == j) { | 
| Chris@74 | 160                     combobox->setCurrentIndex(j); | 
| Chris@74 | 161                 } | 
| Chris@74 | 162             } | 
| Chris@74 | 163             connect(combobox, SIGNAL(activated(int)), | 
| Chris@74 | 164                     this, SLOT(dialChanged(int))); | 
| Chris@74 | 165             m_layout->addWidget(combobox, i + offset, 1, 1, 2); | 
| Chris@74 | 166             rec.combo = combobox; | 
| Chris@74 | 167 | 
| Chris@74 | 168         } else if (min == 0.0 && max == 1.0 && qtz == 1.0) { | 
| Chris@63 | 169 | 
| Chris@63 | 170             QCheckBox *checkbox = new QCheckBox; | 
| Chris@207 | 171             checkbox->setObjectName(identifier); | 
| Chris@293 | 172             checkbox->setCheckState(value < 0.5 ? Qt::Unchecked : Qt::Checked); | 
| Chris@63 | 173             connect(checkbox, SIGNAL(stateChanged(int)), | 
| Chris@63 | 174                     this, SLOT(checkBoxChanged(int))); | 
| Chris@63 | 175             m_layout->addWidget(checkbox, i + offset, 2); | 
| Chris@63 | 176             rec.check = checkbox; | 
| Chris@63 | 177 | 
| Chris@63 | 178         } else { | 
| Chris@63 | 179 | 
| Chris@63 | 180             AudioDial *dial = new AudioDial; | 
| Chris@207 | 181             dial->setObjectName(name); | 
| Chris@63 | 182             dial->setMinimum(imin); | 
| Chris@63 | 183             dial->setMaximum(imax); | 
| Chris@63 | 184             dial->setPageStep(1); | 
| Chris@63 | 185             dial->setNotchesVisible((imax - imin) <= 12); | 
| Chris@342 | 186 //!!!            dial->setDefaultValue(lrintf((deft - min) / qtz)); | 
| Chris@342 | 187 //            dial->setValue(lrintf((value - min) / qtz)); | 
| Chris@63 | 188             dial->setFixedWidth(32); | 
| Chris@63 | 189             dial->setFixedHeight(32); | 
| Chris@1348 | 190             if (max == min || imax == imin) { | 
| Chris@1348 | 191                 SVCERR << "WARNING: for parameter \"" << name | 
| Chris@1348 | 192                        << "\" of plugin \"" << m_plugin->getName() | 
| Chris@1348 | 193                        << "\": invalid range " << min << " -> " << max | 
| Chris@1348 | 194                        << " with quantize step " << qtz << endl; | 
| Chris@342 | 195             } else { | 
| Chris@1408 | 196                 RangeMapper *rm = nullptr; | 
| Chris@1348 | 197                 if (hint & PortHint::Logarithmic) { | 
| Chris@1348 | 198                     rm = new LogRangeMapper(imin, imax, min, max, unit); | 
| Chris@1348 | 199                 } else { | 
| Chris@1348 | 200                     rm = new LinearRangeMapper(imin, imax, min, max, unit); | 
| Chris@1348 | 201                 } | 
| Chris@1348 | 202                 dial->setRangeMapper(rm); | 
| Chris@1348 | 203                 dial->setDefaultValue(rm->getPositionForValue(deft)); | 
| Chris@1348 | 204                 dial->setValue(rm->getPositionForValue(value)); | 
| Chris@342 | 205             } | 
| Chris@168 | 206             dial->setShowToolTip(true); | 
| Chris@63 | 207             connect(dial, SIGNAL(valueChanged(int)), | 
| Chris@63 | 208                     this, SLOT(dialChanged(int))); | 
| Chris@63 | 209             m_layout->addWidget(dial, i + offset, 1); | 
| Chris@63 | 210 | 
| Chris@63 | 211             QDoubleSpinBox *spinbox = new QDoubleSpinBox; | 
| Chris@207 | 212             spinbox->setObjectName(identifier); | 
| Chris@63 | 213             spinbox->setMinimum(min); | 
| Chris@63 | 214             spinbox->setMaximum(max); | 
| Chris@63 | 215             spinbox->setSuffix(QString(" %1").arg(unit)); | 
| Chris@342 | 216             if (qtz != 0) spinbox->setSingleStep(qtz); | 
| Chris@63 | 217             spinbox->setValue(value); | 
| Chris@103 | 218             spinbox->setDecimals(4); | 
| Chris@63 | 219             connect(spinbox, SIGNAL(valueChanged(double)), | 
| Chris@63 | 220                     this, SLOT(spinBoxChanged(double))); | 
| Chris@63 | 221             m_layout->addWidget(spinbox, i + offset, 2); | 
| Chris@63 | 222             rec.dial = dial; | 
| Chris@63 | 223             rec.spin = spinbox; | 
| Chris@63 | 224         } | 
| Chris@63 | 225 | 
| Chris@207 | 226         m_params[identifier] = rec; | 
| Chris@207 | 227         m_nameMap[name] = identifier; | 
| Chris@60 | 228     } | 
| Chris@60 | 229 } | 
| Chris@60 | 230 | 
| Chris@60 | 231 void | 
| Chris@60 | 232 PluginParameterBox::dialChanged(int ival) | 
| Chris@60 | 233 { | 
| Chris@60 | 234     QObject *obj = sender(); | 
| Chris@207 | 235     QString identifier = obj->objectName(); | 
| Chris@60 | 236 | 
| Chris@207 | 237     if (m_params.find(identifier) == m_params.end() && | 
| Chris@207 | 238         m_nameMap.find(identifier) != m_nameMap.end()) { | 
| Chris@207 | 239         identifier = m_nameMap[identifier]; | 
| Chris@167 | 240     } | 
| Chris@167 | 241 | 
| Chris@207 | 242     if (m_params.find(identifier) == m_params.end()) { | 
| Chris@682 | 243         cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << identifier << "\"" << endl; | 
| Chris@60 | 244         return; | 
| Chris@60 | 245     } | 
| Chris@60 | 246 | 
| Chris@207 | 247     Vamp::PluginBase::ParameterDescriptor params = m_params[identifier].param; | 
| Chris@60 | 248 | 
| Chris@60 | 249     float min = params.minValue; | 
| Chris@60 | 250     float max = params.maxValue; | 
| Chris@60 | 251 | 
| Chris@168 | 252     float newValue; | 
| Chris@168 | 253 | 
| Chris@60 | 254     float qtz = 0.0; | 
| Chris@60 | 255     if (params.isQuantized) qtz = params.quantizeStep; | 
| Chris@168 | 256 | 
| Chris@168 | 257     AudioDial *ad = dynamic_cast<AudioDial *>(obj); | 
| Chris@60 | 258 | 
| Chris@168 | 259     if (ad && ad->rangeMapper()) { | 
| Chris@168 | 260 | 
| Chris@908 | 261         newValue = float(ad->mappedValue()); | 
| Chris@168 | 262         if (newValue < min) newValue = min; | 
| Chris@168 | 263         if (newValue > max) newValue = max; | 
| Chris@168 | 264         if (qtz != 0.0) { | 
| Chris@908 | 265             ival = int(lrintf((newValue - min) / qtz)); | 
| Chris@908 | 266             newValue = min + float(ival) * qtz; | 
| Chris@168 | 267         } | 
| Chris@168 | 268 | 
| Chris@168 | 269     } else { | 
| Chris@908 | 270         if (qtz == 0.f) { | 
| Chris@908 | 271             qtz = (max - min) / 100.f; | 
| Chris@168 | 272         } | 
| Chris@908 | 273         newValue = min + float(ival) * qtz; | 
| Chris@60 | 274     } | 
| Chris@60 | 275 | 
| Chris@587 | 276 //    SVDEBUG << "PluginParameterBox::dialChanged: newValue = " << newValue << endl; | 
| Chris@342 | 277 | 
| Chris@207 | 278     QDoubleSpinBox *spin = m_params[identifier].spin; | 
| Chris@63 | 279     if (spin) { | 
| Chris@63 | 280         spin->blockSignals(true); | 
| Chris@63 | 281         spin->setValue(newValue); | 
| Chris@63 | 282         spin->blockSignals(false); | 
| Chris@63 | 283     } | 
| Chris@60 | 284 | 
| Chris@587 | 285 //    SVDEBUG << "setting plugin parameter \"" << identifier << "\" to value " << newValue << endl; | 
| Chris@530 | 286 | 
| Chris@207 | 287     m_plugin->setParameter(identifier.toStdString(), newValue); | 
| Chris@64 | 288 | 
| Chris@293 | 289     updateProgramCombo(); | 
| Chris@293 | 290 | 
| Chris@71 | 291     emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString()); | 
| Chris@60 | 292 } | 
| Chris@60 | 293 | 
| Chris@60 | 294 void | 
| Chris@63 | 295 PluginParameterBox::checkBoxChanged(int state) | 
| Chris@63 | 296 { | 
| Chris@63 | 297     QObject *obj = sender(); | 
| Chris@207 | 298     QString identifier = obj->objectName(); | 
| Chris@63 | 299 | 
| Chris@207 | 300     if (m_params.find(identifier) == m_params.end() && | 
| Chris@207 | 301         m_nameMap.find(identifier) != m_nameMap.end()) { | 
| Chris@207 | 302         identifier = m_nameMap[identifier]; | 
| Chris@167 | 303     } | 
| Chris@167 | 304 | 
| Chris@207 | 305     if (m_params.find(identifier) == m_params.end()) { | 
| Chris@682 | 306         cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << identifier << "\"" << endl; | 
| Chris@63 | 307         return; | 
| Chris@63 | 308     } | 
| Chris@63 | 309 | 
| Chris@207 | 310     Vamp::PluginBase::ParameterDescriptor params = m_params[identifier].param; | 
| Chris@63 | 311 | 
| Chris@207 | 312     if (state) m_plugin->setParameter(identifier.toStdString(), 1.0); | 
| Chris@207 | 313     else m_plugin->setParameter(identifier.toStdString(), 0.0); | 
| Chris@64 | 314 | 
| Chris@293 | 315     updateProgramCombo(); | 
| Chris@293 | 316 | 
| Chris@71 | 317     emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString()); | 
| Chris@63 | 318 } | 
| Chris@63 | 319 | 
| Chris@63 | 320 void | 
| Chris@60 | 321 PluginParameterBox::spinBoxChanged(double value) | 
| Chris@60 | 322 { | 
| Chris@60 | 323     QObject *obj = sender(); | 
| Chris@207 | 324     QString identifier = obj->objectName(); | 
| Chris@60 | 325 | 
| Chris@207 | 326     if (m_params.find(identifier) == m_params.end() && | 
| Chris@207 | 327         m_nameMap.find(identifier) != m_nameMap.end()) { | 
| Chris@207 | 328         identifier = m_nameMap[identifier]; | 
| Chris@167 | 329     } | 
| Chris@167 | 330 | 
| Chris@207 | 331     if (m_params.find(identifier) == m_params.end()) { | 
| Chris@682 | 332         cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << identifier << "\"" << endl; | 
| Chris@60 | 333         return; | 
| Chris@60 | 334     } | 
| Chris@60 | 335 | 
| Chris@207 | 336     Vamp::PluginBase::ParameterDescriptor params = m_params[identifier].param; | 
| Chris@60 | 337 | 
| Chris@60 | 338     float min = params.minValue; | 
| Chris@60 | 339     float max = params.maxValue; | 
| Chris@60 | 340 | 
| Chris@60 | 341     float qtz = 0.0; | 
| Chris@60 | 342     if (params.isQuantized) qtz = params.quantizeStep; | 
| Chris@60 | 343 | 
| Chris@60 | 344     if (qtz > 0.0) { | 
| Chris@908 | 345         int step = int(lrintf(float(value - min) / qtz)); | 
| Chris@908 | 346         value = min + float(step) * qtz; | 
| Chris@60 | 347     } | 
| Chris@60 | 348 | 
| Chris@807 | 349 //    int imax = 100; | 
| Chris@60 | 350 | 
| Chris@60 | 351     if (qtz > 0.0) { | 
| Chris@807 | 352 //        imax = lrintf((max - min) / qtz); | 
| Chris@60 | 353     } else { | 
| Chris@908 | 354         qtz = (max - min) / 100.f; | 
| Chris@60 | 355     } | 
| Chris@60 | 356 | 
| Chris@908 | 357     int ival = int(lrintf(float(value - min) / qtz)); | 
| Chris@60 | 358 | 
| Chris@207 | 359     AudioDial *dial = m_params[identifier].dial; | 
| Chris@63 | 360     if (dial) { | 
| Chris@63 | 361         dial->blockSignals(true); | 
| Chris@342 | 362         if (dial->rangeMapper()) { | 
| Chris@342 | 363             dial->setMappedValue(value); | 
| Chris@342 | 364         } else { | 
| Chris@342 | 365             dial->setValue(ival); | 
| Chris@342 | 366         } | 
| Chris@63 | 367         dial->blockSignals(false); | 
| Chris@63 | 368     } | 
| Chris@60 | 369 | 
| Chris@587 | 370     SVDEBUG << "setting plugin parameter \"" << identifier << "\" to value " << value << endl; | 
| Chris@530 | 371 | 
| Chris@908 | 372     m_plugin->setParameter(identifier.toStdString(), float(value)); | 
| Chris@64 | 373 | 
| Chris@293 | 374     updateProgramCombo(); | 
| Chris@293 | 375 | 
| Chris@71 | 376     emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString()); | 
| Chris@60 | 377 } | 
| Chris@60 | 378 | 
| Chris@63 | 379 void | 
| Chris@63 | 380 PluginParameterBox::programComboChanged(const QString &newProgram) | 
| Chris@63 | 381 { | 
| Chris@63 | 382     m_plugin->selectProgram(newProgram.toStdString()); | 
| Chris@60 | 383 | 
| Chris@63 | 384     for (std::map<QString, ParamRec>::iterator i = m_params.begin(); | 
| Chris@63 | 385          i != m_params.end(); ++i) { | 
| Chris@63 | 386 | 
| Chris@71 | 387         Vamp::PluginBase::ParameterDescriptor ¶m = i->second.param; | 
| Chris@207 | 388         float value = m_plugin->getParameter(param.identifier); | 
| Chris@63 | 389 | 
| Chris@63 | 390         if (i->second.spin) { | 
| Chris@63 | 391             i->second.spin->blockSignals(true); | 
| Chris@63 | 392             i->second.spin->setValue(value); | 
| Chris@63 | 393             i->second.spin->blockSignals(false); | 
| Chris@63 | 394         } | 
| Chris@63 | 395 | 
| Chris@63 | 396         if (i->second.dial) { | 
| Chris@63 | 397 | 
| Chris@63 | 398             float min = param.minValue; | 
| Chris@63 | 399             float max = param.maxValue; | 
| Chris@63 | 400 | 
| Chris@63 | 401             float qtz = 0.0; | 
| Chris@63 | 402             if (param.isQuantized) qtz = param.quantizeStep; | 
| Chris@63 | 403 | 
| Chris@63 | 404             if (qtz == 0.0) { | 
| Chris@908 | 405                 qtz = (max - min) / 100.f; | 
| Chris@63 | 406             } | 
| Chris@63 | 407 | 
| Chris@63 | 408             i->second.dial->blockSignals(true); | 
| Chris@908 | 409             i->second.dial->setValue(int(lrintf(float(value - min) / qtz))); | 
| Chris@63 | 410             i->second.dial->blockSignals(false); | 
| Chris@63 | 411         } | 
| Chris@74 | 412 | 
| Chris@74 | 413         if (i->second.combo) { | 
| Chris@74 | 414             i->second.combo->blockSignals(true); | 
| Chris@908 | 415             i->second.combo->setCurrentIndex(int(lrintf(value))); | 
| Chris@74 | 416             i->second.combo->blockSignals(false); | 
| Chris@74 | 417         } | 
| Chris@293 | 418 | 
| Chris@293 | 419         if (i->second.check) { | 
| Chris@293 | 420             i->second.check->blockSignals(true); | 
| Chris@293 | 421             i->second.check->setCheckState(value < 0.5 ? Qt::Unchecked : Qt::Checked); | 
| Chris@293 | 422             i->second.check->blockSignals(false); | 
| Chris@293 | 423         } | 
| Chris@63 | 424     } | 
| Chris@64 | 425 | 
| Chris@71 | 426     emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString()); | 
| Chris@63 | 427 } | 
| Chris@63 | 428 | 
| Chris@293 | 429 void | 
| Chris@293 | 430 PluginParameterBox::updateProgramCombo() | 
| Chris@293 | 431 { | 
| Chris@293 | 432     if (!m_programCombo || m_programs.empty()) return; | 
| Chris@293 | 433 | 
| Chris@293 | 434     std::string currentProgram = m_plugin->getCurrentProgram(); | 
| Chris@293 | 435 | 
| Chris@908 | 436     for (int i = 0; in_range_for(m_programs, i); ++i) { | 
| Chris@293 | 437         if (m_programs[i] == currentProgram) { | 
| Chris@293 | 438             m_programCombo->setCurrentIndex(i); | 
| Chris@293 | 439         } | 
| Chris@293 | 440     } | 
| Chris@293 | 441 } | 
| Chris@293 | 442 | 
| Chris@293 | 443 |