Mercurial > hg > svgui
comparison widgets/PropertyBox.cpp @ 1196:b1e3ee5f1be6 levelpanwidget
Introduce colour combobox class, to replace ad-hoc code in property box
author | Chris Cannam |
---|---|
date | Fri, 16 Dec 2016 13:08:33 +0000 |
parents | 51bb2582c2cc |
children | ff77b7707c95 |
comparison
equal
deleted
inserted
replaced
1195:51bb2582c2cc | 1196:b1e3ee5f1be6 |
---|---|
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" |
33 | 32 |
34 #include "NotifyingCheckBox.h" | 33 #include "NotifyingCheckBox.h" |
35 #include "NotifyingComboBox.h" | 34 #include "NotifyingComboBox.h" |
36 #include "NotifyingPushButton.h" | 35 #include "NotifyingPushButton.h" |
37 #include "NotifyingToolButton.h" | 36 #include "NotifyingToolButton.h" |
38 #include "ColourNameDialog.h" | 37 #include "ColourComboBox.h" |
39 | 38 |
40 #include <QGridLayout> | 39 #include <QGridLayout> |
41 #include <QHBoxLayout> | 40 #include <QHBoxLayout> |
42 #include <QVBoxLayout> | 41 #include <QVBoxLayout> |
43 #include <QPushButton> | 42 #include <QPushButton> |
105 | 104 |
106 m_layout->setRowStretch(m_layout->rowCount(), 10); | 105 m_layout->setRowStretch(m_layout->rowCount(), 10); |
107 | 106 |
108 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()), | 107 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()), |
109 this, SLOT(unitDatabaseChanged())); | 108 this, SLOT(unitDatabaseChanged())); |
110 | |
111 connect(ColourDatabase::getInstance(), SIGNAL(colourDatabaseChanged()), | |
112 this, SLOT(colourDatabaseChanged())); | |
113 | 109 |
114 #ifdef DEBUG_PROPERTY_BOX | 110 #ifdef DEBUG_PROPERTY_BOX |
115 cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl; | 111 cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl; |
116 #endif | 112 #endif |
117 } | 113 } |
301 case PropertyContainer::ToggleProperty: | 297 case PropertyContainer::ToggleProperty: |
302 { | 298 { |
303 QAbstractButton *button = 0; | 299 QAbstractButton *button = 0; |
304 | 300 |
305 if (have) { | 301 if (have) { |
306 button = dynamic_cast<QAbstractButton *>(m_propertyControllers[name]); | 302 button = qobject_cast<QAbstractButton *>(m_propertyControllers[name]); |
307 assert(button); | 303 assert(button); |
308 } else { | 304 } else { |
309 #ifdef DEBUG_PROPERTY_BOX | 305 #ifdef DEBUG_PROPERTY_BOX |
310 cerr << "PropertyBox: creating new checkbox" << endl; | 306 cerr << "PropertyBox: creating new checkbox" << endl; |
311 #endif | 307 #endif |
347 case PropertyContainer::RangeProperty: | 343 case PropertyContainer::RangeProperty: |
348 { | 344 { |
349 AudioDial *dial; | 345 AudioDial *dial; |
350 | 346 |
351 if (have) { | 347 if (have) { |
352 dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]); | 348 dial = qobject_cast<AudioDial *>(m_propertyControllers[name]); |
353 assert(dial); | 349 assert(dial); |
354 if (rangeChanged) { | 350 if (rangeChanged) { |
355 dial->blockSignals(true); | 351 dial->blockSignals(true); |
356 dial->setMinimum(min); | 352 dial->setMinimum(min); |
357 dial->setMaximum(max); | 353 dial->setMaximum(max); |
406 dial->blockSignals(false); | 402 dial->blockSignals(false); |
407 } | 403 } |
408 break; | 404 break; |
409 } | 405 } |
410 | 406 |
411 case PropertyContainer::ValueProperty: | |
412 case PropertyContainer::UnitsProperty: | |
413 case PropertyContainer::ColourProperty: | 407 case PropertyContainer::ColourProperty: |
414 { | 408 { |
415 NotifyingComboBox *cb; | 409 ColourComboBox *cb; |
416 | 410 |
417 if (have) { | 411 if (have) { |
418 cb = dynamic_cast<NotifyingComboBox *>(m_propertyControllers[name]); | 412 cb = qobject_cast<ColourComboBox *>(m_propertyControllers[name]); |
419 assert(cb); | 413 assert(cb); |
420 } else { | 414 } else { |
421 #ifdef DEBUG_PROPERTY_BOX | 415 #ifdef DEBUG_PROPERTY_BOX |
422 cerr << "PropertyBox: creating new combobox" << endl; | 416 cerr << "PropertyBox: creating new colour combobox" << endl; |
423 #endif | 417 #endif |
424 | 418 cb = new ColourComboBox(true); |
425 cb = new NotifyingComboBox(); | 419 cb->setObjectName(name); |
426 cb->setObjectName(name); | 420 |
427 cb->setDuplicatesEnabled(false); | 421 connect(cb, SIGNAL(colourChanged(int)), |
428 } | |
429 | |
430 if (!have || rangeChanged) { | |
431 | |
432 cb->blockSignals(true); | |
433 cb->clear(); | |
434 cb->setEditable(false); | |
435 | |
436 if (type == PropertyContainer::ValueProperty) { | |
437 | |
438 for (int i = min; i <= max; ++i) { | |
439 | |
440 QString label = m_container->getPropertyValueLabel(name, i); | |
441 QString iname = m_container->getPropertyValueIconName(name, i); | |
442 | |
443 if (iname != "") { | |
444 QIcon icon(IconLoader().load(iname)); | |
445 cb->addItem(icon, label); | |
446 } else { | |
447 cb->addItem(label); | |
448 } | |
449 } | |
450 | |
451 } else if (type == PropertyContainer::UnitsProperty) { | |
452 | |
453 QStringList units = UnitDatabase::getInstance()->getKnownUnits(); | |
454 for (int i = 0; i < units.size(); ++i) { | |
455 cb->addItem(units[i]); | |
456 } | |
457 | |
458 cb->setEditable(true); | |
459 | |
460 } else { // ColourProperty | |
461 | |
462 //!!! should be a proper colour combobox class that | |
463 // manages its own Add New Colour entry... | |
464 | |
465 int size = (QFontMetrics(QFont()).height() * 2) / 3; | |
466 if (size < 12) size = 12; | |
467 | |
468 ColourDatabase *db = ColourDatabase::getInstance(); | |
469 for (int i = 0; i < db->getColourCount(); ++i) { | |
470 QString name = db->getColourName(i); | |
471 cb->addItem(db->getExamplePixmap(i, QSize(size, size)), name); | |
472 } | |
473 cb->addItem(tr("Add New Colour...")); | |
474 } | |
475 | |
476 cb->blockSignals(false); | |
477 if (cb->count() < 20 && cb->count() > cb->maxVisibleItems()) { | |
478 cb->setMaxVisibleItems(cb->count()); | |
479 } | |
480 } | |
481 | |
482 if (!have) { | |
483 connect(cb, SIGNAL(activated(int)), | |
484 this, SLOT(propertyControllerChanged(int))); | 422 this, SLOT(propertyControllerChanged(int))); |
485 connect(cb, SIGNAL(mouseEntered()), | 423 connect(cb, SIGNAL(mouseEntered()), |
486 this, SLOT(mouseEnteredWidget())); | 424 this, SLOT(mouseEnteredWidget())); |
487 connect(cb, SIGNAL(mouseLeft()), | 425 connect(cb, SIGNAL(mouseLeft()), |
488 this, SLOT(mouseLeftWidget())); | 426 this, SLOT(mouseLeftWidget())); |
495 m_layout->addWidget(cb, row, 1, 1, 2); | 433 m_layout->addWidget(cb, row, 1, 1, 2); |
496 } | 434 } |
497 m_propertyControllers[name] = cb; | 435 m_propertyControllers[name] = cb; |
498 } | 436 } |
499 | 437 |
438 if (cb->currentIndex() != value) { | |
439 cb->blockSignals(true); | |
440 cb->setCurrentIndex(value); | |
441 cb->blockSignals(false); | |
442 } | |
443 | |
444 #ifdef Q_OS_MAC | |
445 // Crashes on startup without this, for some reason; also | |
446 // prevents combo boxes from getting weirdly squished | |
447 // vertically | |
448 cb->setMinimumSize(QSize(10, cb->font().pixelSize() * 2)); | |
449 #endif | |
450 | |
451 break; | |
452 } | |
453 | |
454 case PropertyContainer::ValueProperty: | |
455 case PropertyContainer::UnitsProperty: | |
456 { | |
457 NotifyingComboBox *cb; | |
458 | |
459 if (have) { | |
460 cb = qobject_cast<NotifyingComboBox *>(m_propertyControllers[name]); | |
461 assert(cb); | |
462 } else { | |
463 #ifdef DEBUG_PROPERTY_BOX | |
464 cerr << "PropertyBox: creating new combobox" << endl; | |
465 #endif | |
466 | |
467 cb = new NotifyingComboBox(); | |
468 cb->setObjectName(name); | |
469 cb->setDuplicatesEnabled(false); | |
470 } | |
471 | |
472 if (!have || rangeChanged) { | |
473 | |
474 cb->blockSignals(true); | |
475 cb->clear(); | |
476 cb->setEditable(false); | |
477 | |
478 if (type == PropertyContainer::ValueProperty) { | |
479 | |
480 for (int i = min; i <= max; ++i) { | |
481 | |
482 QString label = m_container->getPropertyValueLabel(name, i); | |
483 QString iname = m_container->getPropertyValueIconName(name, i); | |
484 | |
485 if (iname != "") { | |
486 QIcon icon(IconLoader().load(iname)); | |
487 cb->addItem(icon, label); | |
488 } else { | |
489 cb->addItem(label); | |
490 } | |
491 } | |
492 | |
493 } else { // PropertyContainer::UnitsProperty | |
494 | |
495 QStringList units = UnitDatabase::getInstance()->getKnownUnits(); | |
496 for (int i = 0; i < units.size(); ++i) { | |
497 cb->addItem(units[i]); | |
498 } | |
499 | |
500 cb->setEditable(true); | |
501 } | |
502 } | |
503 | |
504 if (!have) { | |
505 connect(cb, SIGNAL(activated(int)), | |
506 this, SLOT(propertyControllerChanged(int))); | |
507 connect(cb, SIGNAL(mouseEntered()), | |
508 this, SLOT(mouseEnteredWidget())); | |
509 connect(cb, SIGNAL(mouseLeft()), | |
510 this, SLOT(mouseLeftWidget())); | |
511 | |
512 if (inGroup) { | |
513 cb->setToolTip(propertyLabel); | |
514 m_groupLayouts[groupName]->addWidget | |
515 (cb, 0, m_groupLayouts[groupName]->columnCount()); | |
516 } else { | |
517 m_layout->addWidget(cb, row, 1, 1, 2); | |
518 } | |
519 m_propertyControllers[name] = cb; | |
520 } | |
521 | |
500 cb->blockSignals(true); | 522 cb->blockSignals(true); |
501 if (type == PropertyContainer::ValueProperty || | 523 if (type == PropertyContainer::ValueProperty) { |
502 type == PropertyContainer::ColourProperty) { | |
503 if (cb->currentIndex() != value) { | 524 if (cb->currentIndex() != value) { |
504 cb->setCurrentIndex(value); | 525 cb->setCurrentIndex(value); |
505 } | 526 } |
506 } else { | 527 } else { |
507 QString unit = UnitDatabase::getInstance()->getUnitById(value); | 528 QString unit = UnitDatabase::getInstance()->getUnitById(value); |
588 | 609 |
589 blockSignals(false); | 610 blockSignals(false); |
590 } | 611 } |
591 | 612 |
592 void | 613 void |
593 PropertyBox::colourDatabaseChanged() | |
594 { | |
595 blockSignals(true); | |
596 | |
597 PropertyContainer::PropertyList properties = m_container->getProperties(); | |
598 for (size_t i = 0; i < properties.size(); ++i) { | |
599 if (m_container->getPropertyType(properties[i]) == | |
600 PropertyContainer::ColourProperty) { | |
601 updatePropertyEditor(properties[i], true); | |
602 } | |
603 } | |
604 | |
605 blockSignals(false); | |
606 } | |
607 | |
608 void | |
609 PropertyBox::propertyControllerChanged(bool on) | 614 PropertyBox::propertyControllerChanged(bool on) |
610 { | 615 { |
611 propertyControllerChanged(on ? 1 : 0); | 616 propertyControllerChanged(on ? 1 : 0); |
612 } | 617 } |
613 | 618 |
625 | 630 |
626 Command *c = 0; | 631 Command *c = 0; |
627 | 632 |
628 if (type == PropertyContainer::UnitsProperty) { | 633 if (type == PropertyContainer::UnitsProperty) { |
629 | 634 |
630 NotifyingComboBox *cb = dynamic_cast<NotifyingComboBox *>(obj); | 635 NotifyingComboBox *cb = qobject_cast<NotifyingComboBox *>(obj); |
631 if (cb) { | 636 if (cb) { |
632 QString unit = cb->currentText(); | 637 QString unit = cb->currentText(); |
633 c = m_container->getSetPropertyCommand | 638 c = m_container->getSetPropertyCommand |
634 (name, UnitDatabase::getInstance()->getUnitId(unit)); | 639 (name, UnitDatabase::getInstance()->getUnitId(unit)); |
635 } | 640 } |
636 | 641 |
637 } else if (type == PropertyContainer::ColourProperty) { | |
638 | |
639 if (value == int(ColourDatabase::getInstance()->getColourCount())) { | |
640 addNewColour(); | |
641 if (value == int(ColourDatabase::getInstance()->getColourCount())) { | |
642 propertyContainerPropertyChanged(m_container); | |
643 return; | |
644 } | |
645 } | |
646 c = m_container->getSetPropertyCommand(name, value); | |
647 | |
648 } else if (type != PropertyContainer::InvalidProperty) { | 642 } else if (type != PropertyContainer::InvalidProperty) { |
649 | 643 |
650 c = m_container->getSetPropertyCommand(name, value); | 644 c = m_container->getSetPropertyCommand(name, value); |
651 } | 645 } |
652 | 646 |
653 if (c) CommandHistory::getInstance()->addCommand(c, true, true); | 647 if (c) CommandHistory::getInstance()->addCommand(c, true, true); |
654 | 648 |
655 updateContextHelp(obj); | 649 updateContextHelp(obj); |
656 } | |
657 | |
658 void | |
659 PropertyBox::addNewColour() | |
660 { | |
661 QColor newColour = QColorDialog::getColor(); | |
662 if (!newColour.isValid()) return; | |
663 | |
664 ColourNameDialog dialog(tr("Name New Colour"), | |
665 tr("Enter a name for the new colour:"), | |
666 newColour, newColour.name(), this); | |
667 dialog.showDarkBackgroundCheckbox(tr("Prefer black background for this colour")); | |
668 if (dialog.exec() == QDialog::Accepted) { | |
669 //!!! command | |
670 ColourDatabase *db = ColourDatabase::getInstance(); | |
671 int index = db->addColour(newColour, dialog.getColourName()); | |
672 db->setUseDarkBackground(index, dialog.isDarkBackgroundChecked()); | |
673 } | |
674 } | 650 } |
675 | 651 |
676 void | 652 void |
677 PropertyBox::playAudibleChanged(bool audible) | 653 PropertyBox::playAudibleChanged(bool audible) |
678 { | 654 { |
801 } | 777 } |
802 | 778 |
803 void | 779 void |
804 PropertyBox::updateContextHelp(QObject *o) | 780 PropertyBox::updateContextHelp(QObject *o) |
805 { | 781 { |
806 QWidget *w = dynamic_cast<QWidget *>(o); | 782 QWidget *w = qobject_cast<QWidget *>(o); |
807 if (!w) return; | 783 if (!w) return; |
808 | 784 |
809 if (!m_container) return; | 785 if (!m_container) return; |
810 QString cname = m_container->getPropertyContainerName(); | 786 QString cname = m_container->getPropertyContainerName(); |
811 if (cname == "") return; | 787 if (cname == "") return; |
846 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname)); | 822 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname)); |
847 } else if (w == m_playButton) { | 823 } else if (w == m_playButton) { |
848 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname)); | 824 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname)); |
849 } else if (wname == "") { | 825 } else if (wname == "") { |
850 return; | 826 return; |
851 } else if (dynamic_cast<QAbstractButton *>(w)) { | 827 } else if (qobject_cast<QAbstractButton *>(w)) { |
852 emit contextHelpChanged(tr("Toggle %1 property of %2") | 828 emit contextHelpChanged(tr("Toggle %1 property of %2") |
853 .arg(wname).arg(cname)); | 829 .arg(wname).arg(cname)); |
854 } else { | 830 } else { |
855 emit contextHelpChanged(tr("Adjust %1 property of %2%3") | 831 emit contextHelpChanged(tr("Adjust %1 property of %2%3") |
856 .arg(wname).arg(cname).arg(extraText)); | 832 .arg(wname).arg(cname).arg(extraText)); |