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@60
|
20 #include <QDoubleSpinBox>
|
Chris@60
|
21 #include <QGridLayout>
|
Chris@63
|
22 #include <QComboBox>
|
Chris@63
|
23 #include <QCheckBox>
|
Chris@60
|
24 #include <QLayout>
|
Chris@60
|
25 #include <QLabel>
|
Chris@60
|
26
|
Chris@60
|
27 #include <iostream>
|
Chris@60
|
28 #include <string>
|
Chris@60
|
29
|
Chris@62
|
30 PluginParameterBox::PluginParameterBox(PluginInstance *plugin, QWidget *parent) :
|
Chris@62
|
31 QFrame(parent),
|
Chris@60
|
32 m_plugin(plugin)
|
Chris@60
|
33 {
|
Chris@60
|
34 m_layout = new QGridLayout;
|
Chris@60
|
35 setLayout(m_layout);
|
Chris@60
|
36 populate();
|
Chris@60
|
37 }
|
Chris@60
|
38
|
Chris@60
|
39 PluginParameterBox::~PluginParameterBox()
|
Chris@60
|
40 {
|
Chris@60
|
41 }
|
Chris@60
|
42
|
Chris@60
|
43 void
|
Chris@60
|
44 PluginParameterBox::populate()
|
Chris@60
|
45 {
|
Chris@60
|
46 PluginInstance::ParameterList params = m_plugin->getParameterDescriptors();
|
Chris@63
|
47 PluginInstance::ProgramList programs = m_plugin->getPrograms();
|
Chris@60
|
48
|
Chris@60
|
49 m_params.clear();
|
Chris@60
|
50
|
Chris@63
|
51 if (params.empty() && programs.empty()) {
|
Chris@62
|
52 m_layout->addWidget
|
Chris@62
|
53 (new QLabel(tr("This plugin has no adjustable parameters.")),
|
Chris@62
|
54 0, 0);
|
Chris@62
|
55 }
|
Chris@62
|
56
|
Chris@63
|
57 int offset = 0;
|
Chris@63
|
58
|
Chris@63
|
59 if (!programs.empty()) {
|
Chris@63
|
60
|
Chris@63
|
61 std::string currentProgram = m_plugin->getCurrentProgram();
|
Chris@63
|
62
|
Chris@63
|
63 QComboBox *programCombo = new QComboBox;
|
Chris@63
|
64 programCombo->setMaxVisibleItems(20);
|
Chris@63
|
65
|
Chris@63
|
66 for (int i = 0; i < programs.size(); ++i) {
|
Chris@63
|
67 programCombo->addItem(programs[i].c_str());
|
Chris@63
|
68 if (programs[i] == currentProgram) {
|
Chris@63
|
69 programCombo->setCurrentIndex(i);
|
Chris@63
|
70 }
|
Chris@63
|
71 }
|
Chris@63
|
72
|
Chris@63
|
73 m_layout->addWidget(new QLabel(tr("Program")), 0, 0);
|
Chris@63
|
74 m_layout->addWidget(programCombo, 0, 1, 1, 2);
|
Chris@63
|
75
|
Chris@63
|
76 connect(programCombo, SIGNAL(currentIndexChanged(const QString &)),
|
Chris@63
|
77 this, SLOT(programComboChanged(const QString &)));
|
Chris@63
|
78
|
Chris@63
|
79 offset = 1;
|
Chris@63
|
80 }
|
Chris@63
|
81
|
Chris@60
|
82 for (size_t i = 0; i < params.size(); ++i) {
|
Chris@60
|
83
|
Chris@60
|
84 QString name = params[i].name.c_str();
|
Chris@60
|
85 QString description = params[i].description.c_str();
|
Chris@60
|
86 QString unit = params[i].unit.c_str();
|
Chris@60
|
87
|
Chris@60
|
88 float min = params[i].minValue;
|
Chris@60
|
89 float max = params[i].maxValue;
|
Chris@60
|
90 float deft = params[i].defaultValue;
|
Chris@62
|
91 float value = m_plugin->getParameter(params[i].name);
|
Chris@60
|
92
|
Chris@60
|
93 float qtz = 0.0;
|
Chris@60
|
94 if (params[i].isQuantized) qtz = params[i].quantizeStep;
|
Chris@60
|
95
|
Chris@60
|
96 // construct an integer range
|
Chris@60
|
97
|
Chris@60
|
98 int imin = 0, imax = 100;
|
Chris@60
|
99
|
Chris@60
|
100 if (qtz > 0.0) {
|
Chris@60
|
101 imax = int((max - min) / qtz);
|
Chris@60
|
102 } else {
|
Chris@60
|
103 qtz = (max - min) / 100.0;
|
Chris@60
|
104 }
|
Chris@60
|
105
|
Chris@60
|
106 //!!! would be nice to ensure the default value corresponds to
|
Chris@60
|
107 // an integer!
|
Chris@60
|
108
|
Chris@60
|
109 QLabel *label = new QLabel(description);
|
Chris@63
|
110 m_layout->addWidget(label, i + offset, 0);
|
Chris@60
|
111
|
Chris@60
|
112 ParamRec rec;
|
Chris@60
|
113 rec.param = params[i];
|
Chris@63
|
114 rec.dial = 0;
|
Chris@63
|
115 rec.spin = 0;
|
Chris@63
|
116 rec.check = 0;
|
Chris@63
|
117
|
Chris@63
|
118 if (min == 0.0 && max == 1.0 && qtz == 1.0) {
|
Chris@63
|
119
|
Chris@63
|
120 QCheckBox *checkbox = new QCheckBox;
|
Chris@63
|
121 checkbox->setObjectName(name);
|
Chris@63
|
122 checkbox->setCheckState(value == 0.0 ? Qt::Unchecked : Qt::Checked);
|
Chris@63
|
123 connect(checkbox, SIGNAL(stateChanged(int)),
|
Chris@63
|
124 this, SLOT(checkBoxChanged(int)));
|
Chris@63
|
125 m_layout->addWidget(checkbox, i + offset, 2);
|
Chris@63
|
126 rec.check = checkbox;
|
Chris@63
|
127
|
Chris@63
|
128 } else {
|
Chris@63
|
129
|
Chris@63
|
130 AudioDial *dial = new AudioDial;
|
Chris@63
|
131 dial->setObjectName(name);
|
Chris@63
|
132 dial->setMinimum(imin);
|
Chris@63
|
133 dial->setMaximum(imax);
|
Chris@63
|
134 dial->setPageStep(1);
|
Chris@63
|
135 dial->setNotchesVisible((imax - imin) <= 12);
|
Chris@63
|
136 dial->setDefaultValue(int((deft - min) / qtz));
|
Chris@63
|
137 dial->setValue(int((value - min) / qtz));
|
Chris@63
|
138 dial->setFixedWidth(32);
|
Chris@63
|
139 dial->setFixedHeight(32);
|
Chris@63
|
140 connect(dial, SIGNAL(valueChanged(int)),
|
Chris@63
|
141 this, SLOT(dialChanged(int)));
|
Chris@63
|
142 m_layout->addWidget(dial, i + offset, 1);
|
Chris@63
|
143
|
Chris@63
|
144 QDoubleSpinBox *spinbox = new QDoubleSpinBox;
|
Chris@63
|
145 spinbox->setObjectName(name);
|
Chris@63
|
146 spinbox->setMinimum(min);
|
Chris@63
|
147 spinbox->setMaximum(max);
|
Chris@63
|
148 spinbox->setSuffix(QString(" %1").arg(unit));
|
Chris@63
|
149 spinbox->setSingleStep(qtz);
|
Chris@63
|
150 spinbox->setValue(value);
|
Chris@63
|
151 connect(spinbox, SIGNAL(valueChanged(double)),
|
Chris@63
|
152 this, SLOT(spinBoxChanged(double)));
|
Chris@63
|
153 m_layout->addWidget(spinbox, i + offset, 2);
|
Chris@63
|
154 rec.dial = dial;
|
Chris@63
|
155 rec.spin = spinbox;
|
Chris@63
|
156 }
|
Chris@63
|
157
|
Chris@60
|
158 m_params[name] = rec;
|
Chris@60
|
159 }
|
Chris@60
|
160 }
|
Chris@60
|
161
|
Chris@60
|
162 void
|
Chris@60
|
163 PluginParameterBox::dialChanged(int ival)
|
Chris@60
|
164 {
|
Chris@60
|
165 QObject *obj = sender();
|
Chris@60
|
166 QString name = obj->objectName();
|
Chris@60
|
167
|
Chris@60
|
168 if (m_params.find(name) == m_params.end()) {
|
Chris@60
|
169 std::cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
|
Chris@60
|
170 return;
|
Chris@60
|
171 }
|
Chris@60
|
172
|
Chris@60
|
173 PluginInstance::ParameterDescriptor params = m_params[name].param;
|
Chris@60
|
174
|
Chris@60
|
175 float min = params.minValue;
|
Chris@60
|
176 float max = params.maxValue;
|
Chris@60
|
177
|
Chris@60
|
178 float qtz = 0.0;
|
Chris@60
|
179 if (params.isQuantized) qtz = params.quantizeStep;
|
Chris@60
|
180
|
Chris@60
|
181 if (qtz == 0.0) {
|
Chris@60
|
182 qtz = (max - min) / 100.0;
|
Chris@60
|
183 }
|
Chris@60
|
184
|
Chris@60
|
185 float newValue = min + ival * qtz;
|
Chris@60
|
186
|
Chris@60
|
187 QDoubleSpinBox *spin = m_params[name].spin;
|
Chris@63
|
188 if (spin) {
|
Chris@63
|
189 spin->blockSignals(true);
|
Chris@63
|
190 spin->setValue(newValue);
|
Chris@63
|
191 spin->blockSignals(false);
|
Chris@63
|
192 }
|
Chris@60
|
193
|
Chris@60
|
194 m_plugin->setParameter(name.toStdString(), newValue);
|
Chris@60
|
195 }
|
Chris@60
|
196
|
Chris@60
|
197 void
|
Chris@63
|
198 PluginParameterBox::checkBoxChanged(int state)
|
Chris@63
|
199 {
|
Chris@63
|
200 QObject *obj = sender();
|
Chris@63
|
201 QString name = obj->objectName();
|
Chris@63
|
202
|
Chris@63
|
203 if (m_params.find(name) == m_params.end()) {
|
Chris@63
|
204 std::cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
|
Chris@63
|
205 return;
|
Chris@63
|
206 }
|
Chris@63
|
207
|
Chris@63
|
208 PluginInstance::ParameterDescriptor params = m_params[name].param;
|
Chris@63
|
209
|
Chris@63
|
210 if (state) m_plugin->setParameter(name.toStdString(), 1.0);
|
Chris@63
|
211 else m_plugin->setParameter(name.toStdString(), 0.0);
|
Chris@63
|
212 }
|
Chris@63
|
213
|
Chris@63
|
214 void
|
Chris@60
|
215 PluginParameterBox::spinBoxChanged(double value)
|
Chris@60
|
216 {
|
Chris@60
|
217 QObject *obj = sender();
|
Chris@60
|
218 QString name = obj->objectName();
|
Chris@60
|
219
|
Chris@60
|
220 if (m_params.find(name) == m_params.end()) {
|
Chris@60
|
221 std::cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << name.toStdString() << "\"" << std::endl;
|
Chris@60
|
222 return;
|
Chris@60
|
223 }
|
Chris@60
|
224
|
Chris@60
|
225 PluginInstance::ParameterDescriptor params = m_params[name].param;
|
Chris@60
|
226
|
Chris@60
|
227 float min = params.minValue;
|
Chris@60
|
228 float max = params.maxValue;
|
Chris@60
|
229
|
Chris@60
|
230 float qtz = 0.0;
|
Chris@60
|
231 if (params.isQuantized) qtz = params.quantizeStep;
|
Chris@60
|
232
|
Chris@60
|
233 if (qtz > 0.0) {
|
Chris@60
|
234 int step = int((value - min) / qtz);
|
Chris@60
|
235 value = min + step * qtz;
|
Chris@60
|
236 }
|
Chris@60
|
237
|
Chris@60
|
238 int imin = 0, imax = 100;
|
Chris@60
|
239
|
Chris@60
|
240 if (qtz > 0.0) {
|
Chris@60
|
241 imax = int((max - min) / qtz);
|
Chris@60
|
242 } else {
|
Chris@60
|
243 qtz = (max - min) / 100.0;
|
Chris@60
|
244 }
|
Chris@60
|
245
|
Chris@60
|
246 int ival = (value - min) / qtz;
|
Chris@60
|
247
|
Chris@60
|
248 AudioDial *dial = m_params[name].dial;
|
Chris@63
|
249 if (dial) {
|
Chris@63
|
250 dial->blockSignals(true);
|
Chris@63
|
251 dial->setValue(ival);
|
Chris@63
|
252 dial->blockSignals(false);
|
Chris@63
|
253 }
|
Chris@60
|
254
|
Chris@60
|
255 m_plugin->setParameter(name.toStdString(), value);
|
Chris@60
|
256 }
|
Chris@60
|
257
|
Chris@63
|
258 void
|
Chris@63
|
259 PluginParameterBox::programComboChanged(const QString &newProgram)
|
Chris@63
|
260 {
|
Chris@63
|
261 m_plugin->selectProgram(newProgram.toStdString());
|
Chris@60
|
262
|
Chris@63
|
263 for (std::map<QString, ParamRec>::iterator i = m_params.begin();
|
Chris@63
|
264 i != m_params.end(); ++i) {
|
Chris@63
|
265
|
Chris@63
|
266 PluginInstance::ParameterDescriptor ¶m = i->second.param;
|
Chris@63
|
267 float value = m_plugin->getParameter(param.name);
|
Chris@63
|
268
|
Chris@63
|
269 if (i->second.spin) {
|
Chris@63
|
270 i->second.spin->blockSignals(true);
|
Chris@63
|
271 i->second.spin->setValue(value);
|
Chris@63
|
272 i->second.spin->blockSignals(false);
|
Chris@63
|
273 }
|
Chris@63
|
274
|
Chris@63
|
275 if (i->second.dial) {
|
Chris@63
|
276
|
Chris@63
|
277 float min = param.minValue;
|
Chris@63
|
278 float max = param.maxValue;
|
Chris@63
|
279
|
Chris@63
|
280 float qtz = 0.0;
|
Chris@63
|
281 if (param.isQuantized) qtz = param.quantizeStep;
|
Chris@63
|
282
|
Chris@63
|
283 if (qtz == 0.0) {
|
Chris@63
|
284 qtz = (max - min) / 100.0;
|
Chris@63
|
285 }
|
Chris@63
|
286
|
Chris@63
|
287 i->second.dial->blockSignals(true);
|
Chris@63
|
288 i->second.dial->setValue(int((value - min) / qtz));
|
Chris@63
|
289 i->second.dial->blockSignals(false);
|
Chris@63
|
290 }
|
Chris@63
|
291 }
|
Chris@63
|
292 }
|
Chris@63
|
293
|