annotate widgets/PluginParameterBox.cpp @ 101:0f36cdf407a6 sv1-v0.9rc1

* Make vertical scale alignment modes work in note layer as well as time-value layer, and several significant fixes to it * Make it possible to draw notes properly on the note layer * Show units (and frequencies etc in note layer's case) in the time-value and note layer description boxes * Minor fix to item edit dialog layout * Some minor menu rearrangement * Comment out a lot of debug output * Add SV website and reference URLs to Help menu, and add code to (attempt to) open them in the user's preferred browser
author Chris Cannam
date Fri, 12 May 2006 14:40:43 +0000
parents 967193b6c7aa
children 5064eeb1c76f
rev   line source
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@60 7 This file copyright 2006 Chris Cannam.
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@71 21
Chris@60 22 #include <QDoubleSpinBox>
Chris@60 23 #include <QGridLayout>
Chris@63 24 #include <QComboBox>
Chris@63 25 #include <QCheckBox>
Chris@60 26 #include <QLayout>
Chris@60 27 #include <QLabel>
Chris@60 28
Chris@60 29 #include <iostream>
Chris@60 30 #include <string>
Chris@60 31
Chris@78 32 #include <cmath>
Chris@78 33
Chris@71 34 PluginParameterBox::PluginParameterBox(Vamp::PluginBase *plugin, QWidget *parent) :
Chris@62 35 QFrame(parent),
Chris@60 36 m_plugin(plugin)
Chris@60 37 {
Chris@60 38 m_layout = new QGridLayout;
Chris@60 39 setLayout(m_layout);
Chris@60 40 populate();
Chris@60 41 }
Chris@60 42
Chris@60 43 PluginParameterBox::~PluginParameterBox()
Chris@60 44 {
Chris@60 45 }
Chris@60 46
Chris@60 47 void
Chris@60 48 PluginParameterBox::populate()
Chris@60 49 {
Chris@71 50 Vamp::PluginBase::ParameterList params = m_plugin->getParameterDescriptors();
Chris@71 51 Vamp::PluginBase::ProgramList programs = m_plugin->getPrograms();
Chris@60 52
Chris@60 53 m_params.clear();
Chris@60 54
Chris@63 55 if (params.empty() && programs.empty()) {
Chris@62 56 m_layout->addWidget
Chris@62 57 (new QLabel(tr("This plugin has no adjustable parameters.")),
Chris@62 58 0, 0);
Chris@62 59 }
Chris@62 60
Chris@63 61 int offset = 0;
Chris@63 62
Chris@63 63 if (!programs.empty()) {
Chris@63 64
Chris@63 65 std::string currentProgram = m_plugin->getCurrentProgram();
Chris@63 66
Chris@63 67 QComboBox *programCombo = new QComboBox;
Chris@63 68 programCombo->setMaxVisibleItems(20);
Chris@63 69
Chris@63 70 for (int i = 0; i < programs.size(); ++i) {
Chris@63 71 programCombo->addItem(programs[i].c_str());
Chris@63 72 if (programs[i] == currentProgram) {
Chris@63 73 programCombo->setCurrentIndex(i);
Chris@63 74 }
Chris@63 75 }
Chris@63 76
Chris@63 77 m_layout->addWidget(new QLabel(tr("Program")), 0, 0);
Chris@63 78 m_layout->addWidget(programCombo, 0, 1, 1, 2);
Chris@63 79
Chris@63 80 connect(programCombo, SIGNAL(currentIndexChanged(const QString &)),
Chris@63 81 this, SLOT(programComboChanged(const QString &)));
Chris@63 82
Chris@63 83 offset = 1;
Chris@63 84 }
Chris@63 85
Chris@60 86 for (size_t i = 0; i < params.size(); ++i) {
Chris@60 87
Chris@60 88 QString name = params[i].name.c_str();
Chris@60 89 QString description = params[i].description.c_str();
Chris@60 90 QString unit = params[i].unit.c_str();
Chris@60 91
Chris@60 92 float min = params[i].minValue;
Chris@60 93 float max = params[i].maxValue;
Chris@60 94 float deft = params[i].defaultValue;
Chris@62 95 float value = m_plugin->getParameter(params[i].name);
Chris@60 96
Chris@60 97 float qtz = 0.0;
Chris@60 98 if (params[i].isQuantized) qtz = params[i].quantizeStep;
Chris@60 99
Chris@74 100 std::vector<std::string> valueNames = params[i].valueNames;
Chris@74 101
Chris@60 102 // construct an integer range
Chris@60 103
Chris@60 104 int imin = 0, imax = 100;
Chris@60 105
Chris@60 106 if (qtz > 0.0) {
Chris@60 107 imax = int((max - min) / qtz);
Chris@60 108 } else {
Chris@60 109 qtz = (max - min) / 100.0;
Chris@60 110 }
Chris@60 111
Chris@60 112 //!!! would be nice to ensure the default value corresponds to
Chris@60 113 // an integer!
Chris@60 114
Chris@60 115 QLabel *label = new QLabel(description);
Chris@63 116 m_layout->addWidget(label, i + offset, 0);
Chris@60 117
Chris@60 118 ParamRec rec;
Chris@60 119 rec.param = params[i];
Chris@63 120 rec.dial = 0;
Chris@63 121 rec.spin = 0;
Chris@63 122 rec.check = 0;
Chris@74 123 rec.combo = 0;
Chris@63 124
Chris@74 125 if (params[i].isQuantized && !valueNames.empty()) {
Chris@74 126
Chris@74 127 QComboBox *combobox = new QComboBox;
Chris@74 128 combobox->setObjectName(name);
Chris@74 129 for (unsigned int j = 0; j < valueNames.size(); ++j) {
Chris@74 130 combobox->addItem(valueNames[j].c_str());
Chris@74 131 if (lrintf((value - min) / qtz) == j) {
Chris@74 132 combobox->setCurrentIndex(j);
Chris@74 133 }
Chris@74 134 }
Chris@74 135 connect(combobox, SIGNAL(activated(int)),
Chris@74 136 this, SLOT(dialChanged(int)));
Chris@74 137 m_layout->addWidget(combobox, i + offset, 1, 1, 2);
Chris@74 138 rec.combo = combobox;
Chris@74 139
Chris@74 140 } else if (min == 0.0 && max == 1.0 && qtz == 1.0) {
Chris@63 141
Chris@63 142 QCheckBox *checkbox = new QCheckBox;
Chris@63 143 checkbox->setObjectName(name);
Chris@63 144 checkbox->setCheckState(value == 0.0 ? Qt::Unchecked : Qt::Checked);
Chris@63 145 connect(checkbox, SIGNAL(stateChanged(int)),
Chris@63 146 this, SLOT(checkBoxChanged(int)));
Chris@63 147 m_layout->addWidget(checkbox, i + offset, 2);
Chris@63 148 rec.check = checkbox;
Chris@63 149
Chris@63 150 } else {
Chris@63 151
Chris@63 152 AudioDial *dial = new AudioDial;
Chris@63 153 dial->setObjectName(name);
Chris@63 154 dial->setMinimum(imin);
Chris@63 155 dial->setMaximum(imax);
Chris@63 156 dial->setPageStep(1);
Chris@63 157 dial->setNotchesVisible((imax - imin) <= 12);
Chris@74 158 dial->setDefaultValue(lrintf((deft - min) / qtz));
Chris@74 159 dial->setValue(lrintf((value - min) / qtz));
Chris@63 160 dial->setFixedWidth(32);
Chris@63 161 dial->setFixedHeight(32);
Chris@63 162 connect(dial, SIGNAL(valueChanged(int)),
Chris@63 163 this, SLOT(dialChanged(int)));
Chris@63 164 m_layout->addWidget(dial, i + offset, 1);
Chris@63 165
Chris@63 166 QDoubleSpinBox *spinbox = new QDoubleSpinBox;
Chris@63 167 spinbox->setObjectName(name);
Chris@63 168 spinbox->setMinimum(min);
Chris@63 169 spinbox->setMaximum(max);
Chris@63 170 spinbox->setSuffix(QString(" %1").arg(unit));
Chris@63 171 spinbox->setSingleStep(qtz);
Chris@63 172 spinbox->setValue(value);
Chris@63 173 connect(spinbox, SIGNAL(valueChanged(double)),
Chris@63 174 this, SLOT(spinBoxChanged(double)));
Chris@63 175 m_layout->addWidget(spinbox, i + offset, 2);
Chris@63 176 rec.dial = dial;
Chris@63 177 rec.spin = spinbox;
Chris@63 178 }
Chris@63 179
Chris@60 180 m_params[name] = rec;
Chris@60 181 }
Chris@60 182 }
Chris@60 183
Chris@60 184 void
Chris@60 185 PluginParameterBox::dialChanged(int ival)
Chris@60 186 {
Chris@60 187 QObject *obj = sender();
Chris@60 188 QString name = obj->objectName();
Chris@60 189
Chris@60 190 if (m_params.find(name) == m_params.end()) {
Chris@60 191 std::cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@60 192 return;
Chris@60 193 }
Chris@60 194
Chris@71 195 Vamp::PluginBase::ParameterDescriptor params = m_params[name].param;
Chris@60 196
Chris@60 197 float min = params.minValue;
Chris@60 198 float max = params.maxValue;
Chris@60 199
Chris@60 200 float qtz = 0.0;
Chris@60 201 if (params.isQuantized) qtz = params.quantizeStep;
Chris@60 202
Chris@60 203 if (qtz == 0.0) {
Chris@60 204 qtz = (max - min) / 100.0;
Chris@60 205 }
Chris@60 206
Chris@60 207 float newValue = min + ival * qtz;
Chris@60 208
Chris@60 209 QDoubleSpinBox *spin = m_params[name].spin;
Chris@63 210 if (spin) {
Chris@63 211 spin->blockSignals(true);
Chris@63 212 spin->setValue(newValue);
Chris@63 213 spin->blockSignals(false);
Chris@63 214 }
Chris@60 215
Chris@60 216 m_plugin->setParameter(name.toStdString(), newValue);
Chris@64 217
Chris@71 218 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@60 219 }
Chris@60 220
Chris@60 221 void
Chris@63 222 PluginParameterBox::checkBoxChanged(int state)
Chris@63 223 {
Chris@63 224 QObject *obj = sender();
Chris@63 225 QString name = obj->objectName();
Chris@63 226
Chris@63 227 if (m_params.find(name) == m_params.end()) {
Chris@63 228 std::cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@63 229 return;
Chris@63 230 }
Chris@63 231
Chris@71 232 Vamp::PluginBase::ParameterDescriptor params = m_params[name].param;
Chris@63 233
Chris@63 234 if (state) m_plugin->setParameter(name.toStdString(), 1.0);
Chris@63 235 else m_plugin->setParameter(name.toStdString(), 0.0);
Chris@64 236
Chris@71 237 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@63 238 }
Chris@63 239
Chris@63 240 void
Chris@60 241 PluginParameterBox::spinBoxChanged(double value)
Chris@60 242 {
Chris@60 243 QObject *obj = sender();
Chris@60 244 QString name = obj->objectName();
Chris@60 245
Chris@60 246 if (m_params.find(name) == m_params.end()) {
Chris@60 247 std::cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
Chris@60 248 return;
Chris@60 249 }
Chris@60 250
Chris@71 251 Vamp::PluginBase::ParameterDescriptor params = m_params[name].param;
Chris@60 252
Chris@60 253 float min = params.minValue;
Chris@60 254 float max = params.maxValue;
Chris@60 255
Chris@60 256 float qtz = 0.0;
Chris@60 257 if (params.isQuantized) qtz = params.quantizeStep;
Chris@60 258
Chris@60 259 if (qtz > 0.0) {
Chris@60 260 int step = int((value - min) / qtz);
Chris@60 261 value = min + step * qtz;
Chris@60 262 }
Chris@60 263
Chris@60 264 int imin = 0, imax = 100;
Chris@60 265
Chris@60 266 if (qtz > 0.0) {
Chris@60 267 imax = int((max - min) / qtz);
Chris@60 268 } else {
Chris@60 269 qtz = (max - min) / 100.0;
Chris@60 270 }
Chris@60 271
Chris@60 272 int ival = (value - min) / qtz;
Chris@60 273
Chris@60 274 AudioDial *dial = m_params[name].dial;
Chris@63 275 if (dial) {
Chris@63 276 dial->blockSignals(true);
Chris@63 277 dial->setValue(ival);
Chris@63 278 dial->blockSignals(false);
Chris@63 279 }
Chris@60 280
Chris@60 281 m_plugin->setParameter(name.toStdString(), value);
Chris@64 282
Chris@71 283 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@60 284 }
Chris@60 285
Chris@63 286 void
Chris@63 287 PluginParameterBox::programComboChanged(const QString &newProgram)
Chris@63 288 {
Chris@63 289 m_plugin->selectProgram(newProgram.toStdString());
Chris@60 290
Chris@63 291 for (std::map<QString, ParamRec>::iterator i = m_params.begin();
Chris@63 292 i != m_params.end(); ++i) {
Chris@63 293
Chris@71 294 Vamp::PluginBase::ParameterDescriptor &param = i->second.param;
Chris@63 295 float value = m_plugin->getParameter(param.name);
Chris@63 296
Chris@63 297 if (i->second.spin) {
Chris@63 298 i->second.spin->blockSignals(true);
Chris@63 299 i->second.spin->setValue(value);
Chris@63 300 i->second.spin->blockSignals(false);
Chris@63 301 }
Chris@63 302
Chris@63 303 if (i->second.dial) {
Chris@63 304
Chris@63 305 float min = param.minValue;
Chris@63 306 float max = param.maxValue;
Chris@63 307
Chris@63 308 float qtz = 0.0;
Chris@63 309 if (param.isQuantized) qtz = param.quantizeStep;
Chris@63 310
Chris@63 311 if (qtz == 0.0) {
Chris@63 312 qtz = (max - min) / 100.0;
Chris@63 313 }
Chris@63 314
Chris@63 315 i->second.dial->blockSignals(true);
Chris@74 316 i->second.dial->setValue(lrintf((value - min) / qtz));
Chris@63 317 i->second.dial->blockSignals(false);
Chris@63 318 }
Chris@74 319
Chris@74 320 if (i->second.combo) {
Chris@74 321 i->second.combo->blockSignals(true);
Chris@74 322 i->second.combo->setCurrentIndex(value);
Chris@74 323 i->second.combo->blockSignals(false);
Chris@74 324 }
Chris@63 325 }
Chris@64 326
Chris@71 327 emit pluginConfigurationChanged(PluginXml(m_plugin).toXmlString());
Chris@63 328 }
Chris@63 329