comparison widgets/PropertyBox.cpp @ 0:2a4f26e85b4c

initial import
author Chris Cannam
date Tue, 10 Jan 2006 16:33:16 +0000
parents
children 37b110168acf
comparison
equal deleted inserted replaced
-1:000000000000 0:2a4f26e85b4c
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 A waveform viewer and audio annotation editor.
5 Chris Cannam, Queen Mary University of London, 2005
6
7 This is experimental software. Not for distribution.
8 */
9
10 #include "PropertyBox.h"
11
12 #include "base/PropertyContainer.h"
13
14 #include "AudioDial.h"
15
16 #include <QGridLayout>
17 #include <QHBoxLayout>
18 #include <QCheckBox>
19 #include <QComboBox>
20 #include <QLabel>
21
22 #include <cassert>
23 #include <iostream>
24
25 //#define DEBUG_PROPERTY_BOX 1
26
27 PropertyBox::PropertyBox(PropertyContainer *container) :
28 m_container(container)
29 {
30 #ifdef DEBUG_PROPERTY_BOX
31 std::cerr << "PropertyBox[" << this << "(\"" <<
32 container->getPropertyContainerName().toStdString() << "\")]::PropertyBox" << std::endl;
33 #endif
34
35 m_layout = new QGridLayout;
36 setLayout(m_layout);
37
38 PropertyContainer::PropertyList properties = container->getProperties();
39
40 blockSignals(true);
41
42 size_t i;
43
44 for (i = 0; i < properties.size(); ++i) {
45 updatePropertyEditor(properties[i]);
46 }
47
48 blockSignals(false);
49
50 m_layout->setRowStretch(m_layout->rowCount(), 10);
51
52 #ifdef DEBUG_PROPERTY_BOX
53 std::cerr << "PropertyBox[" << this << "]::PropertyBox returning" << std::endl;
54 #endif
55 }
56
57 PropertyBox::~PropertyBox()
58 {
59 #ifdef DEBUG_PROPERTY_BOX
60 std::cerr << "PropertyBox[" << this << "(\"" << m_container->getPropertyContainerName().toStdString() << "\")]::~PropertyBox" << std::endl;
61 #endif
62 }
63
64 void
65 PropertyBox::updatePropertyEditor(PropertyContainer::PropertyName name)
66 {
67 PropertyContainer::PropertyType type = m_container->getPropertyType(name);
68 int row = m_layout->rowCount();
69
70 int min = 0, max = 0, value = 0;
71 value = m_container->getPropertyRangeAndValue(name, &min, &max);
72
73 bool have = (m_propertyControllers.find(name) !=
74 m_propertyControllers.end());
75
76 QString groupName = m_container->getPropertyGroupName(name);
77
78 #ifdef DEBUG_PROPERTY_BOX
79 std::cerr << "PropertyBox[" << this
80 << "(\"" << m_container->getPropertyContainerName().toStdString()
81 << "\")]";
82 std::cerr << "::updatePropertyEditor(\"" << name.toStdString() << "\"):";
83 std::cerr << " value " << value << ", have " << have << ", group \""
84 << groupName.toStdString() << "\"" << std::endl;
85 #endif
86
87 bool inGroup = (groupName != QString());
88
89 if (!have) {
90 if (inGroup) {
91 if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) {
92 #ifdef DEBUG_PROPERTY_BOX
93 std::cerr << "PropertyBox: adding label \"" << groupName.toStdString() << "\" and frame for group for \"" << name.toStdString() << "\"" << std::endl;
94 #endif
95 m_layout->addWidget(new QLabel(groupName, this), row, 0);
96 QFrame *frame = new QFrame(this);
97 m_layout->addWidget(frame, row, 1, 1, 2);
98 m_groupLayouts[groupName] = new QHBoxLayout;
99 m_groupLayouts[groupName]->setMargin(0);
100 frame->setLayout(m_groupLayouts[groupName]);
101 }
102 } else {
103 #ifdef DEBUG_PROPERTY_BOX
104 std::cerr << "PropertyBox: adding label \"" << name.toStdString() << "\"" << std::endl;
105 #endif
106 m_layout->addWidget(new QLabel(name, this), row, 0);
107 }
108 }
109
110 switch (type) {
111
112 case PropertyContainer::ToggleProperty:
113 {
114 QCheckBox *cb;
115
116 if (have) {
117 cb = dynamic_cast<QCheckBox *>(m_propertyControllers[name]);
118 assert(cb);
119 } else {
120 #ifdef DEBUG_PROPERTY_BOX
121 std::cerr << "PropertyBox: creating new checkbox" << std::endl;
122 #endif
123 cb = new QCheckBox();
124 cb->setObjectName(name);
125 connect(cb, SIGNAL(stateChanged(int)),
126 this, SLOT(propertyControllerChanged(int)));
127 if (inGroup) {
128 cb->setToolTip(name);
129 m_groupLayouts[groupName]->addWidget(cb);
130 } else {
131 m_layout->addWidget(cb, row, 1, 1, 2);
132 }
133 m_propertyControllers[name] = cb;
134 }
135
136 if (cb->isChecked() != (value > 0)) cb->setChecked(value > 0);
137 break;
138 }
139
140 case PropertyContainer::RangeProperty:
141 {
142 AudioDial *dial;
143
144 if (have) {
145 dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]);
146 assert(dial);
147 } else {
148 #ifdef DEBUG_PROPERTY_BOX
149 std::cerr << "PropertyBox: creating new dial" << std::endl;
150 #endif
151 dial = new AudioDial();
152 dial->setObjectName(name);
153 dial->setMinimum(min);
154 dial->setMaximum(max);
155 dial->setPageStep(1);
156 dial->setNotchesVisible(true);
157 connect(dial, SIGNAL(valueChanged(int)),
158 this, SLOT(propertyControllerChanged(int)));
159
160 if (inGroup) {
161 dial->setFixedWidth(24);
162 dial->setFixedHeight(24);
163 dial->setToolTip(name);
164 m_groupLayouts[groupName]->addWidget(dial);
165 } else {
166 dial->setFixedWidth(32);
167 dial->setFixedHeight(32);
168 m_layout->addWidget(dial, row, 1);
169 QLabel *label = new QLabel(this);
170 connect(dial, SIGNAL(valueChanged(int)),
171 label, SLOT(setNum(int)));
172 label->setNum(value);
173 m_layout->addWidget(label, row, 2);
174 }
175
176 m_propertyControllers[name] = dial;
177 }
178
179 if (dial->value() != value) dial->setValue(value);
180 break;
181 }
182
183 case PropertyContainer::ValueProperty:
184 {
185 QComboBox *cb;
186
187 if (have) {
188 cb = dynamic_cast<QComboBox *>(m_propertyControllers[name]);
189 assert(cb);
190 } else {
191 #ifdef DEBUG_PROPERTY_BOX
192 std::cerr << "PropertyBox: creating new combobox" << std::endl;
193 #endif
194
195 cb = new QComboBox();
196 cb->setObjectName(name);
197 for (int i = min; i <= max; ++i) {
198 cb->addItem(m_container->getPropertyValueLabel(name, i));
199 }
200 connect(cb, SIGNAL(activated(int)),
201 this, SLOT(propertyControllerChanged(int)));
202 if (inGroup) {
203 cb->setToolTip(name);
204 m_groupLayouts[groupName]->addWidget(cb);
205 } else {
206 m_layout->addWidget(cb, row, 1, 1, 2);
207 }
208 m_propertyControllers[name] = cb;
209 }
210
211 if (cb->currentIndex() != value) cb->setCurrentIndex(value);
212
213 #ifdef Q_WS_MAC
214 // Crashes on startup without this, for some reason
215 cb->setMinimumSize(QSize(10, 10));
216 #endif
217
218 break;
219 }
220
221 default:
222 break;
223 }
224 }
225
226 void
227 PropertyBox::propertyContainerPropertyChanged(PropertyContainer *pc)
228 {
229 if (pc != m_container) return;
230
231 PropertyContainer::PropertyList properties = m_container->getProperties();
232 size_t i;
233
234 blockSignals(true);
235
236 for (i = 0; i < properties.size(); ++i) {
237 updatePropertyEditor(properties[i]);
238 }
239
240 blockSignals(false);
241 }
242
243 void
244 PropertyBox::propertyControllerChanged(int value)
245 {
246 QObject *obj = sender();
247 QString name = obj->objectName();
248
249 // std::cerr << "PropertyBox::propertyControllerChanged(" << name.toStdString()
250 // << ", " << value << ")" << std::endl;
251
252 PropertyContainer::PropertyType type = m_container->getPropertyType(name);
253
254 if (type != PropertyContainer::InvalidProperty) {
255 m_container->setProperty(name, value);
256 }
257
258 if (type == PropertyContainer::RangeProperty) {
259 AudioDial *dial = dynamic_cast<AudioDial *>(m_propertyControllers[name]);
260 if (dial) {
261 dial->setToolTip(QString("%1: %2").arg(name).arg(value));
262 //!!! unfortunately this doesn't update an already-visible tooltip
263 }
264 }
265 }
266
267
268
269 #ifdef INCLUDE_MOCFILES
270 #include "PropertyBox.moc.cpp"
271 #endif
272