comparison widgets/PropertyBox.cpp @ 1203:ff042979331b 3.0-integration

Merge from branch svg, and thus (in some subrepos) from levelpanwidget
author Chris Cannam
date Mon, 19 Dec 2016 16:34:38 +0000
parents 73d43e410a6b
children d421df27e184
comparison
equal deleted inserted replaced
1185:f32828ea63d9 1203:ff042979331b
18 18
19 #include "base/PropertyContainer.h" 19 #include "base/PropertyContainer.h"
20 #include "base/PlayParameters.h" 20 #include "base/PlayParameters.h"
21 #include "base/PlayParameterRepository.h" 21 #include "base/PlayParameterRepository.h"
22 #include "layer/Layer.h" 22 #include "layer/Layer.h"
23 #include "layer/ColourDatabase.h"
24 #include "base/UnitDatabase.h" 23 #include "base/UnitDatabase.h"
25 #include "base/RangeMapper.h" 24 #include "base/RangeMapper.h"
26 25
27 #include "AudioDial.h" 26 #include "AudioDial.h"
28 #include "LEDButton.h" 27 #include "LEDButton.h"
29 #include "IconLoader.h" 28 #include "IconLoader.h"
29 #include "LevelPanWidget.h"
30 #include "LevelPanToolButton.h"
31 #include "WidgetScale.h"
30 32
31 #include "NotifyingCheckBox.h" 33 #include "NotifyingCheckBox.h"
32 #include "NotifyingComboBox.h" 34 #include "NotifyingComboBox.h"
33 #include "NotifyingPushButton.h" 35 #include "NotifyingPushButton.h"
34 #include "ColourNameDialog.h" 36 #include "NotifyingToolButton.h"
37 #include "ColourComboBox.h"
38 #include "ColourMapComboBox.h"
35 39
36 #include <QGridLayout> 40 #include <QGridLayout>
37 #include <QHBoxLayout> 41 #include <QHBoxLayout>
38 #include <QVBoxLayout> 42 #include <QVBoxLayout>
39 #include <QPushButton> 43 #include <QPushButton>
44 #include <QToolButton>
40 #include <QLabel> 45 #include <QLabel>
41 #include <QFrame> 46 #include <QFrame>
42 #include <QApplication> 47 #include <QApplication>
43 #include <QColorDialog> 48 #include <QColorDialog>
44 #include <QInputDialog> 49 #include <QInputDialog>
101 m_layout->setRowStretch(m_layout->rowCount(), 10); 106 m_layout->setRowStretch(m_layout->rowCount(), 10);
102 107
103 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()), 108 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()),
104 this, SLOT(unitDatabaseChanged())); 109 this, SLOT(unitDatabaseChanged()));
105 110
106 connect(ColourDatabase::getInstance(), SIGNAL(colourDatabaseChanged()),
107 this, SLOT(colourDatabaseChanged()));
108
109 #ifdef DEBUG_PROPERTY_BOX 111 #ifdef DEBUG_PROPERTY_BOX
110 cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl; 112 cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl;
111 #endif 113 #endif
112 } 114 }
113 115
145 147
146 m_viewPlayFrame = new QFrame; 148 m_viewPlayFrame = new QFrame;
147 m_viewPlayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); 149 m_viewPlayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
148 m_mainBox->addWidget(m_viewPlayFrame); 150 m_mainBox->addWidget(m_viewPlayFrame);
149 151
150 QHBoxLayout *layout = new QHBoxLayout; 152 QGridLayout *layout = new QGridLayout;
151 m_viewPlayFrame->setLayout(layout); 153 m_viewPlayFrame->setLayout(layout);
152 154
153 layout->setMargin(layout->margin() / 2); 155 layout->setMargin(layout->margin() / 2);
154 156
155 #ifdef DEBUG_PROPERTY_BOX 157 #ifdef DEBUG_PROPERTY_BOX
156 SVDEBUG << "PropertyBox::populateViewPlayFrame: container " << m_container << " (name " << m_container->getPropertyContainerName() << ") params " << params << endl; 158 SVDEBUG << "PropertyBox::populateViewPlayFrame: container " << m_container << " (name " << m_container->getPropertyContainerName() << ") params " << params << endl;
157 #endif 159 #endif
158 160
159 if (layer) { 161 QSize buttonSize = WidgetScale::scaleQSize(QSize(26, 26));
160 QLabel *showLabel = new QLabel(tr("Show")); 162 int col = 0;
161 layout->addWidget(showLabel); 163
162 layout->setAlignment(showLabel, Qt::AlignVCenter);
163
164 m_showButton = new LEDButton(Qt::blue);
165 layout->addWidget(m_showButton);
166 connect(m_showButton, SIGNAL(stateChanged(bool)),
167 this, SIGNAL(showLayer(bool)));
168 connect(m_showButton, SIGNAL(mouseEntered()),
169 this, SLOT(mouseEnteredWidget()));
170 connect(m_showButton, SIGNAL(mouseLeft()),
171 this, SLOT(mouseLeftWidget()));
172 layout->setAlignment(m_showButton, Qt::AlignVCenter);
173 }
174
175 if (params) { 164 if (params) {
176 165
177 QLabel *playLabel = new QLabel(tr("Play")); 166 m_playButton = new NotifyingToolButton;
178 layout->addWidget(playLabel); 167 m_playButton->setCheckable(true);
179 layout->setAlignment(playLabel, Qt::AlignVCenter); 168 m_playButton->setIcon(IconLoader().load("speaker"));
180 169 m_playButton->setToolTip(tr("Click to toggle playback"));
181 m_playButton = new LEDButton(Qt::darkGreen); 170 m_playButton->setChecked(!params->isPlayMuted());
182 m_playButton->setState(!params->isPlayMuted()); 171 m_playButton->setFixedSize(buttonSize);
183 layout->addWidget(m_playButton); 172 connect(m_playButton, SIGNAL(toggled(bool)),
184 connect(m_playButton, SIGNAL(stateChanged(bool)),
185 this, SLOT(playAudibleButtonChanged(bool))); 173 this, SLOT(playAudibleButtonChanged(bool)));
186 connect(m_playButton, SIGNAL(mouseEntered()), 174 connect(m_playButton, SIGNAL(mouseEntered()),
187 this, SLOT(mouseEnteredWidget())); 175 this, SLOT(mouseEnteredWidget()));
188 connect(m_playButton, SIGNAL(mouseLeft()), 176 connect(m_playButton, SIGNAL(mouseLeft()),
189 this, SLOT(mouseLeftWidget())); 177 this, SLOT(mouseLeftWidget()));
190 connect(params, SIGNAL(playAudibleChanged(bool)), 178 connect(params, SIGNAL(playAudibleChanged(bool)),
191 this, SLOT(playAudibleChanged(bool))); 179 this, SLOT(playAudibleChanged(bool)));
192 layout->setAlignment(m_playButton, Qt::AlignVCenter); 180
193 181 LevelPanToolButton *levelPan = new LevelPanToolButton;
194 layout->insertStretch(-1, 10); 182 levelPan->setFixedSize(buttonSize);
183 levelPan->setImageSize((buttonSize.height() * 3) / 4);
184 layout->addWidget(levelPan, 0, col++, Qt::AlignCenter);
185 connect(levelPan, SIGNAL(levelChanged(float)),
186 this, SLOT(playGainControlChanged(float)));
187 connect(levelPan, SIGNAL(panChanged(float)),
188 this, SLOT(playPanControlChanged(float)));
189 connect(params, SIGNAL(playGainChanged(float)),
190 levelPan, SLOT(setLevel(float)));
191 connect(params, SIGNAL(playPanChanged(float)),
192 levelPan, SLOT(setPan(float)));
193 connect(levelPan, SIGNAL(mouseEntered()),
194 this, SLOT(mouseEnteredWidget()));
195 connect(levelPan, SIGNAL(mouseLeft()),
196 this, SLOT(mouseLeftWidget()));
197
198 layout->addWidget(m_playButton, 0, col++, Qt::AlignCenter);
195 199
196 if (params->getPlayClipId() != "") { 200 if (params->getPlayClipId() != "") {
197 QPushButton *playParamButton = 201 QToolButton *playParamButton = new QToolButton;
198 new QPushButton(QIcon(":icons/faders.png"), ""); 202 playParamButton->setObjectName("playParamButton");
199 playParamButton->setFixedWidth(24); 203 playParamButton->setIcon(IconLoader().load("faders"));
200 playParamButton->setFixedHeight(24); 204 playParamButton->setFixedSize(buttonSize);
201 layout->addWidget(playParamButton); 205 layout->addWidget(playParamButton, 0, col++, Qt::AlignCenter);
202 connect(playParamButton, SIGNAL(clicked()), 206 connect(playParamButton, SIGNAL(clicked()),
203 this, SLOT(editPlayParameters())); 207 this, SLOT(editPlayParameters()));
204 } 208 connect(playParamButton, SIGNAL(mouseEntered()),
205 209 this, SLOT(mouseEnteredWidget()));
206 AudioDial *gainDial = new AudioDial; 210 connect(playParamButton, SIGNAL(mouseLeft()),
207 layout->addWidget(gainDial); 211 this, SLOT(mouseLeftWidget()));
208 gainDial->setMeterColor(Qt::darkRed); 212 }
209 gainDial->setMinimum(-50); 213 }
210 gainDial->setMaximum(50); 214
211 gainDial->setPageStep(1); 215 layout->setColumnStretch(col++, 10);
212 gainDial->setFixedWidth(24); 216
213 gainDial->setFixedHeight(24); 217 if (layer) {
214 gainDial->setNotchesVisible(false); 218
215 gainDial->setObjectName(tr("Playback Gain")); 219 QLabel *showLabel = new QLabel(tr("Show"));
216 gainDial->setRangeMapper(new LinearRangeMapper 220 layout->addWidget(showLabel, 0, col++, Qt::AlignVCenter | Qt::AlignRight);
217 (-50, 50, -25, 25, tr("dB"))); 221
218 gainDial->setDefaultValue(0); 222 m_showButton = new LEDButton(palette().highlight().color());
219 gainDial->setShowToolTip(true); 223 layout->addWidget(m_showButton, 0, col++, Qt::AlignVCenter | Qt::AlignLeft);
220 connect(gainDial, SIGNAL(valueChanged(int)), 224 connect(m_showButton, SIGNAL(stateChanged(bool)),
221 this, SLOT(playGainDialChanged(int))); 225 this, SIGNAL(showLayer(bool)));
222 connect(params, SIGNAL(playGainChanged(float)), 226 connect(m_showButton, SIGNAL(mouseEntered()),
223 this, SLOT(playGainChanged(float)));
224 connect(this, SIGNAL(changePlayGainDial(int)),
225 gainDial, SLOT(setValue(int)));
226 connect(gainDial, SIGNAL(mouseEntered()),
227 this, SLOT(mouseEnteredWidget())); 227 this, SLOT(mouseEnteredWidget()));
228 connect(gainDial, SIGNAL(mouseLeft()), 228 connect(m_showButton, SIGNAL(mouseLeft()),
229 this, SLOT(mouseLeftWidget())); 229 this, SLOT(mouseLeftWidget()));
230 playGainChanged(params->getPlayGain());
231 layout->setAlignment(gainDial, Qt::AlignVCenter);
232
233 AudioDial *panDial = new AudioDial;
234 layout->addWidget(panDial);
235 panDial->setMeterColor(Qt::darkGreen);
236 panDial->setMinimum(-50);
237 panDial->setMaximum(50);
238 panDial->setPageStep(1);
239 panDial->setFixedWidth(24);
240 panDial->setFixedHeight(24);
241 panDial->setNotchesVisible(false);
242 panDial->setToolTip(tr("Playback Pan / Balance"));
243 panDial->setDefaultValue(0);
244 panDial->setObjectName(tr("Playback Pan / Balance"));
245 panDial->setShowToolTip(true);
246 connect(panDial, SIGNAL(valueChanged(int)),
247 this, SLOT(playPanDialChanged(int)));
248 connect(params, SIGNAL(playPanChanged(float)),
249 this, SLOT(playPanChanged(float)));
250 connect(this, SIGNAL(changePlayPanDial(int)),
251 panDial, SLOT(setValue(int)));
252 connect(panDial, SIGNAL(mouseEntered()),
253 this, SLOT(mouseEnteredWidget()));
254 connect(panDial, SIGNAL(mouseLeft()),
255 this, SLOT(mouseLeftWidget()));
256 playPanChanged(params->getPlayPan());
257 layout->setAlignment(panDial, Qt::AlignVCenter);
258
259 } else {
260
261 layout->insertStretch(-1, 10);
262 } 230 }
263 } 231 }
264 232
265 void 233 void
266 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name, 234 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name,
286 cerr << "::updatePropertyEditor(\"" << name << "\"):"; 254 cerr << "::updatePropertyEditor(\"" << name << "\"):";
287 cerr << " value " << value << ", have " << have << ", group \"" 255 cerr << " value " << value << ", have " << have << ", group \""
288 << groupName << "\"" << endl; 256 << groupName << "\"" << endl;
289 #endif 257 #endif
290 258
291 bool inGroup = (groupName != QString());
292
293 if (!have) { 259 if (!have) {
294 if (inGroup) { 260
261 QLabel *labelWidget = 0;
262
263 if (groupName != QString()) {
295 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) { 264 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) {
296 #ifdef DEBUG_PROPERTY_BOX 265 labelWidget = new QLabel(groupName, m_mainWidget);
297 cerr << "PropertyBox: adding label \"" << groupName << "\" and frame for group for \"" << name << "\"" << endl; 266 }
298 #endif 267 } else {
299 m_layout->addWidget(new QLabel(groupName, m_mainWidget), row, 0); 268 groupName = "ungrouped: " + propertyLabel;
300 QFrame *frame = new QFrame(m_mainWidget); 269 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) {
301 m_layout->addWidget(frame, row, 1, 1, 2); 270 labelWidget = new QLabel(propertyLabel, m_mainWidget);
302 m_groupLayouts[groupName] = new QGridLayout; 271 }
303 m_groupLayouts[groupName]->setMargin(0); 272 }
304 frame->setLayout(m_groupLayouts[groupName]); 273
305 } 274 if (labelWidget) {
306 } else { 275 m_layout->addWidget(labelWidget, row, 0);
307 #ifdef DEBUG_PROPERTY_BOX 276 QWidget *frame = new QWidget(m_mainWidget);
308 cerr << "PropertyBox: adding label \"" << propertyLabel << "\"" << endl; 277 frame->setMinimumSize(WidgetScale::scaleQSize(QSize(1, 24)));
309 #endif 278 m_groupLayouts[groupName] = new QGridLayout;
310 m_layout->addWidget(new QLabel(propertyLabel, m_mainWidget), row, 0); 279 #ifdef Q_OS_MAC
311 } 280 // Seems to be plenty of whitespace already
281 m_groupLayouts[groupName]->setContentsMargins(0, 0, 0, 0);
282 #else
283 // Need a bit of padding on the left
284 m_groupLayouts[groupName]->setContentsMargins
285 (WidgetScale::scalePixelSize(10), 0, 0, 0);
286 #endif
287 frame->setLayout(m_groupLayouts[groupName]);
288 m_layout->addWidget(frame, row, 1, 1, 2);
289 m_layout->setColumnStretch(1, 10);
290 }
312 } 291 }
313 292
314 switch (type) { 293 switch (type) {
315 294
316 case PropertyContainer::ToggleProperty: 295 case PropertyContainer::ToggleProperty:
317 { 296 {
318 QAbstractButton *button = 0; 297 QAbstractButton *button = 0;
319 298
320 if (have) { 299 if (have) {
321 button = dynamic_cast<QAbstractButton *>(m_propertyControllers[name]); 300 button = qobject_cast<QAbstractButton *>(m_propertyControllers[name]);
322 assert(button); 301 assert(button);
323 } else { 302 } else {
324 #ifdef DEBUG_PROPERTY_BOX 303 #ifdef DEBUG_PROPERTY_BOX
325 cerr << "PropertyBox: creating new checkbox" << endl; 304 cerr << "PropertyBox: creating new checkbox" << endl;
326 #endif 305 #endif
328 button = new NotifyingPushButton(); 307 button = new NotifyingPushButton();
329 button->setCheckable(true); 308 button->setCheckable(true);
330 QIcon icon(IconLoader().load(iconName)); 309 QIcon icon(IconLoader().load(iconName));
331 button->setIcon(icon); 310 button->setIcon(icon);
332 button->setObjectName(name); 311 button->setObjectName(name);
333 button->setFixedSize(QSize(18, 18)); 312 button->setFixedSize(WidgetScale::scaleQSize(QSize(18, 18)));
334 } else { 313 } else {
335 button = new NotifyingCheckBox(); 314 button = new NotifyingCheckBox();
336 button->setObjectName(name); 315 button->setObjectName(name);
337 } 316 }
338 connect(button, SIGNAL(toggled(bool)), 317 connect(button, SIGNAL(toggled(bool)),
339 this, SLOT(propertyControllerChanged(bool))); 318 this, SLOT(propertyControllerChanged(bool)));
340 connect(button, SIGNAL(mouseEntered()), 319 connect(button, SIGNAL(mouseEntered()),
341 this, SLOT(mouseEnteredWidget())); 320 this, SLOT(mouseEnteredWidget()));
342 connect(button, SIGNAL(mouseLeft()), 321 connect(button, SIGNAL(mouseLeft()),
343 this, SLOT(mouseLeftWidget())); 322 this, SLOT(mouseLeftWidget()));
344 if (inGroup) { 323 button->setToolTip(propertyLabel);
345 button->setToolTip(propertyLabel); 324 m_groupLayouts[groupName]->addWidget
346 m_groupLayouts[groupName]->addWidget 325 (button, 0, m_groupLayouts[groupName]->columnCount());
347 (button, 0, m_groupLayouts[groupName]->columnCount());
348 } else {
349 m_layout->addWidget(button, row, 1, 1, 2);
350 }
351 m_propertyControllers[name] = button; 326 m_propertyControllers[name] = button;
352 } 327 }
353 328
354 if (button->isChecked() != (value > 0)) { 329 if (button->isChecked() != (value > 0)) {
355 button->blockSignals(true); 330 button->blockSignals(true);
362 case PropertyContainer::RangeProperty: 337 case PropertyContainer::RangeProperty:
363 { 338 {
364 AudioDial *dial; 339 AudioDial *dial;
365 340
366 if (have) { 341 if (have) {
367 dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]); 342 dial = qobject_cast<AudioDial *>(m_propertyControllers[name]);
368 assert(dial); 343 assert(dial);
369 if (rangeChanged) { 344 if (rangeChanged) {
370 dial->blockSignals(true); 345 dial->blockSignals(true);
371 dial->setMinimum(min); 346 dial->setMinimum(min);
372 dial->setMaximum(max); 347 dial->setMaximum(max);
394 connect(dial, SIGNAL(mouseEntered()), 369 connect(dial, SIGNAL(mouseEntered()),
395 this, SLOT(mouseEnteredWidget())); 370 this, SLOT(mouseEnteredWidget()));
396 connect(dial, SIGNAL(mouseLeft()), 371 connect(dial, SIGNAL(mouseLeft()),
397 this, SLOT(mouseLeftWidget())); 372 this, SLOT(mouseLeftWidget()));
398 373
399 if (inGroup) { 374 dial->setFixedWidth(WidgetScale::scalePixelSize(24));
400 dial->setFixedWidth(24); 375 dial->setFixedHeight(WidgetScale::scalePixelSize(24));
401 dial->setFixedHeight(24); 376 m_groupLayouts[groupName]->addWidget
402 m_groupLayouts[groupName]->addWidget 377 (dial, 0, m_groupLayouts[groupName]->columnCount());
403 (dial, 0, m_groupLayouts[groupName]->columnCount());
404 } else {
405 dial->setFixedWidth(32);
406 dial->setFixedHeight(32);
407 m_layout->addWidget(dial, row, 1);
408 QLabel *label = new QLabel(m_mainWidget);
409 connect(dial, SIGNAL(valueChanged(int)),
410 label, SLOT(setNum(int)));
411 label->setNum(value);
412 m_layout->addWidget(label, row, 2);
413 }
414 378
415 m_propertyControllers[name] = dial; 379 m_propertyControllers[name] = dial;
416 } 380 }
417 381
418 if (dial->value() != value) { 382 if (dial->value() != value) {
421 dial->blockSignals(false); 385 dial->blockSignals(false);
422 } 386 }
423 break; 387 break;
424 } 388 }
425 389
390 case PropertyContainer::ColourProperty:
391 {
392 ColourComboBox *cb;
393
394 if (have) {
395 cb = qobject_cast<ColourComboBox *>(m_propertyControllers[name]);
396 assert(cb);
397 } else {
398 #ifdef DEBUG_PROPERTY_BOX
399 cerr << "PropertyBox: creating new colour combobox" << endl;
400 #endif
401 cb = new ColourComboBox(true);
402 cb->setObjectName(name);
403
404 connect(cb, SIGNAL(colourChanged(int)),
405 this, SLOT(propertyControllerChanged(int)));
406 connect(cb, SIGNAL(mouseEntered()),
407 this, SLOT(mouseEnteredWidget()));
408 connect(cb, SIGNAL(mouseLeft()),
409 this, SLOT(mouseLeftWidget()));
410
411 cb->setToolTip(propertyLabel);
412 m_groupLayouts[groupName]->addWidget
413 (cb, 0, m_groupLayouts[groupName]->columnCount());
414 m_propertyControllers[name] = cb;
415 }
416
417 if (cb->currentIndex() != value) {
418 cb->blockSignals(true);
419 cb->setCurrentIndex(value);
420 cb->blockSignals(false);
421 }
422
423 break;
424 }
425
426 case PropertyContainer::ColourMapProperty:
427 {
428 ColourMapComboBox *cb;
429
430 if (have) {
431 cb = qobject_cast<ColourMapComboBox *>(m_propertyControllers[name]);
432 assert(cb);
433 } else {
434 #ifdef DEBUG_PROPERTY_BOX
435 cerr << "PropertyBox: creating new colourmap combobox" << endl;
436 #endif
437 cb = new ColourMapComboBox(false);
438 cb->setObjectName(name);
439
440 connect(cb, SIGNAL(colourMapChanged(int)),
441 this, SLOT(propertyControllerChanged(int)));
442 connect(cb, SIGNAL(mouseEntered()),
443 this, SLOT(mouseEnteredWidget()));
444 connect(cb, SIGNAL(mouseLeft()),
445 this, SLOT(mouseLeftWidget()));
446
447 cb->setToolTip(propertyLabel);
448 m_groupLayouts[groupName]->addWidget
449 (cb, 0, m_groupLayouts[groupName]->columnCount());
450 m_propertyControllers[name] = cb;
451 }
452
453 if (cb->currentIndex() != value) {
454 cb->blockSignals(true);
455 cb->setCurrentIndex(value);
456 cb->blockSignals(false);
457 }
458
459 break;
460 }
461
426 case PropertyContainer::ValueProperty: 462 case PropertyContainer::ValueProperty:
427 case PropertyContainer::UnitsProperty: 463 case PropertyContainer::UnitsProperty:
428 case PropertyContainer::ColourProperty:
429 { 464 {
430 NotifyingComboBox *cb; 465 NotifyingComboBox *cb;
431 466
432 if (have) { 467 if (have) {
433 cb = dynamic_cast<NotifyingComboBox *>(m_propertyControllers[name]); 468 cb = qobject_cast<NotifyingComboBox *>(m_propertyControllers[name]);
434 assert(cb); 469 assert(cb);
435 } else { 470 } else {
436 #ifdef DEBUG_PROPERTY_BOX 471 #ifdef DEBUG_PROPERTY_BOX
437 cerr << "PropertyBox: creating new combobox" << endl; 472 cerr << "PropertyBox: creating new combobox" << endl;
438 #endif 473 #endif
461 } else { 496 } else {
462 cb->addItem(label); 497 cb->addItem(label);
463 } 498 }
464 } 499 }
465 500
466 } else if (type == PropertyContainer::UnitsProperty) { 501 } else { // PropertyContainer::UnitsProperty
467 502
468 QStringList units = UnitDatabase::getInstance()->getKnownUnits(); 503 QStringList units = UnitDatabase::getInstance()->getKnownUnits();
469 for (int i = 0; i < units.size(); ++i) { 504 for (int i = 0; i < units.size(); ++i) {
470 cb->addItem(units[i]); 505 cb->addItem(units[i]);
471 } 506 }
472 507
473 cb->setEditable(true); 508 cb->setEditable(true);
474
475 } else { // ColourProperty
476
477 //!!! should be a proper colour combobox class that
478 // manages its own Add New Colour entry...
479
480 int size = (QFontMetrics(QFont()).height() * 2) / 3;
481 if (size < 12) size = 12;
482
483 ColourDatabase *db = ColourDatabase::getInstance();
484 for (int i = 0; i < db->getColourCount(); ++i) {
485 QString name = db->getColourName(i);
486 cb->addItem(db->getExamplePixmap(i, QSize(size, size)), name);
487 }
488 cb->addItem(tr("Add New Colour..."));
489 }
490
491 cb->blockSignals(false);
492 if (cb->count() < 20 && cb->count() > cb->maxVisibleItems()) {
493 cb->setMaxVisibleItems(cb->count());
494 } 509 }
495 } 510 }
496 511
497 if (!have) { 512 if (!have) {
498 connect(cb, SIGNAL(activated(int)), 513 connect(cb, SIGNAL(activated(int)),
500 connect(cb, SIGNAL(mouseEntered()), 515 connect(cb, SIGNAL(mouseEntered()),
501 this, SLOT(mouseEnteredWidget())); 516 this, SLOT(mouseEnteredWidget()));
502 connect(cb, SIGNAL(mouseLeft()), 517 connect(cb, SIGNAL(mouseLeft()),
503 this, SLOT(mouseLeftWidget())); 518 this, SLOT(mouseLeftWidget()));
504 519
505 if (inGroup) { 520 cb->setToolTip(propertyLabel);
506 cb->setToolTip(propertyLabel); 521 m_groupLayouts[groupName]->addWidget
507 m_groupLayouts[groupName]->addWidget 522 (cb, 0, m_groupLayouts[groupName]->columnCount());
508 (cb, 0, m_groupLayouts[groupName]->columnCount());
509 } else {
510 m_layout->addWidget(cb, row, 1, 1, 2);
511 }
512 m_propertyControllers[name] = cb; 523 m_propertyControllers[name] = cb;
513 } 524 }
514 525
515 cb->blockSignals(true); 526 cb->blockSignals(true);
516 if (type == PropertyContainer::ValueProperty || 527 if (type == PropertyContainer::ValueProperty) {
517 type == PropertyContainer::ColourProperty) {
518 if (cb->currentIndex() != value) { 528 if (cb->currentIndex() != value) {
519 cb->setCurrentIndex(value); 529 cb->setCurrentIndex(value);
520 } 530 }
521 } else { 531 } else {
522 QString unit = UnitDatabase::getInstance()->getUnitById(value); 532 QString unit = UnitDatabase::getInstance()->getUnitById(value);
529 } 539 }
530 } 540 }
531 } 541 }
532 cb->blockSignals(false); 542 cb->blockSignals(false);
533 543
534 #ifdef Q_OS_MAC
535 // Crashes on startup without this, for some reason; also
536 // prevents combo boxes from getting weirdly squished
537 // vertically
538 cb->setMinimumSize(QSize(10, cb->font().pixelSize() * 2));
539 #endif
540
541 break; 544 break;
542 } 545 }
543 546
544 case PropertyContainer::InvalidProperty: 547 case PropertyContainer::InvalidProperty:
545 default: 548 default:
603 606
604 blockSignals(false); 607 blockSignals(false);
605 } 608 }
606 609
607 void 610 void
608 PropertyBox::colourDatabaseChanged()
609 {
610 blockSignals(true);
611
612 PropertyContainer::PropertyList properties = m_container->getProperties();
613 for (size_t i = 0; i < properties.size(); ++i) {
614 if (m_container->getPropertyType(properties[i]) ==
615 PropertyContainer::ColourProperty) {
616 updatePropertyEditor(properties[i], true);
617 }
618 }
619
620 blockSignals(false);
621 }
622
623 void
624 PropertyBox::propertyControllerChanged(bool on) 611 PropertyBox::propertyControllerChanged(bool on)
625 { 612 {
626 propertyControllerChanged(on ? 1 : 0); 613 propertyControllerChanged(on ? 1 : 0);
627 } 614 }
628 615
640 627
641 Command *c = 0; 628 Command *c = 0;
642 629
643 if (type == PropertyContainer::UnitsProperty) { 630 if (type == PropertyContainer::UnitsProperty) {
644 631
645 NotifyingComboBox *cb = dynamic_cast<NotifyingComboBox *>(obj); 632 NotifyingComboBox *cb = qobject_cast<NotifyingComboBox *>(obj);
646 if (cb) { 633 if (cb) {
647 QString unit = cb->currentText(); 634 QString unit = cb->currentText();
648 c = m_container->getSetPropertyCommand 635 c = m_container->getSetPropertyCommand
649 (name, UnitDatabase::getInstance()->getUnitId(unit)); 636 (name, UnitDatabase::getInstance()->getUnitId(unit));
650 } 637 }
651 638
652 } else if (type == PropertyContainer::ColourProperty) {
653
654 if (value == int(ColourDatabase::getInstance()->getColourCount())) {
655 addNewColour();
656 if (value == int(ColourDatabase::getInstance()->getColourCount())) {
657 propertyContainerPropertyChanged(m_container);
658 return;
659 }
660 }
661 c = m_container->getSetPropertyCommand(name, value);
662
663 } else if (type != PropertyContainer::InvalidProperty) { 639 } else if (type != PropertyContainer::InvalidProperty) {
664 640
665 c = m_container->getSetPropertyCommand(name, value); 641 c = m_container->getSetPropertyCommand(name, value);
666 } 642 }
667 643
669 645
670 updateContextHelp(obj); 646 updateContextHelp(obj);
671 } 647 }
672 648
673 void 649 void
674 PropertyBox::addNewColour()
675 {
676 QColor newColour = QColorDialog::getColor();
677 if (!newColour.isValid()) return;
678
679 ColourNameDialog dialog(tr("Name New Colour"),
680 tr("Enter a name for the new colour:"),
681 newColour, newColour.name(), this);
682 dialog.showDarkBackgroundCheckbox(tr("Prefer black background for this colour"));
683 if (dialog.exec() == QDialog::Accepted) {
684 //!!! command
685 ColourDatabase *db = ColourDatabase::getInstance();
686 int index = db->addColour(newColour, dialog.getColourName());
687 db->setUseDarkBackground(index, dialog.isDarkBackgroundChecked());
688 }
689 }
690
691 void
692 PropertyBox::playAudibleChanged(bool audible) 650 PropertyBox::playAudibleChanged(bool audible)
693 { 651 {
694 m_playButton->setState(audible); 652 m_playButton->setChecked(audible);
695 } 653 }
696 654
697 void 655 void
698 PropertyBox::playAudibleButtonChanged(bool audible) 656 PropertyBox::playAudibleButtonChanged(bool audible)
699 { 657 {
705 new PlayParameterRepository::EditCommand(params); 663 new PlayParameterRepository::EditCommand(params);
706 command->setPlayAudible(audible); 664 command->setPlayAudible(audible);
707 CommandHistory::getInstance()->addCommand(command, true, true); 665 CommandHistory::getInstance()->addCommand(command, true, true);
708 } 666 }
709 } 667 }
710 668
711 void 669 void
712 PropertyBox::playGainChanged(float gain) 670 PropertyBox::playGainControlChanged(float gain)
713 {
714 int dialValue = int(lrint(log10(gain) * 20.0));
715 if (dialValue < -50) dialValue = -50;
716 if (dialValue > 50) dialValue = 50;
717 emit changePlayGainDial(dialValue);
718 }
719
720 void
721 PropertyBox::playGainDialChanged(int dialValue)
722 { 671 {
723 QObject *obj = sender(); 672 QObject *obj = sender();
724 673
725 PlayParameters *params = m_container->getPlayParameters(); 674 PlayParameters *params = m_container->getPlayParameters();
726 if (!params) return; 675 if (!params) return;
727
728 float gain = float(pow(10, float(dialValue) / 20.0));
729 676
730 if (params->getPlayGain() != gain) { 677 if (params->getPlayGain() != gain) {
731 PlayParameterRepository::EditCommand *command = 678 PlayParameterRepository::EditCommand *command =
732 new PlayParameterRepository::EditCommand(params); 679 new PlayParameterRepository::EditCommand(params);
733 command->setPlayGain(gain); 680 command->setPlayGain(gain);
734 CommandHistory::getInstance()->addCommand(command, true, true); 681 CommandHistory::getInstance()->addCommand(command, true, true);
735 } 682 }
736 683
737 updateContextHelp(obj); 684 updateContextHelp(obj);
738 } 685 }
739 686
740 void 687 void
741 PropertyBox::playPanChanged(float pan) 688 PropertyBox::playPanControlChanged(float pan)
742 {
743 int dialValue = int(lrint(pan * 50.0));
744 if (dialValue < -50) dialValue = -50;
745 if (dialValue > 50) dialValue = 50;
746 emit changePlayPanDial(dialValue);
747 }
748
749 void
750 PropertyBox::playPanDialChanged(int dialValue)
751 { 689 {
752 QObject *obj = sender(); 690 QObject *obj = sender();
753 691
754 PlayParameters *params = m_container->getPlayParameters(); 692 PlayParameters *params = m_container->getPlayParameters();
755 if (!params) return; 693 if (!params) return;
756
757 float pan = float(dialValue) / 50.f;
758 if (pan < -1.f) pan = -1.f;
759 if (pan > 1.f) pan = 1.f;
760 694
761 if (params->getPlayPan() != pan) { 695 if (params->getPlayPan() != pan) {
762 PlayParameterRepository::EditCommand *command = 696 PlayParameterRepository::EditCommand *command =
763 new PlayParameterRepository::EditCommand(params); 697 new PlayParameterRepository::EditCommand(params);
764 command->setPlayPan(pan); 698 command->setPlayPan(pan);
840 } 774 }
841 775
842 void 776 void
843 PropertyBox::updateContextHelp(QObject *o) 777 PropertyBox::updateContextHelp(QObject *o)
844 { 778 {
845 QWidget *w = dynamic_cast<QWidget *>(o); 779 QWidget *w = qobject_cast<QWidget *>(o);
846 if (!w) return; 780 if (!w) return;
847 781
848 if (!m_container) return; 782 if (!m_container) return;
849 QString cname = m_container->getPropertyContainerName(); 783 QString cname = m_container->getPropertyContainerName();
850 if (cname == "") return; 784 if (cname == "") return;
851 785
786 LevelPanToolButton *lp = qobject_cast<LevelPanToolButton *>(w);
787 if (lp) {
788 emit contextHelpChanged(tr("Adjust playback level and pan of %1").arg(cname));
789 return;
790 }
791
852 QString wname = w->objectName(); 792 QString wname = w->objectName();
853 793
794 if (wname == "playParamButton") {
795 PlayParameters *params = m_container->getPlayParameters();
796 if (params) {
797 emit contextHelpChanged
798 (tr("Change sound used for playback (currently \"%1\")")
799 .arg(params->getPlayClipId()));
800 return;
801 }
802 }
803
854 QString extraText; 804 QString extraText;
855 AudioDial *dial = dynamic_cast<AudioDial *>(w); 805
806 AudioDial *dial = qobject_cast<AudioDial *>(w);
856 if (dial) { 807 if (dial) {
857 double mv = dial->mappedValue(); 808 double mv = dial->mappedValue();
858 QString unit = ""; 809 QString unit = "";
859 if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit(); 810 if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit();
860 if (unit != "") { 811 if (unit != "") {
868 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname)); 819 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname));
869 } else if (w == m_playButton) { 820 } else if (w == m_playButton) {
870 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname)); 821 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname));
871 } else if (wname == "") { 822 } else if (wname == "") {
872 return; 823 return;
873 } else if (dynamic_cast<QAbstractButton *>(w)) { 824 } else if (qobject_cast<QAbstractButton *>(w)) {
874 emit contextHelpChanged(tr("Toggle %1 property of %2") 825 emit contextHelpChanged(tr("Toggle %1 property of %2")
875 .arg(wname).arg(cname)); 826 .arg(wname).arg(cname));
876 } else { 827 } else {
877 emit contextHelpChanged(tr("Adjust %1 property of %2%3") 828 emit contextHelpChanged(tr("Adjust %1 property of %2%3")
878 .arg(wname).arg(cname).arg(extraText)); 829 .arg(wname).arg(cname).arg(extraText));