Mercurial > hg > svgui
diff widgets/PropertyBox.cpp @ 0:2a4f26e85b4c
initial import
author | Chris Cannam |
---|---|
date | Tue, 10 Jan 2006 16:33:16 +0000 |
parents | |
children | 37b110168acf |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/PropertyBox.cpp Tue Jan 10 16:33:16 2006 +0000 @@ -0,0 +1,272 @@ +/* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ + +/* + A waveform viewer and audio annotation editor. + Chris Cannam, Queen Mary University of London, 2005 + + This is experimental software. Not for distribution. +*/ + +#include "PropertyBox.h" + +#include "base/PropertyContainer.h" + +#include "AudioDial.h" + +#include <QGridLayout> +#include <QHBoxLayout> +#include <QCheckBox> +#include <QComboBox> +#include <QLabel> + +#include <cassert> +#include <iostream> + +//#define DEBUG_PROPERTY_BOX 1 + +PropertyBox::PropertyBox(PropertyContainer *container) : + m_container(container) +{ +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox[" << this << "(\"" << + container->getPropertyContainerName().toStdString() << "\")]::PropertyBox" << std::endl; +#endif + + m_layout = new QGridLayout; + setLayout(m_layout); + + PropertyContainer::PropertyList properties = container->getProperties(); + + blockSignals(true); + + size_t i; + + for (i = 0; i < properties.size(); ++i) { + updatePropertyEditor(properties[i]); + } + + blockSignals(false); + + m_layout->setRowStretch(m_layout->rowCount(), 10); + +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox[" << this << "]::PropertyBox returning" << std::endl; +#endif +} + +PropertyBox::~PropertyBox() +{ +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox[" << this << "(\"" << m_container->getPropertyContainerName().toStdString() << "\")]::~PropertyBox" << std::endl; +#endif +} + +void +PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name) +{ + PropertyContainer::PropertyType type = m_container->getPropertyType(name); + int row = m_layout->rowCount(); + + int min = 0, max = 0, value = 0; + value = m_container->getPropertyRangeAndValue(name, &min, &max); + + bool have = (m_propertyControllers.find(name) != + m_propertyControllers.end()); + + QString groupName = m_container->getPropertyGroupName(name); + +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox[" << this + << "(\"" << m_container->getPropertyContainerName().toStdString() + << "\")]"; + std::cerr << "::updatePropertyEditor(\"" << name.toStdString() << "\"):"; + std::cerr << " value " << value << ", have " << have << ", group \"" + << groupName.toStdString() << "\"" << std::endl; +#endif + + bool inGroup = (groupName != QString()); + + if (!have) { + if (inGroup) { + if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) { +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox: adding label \"" << groupName.toStdString() << "\" and frame for group for \"" << name.toStdString() << "\"" << std::endl; +#endif + m_layout->addWidget(new QLabel(groupName, this), row, 0); + QFrame *frame = new QFrame(this); + m_layout->addWidget(frame, row, 1, 1, 2); + m_groupLayouts[groupName] = new QHBoxLayout; + m_groupLayouts[groupName]->setMargin(0); + frame->setLayout(m_groupLayouts[groupName]); + } + } else { +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox: adding label \"" << name.toStdString() << "\"" << std::endl; +#endif + m_layout->addWidget(new QLabel(name, this), row, 0); + } + } + + switch (type) { + + case PropertyContainer::ToggleProperty: + { + QCheckBox *cb; + + if (have) { + cb = dynamic_cast<QCheckBox *>(m_propertyControllers[name]); + assert(cb); + } else { +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox: creating new checkbox" << std::endl; +#endif + cb = new QCheckBox(); + cb->setObjectName(name); + connect(cb, SIGNAL(stateChanged(int)), + this, SLOT(propertyControllerChanged(int))); + if (inGroup) { + cb->setToolTip(name); + m_groupLayouts[groupName]->addWidget(cb); + } else { + m_layout->addWidget(cb, row, 1, 1, 2); + } + m_propertyControllers[name] = cb; + } + + if (cb->isChecked() != (value > 0)) cb->setChecked(value > 0); + break; + } + + case PropertyContainer::RangeProperty: + { + AudioDial *dial; + + if (have) { + dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]); + assert(dial); + } else { +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox: creating new dial" << std::endl; +#endif + dial = new AudioDial(); + dial->setObjectName(name); + dial->setMinimum(min); + dial->setMaximum(max); + dial->setPageStep(1); + dial->setNotchesVisible(true); + connect(dial, SIGNAL(valueChanged(int)), + this, SLOT(propertyControllerChanged(int))); + + if (inGroup) { + dial->setFixedWidth(24); + dial->setFixedHeight(24); + dial->setToolTip(name); + m_groupLayouts[groupName]->addWidget(dial); + } else { + dial->setFixedWidth(32); + dial->setFixedHeight(32); + m_layout->addWidget(dial, row, 1); + QLabel *label = new QLabel(this); + connect(dial, SIGNAL(valueChanged(int)), + label, SLOT(setNum(int))); + label->setNum(value); + m_layout->addWidget(label, row, 2); + } + + m_propertyControllers[name] = dial; + } + + if (dial->value() != value) dial->setValue(value); + break; + } + + case PropertyContainer::ValueProperty: + { + QComboBox *cb; + + if (have) { + cb = dynamic_cast<QComboBox *>(m_propertyControllers[name]); + assert(cb); + } else { +#ifdef DEBUG_PROPERTY_BOX + std::cerr << "PropertyBox: creating new combobox" << std::endl; +#endif + + cb = new QComboBox(); + cb->setObjectName(name); + for (int i = min; i <= max; ++i) { + cb->addItem(m_container->getPropertyValueLabel(name, i)); + } + connect(cb, SIGNAL(activated(int)), + this, SLOT(propertyControllerChanged(int))); + if (inGroup) { + cb->setToolTip(name); + m_groupLayouts[groupName]->addWidget(cb); + } else { + m_layout->addWidget(cb, row, 1, 1, 2); + } + m_propertyControllers[name] = cb; + } + + if (cb->currentIndex() != value) cb->setCurrentIndex(value); + +#ifdef Q_WS_MAC + // Crashes on startup without this, for some reason + cb->setMinimumSize(QSize(10, 10)); +#endif + + break; + } + + default: + break; + } +} + +void +PropertyBox::propertyContainerPropertyChanged(PropertyContainer *pc) +{ + if (pc != m_container) return; + + PropertyContainer::PropertyList properties = m_container->getProperties(); + size_t i; + + blockSignals(true); + + for (i = 0; i < properties.size(); ++i) { + updatePropertyEditor(properties[i]); + } + + blockSignals(false); +} + +void +PropertyBox::propertyControllerChanged(int value) +{ + QObject *obj = sender(); + QString name = obj->objectName(); + +// std::cerr << "PropertyBox::propertyControllerChanged(" << name.toStdString() +// << ", " << value << ")" << std::endl; + + PropertyContainer::PropertyType type = m_container->getPropertyType(name); + + if (type != PropertyContainer::InvalidProperty) { + m_container->setProperty(name, value); + } + + if (type == PropertyContainer::RangeProperty) { + AudioDial *dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]); + if (dial) { + dial->setToolTip(QString("%1: %2").arg(name).arg(value)); + //!!! unfortunately this doesn't update an already-visible tooltip + } + } +} + + + +#ifdef INCLUDE_MOCFILES +#include "PropertyBox.moc.cpp" +#endif +