Mercurial > hg > svgui
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 |