annotate widgets/PropertyBox.cpp @ 738:d26545a2a02d tonioni

Rather than undrawing the bottom bit of the dial, don't draw it in the first place (necessary on shaded background)
author Chris Cannam
date Thu, 06 Mar 2014 13:52:33 +0000
parents 596414d20ef0
children b6dc57688c72
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@182 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "PropertyBox.h"
Chris@63 17 #include "PluginParameterDialog.h"
Chris@0 18
Chris@0 19 #include "base/PropertyContainer.h"
Chris@33 20 #include "base/PlayParameters.h"
Chris@377 21 #include "base/PlayParameterRepository.h"
Chris@128 22 #include "layer/Layer.h"
Chris@376 23 #include "layer/ColourDatabase.h"
Chris@100 24 #include "base/UnitDatabase.h"
Chris@167 25 #include "base/RangeMapper.h"
Chris@0 26
Chris@63 27 #include "plugin/RealTimePluginFactory.h"
Chris@63 28 #include "plugin/RealTimePluginInstance.h"
Chris@71 29 #include "plugin/PluginXml.h"
Chris@63 30
Chris@0 31 #include "AudioDial.h"
Chris@33 32 #include "LEDButton.h"
Chris@335 33 #include "IconLoader.h"
Chris@0 34
Chris@189 35 #include "NotifyingCheckBox.h"
Chris@189 36 #include "NotifyingComboBox.h"
Chris@335 37 #include "NotifyingPushButton.h"
Chris@285 38 #include "ColourNameDialog.h"
Chris@189 39
Chris@0 40 #include <QGridLayout>
Chris@0 41 #include <QHBoxLayout>
Chris@33 42 #include <QVBoxLayout>
Chris@63 43 #include <QPushButton>
Chris@0 44 #include <QLabel>
Chris@33 45 #include <QFrame>
Chris@218 46 #include <QApplication>
Chris@285 47 #include <QColorDialog>
Chris@285 48 #include <QInputDialog>
Chris@0 49
Chris@0 50 #include <cassert>
Chris@0 51 #include <iostream>
Martin@46 52 #include <cmath>
Chris@0 53
Chris@456 54 //#define DEBUG_PROPERTY_BOX 1
Chris@0 55
Chris@0 56 PropertyBox::PropertyBox(PropertyContainer *container) :
Chris@185 57 m_container(container),
Chris@189 58 m_showButton(0),
Chris@189 59 m_playButton(0)
Chris@0 60 {
Chris@0 61 #ifdef DEBUG_PROPERTY_BOX
Chris@682 62 cerr << "PropertyBox[" << this << "(\"" <<
Chris@682 63 container->getPropertyContainerName() << "\" at " << container << ")]::PropertyBox" << endl;
Chris@0 64 #endif
Chris@0 65
Chris@34 66 m_mainBox = new QVBoxLayout;
Chris@34 67 setLayout(m_mainBox);
Chris@33 68
Chris@107 69 // m_nameWidget = new QLabel;
Chris@107 70 // m_mainBox->addWidget(m_nameWidget);
Chris@107 71 // m_nameWidget->setText(container->objectName());
Chris@107 72
Chris@34 73 m_mainWidget = new QWidget;
Chris@34 74 m_mainBox->addWidget(m_mainWidget);
Chris@107 75 m_mainBox->insertStretch(2, 10);
Chris@33 76
Chris@34 77 m_viewPlayFrame = 0;
Chris@34 78 populateViewPlayFrame();
Chris@33 79
Chris@0 80 m_layout = new QGridLayout;
Chris@34 81 m_layout->setMargin(0);
Chris@33 82 m_mainWidget->setLayout(m_layout);
Chris@0 83
Chris@34 84 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@0 85
Chris@0 86 blockSignals(true);
Chris@0 87
Chris@0 88 size_t i;
Chris@0 89
Chris@0 90 for (i = 0; i < properties.size(); ++i) {
Chris@0 91 updatePropertyEditor(properties[i]);
Chris@0 92 }
Chris@0 93
Chris@0 94 blockSignals(false);
Chris@0 95
Chris@0 96 m_layout->setRowStretch(m_layout->rowCount(), 10);
Chris@0 97
Chris@100 98 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()),
Chris@100 99 this, SLOT(unitDatabaseChanged()));
Chris@100 100
Chris@285 101 connect(ColourDatabase::getInstance(), SIGNAL(colourDatabaseChanged()),
Chris@285 102 this, SLOT(colourDatabaseChanged()));
Chris@285 103
Chris@0 104 #ifdef DEBUG_PROPERTY_BOX
Chris@682 105 cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl;
Chris@0 106 #endif
Chris@0 107 }
Chris@0 108
Chris@0 109 PropertyBox::~PropertyBox()
Chris@0 110 {
Chris@0 111 #ifdef DEBUG_PROPERTY_BOX
Chris@682 112 cerr << "PropertyBox[" << this << "]::~PropertyBox" << endl;
Chris@0 113 #endif
Chris@0 114 }
Chris@0 115
Chris@0 116 void
Chris@34 117 PropertyBox::populateViewPlayFrame()
Chris@33 118 {
Chris@36 119 #ifdef DEBUG_PROPERTY_BOX
Chris@728 120 cerr << "PropertyBox[" << this << ":" << m_container << "]::populateViewPlayFrame" << endl;
Chris@36 121 #endif
Chris@34 122
Chris@34 123 if (m_viewPlayFrame) {
Chris@34 124 delete m_viewPlayFrame;
Chris@34 125 m_viewPlayFrame = 0;
Chris@34 126 }
Chris@34 127
Chris@34 128 if (!m_container) return;
Chris@34 129
Chris@34 130 Layer *layer = dynamic_cast<Layer *>(m_container);
Chris@34 131 if (layer) {
Chris@193 132 disconnect(layer, SIGNAL(modelReplaced()),
Chris@193 133 this, SLOT(populateViewPlayFrame()));
Chris@34 134 connect(layer, SIGNAL(modelReplaced()),
Chris@34 135 this, SLOT(populateViewPlayFrame()));
Chris@34 136 }
Chris@34 137
Chris@34 138 PlayParameters *params = m_container->getPlayParameters();
Chris@33 139 if (!params && !layer) return;
Chris@33 140
Chris@34 141 m_viewPlayFrame = new QFrame;
Chris@34 142 m_viewPlayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
Chris@34 143 m_mainBox->addWidget(m_viewPlayFrame);
Chris@34 144
Chris@34 145 QHBoxLayout *layout = new QHBoxLayout;
Chris@34 146 m_viewPlayFrame->setLayout(layout);
Chris@34 147
Chris@34 148 layout->setMargin(layout->margin() / 2);
Chris@34 149
Chris@36 150 #ifdef DEBUG_PROPERTY_BOX
Chris@587 151 SVDEBUG << "PropertyBox::populateViewPlayFrame: container " << m_container << " (name " << m_container->getPropertyContainerName() << ") params " << params << endl;
Chris@36 152 #endif
Chris@36 153
Chris@33 154 if (layer) {
Chris@34 155 QLabel *showLabel = new QLabel(tr("Show"));
Chris@34 156 layout->addWidget(showLabel);
Chris@34 157 layout->setAlignment(showLabel, Qt::AlignVCenter);
Chris@34 158
Chris@185 159 m_showButton = new LEDButton(Qt::blue);
Chris@185 160 layout->addWidget(m_showButton);
Chris@185 161 connect(m_showButton, SIGNAL(stateChanged(bool)),
Chris@47 162 this, SIGNAL(showLayer(bool)));
Chris@189 163 connect(m_showButton, SIGNAL(mouseEntered()),
Chris@189 164 this, SLOT(mouseEnteredWidget()));
Chris@189 165 connect(m_showButton, SIGNAL(mouseLeft()),
Chris@189 166 this, SLOT(mouseLeftWidget()));
Chris@185 167 layout->setAlignment(m_showButton, Qt::AlignVCenter);
Chris@33 168 }
Chris@33 169
Chris@33 170 if (params) {
Chris@34 171
Chris@34 172 QLabel *playLabel = new QLabel(tr("Play"));
Chris@34 173 layout->addWidget(playLabel);
Chris@34 174 layout->setAlignment(playLabel, Qt::AlignVCenter);
Chris@34 175
Chris@189 176 m_playButton = new LEDButton(Qt::darkGreen);
Chris@189 177 m_playButton->setState(!params->isPlayMuted());
Chris@189 178 layout->addWidget(m_playButton);
Chris@189 179 connect(m_playButton, SIGNAL(stateChanged(bool)),
Chris@377 180 this, SLOT(playAudibleButtonChanged(bool)));
Chris@189 181 connect(m_playButton, SIGNAL(mouseEntered()),
Chris@189 182 this, SLOT(mouseEnteredWidget()));
Chris@189 183 connect(m_playButton, SIGNAL(mouseLeft()),
Chris@189 184 this, SLOT(mouseLeftWidget()));
Chris@34 185 connect(params, SIGNAL(playAudibleChanged(bool)),
Chris@377 186 this, SLOT(playAudibleChanged(bool)));
Chris@189 187 layout->setAlignment(m_playButton, Qt::AlignVCenter);
Chris@34 188
Chris@34 189 layout->insertStretch(-1, 10);
Chris@34 190
Chris@707 191 /*!!! todo: restore playback sample selection
Chris@63 192 if (params->getPlayPluginId() != "") {
Chris@64 193 QPushButton *pluginButton = new QPushButton(QIcon(":icons/faders.png"), "");
Chris@64 194 pluginButton->setFixedWidth(24);
Chris@64 195 pluginButton->setFixedHeight(24);
Chris@63 196 layout->addWidget(pluginButton);
Chris@63 197 connect(pluginButton, SIGNAL(clicked()),
Chris@63 198 this, SLOT(editPlugin()));
Chris@63 199 }
Chris@707 200 */
Chris@63 201
Chris@34 202 AudioDial *gainDial = new AudioDial;
Chris@34 203 layout->addWidget(gainDial);
Chris@34 204 gainDial->setMeterColor(Qt::darkRed);
Chris@34 205 gainDial->setMinimum(-50);
Chris@34 206 gainDial->setMaximum(50);
Chris@34 207 gainDial->setPageStep(1);
Chris@34 208 gainDial->setFixedWidth(24);
Chris@34 209 gainDial->setFixedHeight(24);
Chris@34 210 gainDial->setNotchesVisible(false);
Chris@34 211 gainDial->setDefaultValue(0);
Chris@168 212 gainDial->setObjectName(tr("Playback Gain"));
Chris@167 213 gainDial->setRangeMapper(new LinearRangeMapper
Chris@167 214 (-50, 50, -25, 25, tr("dB")));
Chris@168 215 gainDial->setShowToolTip(true);
Chris@34 216 connect(gainDial, SIGNAL(valueChanged(int)),
Chris@34 217 this, SLOT(playGainDialChanged(int)));
Chris@34 218 connect(params, SIGNAL(playGainChanged(float)),
Chris@34 219 this, SLOT(playGainChanged(float)));
Chris@34 220 connect(this, SIGNAL(changePlayGainDial(int)),
Chris@34 221 gainDial, SLOT(setValue(int)));
Chris@189 222 connect(gainDial, SIGNAL(mouseEntered()),
Chris@189 223 this, SLOT(mouseEnteredWidget()));
Chris@189 224 connect(gainDial, SIGNAL(mouseLeft()),
Chris@189 225 this, SLOT(mouseLeftWidget()));
Chris@377 226 playGainChanged(params->getPlayGain());
Chris@34 227 layout->setAlignment(gainDial, Qt::AlignVCenter);
Chris@34 228
Chris@34 229 AudioDial *panDial = new AudioDial;
Chris@34 230 layout->addWidget(panDial);
Chris@34 231 panDial->setMeterColor(Qt::darkGreen);
Chris@34 232 panDial->setMinimum(-50);
Chris@34 233 panDial->setMaximum(50);
Chris@34 234 panDial->setPageStep(1);
Chris@34 235 panDial->setFixedWidth(24);
Chris@34 236 panDial->setFixedHeight(24);
Chris@34 237 panDial->setNotchesVisible(false);
Chris@57 238 panDial->setToolTip(tr("Playback Pan / Balance"));
Chris@34 239 panDial->setDefaultValue(0);
Chris@168 240 panDial->setObjectName(tr("Playback Pan / Balance"));
Chris@168 241 panDial->setShowToolTip(true);
Chris@34 242 connect(panDial, SIGNAL(valueChanged(int)),
Chris@34 243 this, SLOT(playPanDialChanged(int)));
Chris@34 244 connect(params, SIGNAL(playPanChanged(float)),
Chris@34 245 this, SLOT(playPanChanged(float)));
Chris@34 246 connect(this, SIGNAL(changePlayPanDial(int)),
Chris@34 247 panDial, SLOT(setValue(int)));
Chris@189 248 connect(panDial, SIGNAL(mouseEntered()),
Chris@189 249 this, SLOT(mouseEnteredWidget()));
Chris@189 250 connect(panDial, SIGNAL(mouseLeft()),
Chris@189 251 this, SLOT(mouseLeftWidget()));
Chris@377 252 playPanChanged(params->getPlayPan());
Chris@34 253 layout->setAlignment(panDial, Qt::AlignVCenter);
Chris@34 254
Chris@34 255 } else {
Chris@34 256
Chris@34 257 layout->insertStretch(-1, 10);
Chris@33 258 }
Chris@33 259 }
Chris@33 260
Chris@33 261 void
Chris@197 262 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name,
Chris@197 263 bool rangeChanged)
Chris@0 264 {
Chris@0 265 PropertyContainer::PropertyType type = m_container->getPropertyType(name);
Chris@0 266 int row = m_layout->rowCount();
Chris@0 267
Chris@216 268 int min = 0, max = 0, value = 0, deflt = 0;
Chris@216 269 value = m_container->getPropertyRangeAndValue(name, &min, &max, &deflt);
Chris@0 270
Chris@0 271 bool have = (m_propertyControllers.find(name) !=
Chris@0 272 m_propertyControllers.end());
Chris@0 273
Chris@0 274 QString groupName = m_container->getPropertyGroupName(name);
Chris@87 275 QString propertyLabel = m_container->getPropertyLabel(name);
Chris@335 276 QString iconName = m_container->getPropertyIconName(name);
Chris@0 277
Chris@0 278 #ifdef DEBUG_PROPERTY_BOX
Chris@682 279 cerr << "PropertyBox[" << this
Chris@683 280 << "(\"" << m_container->getPropertyContainerName()
Chris@0 281 << "\")]";
Chris@682 282 cerr << "::updatePropertyEditor(\"" << name << "\"):";
Chris@682 283 cerr << " value " << value << ", have " << have << ", group \""
Chris@682 284 << groupName << "\"" << endl;
Chris@0 285 #endif
Chris@0 286
Chris@0 287 bool inGroup = (groupName != QString());
Chris@0 288
Chris@0 289 if (!have) {
Chris@0 290 if (inGroup) {
Chris@0 291 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) {
Chris@0 292 #ifdef DEBUG_PROPERTY_BOX
Chris@682 293 cerr << "PropertyBox: adding label \"" << groupName << "\" and frame for group for \"" << name << "\"" << endl;
Chris@0 294 #endif
Chris@33 295 m_layout->addWidget(new QLabel(groupName, m_mainWidget), row, 0);
Chris@33 296 QFrame *frame = new QFrame(m_mainWidget);
Chris@0 297 m_layout->addWidget(frame, row, 1, 1, 2);
Chris@493 298 m_groupLayouts[groupName] = new QGridLayout;
Chris@0 299 m_groupLayouts[groupName]->setMargin(0);
Chris@0 300 frame->setLayout(m_groupLayouts[groupName]);
Chris@0 301 }
Chris@0 302 } else {
Chris@0 303 #ifdef DEBUG_PROPERTY_BOX
Chris@682 304 cerr << "PropertyBox: adding label \"" << propertyLabel << "\"" << endl;
Chris@0 305 #endif
Chris@87 306 m_layout->addWidget(new QLabel(propertyLabel, m_mainWidget), row, 0);
Chris@0 307 }
Chris@0 308 }
Chris@0 309
Chris@0 310 switch (type) {
Chris@0 311
Chris@0 312 case PropertyContainer::ToggleProperty:
Chris@0 313 {
Chris@335 314 QAbstractButton *button = 0;
Chris@0 315
Chris@0 316 if (have) {
Chris@335 317 button = dynamic_cast<QAbstractButton *>(m_propertyControllers[name]);
Chris@335 318 assert(button);
Chris@0 319 } else {
Chris@0 320 #ifdef DEBUG_PROPERTY_BOX
Chris@682 321 cerr << "PropertyBox: creating new checkbox" << endl;
Chris@0 322 #endif
Chris@335 323 if (iconName != "") {
Chris@335 324 button = new NotifyingPushButton();
Chris@335 325 button->setCheckable(true);
Chris@335 326 QIcon icon(IconLoader().load(iconName));
Chris@335 327 button->setIcon(icon);
Chris@335 328 button->setObjectName(name);
Chris@335 329 button->setFixedSize(QSize(18, 18));
Chris@335 330 } else {
Chris@335 331 button = new NotifyingCheckBox();
Chris@335 332 button->setObjectName(name);
Chris@335 333 }
Chris@335 334 connect(button, SIGNAL(toggled(bool)),
Chris@335 335 this, SLOT(propertyControllerChanged(bool)));
Chris@335 336 connect(button, SIGNAL(mouseEntered()),
Chris@189 337 this, SLOT(mouseEnteredWidget()));
Chris@335 338 connect(button, SIGNAL(mouseLeft()),
Chris@189 339 this, SLOT(mouseLeftWidget()));
Chris@0 340 if (inGroup) {
Chris@335 341 button->setToolTip(propertyLabel);
Chris@493 342 m_groupLayouts[groupName]->addWidget
Chris@493 343 (button, 0, m_groupLayouts[groupName]->columnCount());
Chris@0 344 } else {
Chris@335 345 m_layout->addWidget(button, row, 1, 1, 2);
Chris@0 346 }
Chris@335 347 m_propertyControllers[name] = button;
Chris@0 348 }
Chris@0 349
Chris@335 350 if (button->isChecked() != (value > 0)) {
Chris@335 351 button->blockSignals(true);
Chris@335 352 button->setChecked(value > 0);
Chris@335 353 button->blockSignals(false);
Chris@55 354 }
Chris@0 355 break;
Chris@0 356 }
Chris@0 357
Chris@0 358 case PropertyContainer::RangeProperty:
Chris@0 359 {
Chris@0 360 AudioDial *dial;
Chris@0 361
Chris@0 362 if (have) {
Chris@0 363 dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]);
Chris@0 364 assert(dial);
Chris@197 365 if (rangeChanged) {
Chris@197 366 dial->blockSignals(true);
Chris@197 367 dial->setMinimum(min);
Chris@197 368 dial->setMaximum(max);
Chris@197 369 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name));
Chris@197 370 dial->blockSignals(false);
Chris@197 371 }
Chris@197 372
Chris@0 373 } else {
Chris@0 374 #ifdef DEBUG_PROPERTY_BOX
Chris@682 375 cerr << "PropertyBox: creating new dial" << endl;
Chris@0 376 #endif
Chris@0 377 dial = new AudioDial();
Chris@0 378 dial->setObjectName(name);
Chris@0 379 dial->setMinimum(min);
Chris@0 380 dial->setMaximum(max);
Chris@0 381 dial->setPageStep(1);
Chris@34 382 dial->setNotchesVisible((max - min) <= 12);
Chris@216 383 dial->setDefaultValue(deflt);
Chris@167 384 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name));
Chris@168 385 dial->setShowToolTip(true);
Chris@0 386 connect(dial, SIGNAL(valueChanged(int)),
Chris@0 387 this, SLOT(propertyControllerChanged(int)));
Chris@189 388 connect(dial, SIGNAL(mouseEntered()),
Chris@189 389 this, SLOT(mouseEnteredWidget()));
Chris@189 390 connect(dial, SIGNAL(mouseLeft()),
Chris@189 391 this, SLOT(mouseLeftWidget()));
Chris@0 392
Chris@0 393 if (inGroup) {
Chris@0 394 dial->setFixedWidth(24);
Chris@0 395 dial->setFixedHeight(24);
Chris@493 396 m_groupLayouts[groupName]->addWidget
Chris@493 397 (dial, 0, m_groupLayouts[groupName]->columnCount());
Chris@0 398 } else {
Chris@0 399 dial->setFixedWidth(32);
Chris@0 400 dial->setFixedHeight(32);
Chris@0 401 m_layout->addWidget(dial, row, 1);
Chris@33 402 QLabel *label = new QLabel(m_mainWidget);
Chris@0 403 connect(dial, SIGNAL(valueChanged(int)),
Chris@0 404 label, SLOT(setNum(int)));
Chris@0 405 label->setNum(value);
Chris@0 406 m_layout->addWidget(label, row, 2);
Chris@0 407 }
Chris@0 408
Chris@0 409 m_propertyControllers[name] = dial;
Chris@0 410 }
Chris@0 411
Chris@55 412 if (dial->value() != value) {
Chris@55 413 dial->blockSignals(true);
Chris@55 414 dial->setValue(value);
Chris@55 415 dial->blockSignals(false);
Chris@55 416 }
Chris@0 417 break;
Chris@0 418 }
Chris@0 419
Chris@0 420 case PropertyContainer::ValueProperty:
Chris@100 421 case PropertyContainer::UnitsProperty:
Chris@285 422 case PropertyContainer::ColourProperty:
Chris@0 423 {
Chris@189 424 NotifyingComboBox *cb;
Chris@0 425
Chris@0 426 if (have) {
Chris@189 427 cb = dynamic_cast<NotifyingComboBox *>(m_propertyControllers[name]);
Chris@0 428 assert(cb);
Chris@0 429 } else {
Chris@0 430 #ifdef DEBUG_PROPERTY_BOX
Chris@682 431 cerr << "PropertyBox: creating new combobox" << endl;
Chris@0 432 #endif
Chris@0 433
Chris@189 434 cb = new NotifyingComboBox();
Chris@0 435 cb->setObjectName(name);
Chris@100 436 cb->setDuplicatesEnabled(false);
Chris@197 437 }
Chris@100 438
Chris@197 439 if (!have || rangeChanged) {
Chris@285 440
Chris@197 441 cb->blockSignals(true);
Chris@197 442 cb->clear();
Chris@285 443 cb->setEditable(false);
Chris@285 444
Chris@100 445 if (type == PropertyContainer::ValueProperty) {
Chris@285 446
Chris@100 447 for (int i = min; i <= max; ++i) {
Chris@100 448 cb->addItem(m_container->getPropertyValueLabel(name, i));
Chris@100 449 }
Chris@285 450
Chris@285 451 } else if (type == PropertyContainer::UnitsProperty) {
Chris@285 452
Chris@100 453 QStringList units = UnitDatabase::getInstance()->getKnownUnits();
Chris@100 454 for (int i = 0; i < units.size(); ++i) {
Chris@100 455 cb->addItem(units[i]);
Chris@100 456 }
Chris@285 457
Chris@100 458 cb->setEditable(true);
Chris@285 459
Chris@285 460 } else { // ColourProperty
Chris@290 461
Chris@290 462 //!!! should be a proper colour combobox class that
Chris@290 463 // manages its own Add New Colour entry...
Chris@285 464
Chris@285 465 ColourDatabase *db = ColourDatabase::getInstance();
Chris@285 466 for (size_t i = 0; i < db->getColourCount(); ++i) {
Chris@285 467 QString name = db->getColourName(i);
Chris@287 468 cb->addItem(db->getExamplePixmap(i, QSize(12, 12)), name);
Chris@285 469 }
Chris@285 470 cb->addItem(tr("Add New Colour..."));
Chris@285 471 }
Chris@285 472
Chris@197 473 cb->blockSignals(false);
Chris@280 474 if (cb->count() < 20 && cb->count() > cb->maxVisibleItems()) {
Chris@280 475 cb->setMaxVisibleItems(cb->count());
Chris@280 476 }
Chris@197 477 }
Chris@100 478
Chris@197 479 if (!have) {
Chris@0 480 connect(cb, SIGNAL(activated(int)),
Chris@0 481 this, SLOT(propertyControllerChanged(int)));
Chris@189 482 connect(cb, SIGNAL(mouseEntered()),
Chris@189 483 this, SLOT(mouseEnteredWidget()));
Chris@189 484 connect(cb, SIGNAL(mouseLeft()),
Chris@189 485 this, SLOT(mouseLeftWidget()));
Chris@100 486
Chris@0 487 if (inGroup) {
Chris@108 488 cb->setToolTip(propertyLabel);
Chris@493 489 m_groupLayouts[groupName]->addWidget
Chris@493 490 (cb, 0, m_groupLayouts[groupName]->columnCount());
Chris@0 491 } else {
Chris@0 492 m_layout->addWidget(cb, row, 1, 1, 2);
Chris@0 493 }
Chris@0 494 m_propertyControllers[name] = cb;
Chris@0 495 }
Chris@0 496
Chris@100 497 cb->blockSignals(true);
Chris@285 498 if (type == PropertyContainer::ValueProperty ||
Chris@285 499 type == PropertyContainer::ColourProperty) {
Chris@100 500 if (cb->currentIndex() != value) {
Chris@100 501 cb->setCurrentIndex(value);
Chris@100 502 }
Chris@100 503 } else {
Chris@100 504 QString unit = UnitDatabase::getInstance()->getUnitById(value);
Chris@100 505 if (cb->currentText() != unit) {
Chris@100 506 for (int i = 0; i < cb->count(); ++i) {
Chris@100 507 if (cb->itemText(i) == unit) {
Chris@100 508 cb->setCurrentIndex(i);
Chris@100 509 break;
Chris@100 510 }
Chris@100 511 }
Chris@100 512 }
Chris@100 513 }
Chris@100 514 cb->blockSignals(false);
Chris@0 515
Chris@681 516 #ifdef Q_OS_MAC
Chris@0 517 // Crashes on startup without this, for some reason
Chris@0 518 cb->setMinimumSize(QSize(10, 10));
Chris@0 519 #endif
Chris@0 520
Chris@0 521 break;
Chris@0 522 }
Chris@0 523
Chris@0 524 default:
Chris@0 525 break;
Chris@0 526 }
Chris@0 527 }
Chris@0 528
Chris@0 529 void
Chris@0 530 PropertyBox::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@0 531 {
Chris@0 532 if (pc != m_container) return;
Chris@0 533
Chris@55 534 #ifdef DEBUG_PROPERTY_BOX
Chris@587 535 SVDEBUG << "PropertyBox::propertyContainerPropertyChanged" << endl;
Chris@55 536 #endif
Chris@55 537
Chris@0 538 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@0 539 size_t i;
Chris@0 540
Chris@0 541 blockSignals(true);
Chris@0 542
Chris@0 543 for (i = 0; i < properties.size(); ++i) {
Chris@0 544 updatePropertyEditor(properties[i]);
Chris@0 545 }
Chris@0 546
Chris@0 547 blockSignals(false);
Chris@0 548 }
Chris@0 549
Chris@0 550 void
Chris@249 551 PropertyBox::propertyContainerPropertyRangeChanged(PropertyContainer *)
Chris@197 552 {
Chris@197 553 blockSignals(true);
Chris@197 554
Chris@197 555 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@197 556 for (size_t i = 0; i < properties.size(); ++i) {
Chris@197 557 updatePropertyEditor(properties[i], true);
Chris@197 558 }
Chris@197 559
Chris@197 560 blockSignals(false);
Chris@197 561 }
Chris@197 562
Chris@197 563 void
Chris@100 564 PropertyBox::unitDatabaseChanged()
Chris@100 565 {
Chris@728 566 #ifdef DEBUG_PROPERTY_BOX
Chris@682 567 cerr << "PropertyBox[" << this << "]: unitDatabaseChanged" << endl;
Chris@728 568 #endif
Chris@100 569 blockSignals(true);
Chris@100 570
Chris@682 571 // cerr << "my container is " << m_container << endl;
Chris@682 572 // cerr << "my container's name is... " << endl;
Chris@682 573 // cerr << m_container->objectName() << endl;
Chris@456 574
Chris@100 575 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@100 576 for (size_t i = 0; i < properties.size(); ++i) {
Chris@285 577 if (m_container->getPropertyType(properties[i]) ==
Chris@285 578 PropertyContainer::UnitsProperty) {
Chris@285 579 updatePropertyEditor(properties[i]);
Chris@285 580 }
Chris@285 581 }
Chris@285 582
Chris@285 583 blockSignals(false);
Chris@285 584 }
Chris@285 585
Chris@285 586 void
Chris@285 587 PropertyBox::colourDatabaseChanged()
Chris@285 588 {
Chris@285 589 blockSignals(true);
Chris@285 590
Chris@285 591 PropertyContainer::PropertyList properties = m_container->getProperties();
Chris@285 592 for (size_t i = 0; i < properties.size(); ++i) {
Chris@285 593 if (m_container->getPropertyType(properties[i]) ==
Chris@285 594 PropertyContainer::ColourProperty) {
Chris@285 595 updatePropertyEditor(properties[i], true);
Chris@285 596 }
Chris@100 597 }
Chris@100 598
Chris@100 599 blockSignals(false);
Chris@100 600 }
Chris@100 601
Chris@100 602 void
Chris@335 603 PropertyBox::propertyControllerChanged(bool on)
Chris@335 604 {
Chris@335 605 propertyControllerChanged(on ? 1 : 0);
Chris@335 606 }
Chris@335 607
Chris@335 608 void
Chris@0 609 PropertyBox::propertyControllerChanged(int value)
Chris@0 610 {
Chris@0 611 QObject *obj = sender();
Chris@0 612 QString name = obj->objectName();
Chris@0 613
Chris@34 614 #ifdef DEBUG_PROPERTY_BOX
Chris@587 615 SVDEBUG << "PropertyBox::propertyControllerChanged(" << name << ", " << value << ")" << endl;
Chris@34 616 #endif
Chris@0 617
Chris@0 618 PropertyContainer::PropertyType type = m_container->getPropertyType(name);
Chris@100 619
Chris@376 620 Command *c = 0;
Chris@376 621
Chris@100 622 if (type == PropertyContainer::UnitsProperty) {
Chris@285 623
Chris@189 624 NotifyingComboBox *cb = dynamic_cast<NotifyingComboBox *>(obj);
Chris@100 625 if (cb) {
Chris@100 626 QString unit = cb->currentText();
Chris@376 627 c = m_container->getSetPropertyCommand
Chris@100 628 (name, UnitDatabase::getInstance()->getUnitId(unit));
Chris@100 629 }
Chris@285 630
Chris@285 631 } else if (type == PropertyContainer::ColourProperty) {
Chris@285 632
Chris@285 633 if (value == int(ColourDatabase::getInstance()->getColourCount())) {
Chris@285 634 addNewColour();
Chris@285 635 if (value == int(ColourDatabase::getInstance()->getColourCount())) {
Chris@285 636 propertyContainerPropertyChanged(m_container);
Chris@285 637 return;
Chris@285 638 }
Chris@285 639 }
Chris@376 640 c = m_container->getSetPropertyCommand(name, value);
Chris@285 641
Chris@100 642 } else if (type != PropertyContainer::InvalidProperty) {
Chris@285 643
Chris@376 644 c = m_container->getSetPropertyCommand(name, value);
Chris@0 645 }
Chris@376 646
Chris@376 647 if (c) CommandHistory::getInstance()->addCommand(c, true, true);
Chris@218 648
Chris@218 649 updateContextHelp(obj);
Chris@0 650 }
Chris@285 651
Chris@285 652 void
Chris@285 653 PropertyBox::addNewColour()
Chris@285 654 {
Chris@285 655 QColor newColour = QColorDialog::getColor();
Chris@285 656 if (!newColour.isValid()) return;
Chris@285 657
Chris@285 658 ColourNameDialog dialog(tr("Name New Colour"),
Chris@361 659 tr("Enter a name for the new colour:"),
Chris@361 660 newColour, newColour.name(), this);
Chris@285 661 dialog.showDarkBackgroundCheckbox(tr("Prefer black background for this colour"));
Chris@285 662 if (dialog.exec() == QDialog::Accepted) {
Chris@285 663 //!!! command
Chris@285 664 ColourDatabase *db = ColourDatabase::getInstance();
Chris@285 665 int index = db->addColour(newColour, dialog.getColourName());
Chris@285 666 db->setUseDarkBackground(index, dialog.isDarkBackgroundChecked());
Chris@285 667 }
Chris@285 668 }
Chris@377 669
Chris@377 670 void
Chris@377 671 PropertyBox::playAudibleChanged(bool audible)
Chris@377 672 {
Chris@377 673 m_playButton->setState(audible);
Chris@377 674 }
Chris@377 675
Chris@377 676 void
Chris@377 677 PropertyBox::playAudibleButtonChanged(bool audible)
Chris@377 678 {
Chris@377 679 PlayParameters *params = m_container->getPlayParameters();
Chris@377 680 if (!params) return;
Chris@377 681
Chris@377 682 if (params->isPlayAudible() != audible) {
Chris@377 683 PlayParameterRepository::EditCommand *command =
Chris@377 684 new PlayParameterRepository::EditCommand(params);
Chris@377 685 command->setPlayAudible(audible);
Chris@377 686 CommandHistory::getInstance()->addCommand(command, true, true);
Chris@377 687 }
Chris@377 688 }
Chris@0 689
Chris@34 690 void
Chris@34 691 PropertyBox::playGainChanged(float gain)
Chris@34 692 {
Chris@34 693 int dialValue = lrint(log10(gain) * 20.0);
Chris@34 694 if (dialValue < -50) dialValue = -50;
Chris@34 695 if (dialValue > 50) dialValue = 50;
Chris@34 696 emit changePlayGainDial(dialValue);
Chris@34 697 }
Chris@34 698
Chris@34 699 void
Chris@34 700 PropertyBox::playGainDialChanged(int dialValue)
Chris@34 701 {
Chris@218 702 QObject *obj = sender();
Chris@377 703
Chris@377 704 PlayParameters *params = m_container->getPlayParameters();
Chris@377 705 if (!params) return;
Chris@377 706
Chris@34 707 float gain = pow(10, float(dialValue) / 20.0);
Chris@377 708
Chris@377 709 if (params->getPlayGain() != gain) {
Chris@377 710 PlayParameterRepository::EditCommand *command =
Chris@377 711 new PlayParameterRepository::EditCommand(params);
Chris@377 712 command->setPlayGain(gain);
Chris@377 713 CommandHistory::getInstance()->addCommand(command, true, true);
Chris@377 714 }
Chris@377 715
Chris@218 716 updateContextHelp(obj);
Chris@34 717 }
Chris@34 718
Chris@34 719 void
Chris@34 720 PropertyBox::playPanChanged(float pan)
Chris@34 721 {
Chris@34 722 int dialValue = lrint(pan * 50.0);
Chris@34 723 if (dialValue < -50) dialValue = -50;
Chris@34 724 if (dialValue > 50) dialValue = 50;
Chris@34 725 emit changePlayPanDial(dialValue);
Chris@34 726 }
Chris@34 727
Chris@34 728 void
Chris@34 729 PropertyBox::playPanDialChanged(int dialValue)
Chris@34 730 {
Chris@218 731 QObject *obj = sender();
Chris@377 732
Chris@377 733 PlayParameters *params = m_container->getPlayParameters();
Chris@377 734 if (!params) return;
Chris@377 735
Chris@34 736 float pan = float(dialValue) / 50.0;
Chris@34 737 if (pan < -1.0) pan = -1.0;
Chris@34 738 if (pan > 1.0) pan = 1.0;
Chris@377 739
Chris@377 740 if (params->getPlayPan() != pan) {
Chris@377 741 PlayParameterRepository::EditCommand *command =
Chris@377 742 new PlayParameterRepository::EditCommand(params);
Chris@377 743 command->setPlayPan(pan);
Chris@377 744 CommandHistory::getInstance()->addCommand(command, true, true);
Chris@377 745 }
Chris@377 746
Chris@218 747 updateContextHelp(obj);
Chris@34 748 }
Chris@707 749 /*!!! todo: restore playback sample selection
Chris@63 750 void
Chris@63 751 PropertyBox::editPlugin()
Chris@63 752 {
Chris@63 753 //!!! should probably just emit and let something else do this
Chris@63 754
Chris@63 755 PlayParameters *params = m_container->getPlayParameters();
Chris@63 756 if (!params) return;
Chris@63 757
Chris@63 758 QString pluginId = params->getPlayPluginId();
Chris@63 759 QString configurationXml = params->getPlayPluginConfiguration();
Chris@377 760
Chris@377 761 PlayParameterRepository::EditCommand *command =
Chris@377 762 new PlayParameterRepository::EditCommand(params);
Chris@63 763
Chris@63 764 RealTimePluginFactory *factory =
Chris@63 765 RealTimePluginFactory::instanceFor(pluginId);
Chris@63 766 if (!factory) return;
Chris@63 767
Chris@63 768 RealTimePluginInstance *instance =
Chris@63 769 factory->instantiatePlugin(pluginId, 0, 0, 48000, 1024, 1);
Chris@63 770 if (!instance) return;
Chris@63 771
Chris@71 772 PluginXml(instance).setParametersFromXml(configurationXml);
Chris@63 773
Chris@163 774 PluginParameterDialog *dialog = new PluginParameterDialog(instance);
Chris@64 775 connect(dialog, SIGNAL(pluginConfigurationChanged(QString)),
Chris@64 776 this, SLOT(pluginConfigurationChanged(QString)));
Chris@64 777
Chris@63 778 if (dialog->exec() == QDialog::Accepted) {
Chris@377 779 QString newConfiguration = PluginXml(instance).toXmlString();
Chris@377 780 command->setPlayPluginConfiguration(newConfiguration);
Chris@377 781 CommandHistory::getInstance()->addCommand(command, true);
Chris@64 782 } else {
Chris@377 783 delete command;
Chris@64 784 // restore in case we mucked about with the configuration
Chris@64 785 // as a consequence of signals from the dialog
Chris@64 786 params->setPlayPluginConfiguration(configurationXml);
Chris@63 787 }
Chris@63 788
Chris@63 789 delete dialog;
Chris@63 790 delete instance;
Chris@63 791 }
Chris@63 792
Chris@64 793 void
Chris@64 794 PropertyBox::pluginConfigurationChanged(QString configurationXml)
Chris@64 795 {
Chris@64 796 PlayParameters *params = m_container->getPlayParameters();
Chris@64 797 if (!params) return;
Chris@64 798
Chris@64 799 params->setPlayPluginConfiguration(configurationXml);
Chris@64 800 }
Chris@707 801 */
Chris@185 802 void
Chris@185 803 PropertyBox::layerVisibilityChanged(bool visible)
Chris@185 804 {
Chris@185 805 if (m_showButton) m_showButton->setState(visible);
Chris@185 806 }
Chris@189 807
Chris@189 808 void
Chris@189 809 PropertyBox::mouseEnteredWidget()
Chris@189 810 {
Chris@218 811 updateContextHelp(sender());
Chris@218 812 }
Chris@218 813
Chris@218 814 void
Chris@218 815 PropertyBox::updateContextHelp(QObject *o)
Chris@218 816 {
Chris@218 817 QWidget *w = dynamic_cast<QWidget *>(o);
Chris@189 818 if (!w) return;
Chris@218 819
Chris@189 820 if (!m_container) return;
Chris@190 821 QString cname = m_container->getPropertyContainerName();
Chris@189 822 if (cname == "") return;
Chris@189 823
Chris@189 824 QString wname = w->objectName();
Chris@189 825
Chris@218 826 QString extraText;
Chris@218 827 AudioDial *dial = dynamic_cast<AudioDial *>(w);
Chris@218 828 if (dial) {
Chris@218 829 float mv = dial->mappedValue();
Chris@218 830 QString unit = "";
Chris@218 831 if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit();
Chris@218 832 if (unit != "") {
Chris@218 833 extraText = tr(" (current value: %1%2)").arg(mv).arg(unit);
Chris@218 834 } else {
Chris@218 835 extraText = tr(" (current value: %1)").arg(mv);
Chris@218 836 }
Chris@218 837 }
Chris@218 838
Chris@189 839 if (w == m_showButton) {
Chris@190 840 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname));
Chris@189 841 } else if (w == m_playButton) {
Chris@190 842 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname));
Chris@189 843 } else if (wname == "") {
Chris@189 844 return;
Chris@335 845 } else if (dynamic_cast<QAbstractButton *>(w)) {
Chris@190 846 emit contextHelpChanged(tr("Toggle %1 property of %2")
Chris@189 847 .arg(wname).arg(cname));
Chris@189 848 } else {
Chris@218 849 emit contextHelpChanged(tr("Adjust %1 property of %2%3")
Chris@218 850 .arg(wname).arg(cname).arg(extraText));
Chris@189 851 }
Chris@189 852 }
Chris@189 853
Chris@189 854 void
Chris@189 855 PropertyBox::mouseLeftWidget()
Chris@189 856 {
Chris@218 857 if (!(QApplication::mouseButtons() & Qt::LeftButton)) {
Chris@218 858 emit contextHelpChanged("");
Chris@218 859 }
Chris@189 860 }
Chris@189 861
Chris@64 862