comparison widgets/UnitConverter.cpp @ 893:78ae34f388f6

Tidy up layout and ranges for unit conversion dialog, highlight in red any out-of-range values
author Chris Cannam
date Mon, 15 Dec 2014 16:08:26 +0000
parents af63372e9002
children 8e4b90aeefaa
comparison
equal deleted inserted replaced
892:af63372e9002 893:78ae34f388f6
57 m_freq->setDecimals(6); 57 m_freq->setDecimals(6);
58 m_freq->setMinimum(1e-3); 58 m_freq->setMinimum(1e-3);
59 m_freq->setMaximum(1e6); 59 m_freq->setMaximum(1e6);
60 m_freq->setValue(440); 60 m_freq->setValue(440);
61 connect(m_freq, SIGNAL(valueChanged(double)), 61 connect(m_freq, SIGNAL(valueChanged(double)),
62 this, SLOT(freqChanged(double))); 62 this, SLOT(freqChanged()));
63 63
64 // The min and max range values for all the remaining controls are 64 // The min and max range values for all the remaining controls are
65 // determined by the min and max Hz above 65 // determined by the min and max Hz above
66 66
67 m_midi = new QSpinBox; 67 m_midi = new QSpinBox;
68 m_midi->setMinimum(-156); 68 m_midi->setMinimum(-156);
69 m_midi->setMaximum(203); 69 m_midi->setMaximum(203);
70 connect(m_midi, SIGNAL(valueChanged(int)), 70 connect(m_midi, SIGNAL(valueChanged(int)),
71 this, SLOT(midiChanged(int))); 71 this, SLOT(midiChanged()));
72 72
73 m_note = new QComboBox; 73 m_note = new QComboBox;
74 for (int i = 0; i < 12; ++i) { 74 for (int i = 0; i < 12; ++i) {
75 m_note->addItem(pianoNotes[i]); 75 m_note->addItem(pianoNotes[i]);
76 } 76 }
77 connect(m_note, SIGNAL(currentIndexChanged(int)), 77 connect(m_note, SIGNAL(currentIndexChanged(int)),
78 this, SLOT(noteChanged(int))); 78 this, SLOT(noteChanged()));
79 79
80 m_octave = new QSpinBox; 80 m_octave = new QSpinBox;
81 m_octave->setMinimum(-14); 81 m_octave->setMinimum(-14);
82 m_octave->setMaximum(15); 82 m_octave->setMaximum(15);
83 connect(m_octave, SIGNAL(valueChanged(int)), 83 connect(m_octave, SIGNAL(valueChanged(int)),
84 this, SLOT(octaveChanged(int))); 84 this, SLOT(octaveChanged()));
85 85
86 m_cents = new QDoubleSpinBox; 86 m_cents = new QDoubleSpinBox;
87 m_cents->setSuffix(tr(" cents")); 87 m_cents->setSuffix(tr(" cents"));
88 m_cents->setDecimals(4); 88 m_cents->setDecimals(4);
89 m_cents->setMinimum(-50); 89 m_cents->setMinimum(-50);
90 m_cents->setMaximum(50); 90 m_cents->setMaximum(50);
91 connect(m_cents, SIGNAL(valueChanged(double)), 91 connect(m_cents, SIGNAL(valueChanged(double)),
92 this, SLOT(centsChanged(double))); 92 this, SLOT(centsChanged()));
93 93
94 int row = 1; 94 int row = 0;
95
96 grid->addWidget(new QLabel(tr("In 12-tone Equal Temperament:")), row, 0, 1, 9);
97
98 ++row;
99
100 grid->setRowMinimumHeight(row, 8);
101
102 ++row;
95 103
96 grid->addWidget(m_freq, row, 0, 2, 1, Qt::AlignRight | Qt::AlignVCenter); 104 grid->addWidget(m_freq, row, 0, 2, 1, Qt::AlignRight | Qt::AlignVCenter);
97 grid->addWidget(new QLabel(tr("=")), row, 1, 2, 1, Qt::AlignHCenter | Qt::AlignVCenter); 105 grid->addWidget(new QLabel(tr("=")), row, 1, 2, 1, Qt::AlignHCenter | Qt::AlignVCenter);
98 106
99 grid->addWidget(new QLabel(tr("+")), row, 7, 2, 1, Qt::AlignHCenter | Qt::AlignVCenter); 107 grid->addWidget(new QLabel(tr("+")), row, 7, 2, 1, Qt::AlignHCenter | Qt::AlignVCenter);
109 grid->addWidget(new QLabel(tr("MIDI pitch")), row, 2, 1, 2); 117 grid->addWidget(new QLabel(tr("MIDI pitch")), row, 2, 1, 2);
110 grid->addWidget(m_midi, row, 4); 118 grid->addWidget(m_midi, row, 4);
111 119
112 ++row; 120 ++row;
113 121
122 grid->setRowStretch(row, 20);
123 grid->setRowMinimumHeight(row, 8);
124
125 ++row;
126
114 m_pitchPrefsLabel = new QLabel; 127 m_pitchPrefsLabel = new QLabel;
115 grid->addWidget(m_pitchPrefsLabel, row, 0, 1, 9); 128 grid->addWidget(m_pitchPrefsLabel, row, 0, 1, 9);
116 129
117 ++row; 130 ++row;
118 131
129 grid = new QGridLayout; 142 grid = new QGridLayout;
130 frame->setLayout(grid); 143 frame->setLayout(grid);
131 144
132 m_samples = new QDoubleSpinBox; 145 m_samples = new QDoubleSpinBox;
133 m_samples->setSuffix(QString(" samples")); 146 m_samples->setSuffix(QString(" samples"));
134 m_samples->setDecimals(3); 147 m_samples->setDecimals(2);
135 m_samples->setMinimum(2); 148 m_samples->setMinimum(1);
136 m_samples->setMaximum(1e10); 149 m_samples->setMaximum(1e8);
137 m_samples->setValue(22050); 150 m_samples->setValue(22050);
138 connect(m_samples, SIGNAL(valueChanged(double)), 151 connect(m_samples, SIGNAL(valueChanged(double)),
139 this, SLOT(samplesChanged(double))); 152 this, SLOT(samplesChanged()));
140 153
141 m_period = new QDoubleSpinBox; 154 m_period = new QDoubleSpinBox;
142 m_period->setSuffix(QString(" ms")); 155 m_period->setSuffix(QString(" ms"));
143 m_period->setDecimals(4); 156 m_period->setDecimals(4);
144 m_period->setMinimum(1e-10); 157 m_period->setMinimum(1e-3);
145 m_period->setMaximum(1000); 158 m_period->setMaximum(100000);
146 m_period->setValue(500); 159 m_period->setValue(500);
147 connect(m_period, SIGNAL(valueChanged(double)), 160 connect(m_period, SIGNAL(valueChanged(double)),
148 this, SLOT(periodChanged(double))); 161 this, SLOT(periodChanged()));
149 162
150 m_bpm = new QDoubleSpinBox; 163 m_bpm = new QDoubleSpinBox;
151 m_bpm->setSuffix(QString(" bpm")); 164 m_bpm->setSuffix(QString(" bpm"));
152 m_bpm->setDecimals(4); 165 m_bpm->setDecimals(4);
153 m_bpm->setMinimum(0.1); 166 m_bpm->setMinimum(0.1);
154 m_bpm->setMaximum(1e6); 167 m_bpm->setMaximum(1e6);
155 m_bpm->setValue(120); 168 m_bpm->setValue(120);
156 connect(m_bpm, SIGNAL(valueChanged(double)), 169 connect(m_bpm, SIGNAL(valueChanged(double)),
157 this, SLOT(bpmChanged(double))); 170 this, SLOT(bpmChanged()));
158 171
159 m_tempofreq = new QDoubleSpinBox; 172 m_tempofreq = new QDoubleSpinBox;
160 m_tempofreq->setSuffix(QString(" beats/sec")); 173 m_tempofreq->setSuffix(QString(" beats/sec"));
161 m_tempofreq->setDecimals(4); 174 m_tempofreq->setDecimals(4);
162 m_tempofreq->setMinimum(1e-4); 175 m_tempofreq->setMinimum(1e-3);
163 m_tempofreq->setMaximum(1e6); 176 m_tempofreq->setMaximum(1e5);
164 m_tempofreq->setValue(0.5); 177 m_tempofreq->setValue(0.5);
178
165 connect(m_tempofreq, SIGNAL(valueChanged(double)), 179 connect(m_tempofreq, SIGNAL(valueChanged(double)),
166 this, SLOT(tempofreqChanged(double))); 180 this, SLOT(tempofreqChanged()));
167 181
168 m_samplerate = new QComboBox; 182 m_samplerate = new QComboBox;
169 QList<int> rates; 183 QList<int> rates;
170 rates << 8000; 184 rates << 8000;
171 for (int i = 1; i <= 16; i *= 2) { 185 for (int i = 1; i <= 16; i *= 2) {
172 rates << 11025 * i << 12000 * i; 186 rates << 11025 * i << 12000 * i;
173 } 187 }
174 foreach (int r, rates) { 188 foreach (int r, rates) {
175 m_samplerate->addItem(QString("%1 Hz").arg(r)); 189 m_samplerate->addItem(QString("%1 Hz").arg(r));
176 } 190 }
177 connect(m_samplerate, SIGNAL(currentItemChanged(QString)), 191 connect(m_samplerate, SIGNAL(currentIndexChanged(int)),
178 this, SLOT(samplerateChanged(QString))); 192 this, SLOT(samplerateChanged()));
179 m_samplerate->setCurrentText("44100 Hz"); 193 m_samplerate->setCurrentText("44100 Hz");
180 194
181 connect(Preferences::getInstance(), 195 connect(Preferences::getInstance(),
182 SIGNAL(propertyChanged(PropertyContainer::PropertyName)), 196 SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
183 this, SLOT(preferenceChanged(PropertyContainer::PropertyName))); 197 this, SLOT(preferenceChanged(PropertyContainer::PropertyName)));
184 198
185 row = 1; 199 row = 0;
186 200
187 grid->addWidget(new QLabel(tr("Beat period")), row, 0); 201 grid->setRowStretch(row, 20);
202 grid->setRowMinimumHeight(row, 8);
203
204 ++row;
205
206 grid->addWidget(new QLabel(tr("Beat period")), row, 0, 2, 1, Qt::AlignVCenter);
207 grid->addWidget(m_period, row, 1);
208 grid->addWidget(new QLabel(tr("=")), row, 2, 2, 1, Qt::AlignVCenter);
209
210 grid->addWidget(m_tempofreq, row, 3);
211
212 grid->addWidget(new QLabel(tr("at")), row, 4, 2, 1, Qt::AlignVCenter);
213 grid->addWidget(m_samplerate, row, 5, 2, 1, Qt::AlignVCenter);
214
215 ++row;
216
188 grid->addWidget(m_samples, row, 1); 217 grid->addWidget(m_samples, row, 1);
189 grid->addWidget(new QLabel(tr("=")), row, 2);
190
191 grid->addWidget(new QLabel(tr("at sample rate")), row, 4);
192 grid->addWidget(m_samplerate, row, 5);
193
194 grid->addWidget(m_bpm, row, 3); 218 grid->addWidget(m_bpm, row, 3);
195 219
196 ++row; 220 ++row;
197 221
198 grid->addWidget(m_period, row, 3); 222 grid->setRowStretch(row, 20);
199 223 grid->setRowMinimumHeight(row, 8);
200 ++row; 224
201
202 grid->addWidget(m_tempofreq, row, 3);
203
204 updatePitchesFromFreq(); 225 updatePitchesFromFreq();
205 updatePitchPrefsLabel(); 226 updatePitchPrefsLabel();
206 updateTempiFromSamples(); 227 updateTempiFromSamples();
207 } 228 }
208 229
209 UnitConverter::~UnitConverter() 230 UnitConverter::~UnitConverter()
210 { 231 {
232 }
233
234 void
235 UnitConverter::setTo(QSpinBox *box, int value)
236 {
237 box->blockSignals(true);
238 if (value < box->minimum() || value > box->maximum()) {
239 QPalette p;
240 p.setColor(QPalette::Text, Qt::red);
241 box->setPalette(p);
242 } else {
243 box->setPalette(QPalette());
244 }
245 box->setValue(value);
246 box->blockSignals(false);
247 }
248
249 void
250 UnitConverter::setTo(QDoubleSpinBox *box, double value)
251 {
252 box->blockSignals(true);
253 if (value < box->minimum() || value > box->maximum()) {
254 QPalette p;
255 p.setColor(QPalette::Text, Qt::red);
256 box->setPalette(p);
257 } else {
258 box->setPalette(QPalette());
259 }
260 box->setValue(value);
261 box->blockSignals(false);
211 } 262 }
212 263
213 void 264 void
214 UnitConverter::preferenceChanged(PropertyContainer::PropertyName) 265 UnitConverter::preferenceChanged(PropertyContainer::PropertyName)
215 { 266 {
227 .arg(Preferences::getInstance()->getTuningFrequency()) 278 .arg(Preferences::getInstance()->getTuningFrequency())
228 .arg(Preferences::getInstance()->getOctaveOfMiddleC())); 279 .arg(Preferences::getInstance()->getOctaveOfMiddleC()));
229 } 280 }
230 281
231 void 282 void
232 UnitConverter::freqChanged(double freq) 283 UnitConverter::freqChanged()
233 { 284 {
234 cerr << "freqChanged: " << freq << endl;
235 updatePitchesFromFreq(); 285 updatePitchesFromFreq();
236 } 286 }
237 287
238 void 288 void
239 UnitConverter::midiChanged(int midi) 289 UnitConverter::midiChanged()
240 { 290 {
241 cerr << "midiChanged: " << midi << endl;
242 double freq = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value()); 291 double freq = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value());
243 cerr << "freq -> " << freq << endl;
244 m_freq->setValue(freq); 292 m_freq->setValue(freq);
245 } 293 }
246 294
247 void 295 void
248 UnitConverter::noteChanged(int note) 296 UnitConverter::noteChanged()
249 { 297 {
250 cerr << "noteChanged: " << note << endl;
251 int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(), 298 int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(),
252 m_octave->value()); 299 m_octave->value());
253 double freq = Pitch::getFrequencyForPitch(pitch, m_cents->value()); 300 double freq = Pitch::getFrequencyForPitch(pitch, m_cents->value());
254 cerr << "freq -> " << freq << endl;
255 m_freq->setValue(freq); 301 m_freq->setValue(freq);
256 } 302 }
257 303
258 void 304 void
259 UnitConverter::octaveChanged(int oct) 305 UnitConverter::octaveChanged()
260 { 306 {
261 cerr << "octaveChanged: " << oct << endl;
262 int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(), 307 int pitch = Pitch::getPitchForNoteAndOctave(m_note->currentIndex(),
263 m_octave->value()); 308 m_octave->value());
264 double freq = Pitch::getFrequencyForPitch(pitch, m_cents->value()); 309 double freq = Pitch::getFrequencyForPitch(pitch, m_cents->value());
265 cerr << "freq -> " << freq << endl;
266 m_freq->setValue(freq); 310 m_freq->setValue(freq);
267 } 311 }
268 312
269 void 313 void
270 UnitConverter::centsChanged(double cents) 314 UnitConverter::centsChanged()
271 { 315 {
272 cerr << "centsChanged: " << cents << endl;
273 double freq = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value()); 316 double freq = Pitch::getFrequencyForPitch(m_midi->value(), m_cents->value());
274 cerr << "freq -> " << freq << endl;
275 m_freq->setValue(freq); 317 m_freq->setValue(freq);
276 } 318 }
277 319
278 void 320 void
279 UnitConverter::updatePitchesFromFreq() 321 UnitConverter::updatePitchesFromFreq()
282 int pitch = Pitch::getPitchForFrequency(m_freq->value(), &cents); 324 int pitch = Pitch::getPitchForFrequency(m_freq->value(), &cents);
283 int note, octave; 325 int note, octave;
284 Pitch::getNoteAndOctaveForPitch(pitch, note, octave); 326 Pitch::getNoteAndOctaveForPitch(pitch, note, octave);
285 327
286 cerr << "pitch " << pitch << " note " << note << " octave " << octave << " cents " << cents << endl; 328 cerr << "pitch " << pitch << " note " << note << " octave " << octave << " cents " << cents << endl;
287 329
288 m_midi->blockSignals(true); 330 setTo(m_midi, pitch);
289 m_cents->blockSignals(true); 331 setTo(m_cents, cents);
332 setTo(m_octave, octave);
333
290 m_note->blockSignals(true); 334 m_note->blockSignals(true);
291 m_octave->blockSignals(true);
292
293 m_midi->setValue(pitch);
294 m_cents->setValue(cents);
295 m_note->setCurrentIndex(note); 335 m_note->setCurrentIndex(note);
296 m_octave->setValue(octave);
297
298 m_midi->blockSignals(false);
299 m_cents->blockSignals(false);
300 m_note->blockSignals(false); 336 m_note->blockSignals(false);
301 m_octave->blockSignals(false); 337 }
302 } 338
303 339 void
304 void 340 UnitConverter::samplesChanged()
305 UnitConverter::samplesChanged(double)
306 { 341 {
307 updateTempiFromSamples(); 342 updateTempiFromSamples();
308 } 343 }
309 344
310 void 345 void
311 UnitConverter::periodChanged(double) 346 UnitConverter::periodChanged()
312 { 347 {
313 double rate = getSampleRate(); 348 double rate = getSampleRate();
314 double sec = m_period->value() / 1000.0; 349 double sec = m_period->value() / 1000.0;
315 double samples = rate * sec; 350 double samples = rate * sec;
316 m_samples->setValue(samples); 351 m_samples->setValue(samples);
317 } 352 }
318 353
319 void 354 void
320 UnitConverter::bpmChanged(double) 355 UnitConverter::bpmChanged()
321 { 356 {
322 double rate = getSampleRate(); 357 double rate = getSampleRate();
323 double sec = 60.0 / m_bpm->value(); 358 double sec = 60.0 / m_bpm->value();
324 double samples = rate * sec; 359 double samples = rate * sec;
325 m_samples->setValue(samples); 360 m_samples->setValue(samples);
326 } 361 }
327 362
328 void 363 void
329 UnitConverter::tempofreqChanged(double) 364 UnitConverter::tempofreqChanged()
330 { 365 {
331 double rate = getSampleRate(); 366 double rate = getSampleRate();
332 double samples = rate / m_tempofreq->value(); 367 double samples = rate / m_tempofreq->value();
333 m_samples->setValue(samples); 368 m_samples->setValue(samples);
334 } 369 }
335 370
336 void 371 void
337 UnitConverter::samplerateChanged(QString) 372 UnitConverter::samplerateChanged()
338 { 373 {
339 updateTempiFromSamples(); 374 // Preserve the beat period in seconds, here, not in samples
375 periodChanged();
340 } 376 }
341 377
342 double 378 double
343 UnitConverter::getSampleRate() 379 UnitConverter::getSampleRate()
344 { 380 {
355 391
356 double sec = samples / rate; 392 double sec = samples / rate;
357 double hz = rate / samples; 393 double hz = rate / samples;
358 double bpm = 60.0 / sec; 394 double bpm = 60.0 / sec;
359 395
360 m_bpm->blockSignals(true); 396 setTo(m_bpm, bpm);
361 m_period->blockSignals(true); 397 setTo(m_period, sec * 1000.0);
362 m_tempofreq->blockSignals(true); 398 setTo(m_tempofreq, hz);
363
364 m_bpm->setValue(bpm);
365 m_period->setValue(sec * 1000.0);
366 m_tempofreq->setValue(hz);
367
368 m_bpm->blockSignals(false);
369 m_period->blockSignals(false);
370 m_tempofreq->blockSignals(false);
371 } 399 }
372 400
373 401