annotate widgets/PropertyBox.cpp @ 1174:3f5c82034f9b more-hidpi

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