Mercurial > hg > svgui
comparison widgets/PropertyBox.cpp @ 1216:dc2af6616c83
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:50 +0000 |
parents | d421df27e184 |
children | 312f99a9f2aa |
comparison
equal
deleted
inserted
replaced
1048:e8102ff5573b | 1216:dc2af6616c83 |
---|---|
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" |
29 #include "IconLoader.h" | 28 #include "IconLoader.h" |
29 #include "LevelPanWidget.h" | |
30 #include "LevelPanToolButton.h" | |
31 #include "WidgetScale.h" | |
30 | 32 |
31 #include "NotifyingCheckBox.h" | 33 #include "NotifyingCheckBox.h" |
32 #include "NotifyingComboBox.h" | 34 #include "NotifyingComboBox.h" |
33 #include "NotifyingPushButton.h" | 35 #include "NotifyingPushButton.h" |
34 #include "ColourNameDialog.h" | 36 #include "NotifyingToolButton.h" |
37 #include "ColourComboBox.h" | |
38 #include "ColourMapComboBox.h" | |
35 | 39 |
36 #include <QGridLayout> | 40 #include <QGridLayout> |
37 #include <QHBoxLayout> | 41 #include <QHBoxLayout> |
38 #include <QVBoxLayout> | 42 #include <QVBoxLayout> |
39 #include <QPushButton> | 43 #include <QPushButton> |
44 #include <QToolButton> | |
40 #include <QLabel> | 45 #include <QLabel> |
41 #include <QFrame> | 46 #include <QFrame> |
42 #include <QApplication> | 47 #include <QApplication> |
43 #include <QColorDialog> | 48 #include <QColorDialog> |
44 #include <QInputDialog> | 49 #include <QInputDialog> |
61 #endif | 66 #endif |
62 | 67 |
63 m_mainBox = new QVBoxLayout; | 68 m_mainBox = new QVBoxLayout; |
64 setLayout(m_mainBox); | 69 setLayout(m_mainBox); |
65 | 70 |
71 #ifdef Q_OS_MAC | |
72 QMargins mm = m_mainBox->contentsMargins(); | |
73 QMargins mmhalf(mm.left()/2, mm.top()/3, mm.right()/2, mm.bottom()/3); | |
74 m_mainBox->setContentsMargins(mmhalf); | |
75 #endif | |
76 | |
66 // m_nameWidget = new QLabel; | 77 // m_nameWidget = new QLabel; |
67 // m_mainBox->addWidget(m_nameWidget); | 78 // m_mainBox->addWidget(m_nameWidget); |
68 // m_nameWidget->setText(container->objectName()); | 79 // m_nameWidget->setText(container->objectName()); |
69 | 80 |
70 m_mainWidget = new QWidget; | 81 m_mainWidget = new QWidget; |
94 | 105 |
95 m_layout->setRowStretch(m_layout->rowCount(), 10); | 106 m_layout->setRowStretch(m_layout->rowCount(), 10); |
96 | 107 |
97 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()), | 108 connect(UnitDatabase::getInstance(), SIGNAL(unitDatabaseChanged()), |
98 this, SLOT(unitDatabaseChanged())); | 109 this, SLOT(unitDatabaseChanged())); |
99 | |
100 connect(ColourDatabase::getInstance(), SIGNAL(colourDatabaseChanged()), | |
101 this, SLOT(colourDatabaseChanged())); | |
102 | 110 |
103 #ifdef DEBUG_PROPERTY_BOX | 111 #ifdef DEBUG_PROPERTY_BOX |
104 cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl; | 112 cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl; |
105 #endif | 113 #endif |
106 } | 114 } |
139 | 147 |
140 m_viewPlayFrame = new QFrame; | 148 m_viewPlayFrame = new QFrame; |
141 m_viewPlayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); | 149 m_viewPlayFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); |
142 m_mainBox->addWidget(m_viewPlayFrame); | 150 m_mainBox->addWidget(m_viewPlayFrame); |
143 | 151 |
144 QHBoxLayout *layout = new QHBoxLayout; | 152 QGridLayout *layout = new QGridLayout; |
145 m_viewPlayFrame->setLayout(layout); | 153 m_viewPlayFrame->setLayout(layout); |
146 | 154 |
147 layout->setMargin(layout->margin() / 2); | 155 layout->setMargin(layout->margin() / 2); |
148 | 156 |
149 #ifdef DEBUG_PROPERTY_BOX | 157 #ifdef DEBUG_PROPERTY_BOX |
150 SVDEBUG << "PropertyBox::populateViewPlayFrame: container " << m_container << " (name " << m_container->getPropertyContainerName() << ") params " << params << endl; | 158 SVDEBUG << "PropertyBox::populateViewPlayFrame: container " << m_container << " (name " << m_container->getPropertyContainerName() << ") params " << params << endl; |
151 #endif | 159 #endif |
152 | 160 |
153 if (layer) { | 161 QSize buttonSize = WidgetScale::scaleQSize(QSize(26, 26)); |
154 QLabel *showLabel = new QLabel(tr("Show")); | 162 int col = 0; |
155 layout->addWidget(showLabel); | 163 |
156 layout->setAlignment(showLabel, Qt::AlignVCenter); | |
157 | |
158 m_showButton = new LEDButton(Qt::blue); | |
159 layout->addWidget(m_showButton); | |
160 connect(m_showButton, SIGNAL(stateChanged(bool)), | |
161 this, SIGNAL(showLayer(bool))); | |
162 connect(m_showButton, SIGNAL(mouseEntered()), | |
163 this, SLOT(mouseEnteredWidget())); | |
164 connect(m_showButton, SIGNAL(mouseLeft()), | |
165 this, SLOT(mouseLeftWidget())); | |
166 layout->setAlignment(m_showButton, Qt::AlignVCenter); | |
167 } | |
168 | |
169 if (params) { | 164 if (params) { |
170 | 165 |
171 QLabel *playLabel = new QLabel(tr("Play")); | 166 m_playButton = new NotifyingToolButton; |
172 layout->addWidget(playLabel); | 167 m_playButton->setCheckable(true); |
173 layout->setAlignment(playLabel, Qt::AlignVCenter); | 168 m_playButton->setIcon(IconLoader().load("speaker")); |
174 | 169 m_playButton->setToolTip(tr("Click to toggle playback")); |
175 m_playButton = new LEDButton(Qt::darkGreen); | 170 m_playButton->setChecked(!params->isPlayMuted()); |
176 m_playButton->setState(!params->isPlayMuted()); | 171 m_playButton->setFixedSize(buttonSize); |
177 layout->addWidget(m_playButton); | 172 connect(m_playButton, SIGNAL(toggled(bool)), |
178 connect(m_playButton, SIGNAL(stateChanged(bool)), | |
179 this, SLOT(playAudibleButtonChanged(bool))); | 173 this, SLOT(playAudibleButtonChanged(bool))); |
180 connect(m_playButton, SIGNAL(mouseEntered()), | 174 connect(m_playButton, SIGNAL(mouseEntered()), |
181 this, SLOT(mouseEnteredWidget())); | 175 this, SLOT(mouseEnteredWidget())); |
182 connect(m_playButton, SIGNAL(mouseLeft()), | 176 connect(m_playButton, SIGNAL(mouseLeft()), |
183 this, SLOT(mouseLeftWidget())); | 177 this, SLOT(mouseLeftWidget())); |
184 connect(params, SIGNAL(playAudibleChanged(bool)), | 178 connect(params, SIGNAL(playAudibleChanged(bool)), |
185 this, SLOT(playAudibleChanged(bool))); | 179 this, SLOT(playAudibleChanged(bool))); |
186 layout->setAlignment(m_playButton, Qt::AlignVCenter); | 180 |
187 | 181 LevelPanToolButton *levelPan = new LevelPanToolButton; |
188 layout->insertStretch(-1, 10); | 182 levelPan->setFixedSize(buttonSize); |
183 levelPan->setImageSize((buttonSize.height() * 3) / 4); | |
184 layout->addWidget(levelPan, 0, col++, Qt::AlignCenter); | |
185 connect(levelPan, SIGNAL(levelChanged(float)), | |
186 this, SLOT(playGainControlChanged(float))); | |
187 connect(levelPan, SIGNAL(panChanged(float)), | |
188 this, SLOT(playPanControlChanged(float))); | |
189 connect(params, SIGNAL(playGainChanged(float)), | |
190 levelPan, SLOT(setLevel(float))); | |
191 connect(params, SIGNAL(playPanChanged(float)), | |
192 levelPan, SLOT(setPan(float))); | |
193 connect(levelPan, SIGNAL(mouseEntered()), | |
194 this, SLOT(mouseEnteredWidget())); | |
195 connect(levelPan, SIGNAL(mouseLeft()), | |
196 this, SLOT(mouseLeftWidget())); | |
197 | |
198 layout->addWidget(m_playButton, 0, col++, Qt::AlignCenter); | |
189 | 199 |
190 if (params->getPlayClipId() != "") { | 200 if (params->getPlayClipId() != "") { |
191 QPushButton *playParamButton = | 201 QToolButton *playParamButton = new QToolButton; |
192 new QPushButton(QIcon(":icons/faders.png"), ""); | 202 playParamButton->setObjectName("playParamButton"); |
193 playParamButton->setFixedWidth(24); | 203 playParamButton->setIcon(IconLoader().load("faders")); |
194 playParamButton->setFixedHeight(24); | 204 playParamButton->setFixedSize(buttonSize); |
195 layout->addWidget(playParamButton); | 205 layout->addWidget(playParamButton, 0, col++, Qt::AlignCenter); |
196 connect(playParamButton, SIGNAL(clicked()), | 206 connect(playParamButton, SIGNAL(clicked()), |
197 this, SLOT(editPlayParameters())); | 207 this, SLOT(editPlayParameters())); |
198 } | 208 connect(playParamButton, SIGNAL(mouseEntered()), |
199 | 209 this, SLOT(mouseEnteredWidget())); |
200 AudioDial *gainDial = new AudioDial; | 210 connect(playParamButton, SIGNAL(mouseLeft()), |
201 layout->addWidget(gainDial); | 211 this, SLOT(mouseLeftWidget())); |
202 gainDial->setMeterColor(Qt::darkRed); | 212 } |
203 gainDial->setMinimum(-50); | 213 } |
204 gainDial->setMaximum(50); | 214 |
205 gainDial->setPageStep(1); | 215 layout->setColumnStretch(col++, 10); |
206 gainDial->setFixedWidth(24); | 216 |
207 gainDial->setFixedHeight(24); | 217 if (layer) { |
208 gainDial->setNotchesVisible(false); | 218 |
209 gainDial->setDefaultValue(0); | 219 QLabel *showLabel = new QLabel(tr("Show")); |
210 gainDial->setObjectName(tr("Playback Gain")); | 220 layout->addWidget(showLabel, 0, col++, Qt::AlignVCenter | Qt::AlignRight); |
211 gainDial->setRangeMapper(new LinearRangeMapper | 221 |
212 (-50, 50, -25, 25, tr("dB"))); | 222 m_showButton = new LEDButton(palette().highlight().color()); |
213 gainDial->setShowToolTip(true); | 223 layout->addWidget(m_showButton, 0, col++, Qt::AlignVCenter | Qt::AlignLeft); |
214 connect(gainDial, SIGNAL(valueChanged(int)), | 224 connect(m_showButton, SIGNAL(stateChanged(bool)), |
215 this, SLOT(playGainDialChanged(int))); | 225 this, SIGNAL(showLayer(bool))); |
216 connect(params, SIGNAL(playGainChanged(float)), | 226 connect(m_showButton, SIGNAL(mouseEntered()), |
217 this, SLOT(playGainChanged(float))); | |
218 connect(this, SIGNAL(changePlayGainDial(int)), | |
219 gainDial, SLOT(setValue(int))); | |
220 connect(gainDial, SIGNAL(mouseEntered()), | |
221 this, SLOT(mouseEnteredWidget())); | 227 this, SLOT(mouseEnteredWidget())); |
222 connect(gainDial, SIGNAL(mouseLeft()), | 228 connect(m_showButton, SIGNAL(mouseLeft()), |
223 this, SLOT(mouseLeftWidget())); | 229 this, SLOT(mouseLeftWidget())); |
224 playGainChanged(params->getPlayGain()); | |
225 layout->setAlignment(gainDial, Qt::AlignVCenter); | |
226 | |
227 AudioDial *panDial = new AudioDial; | |
228 layout->addWidget(panDial); | |
229 panDial->setMeterColor(Qt::darkGreen); | |
230 panDial->setMinimum(-50); | |
231 panDial->setMaximum(50); | |
232 panDial->setPageStep(1); | |
233 panDial->setFixedWidth(24); | |
234 panDial->setFixedHeight(24); | |
235 panDial->setNotchesVisible(false); | |
236 panDial->setToolTip(tr("Playback Pan / Balance")); | |
237 panDial->setDefaultValue(0); | |
238 panDial->setObjectName(tr("Playback Pan / Balance")); | |
239 panDial->setShowToolTip(true); | |
240 connect(panDial, SIGNAL(valueChanged(int)), | |
241 this, SLOT(playPanDialChanged(int))); | |
242 connect(params, SIGNAL(playPanChanged(float)), | |
243 this, SLOT(playPanChanged(float))); | |
244 connect(this, SIGNAL(changePlayPanDial(int)), | |
245 panDial, SLOT(setValue(int))); | |
246 connect(panDial, SIGNAL(mouseEntered()), | |
247 this, SLOT(mouseEnteredWidget())); | |
248 connect(panDial, SIGNAL(mouseLeft()), | |
249 this, SLOT(mouseLeftWidget())); | |
250 playPanChanged(params->getPlayPan()); | |
251 layout->setAlignment(panDial, Qt::AlignVCenter); | |
252 | |
253 } else { | |
254 | |
255 layout->insertStretch(-1, 10); | |
256 } | 230 } |
257 } | 231 } |
258 | 232 |
259 void | 233 void |
260 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name, | 234 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name, |
280 cerr << "::updatePropertyEditor(\"" << name << "\"):"; | 254 cerr << "::updatePropertyEditor(\"" << name << "\"):"; |
281 cerr << " value " << value << ", have " << have << ", group \"" | 255 cerr << " value " << value << ", have " << have << ", group \"" |
282 << groupName << "\"" << endl; | 256 << groupName << "\"" << endl; |
283 #endif | 257 #endif |
284 | 258 |
285 bool inGroup = (groupName != QString()); | 259 QString groupLabel = groupName; |
286 | 260 if (groupName == QString()) { |
261 groupName = "ungrouped: " + name; // not tr(), this is internal id | |
262 groupLabel = propertyLabel; | |
263 } | |
264 | |
287 if (!have) { | 265 if (!have) { |
288 if (inGroup) { | 266 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) { |
289 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) { | 267 QWidget *labelWidget = new QLabel(groupLabel, m_mainWidget); |
290 #ifdef DEBUG_PROPERTY_BOX | 268 m_layout->addWidget(labelWidget, row, 0); |
291 cerr << "PropertyBox: adding label \"" << groupName << "\" and frame for group for \"" << name << "\"" << endl; | 269 QWidget *frame = new QWidget(m_mainWidget); |
292 #endif | 270 frame->setMinimumSize(WidgetScale::scaleQSize(QSize(1, 24))); |
293 m_layout->addWidget(new QLabel(groupName, m_mainWidget), row, 0); | 271 m_groupLayouts[groupName] = new QGridLayout; |
294 QFrame *frame = new QFrame(m_mainWidget); | 272 #ifdef Q_OS_MAC |
295 m_layout->addWidget(frame, row, 1, 1, 2); | 273 // Seems to be plenty of whitespace already |
296 m_groupLayouts[groupName] = new QGridLayout; | 274 m_groupLayouts[groupName]->setContentsMargins(0, 0, 0, 0); |
297 m_groupLayouts[groupName]->setMargin(0); | 275 #else |
298 frame->setLayout(m_groupLayouts[groupName]); | 276 // Need a bit of padding on the left |
299 } | 277 m_groupLayouts[groupName]->setContentsMargins |
300 } else { | 278 (WidgetScale::scalePixelSize(10), 0, 0, 0); |
301 #ifdef DEBUG_PROPERTY_BOX | 279 #endif |
302 cerr << "PropertyBox: adding label \"" << propertyLabel << "\"" << endl; | 280 frame->setLayout(m_groupLayouts[groupName]); |
303 #endif | 281 m_layout->addWidget(frame, row, 1, 1, 2); |
304 m_layout->addWidget(new QLabel(propertyLabel, m_mainWidget), row, 0); | 282 m_layout->setColumnStretch(1, 10); |
305 } | 283 } |
306 } | 284 } |
307 | 285 |
286 QGridLayout *groupLayout = m_groupLayouts[groupName]; | |
287 | |
288 #ifdef DEBUG_PROPERTY_BOX | |
289 cerr << "groupName becomes \"" << groupName << "\", groupLabel = \"" | |
290 << groupLabel << "\", groupLayout = " << groupLayout << endl; | |
291 #endif | |
292 | |
293 assert(groupLayout); | |
294 | |
295 QWidget *existing = m_propertyControllers[name]; | |
296 | |
308 switch (type) { | 297 switch (type) { |
309 | 298 |
310 case PropertyContainer::ToggleProperty: | 299 case PropertyContainer::ToggleProperty: |
311 { | 300 { |
312 QAbstractButton *button = 0; | 301 QAbstractButton *button; |
313 | 302 |
314 if (have) { | 303 if (!(button = qobject_cast<QAbstractButton *>(existing))) { |
315 button = dynamic_cast<QAbstractButton *>(m_propertyControllers[name]); | |
316 assert(button); | |
317 } else { | |
318 #ifdef DEBUG_PROPERTY_BOX | 304 #ifdef DEBUG_PROPERTY_BOX |
319 cerr << "PropertyBox: creating new checkbox" << endl; | 305 cerr << "PropertyBox: creating new checkbox" << endl; |
320 #endif | 306 #endif |
321 if (iconName != "") { | 307 if (iconName != "") { |
322 button = new NotifyingPushButton(); | 308 button = new NotifyingPushButton(); |
323 button->setCheckable(true); | 309 button->setCheckable(true); |
324 QIcon icon(IconLoader().load(iconName)); | 310 QIcon icon(IconLoader().load(iconName)); |
325 button->setIcon(icon); | 311 button->setIcon(icon); |
326 button->setObjectName(name); | 312 button->setObjectName(name); |
327 button->setFixedSize(QSize(18, 18)); | 313 button->setFixedSize(WidgetScale::scaleQSize(QSize(18, 18))); |
328 } else { | 314 } else { |
329 button = new NotifyingCheckBox(); | 315 button = new NotifyingCheckBox(); |
330 button->setObjectName(name); | 316 button->setObjectName(name); |
331 } | 317 } |
332 connect(button, SIGNAL(toggled(bool)), | 318 connect(button, SIGNAL(toggled(bool)), |
333 this, SLOT(propertyControllerChanged(bool))); | 319 this, SLOT(propertyControllerChanged(bool))); |
334 connect(button, SIGNAL(mouseEntered()), | 320 connect(button, SIGNAL(mouseEntered()), |
335 this, SLOT(mouseEnteredWidget())); | 321 this, SLOT(mouseEnteredWidget())); |
336 connect(button, SIGNAL(mouseLeft()), | 322 connect(button, SIGNAL(mouseLeft()), |
337 this, SLOT(mouseLeftWidget())); | 323 this, SLOT(mouseLeftWidget())); |
338 if (inGroup) { | 324 button->setToolTip(propertyLabel); |
339 button->setToolTip(propertyLabel); | 325 |
340 m_groupLayouts[groupName]->addWidget | 326 if (existing) { |
341 (button, 0, m_groupLayouts[groupName]->columnCount()); | 327 groupLayout->replaceWidget(existing, button); |
342 } else { | 328 delete existing; |
343 m_layout->addWidget(button, row, 1, 1, 2); | 329 } else { |
344 } | 330 groupLayout->addWidget(button, 0, groupLayout->columnCount()); |
331 } | |
332 | |
345 m_propertyControllers[name] = button; | 333 m_propertyControllers[name] = button; |
346 } | 334 } |
347 | 335 |
348 if (button->isChecked() != (value > 0)) { | 336 if (button->isChecked() != (value > 0)) { |
349 button->blockSignals(true); | 337 button->blockSignals(true); |
355 | 343 |
356 case PropertyContainer::RangeProperty: | 344 case PropertyContainer::RangeProperty: |
357 { | 345 { |
358 AudioDial *dial; | 346 AudioDial *dial; |
359 | 347 |
360 if (have) { | 348 if ((dial = qobject_cast<AudioDial *>(existing))) { |
361 dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]); | |
362 assert(dial); | |
363 if (rangeChanged) { | 349 if (rangeChanged) { |
364 dial->blockSignals(true); | 350 dial->blockSignals(true); |
365 dial->setMinimum(min); | 351 dial->setMinimum(min); |
366 dial->setMaximum(max); | 352 dial->setMaximum(max); |
367 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name)); | 353 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name)); |
368 dial->blockSignals(false); | 354 dial->blockSignals(false); |
369 } | 355 } |
370 | 356 } else { |
371 } else { | |
372 #ifdef DEBUG_PROPERTY_BOX | 357 #ifdef DEBUG_PROPERTY_BOX |
373 cerr << "PropertyBox: creating new dial" << endl; | 358 cerr << "PropertyBox: creating new dial" << endl; |
374 #endif | 359 #endif |
375 dial = new AudioDial(); | 360 dial = new AudioDial(); |
376 dial->setObjectName(name); | 361 dial->setObjectName(name); |
377 dial->setMinimum(min); | 362 dial->setMinimum(min); |
378 dial->setMaximum(max); | 363 dial->setMaximum(max); |
379 dial->setPageStep(1); | 364 dial->setPageStep(1); |
380 dial->setNotchesVisible((max - min) <= 12); | 365 dial->setNotchesVisible((max - min) <= 12); |
366 // important to set the range mapper before the default, | |
367 // because the range mapper is used to map the default | |
368 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name)); | |
381 dial->setDefaultValue(deflt); | 369 dial->setDefaultValue(deflt); |
382 dial->setRangeMapper(m_container->getNewPropertyRangeMapper(name)); | |
383 dial->setShowToolTip(true); | 370 dial->setShowToolTip(true); |
384 connect(dial, SIGNAL(valueChanged(int)), | 371 connect(dial, SIGNAL(valueChanged(int)), |
385 this, SLOT(propertyControllerChanged(int))); | 372 this, SLOT(propertyControllerChanged(int))); |
386 connect(dial, SIGNAL(mouseEntered()), | 373 connect(dial, SIGNAL(mouseEntered()), |
387 this, SLOT(mouseEnteredWidget())); | 374 this, SLOT(mouseEnteredWidget())); |
388 connect(dial, SIGNAL(mouseLeft()), | 375 connect(dial, SIGNAL(mouseLeft()), |
389 this, SLOT(mouseLeftWidget())); | 376 this, SLOT(mouseLeftWidget())); |
390 | 377 |
391 if (inGroup) { | 378 dial->setFixedWidth(WidgetScale::scalePixelSize(24)); |
392 dial->setFixedWidth(24); | 379 dial->setFixedHeight(WidgetScale::scalePixelSize(24)); |
393 dial->setFixedHeight(24); | 380 |
394 m_groupLayouts[groupName]->addWidget | 381 if (existing) { |
395 (dial, 0, m_groupLayouts[groupName]->columnCount()); | 382 groupLayout->replaceWidget(existing, dial); |
396 } else { | 383 delete existing; |
397 dial->setFixedWidth(32); | 384 } else { |
398 dial->setFixedHeight(32); | 385 groupLayout->addWidget(dial, 0, groupLayout->columnCount()); |
399 m_layout->addWidget(dial, row, 1); | 386 } |
400 QLabel *label = new QLabel(m_mainWidget); | |
401 connect(dial, SIGNAL(valueChanged(int)), | |
402 label, SLOT(setNum(int))); | |
403 label->setNum(value); | |
404 m_layout->addWidget(label, row, 2); | |
405 } | |
406 | 387 |
407 m_propertyControllers[name] = dial; | 388 m_propertyControllers[name] = dial; |
408 } | 389 } |
409 | 390 |
410 if (dial->value() != value) { | 391 if (dial->value() != value) { |
413 dial->blockSignals(false); | 394 dial->blockSignals(false); |
414 } | 395 } |
415 break; | 396 break; |
416 } | 397 } |
417 | 398 |
399 case PropertyContainer::ColourProperty: | |
400 { | |
401 ColourComboBox *cb; | |
402 | |
403 if (!(cb = qobject_cast<ColourComboBox *>(existing))) { | |
404 | |
405 #ifdef DEBUG_PROPERTY_BOX | |
406 cerr << "PropertyBox: creating new colour combobox" << endl; | |
407 #endif | |
408 cb = new ColourComboBox(true); | |
409 cb->setObjectName(name); | |
410 | |
411 connect(cb, SIGNAL(colourChanged(int)), | |
412 this, SLOT(propertyControllerChanged(int))); | |
413 connect(cb, SIGNAL(mouseEntered()), | |
414 this, SLOT(mouseEnteredWidget())); | |
415 connect(cb, SIGNAL(mouseLeft()), | |
416 this, SLOT(mouseLeftWidget())); | |
417 | |
418 cb->setToolTip(propertyLabel); | |
419 | |
420 if (existing) { | |
421 groupLayout->replaceWidget(existing, cb); | |
422 delete existing; | |
423 } else { | |
424 groupLayout->addWidget(cb, 0, groupLayout->columnCount()); | |
425 } | |
426 | |
427 m_propertyControllers[name] = cb; | |
428 } | |
429 | |
430 if (cb->currentIndex() != value) { | |
431 cb->blockSignals(true); | |
432 cb->setCurrentIndex(value); | |
433 cb->blockSignals(false); | |
434 } | |
435 | |
436 break; | |
437 } | |
438 | |
439 case PropertyContainer::ColourMapProperty: | |
440 { | |
441 ColourMapComboBox *cb; | |
442 | |
443 if (!(cb = qobject_cast<ColourMapComboBox *>(existing))) { | |
444 #ifdef DEBUG_PROPERTY_BOX | |
445 cerr << "PropertyBox: creating new colourmap combobox" << endl; | |
446 #endif | |
447 cb = new ColourMapComboBox(false); | |
448 cb->setObjectName(name); | |
449 | |
450 connect(cb, SIGNAL(colourMapChanged(int)), | |
451 this, SLOT(propertyControllerChanged(int))); | |
452 connect(cb, SIGNAL(mouseEntered()), | |
453 this, SLOT(mouseEnteredWidget())); | |
454 connect(cb, SIGNAL(mouseLeft()), | |
455 this, SLOT(mouseLeftWidget())); | |
456 | |
457 cb->setToolTip(propertyLabel); | |
458 | |
459 if (existing) { | |
460 groupLayout->replaceWidget(existing, cb); | |
461 delete existing; | |
462 } else { | |
463 groupLayout->addWidget(cb, 0, groupLayout->columnCount()); | |
464 } | |
465 | |
466 m_propertyControllers[name] = cb; | |
467 } | |
468 | |
469 if (cb->currentIndex() != value) { | |
470 cb->blockSignals(true); | |
471 cb->setCurrentIndex(value); | |
472 cb->blockSignals(false); | |
473 } | |
474 | |
475 break; | |
476 } | |
477 | |
418 case PropertyContainer::ValueProperty: | 478 case PropertyContainer::ValueProperty: |
419 case PropertyContainer::UnitsProperty: | 479 case PropertyContainer::UnitsProperty: |
420 case PropertyContainer::ColourProperty: | |
421 { | 480 { |
422 NotifyingComboBox *cb; | 481 NotifyingComboBox *cb; |
423 | 482 |
424 if (have) { | 483 if (!(cb = qobject_cast<NotifyingComboBox *>(existing))) { |
425 cb = dynamic_cast<NotifyingComboBox *>(m_propertyControllers[name]); | |
426 assert(cb); | |
427 } else { | |
428 #ifdef DEBUG_PROPERTY_BOX | 484 #ifdef DEBUG_PROPERTY_BOX |
429 cerr << "PropertyBox: creating new combobox" << endl; | 485 cerr << "PropertyBox: creating new combobox" << endl; |
430 #endif | 486 #endif |
431 | |
432 cb = new NotifyingComboBox(); | 487 cb = new NotifyingComboBox(); |
433 cb->setObjectName(name); | 488 cb->setObjectName(name); |
434 cb->setDuplicatesEnabled(false); | 489 cb->setDuplicatesEnabled(false); |
435 } | 490 } |
436 | 491 |
441 cb->setEditable(false); | 496 cb->setEditable(false); |
442 | 497 |
443 if (type == PropertyContainer::ValueProperty) { | 498 if (type == PropertyContainer::ValueProperty) { |
444 | 499 |
445 for (int i = min; i <= max; ++i) { | 500 for (int i = min; i <= max; ++i) { |
446 cb->addItem(m_container->getPropertyValueLabel(name, i)); | 501 |
502 QString label = m_container->getPropertyValueLabel(name, i); | |
503 QString iname = m_container->getPropertyValueIconName(name, i); | |
504 | |
505 if (iname != "") { | |
506 QIcon icon(IconLoader().load(iname)); | |
507 cb->addItem(icon, label); | |
508 } else { | |
509 cb->addItem(label); | |
510 } | |
447 } | 511 } |
448 | 512 |
449 } else if (type == PropertyContainer::UnitsProperty) { | 513 } else { // PropertyContainer::UnitsProperty |
450 | 514 |
451 QStringList units = UnitDatabase::getInstance()->getKnownUnits(); | 515 QStringList units = UnitDatabase::getInstance()->getKnownUnits(); |
452 for (int i = 0; i < units.size(); ++i) { | 516 for (int i = 0; i < units.size(); ++i) { |
453 cb->addItem(units[i]); | 517 cb->addItem(units[i]); |
454 } | 518 } |
455 | 519 |
456 cb->setEditable(true); | 520 cb->setEditable(true); |
457 | |
458 } else { // ColourProperty | |
459 | |
460 //!!! should be a proper colour combobox class that | |
461 // manages its own Add New Colour entry... | |
462 | |
463 ColourDatabase *db = ColourDatabase::getInstance(); | |
464 for (int i = 0; i < db->getColourCount(); ++i) { | |
465 QString name = db->getColourName(i); | |
466 cb->addItem(db->getExamplePixmap(i, QSize(12, 12)), name); | |
467 } | |
468 cb->addItem(tr("Add New Colour...")); | |
469 } | |
470 | |
471 cb->blockSignals(false); | |
472 if (cb->count() < 20 && cb->count() > cb->maxVisibleItems()) { | |
473 cb->setMaxVisibleItems(cb->count()); | |
474 } | 521 } |
475 } | 522 } |
476 | 523 |
477 if (!have) { | 524 if (!have) { |
478 connect(cb, SIGNAL(activated(int)), | 525 connect(cb, SIGNAL(activated(int)), |
480 connect(cb, SIGNAL(mouseEntered()), | 527 connect(cb, SIGNAL(mouseEntered()), |
481 this, SLOT(mouseEnteredWidget())); | 528 this, SLOT(mouseEnteredWidget())); |
482 connect(cb, SIGNAL(mouseLeft()), | 529 connect(cb, SIGNAL(mouseLeft()), |
483 this, SLOT(mouseLeftWidget())); | 530 this, SLOT(mouseLeftWidget())); |
484 | 531 |
485 if (inGroup) { | 532 cb->setToolTip(propertyLabel); |
486 cb->setToolTip(propertyLabel); | 533 groupLayout->addWidget(cb, 0, groupLayout->columnCount()); |
487 m_groupLayouts[groupName]->addWidget | |
488 (cb, 0, m_groupLayouts[groupName]->columnCount()); | |
489 } else { | |
490 m_layout->addWidget(cb, row, 1, 1, 2); | |
491 } | |
492 m_propertyControllers[name] = cb; | 534 m_propertyControllers[name] = cb; |
493 } | 535 } else if (existing != cb) { |
536 groupLayout->replaceWidget(existing, cb); | |
537 delete existing; | |
538 } | |
494 | 539 |
495 cb->blockSignals(true); | 540 cb->blockSignals(true); |
496 if (type == PropertyContainer::ValueProperty || | 541 if (type == PropertyContainer::ValueProperty) { |
497 type == PropertyContainer::ColourProperty) { | |
498 if (cb->currentIndex() != value) { | 542 if (cb->currentIndex() != value) { |
499 cb->setCurrentIndex(value); | 543 cb->setCurrentIndex(value); |
500 } | 544 } |
501 } else { | 545 } else { |
502 QString unit = UnitDatabase::getInstance()->getUnitById(value); | 546 QString unit = UnitDatabase::getInstance()->getUnitById(value); |
509 } | 553 } |
510 } | 554 } |
511 } | 555 } |
512 cb->blockSignals(false); | 556 cb->blockSignals(false); |
513 | 557 |
514 #ifdef Q_OS_MAC | |
515 // Crashes on startup without this, for some reason | |
516 cb->setMinimumSize(QSize(10, 10)); | |
517 #endif | |
518 | |
519 break; | 558 break; |
520 } | 559 } |
521 | 560 |
522 case PropertyContainer::InvalidProperty: | 561 case PropertyContainer::InvalidProperty: |
523 default: | 562 default: |
581 | 620 |
582 blockSignals(false); | 621 blockSignals(false); |
583 } | 622 } |
584 | 623 |
585 void | 624 void |
586 PropertyBox::colourDatabaseChanged() | |
587 { | |
588 blockSignals(true); | |
589 | |
590 PropertyContainer::PropertyList properties = m_container->getProperties(); | |
591 for (size_t i = 0; i < properties.size(); ++i) { | |
592 if (m_container->getPropertyType(properties[i]) == | |
593 PropertyContainer::ColourProperty) { | |
594 updatePropertyEditor(properties[i], true); | |
595 } | |
596 } | |
597 | |
598 blockSignals(false); | |
599 } | |
600 | |
601 void | |
602 PropertyBox::propertyControllerChanged(bool on) | 625 PropertyBox::propertyControllerChanged(bool on) |
603 { | 626 { |
604 propertyControllerChanged(on ? 1 : 0); | 627 propertyControllerChanged(on ? 1 : 0); |
605 } | 628 } |
606 | 629 |
618 | 641 |
619 Command *c = 0; | 642 Command *c = 0; |
620 | 643 |
621 if (type == PropertyContainer::UnitsProperty) { | 644 if (type == PropertyContainer::UnitsProperty) { |
622 | 645 |
623 NotifyingComboBox *cb = dynamic_cast<NotifyingComboBox *>(obj); | 646 NotifyingComboBox *cb = qobject_cast<NotifyingComboBox *>(obj); |
624 if (cb) { | 647 if (cb) { |
625 QString unit = cb->currentText(); | 648 QString unit = cb->currentText(); |
626 c = m_container->getSetPropertyCommand | 649 c = m_container->getSetPropertyCommand |
627 (name, UnitDatabase::getInstance()->getUnitId(unit)); | 650 (name, UnitDatabase::getInstance()->getUnitId(unit)); |
628 } | 651 } |
629 | 652 |
630 } else if (type == PropertyContainer::ColourProperty) { | |
631 | |
632 if (value == int(ColourDatabase::getInstance()->getColourCount())) { | |
633 addNewColour(); | |
634 if (value == int(ColourDatabase::getInstance()->getColourCount())) { | |
635 propertyContainerPropertyChanged(m_container); | |
636 return; | |
637 } | |
638 } | |
639 c = m_container->getSetPropertyCommand(name, value); | |
640 | |
641 } else if (type != PropertyContainer::InvalidProperty) { | 653 } else if (type != PropertyContainer::InvalidProperty) { |
642 | 654 |
643 c = m_container->getSetPropertyCommand(name, value); | 655 c = m_container->getSetPropertyCommand(name, value); |
644 } | 656 } |
645 | 657 |
647 | 659 |
648 updateContextHelp(obj); | 660 updateContextHelp(obj); |
649 } | 661 } |
650 | 662 |
651 void | 663 void |
652 PropertyBox::addNewColour() | |
653 { | |
654 QColor newColour = QColorDialog::getColor(); | |
655 if (!newColour.isValid()) return; | |
656 | |
657 ColourNameDialog dialog(tr("Name New Colour"), | |
658 tr("Enter a name for the new colour:"), | |
659 newColour, newColour.name(), this); | |
660 dialog.showDarkBackgroundCheckbox(tr("Prefer black background for this colour")); | |
661 if (dialog.exec() == QDialog::Accepted) { | |
662 //!!! command | |
663 ColourDatabase *db = ColourDatabase::getInstance(); | |
664 int index = db->addColour(newColour, dialog.getColourName()); | |
665 db->setUseDarkBackground(index, dialog.isDarkBackgroundChecked()); | |
666 } | |
667 } | |
668 | |
669 void | |
670 PropertyBox::playAudibleChanged(bool audible) | 664 PropertyBox::playAudibleChanged(bool audible) |
671 { | 665 { |
672 m_playButton->setState(audible); | 666 m_playButton->setChecked(audible); |
673 } | 667 } |
674 | 668 |
675 void | 669 void |
676 PropertyBox::playAudibleButtonChanged(bool audible) | 670 PropertyBox::playAudibleButtonChanged(bool audible) |
677 { | 671 { |
683 new PlayParameterRepository::EditCommand(params); | 677 new PlayParameterRepository::EditCommand(params); |
684 command->setPlayAudible(audible); | 678 command->setPlayAudible(audible); |
685 CommandHistory::getInstance()->addCommand(command, true, true); | 679 CommandHistory::getInstance()->addCommand(command, true, true); |
686 } | 680 } |
687 } | 681 } |
688 | 682 |
689 void | 683 void |
690 PropertyBox::playGainChanged(float gain) | 684 PropertyBox::playGainControlChanged(float gain) |
691 { | |
692 int dialValue = int(lrint(log10(gain) * 20.0)); | |
693 if (dialValue < -50) dialValue = -50; | |
694 if (dialValue > 50) dialValue = 50; | |
695 emit changePlayGainDial(dialValue); | |
696 } | |
697 | |
698 void | |
699 PropertyBox::playGainDialChanged(int dialValue) | |
700 { | 685 { |
701 QObject *obj = sender(); | 686 QObject *obj = sender(); |
702 | 687 |
703 PlayParameters *params = m_container->getPlayParameters(); | 688 PlayParameters *params = m_container->getPlayParameters(); |
704 if (!params) return; | 689 if (!params) return; |
705 | |
706 float gain = float(pow(10, float(dialValue) / 20.0)); | |
707 | 690 |
708 if (params->getPlayGain() != gain) { | 691 if (params->getPlayGain() != gain) { |
709 PlayParameterRepository::EditCommand *command = | 692 PlayParameterRepository::EditCommand *command = |
710 new PlayParameterRepository::EditCommand(params); | 693 new PlayParameterRepository::EditCommand(params); |
711 command->setPlayGain(gain); | 694 command->setPlayGain(gain); |
712 CommandHistory::getInstance()->addCommand(command, true, true); | 695 CommandHistory::getInstance()->addCommand(command, true, true); |
713 } | 696 } |
714 | 697 |
715 updateContextHelp(obj); | 698 updateContextHelp(obj); |
716 } | 699 } |
717 | 700 |
718 void | 701 void |
719 PropertyBox::playPanChanged(float pan) | 702 PropertyBox::playPanControlChanged(float pan) |
720 { | |
721 int dialValue = int(lrint(pan * 50.0)); | |
722 if (dialValue < -50) dialValue = -50; | |
723 if (dialValue > 50) dialValue = 50; | |
724 emit changePlayPanDial(dialValue); | |
725 } | |
726 | |
727 void | |
728 PropertyBox::playPanDialChanged(int dialValue) | |
729 { | 703 { |
730 QObject *obj = sender(); | 704 QObject *obj = sender(); |
731 | 705 |
732 PlayParameters *params = m_container->getPlayParameters(); | 706 PlayParameters *params = m_container->getPlayParameters(); |
733 if (!params) return; | 707 if (!params) return; |
734 | |
735 float pan = float(dialValue) / 50.f; | |
736 if (pan < -1.f) pan = -1.f; | |
737 if (pan > 1.f) pan = 1.f; | |
738 | 708 |
739 if (params->getPlayPan() != pan) { | 709 if (params->getPlayPan() != pan) { |
740 PlayParameterRepository::EditCommand *command = | 710 PlayParameterRepository::EditCommand *command = |
741 new PlayParameterRepository::EditCommand(params); | 711 new PlayParameterRepository::EditCommand(params); |
742 command->setPlayPan(pan); | 712 command->setPlayPan(pan); |
818 } | 788 } |
819 | 789 |
820 void | 790 void |
821 PropertyBox::updateContextHelp(QObject *o) | 791 PropertyBox::updateContextHelp(QObject *o) |
822 { | 792 { |
823 QWidget *w = dynamic_cast<QWidget *>(o); | 793 QWidget *w = qobject_cast<QWidget *>(o); |
824 if (!w) return; | 794 if (!w) return; |
825 | 795 |
826 if (!m_container) return; | 796 if (!m_container) return; |
827 QString cname = m_container->getPropertyContainerName(); | 797 QString cname = m_container->getPropertyContainerName(); |
828 if (cname == "") return; | 798 if (cname == "") return; |
829 | 799 |
800 LevelPanToolButton *lp = qobject_cast<LevelPanToolButton *>(w); | |
801 if (lp) { | |
802 emit contextHelpChanged(tr("Adjust playback level and pan of %1").arg(cname)); | |
803 return; | |
804 } | |
805 | |
830 QString wname = w->objectName(); | 806 QString wname = w->objectName(); |
831 | 807 |
808 if (wname == "playParamButton") { | |
809 PlayParameters *params = m_container->getPlayParameters(); | |
810 if (params) { | |
811 emit contextHelpChanged | |
812 (tr("Change sound used for playback (currently \"%1\")") | |
813 .arg(params->getPlayClipId())); | |
814 return; | |
815 } | |
816 } | |
817 | |
832 QString extraText; | 818 QString extraText; |
833 AudioDial *dial = dynamic_cast<AudioDial *>(w); | 819 |
820 AudioDial *dial = qobject_cast<AudioDial *>(w); | |
834 if (dial) { | 821 if (dial) { |
835 double mv = dial->mappedValue(); | 822 double mv = dial->mappedValue(); |
836 QString unit = ""; | 823 QString unit = ""; |
837 if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit(); | 824 if (dial->rangeMapper()) unit = dial->rangeMapper()->getUnit(); |
838 if (unit != "") { | 825 if (unit != "") { |
846 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname)); | 833 emit contextHelpChanged(tr("Toggle Visibility of %1").arg(cname)); |
847 } else if (w == m_playButton) { | 834 } else if (w == m_playButton) { |
848 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname)); | 835 emit contextHelpChanged(tr("Toggle Playback of %1").arg(cname)); |
849 } else if (wname == "") { | 836 } else if (wname == "") { |
850 return; | 837 return; |
851 } else if (dynamic_cast<QAbstractButton *>(w)) { | 838 } else if (qobject_cast<QAbstractButton *>(w)) { |
852 emit contextHelpChanged(tr("Toggle %1 property of %2") | 839 emit contextHelpChanged(tr("Toggle %1 property of %2") |
853 .arg(wname).arg(cname)); | 840 .arg(wname).arg(cname)); |
854 } else { | 841 } else { |
855 emit contextHelpChanged(tr("Adjust %1 property of %2%3") | 842 emit contextHelpChanged(tr("Adjust %1 property of %2%3") |
856 .arg(wname).arg(cname).arg(extraText)); | 843 .arg(wname).arg(cname).arg(extraText)); |