19 #include "base/PropertyContainer.h" 20 #include "base/PlayParameters.h" 21 #include "base/PlayParameterRepository.h" 23 #include "base/UnitDatabase.h" 24 #include "base/RangeMapper.h" 41 #include <QGridLayout> 42 #include <QHBoxLayout> 43 #include <QVBoxLayout> 44 #include <QPushButton> 45 #include <QToolButton> 48 #include <QApplication> 49 #include <QColorDialog> 50 #include <QInputDialog> 61 m_container(container),
62 m_showButton(nullptr),
63 m_playButton(nullptr),
64 m_lastContextMenu(nullptr),
65 m_contextMenuOn(nullptr)
67 #ifdef DEBUG_PROPERTY_BOX 68 SVDEBUG <<
"PropertyBox[" <<
this <<
"(\"" <<
69 container->getPropertyContainerName() <<
"\" at " << container <<
")]::PropertyBox" << endl;
76 QMargins mm =
m_mainBox->contentsMargins();
77 QMargins mmhalf(mm.left()/2, mm.top()/3, mm.right()/2, mm.bottom()/3);
98 PropertyContainer::PropertyList properties =
m_container->getProperties();
104 for (i = 0; i < properties.size(); ++i) {
115 #ifdef DEBUG_PROPERTY_BOX 116 SVDEBUG <<
"PropertyBox[" <<
this <<
"]::PropertyBox returning" << endl;
122 #ifdef DEBUG_PROPERTY_BOX 123 SVDEBUG <<
"PropertyBox[" <<
this <<
"]::~PropertyBox" << endl;
131 #ifdef DEBUG_PROPERTY_BOX 132 SVDEBUG <<
"PropertyBox[" <<
this <<
":" <<
m_container <<
"]::populateViewPlayFrame" << endl;
144 disconnect(layer, SIGNAL(modelReplaced()),
146 connect(layer, SIGNAL(modelReplaced()),
151 if (!params && !layer)
return;
157 QGridLayout *layout =
new QGridLayout;
160 layout->setMargin(layout->margin() / 2);
162 #ifdef DEBUG_PROPERTY_BOX 163 SVDEBUG <<
"PropertyBox::populateViewPlayFrame: container " <<
m_container <<
" (name " <<
m_container->getPropertyContainerName() <<
") params " << params << endl;
174 m_playButton->setToolTip(tr(
"Click to toggle playback"));
187 levelPan->setFixedSize(buttonSize);
189 layout->addWidget(levelPan, 0, col++, Qt::AlignCenter);
190 connect(levelPan, SIGNAL(levelChanged(
float)),
192 connect(levelPan, SIGNAL(panChanged(
float)),
194 connect(params.get(), SIGNAL(playGainChanged(
float)),
195 levelPan, SLOT(setLevel(
float)));
196 connect(params.get(), SIGNAL(playPanChanged(
float)),
197 levelPan, SLOT(setPan(
float)));
198 connect(levelPan, SIGNAL(mouseEntered()),
200 connect(levelPan, SIGNAL(mouseLeft()),
203 layout->addWidget(
m_playButton, 0, col++, Qt::AlignCenter);
205 if (params->getPlayClipId() !=
"") {
207 playParamButton->setObjectName(
"playParamButton");
208 playParamButton->setIcon(
IconLoader().load(
"faders"));
209 playParamButton->setFixedSize(buttonSize);
210 layout->addWidget(playParamButton, 0, col++, Qt::AlignCenter);
211 connect(playParamButton, SIGNAL(clicked()),
213 connect(playParamButton, SIGNAL(mouseEntered()),
215 connect(playParamButton, SIGNAL(mouseLeft()),
220 layout->setColumnStretch(col++, 10);
224 QLabel *showLabel =
new QLabel(tr(
"Show"));
225 layout->addWidget(showLabel, 0, col++, Qt::AlignVCenter | Qt::AlignRight);
228 layout->addWidget(
m_showButton, 0, col++, Qt::AlignVCenter | Qt::AlignLeft);
242 PropertyContainer::PropertyType type =
m_container->getPropertyType(name);
245 int min = 0, max = 0, value = 0, deflt = 0;
246 value =
m_container->getPropertyRangeAndValue(name, &min, &max, &deflt);
251 QString groupName =
m_container->getPropertyGroupName(name);
252 QString propertyLabel =
m_container->getPropertyLabel(name);
253 QString iconName =
m_container->getPropertyIconName(name);
255 #ifdef DEBUG_PROPERTY_BOX 256 SVDEBUG <<
"PropertyBox[" <<
this 257 <<
"(\"" <<
m_container->getPropertyContainerName()
259 SVDEBUG <<
"::updatePropertyEditor(\"" << name <<
"\", " 260 << rangeChanged <<
"):";
261 SVDEBUG <<
" type " << type <<
", value " << value
262 <<
", have " << have <<
", group \"" << groupName <<
"\"" << endl;
265 QString groupLabel = groupName;
266 if (groupName == QString()) {
267 groupName =
"ungrouped: " + name;
268 groupLabel = propertyLabel;
273 QWidget *labelWidget =
new QLabel(groupLabel,
m_mainWidget);
274 m_layout->addWidget(labelWidget, row, 0);
287 m_layout->addWidget(frame, row, 1, 1, 2);
294 #ifdef DEBUG_PROPERTY_BOX 295 SVDEBUG <<
"groupName becomes \"" << groupName <<
"\", groupLabel = \"" 296 << groupLabel <<
"\", groupLayout = " << groupLayout << endl;
305 case PropertyContainer::ToggleProperty:
307 QAbstractButton *button;
309 if (!(button = qobject_cast<QAbstractButton *>(existing))) {
310 #ifdef DEBUG_PROPERTY_BOX 311 SVDEBUG <<
"PropertyBox: creating new checkbox" << endl;
313 if (iconName !=
"") {
319 button->setCheckable(
true);
321 button->setIcon(icon);
322 button->setObjectName(name);
326 button->setObjectName(name);
328 connect(button, SIGNAL(toggled(
bool)),
330 connect(button, SIGNAL(mouseEntered()),
332 connect(button, SIGNAL(mouseLeft()),
334 button->setToolTip(propertyLabel);
336 button->setContextMenuPolicy(Qt::CustomContextMenu);
337 connect(button, SIGNAL(customContextMenuRequested(
const QPoint &)),
341 groupLayout->replaceWidget(existing, button);
344 groupLayout->addWidget(button, 0, groupLayout->columnCount());
350 if (button->isChecked() != (value > 0)) {
351 button->blockSignals(
true);
352 button->setChecked(value > 0);
353 button->blockSignals(
false);
358 case PropertyContainer::RangeProperty:
362 if ((dial = qobject_cast<AudioDial *>(existing))) {
364 dial->blockSignals(
true);
365 dial->setMinimum(min);
366 dial->setMaximum(max);
368 dial->blockSignals(
false);
371 #ifdef DEBUG_PROPERTY_BOX 372 SVDEBUG <<
"PropertyBox: creating new dial" << endl;
375 dial->setObjectName(name);
376 dial->setMinimum(min);
377 dial->setMaximum(max);
378 dial->setPageStep(1);
379 dial->setNotchesVisible((max - min) <= 12);
385 connect(dial, SIGNAL(valueChanged(
int)),
387 connect(dial, SIGNAL(mouseEntered()),
389 connect(dial, SIGNAL(mouseLeft()),
396 groupLayout->replaceWidget(existing, dial);
399 groupLayout->addWidget(dial, 0, groupLayout->columnCount());
405 if (dial->value() != value) {
406 dial->blockSignals(
true);
408 dial->blockSignals(
false);
413 case PropertyContainer::ColourProperty:
417 if (!(cb = qobject_cast<ColourComboBox *>(existing))) {
419 #ifdef DEBUG_PROPERTY_BOX 420 SVDEBUG <<
"PropertyBox: creating new colour combobox" << endl;
423 cb->setObjectName(name);
425 connect(cb, SIGNAL(colourChanged(
int)),
427 connect(cb, SIGNAL(mouseEntered()),
429 connect(cb, SIGNAL(mouseLeft()),
432 cb->setToolTip(propertyLabel);
434 cb->setContextMenuPolicy(Qt::CustomContextMenu);
435 connect(cb, SIGNAL(customContextMenuRequested(
const QPoint &)),
439 groupLayout->replaceWidget(existing, cb);
442 groupLayout->addWidget(cb, 0, groupLayout->columnCount());
448 if (cb->currentIndex() != value) {
449 cb->blockSignals(
true);
450 cb->setCurrentIndex(value);
451 cb->blockSignals(
false);
457 case PropertyContainer::ColourMapProperty:
461 if (!(cb = qobject_cast<ColourMapComboBox *>(existing))) {
462 #ifdef DEBUG_PROPERTY_BOX 463 SVDEBUG <<
"PropertyBox: creating new colourmap combobox" << endl;
466 cb->setObjectName(name);
468 connect(cb, SIGNAL(colourMapChanged(
int)),
470 connect(cb, SIGNAL(mouseEntered()),
472 connect(cb, SIGNAL(mouseLeft()),
475 cb->setToolTip(propertyLabel);
478 groupLayout->replaceWidget(existing, cb);
481 groupLayout->addWidget(cb, 0, groupLayout->columnCount());
487 if (cb->currentIndex() != value) {
488 cb->blockSignals(
true);
489 cb->setCurrentIndex(value);
490 cb->blockSignals(
false);
496 case PropertyContainer::ValueProperty:
497 case PropertyContainer::UnitsProperty:
501 if (!(cb = qobject_cast<NotifyingComboBox *>(existing))) {
502 #ifdef DEBUG_PROPERTY_BOX 503 SVDEBUG <<
"PropertyBox: creating new combobox" << endl;
506 cb->setObjectName(name);
507 cb->setDuplicatesEnabled(
false);
510 if (!have || rangeChanged) {
512 cb->blockSignals(
true);
514 cb->setEditable(
false);
516 if (type == PropertyContainer::ValueProperty) {
518 for (
int i = min; i <= max; ++i) {
520 QString label =
m_container->getPropertyValueLabel(name, i);
521 QString iname =
m_container->getPropertyValueIconName(name, i);
525 cb->addItem(icon, label);
533 QStringList units = UnitDatabase::getInstance()->getKnownUnits();
534 for (
int i = 0; i < units.size(); ++i) {
535 cb->addItem(units[i]);
538 cb->setEditable(
true);
543 connect(cb, SIGNAL(activated(
int)),
545 connect(cb, SIGNAL(mouseEntered()),
547 connect(cb, SIGNAL(mouseLeft()),
550 cb->setToolTip(propertyLabel);
552 cb->setContextMenuPolicy(Qt::CustomContextMenu);
553 connect(cb, SIGNAL(customContextMenuRequested(
const QPoint &)),
556 groupLayout->addWidget(cb, 0, groupLayout->columnCount());
558 }
else if (existing != cb) {
559 groupLayout->replaceWidget(existing, cb);
563 cb->blockSignals(
true);
564 if (type == PropertyContainer::ValueProperty) {
565 if (cb->currentIndex() != value) {
566 cb->setCurrentIndex(value);
569 QString unit = UnitDatabase::getInstance()->getUnitById(value);
570 if (cb->currentText() != unit) {
571 for (
int i = 0; i < cb->count(); ++i) {
572 if (cb->itemText(i) == unit) {
573 cb->setCurrentIndex(i);
579 cb->blockSignals(
false);
584 case PropertyContainer::InvalidProperty:
595 #ifdef DEBUG_PROPERTY_BOX 596 SVDEBUG <<
"PropertyBox::propertyContainerPropertyChanged" << endl;
599 PropertyContainer::PropertyList properties =
m_container->getProperties();
604 for (i = 0; i < properties.size(); ++i) {
616 PropertyContainer::PropertyList properties =
m_container->getProperties();
617 for (
size_t i = 0; i < properties.size(); ++i) {
627 #ifdef DEBUG_PROPERTY_BOX 628 SVDEBUG <<
"PropertyBox[" <<
this <<
"]: unitDatabaseChanged" << endl;
636 PropertyContainer::PropertyList properties =
m_container->getProperties();
637 for (
size_t i = 0; i < properties.size(); ++i) {
639 PropertyContainer::UnitsProperty) {
656 QObject *obj = sender();
657 QString name = obj->objectName();
659 #ifdef DEBUG_PROPERTY_BOX 660 SVDEBUG <<
"PropertyBox::propertyControllerChanged(" << name
661 <<
", " << value <<
")" << endl;
664 PropertyContainer::PropertyType type =
m_container->getPropertyType(name);
666 Command *c =
nullptr;
668 if (type == PropertyContainer::UnitsProperty) {
672 QString unit = cb->currentText();
674 (name, UnitDatabase::getInstance()->getUnitId(unit));
677 }
else if (type != PropertyContainer::InvalidProperty) {
679 c =
m_container->getSetPropertyCommand(name, value);
690 QObject *obj = sender();
691 QString name = obj->objectName();
693 QString label =
m_container->getPropertyLabel(name);
694 int min = 0, max = 0, value = 0, deflt = 0;
695 value =
m_container->getPropertyRangeAndValue(name, &min, &max, &deflt);
698 QMenu *m =
new QMenu;
703 if (qobject_cast<QAbstractButton *>(obj)) {
709 m->addAction(tr(
"&Reset to Default"),
this,
712 }
else if (
auto cb = qobject_cast<QComboBox *>(obj)) {
714 m->addAction(tr(
"&Reset to Default"),
this,
722 m->popup(qobject_cast<QWidget *>(sender())->mapToGlobal(pos));
732 QString label =
m_container->getPropertyLabel(name);
733 int min = 0, max = 0, deflt = 0;
734 (void)
m_container->getPropertyRangeAndValue(name, &min, &max, &deflt);
737 button->setChecked(deflt > 0);
739 cb->setCurrentIndex(deflt);
755 if (params->isPlayAudible() != audible) {
756 PlayParameterRepository::EditCommand *command =
757 new PlayParameterRepository::EditCommand(params);
758 command->setPlayAudible(audible);
766 QObject *obj = sender();
771 if (params->getPlayGain() != gain) {
772 PlayParameterRepository::EditCommand *command =
773 new PlayParameterRepository::EditCommand(params);
774 command->setPlayGain(gain);
784 QObject *obj = sender();
789 if (params->getPlayPan() != pan) {
790 PlayParameterRepository::EditCommand *command =
791 new PlayParameterRepository::EditCommand(params);
792 command->setPlayPan(pan);
805 QString clip = params->getPlayClipId();
807 PlayParameterRepository::EditCommand *command =
808 new PlayParameterRepository::EditCommand(params);
810 QInputDialog *dialog =
new QInputDialog(
this);
812 QDir dir(
":/samples");
813 QStringList clipFiles = dir.entryList(QStringList() <<
"*.wav", QDir::Files);
816 foreach (QString str, clipFiles) {
817 clips.push_back(str.replace(
".wav",
""));
819 dialog->setComboBoxItems(clips);
821 dialog->setLabelText(tr(
"Set playback clip:"));
823 QComboBox *cb = dialog->findChild<QComboBox *>();
825 for (
int i = 0; i < cb->count(); ++i) {
826 if (cb->itemText(i) == clip) {
827 cb->setCurrentIndex(i);
832 connect(dialog, SIGNAL(textValueChanged(QString)),
835 if (dialog->exec() == QDialog::Accepted) {
836 QString newClip = dialog->textValue();
837 command->setPlayClipId(newClip);
843 params->setPlayClipId(clip);
855 params->setPlayClipId(
id);
873 QWidget *w = qobject_cast<QWidget *>(o);
877 QString cname =
m_container->getPropertyContainerName();
878 if (cname ==
"")
return;
885 QString wname = w->objectName();
886 QString propertyLabel;
888 propertyLabel =
m_container->getPropertyLabel(wname);
896 mainText = tr(
"Adjust playback level and pan of %1").arg(cname);
897 editText = tr(
"click then drag to adjust, ctrl+click to reset");
899 }
else if (wname ==
"playParamButton") {
903 help = tr(
"Change sound used for playback (currently \"%1\")")
904 .arg(params->getPlayClipId());
909 double mv = dial->mappedValue();
911 if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit();
913 extraText = tr(
" (current value: %1%2)").arg(mv).arg(unit);
915 extraText = tr(
" (current value: %1)").arg(mv);
917 editText = tr(
"drag up/down to adjust, ctrl+click to reset");
920 help = tr(
"Toggle Visibility of %1").arg(cname);
923 help = tr(
"Toggle Playback of %1").arg(cname);
927 if (help ==
"" && wname !=
"") {
929 if (qobject_cast<QAbstractButton *>(w)) {
930 mainText = tr(
"Toggle %1 property of %2")
931 .arg(propertyLabel).arg(cname);
937 mainText = tr(
"Adjust %1 property of %2%3")
938 .arg(propertyLabel).arg(cname).arg(
"");
943 if (mainText !=
"") {
944 if (editText !=
"") {
945 help = tr(
"%1%2: %3")
946 .arg(mainText).arg(extraText).arg(editText);
949 .arg(mainText).arg(extraText);
962 if (!(QApplication::mouseButtons() & Qt::LeftButton)) {
Very trivial enhancement to QComboBox to make it emit signals when the mouse enters and leaves (for c...
void propertyContainerPropertyChanged(PropertyContainer *)
The base class for visual representations of the data found in a Model.
void playPanControlChanged(float)
Very trivial enhancement to QCheckBox to make it emit signals when the mouse enters and leaves (for c...
void setDefaultValue(int defaultValue)
void mouseEnteredWidget()
Colour-picker combo box with swatches, optionally including "Add New Colour..." entry to invoke a QCo...
Colour map picker combo box with optional swatches.
std::map< QString, QWidget * > m_propertyControllers
void updateContextHelp(QObject *o)
void propertyControllerChanged(int)
void addCommand(Command *command)
Add a command to the command history.
void playGainControlChanged(float)
void updatePropertyEditor(PropertyContainer::PropertyName, bool rangeChanged=false)
void contextHelpChanged(const QString &)
QToolButton * m_playButton
void playAudibleChanged(bool)
QMenu * m_lastContextMenu
AudioDial is a nicer-looking QDial that by default reacts to mouse movement on horizontal and vertica...
void layerVisibilityChanged(bool)
void propertyContainerPropertyRangeChanged(PropertyContainer *)
void propertyControllerResetRequested()
std::map< QString, QGridLayout * > m_groupLayouts
void contextMenuRequested(const QPoint &)
PropertyContainer * m_container
void editPlayParameters()
static CommandHistory * getInstance()
PropertyBox(PropertyContainer *)
void setRangeMapper(RangeMapper *mapper)
void populateViewPlayFrame()
void playAudibleButtonChanged(bool)
void playClipChanged(QString)
void unitDatabaseChanged()
QObject * m_contextMenuOn
void setShowToolTip(bool show)