comparison widgets/PluginParameterBox.cpp @ 0:fc9323a41f5a

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