comparison widgets/PaneStack.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
2 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
3
4 /*
5 A waveform viewer and audio annotation editor.
6 Chris Cannam, Queen Mary University of London, 2005
7
8 This is experimental software. Not for distribution.
9 */
10
11 #include "PaneStack.h"
12
13 #include "widgets/Pane.h"
14 #include "widgets/PropertyStack.h"
15 #include "base/Layer.h"
16 #include "base/ViewManager.h"
17
18 #include <QApplication>
19 #include <QHBoxLayout>
20 #include <QPainter>
21 #include <QPalette>
22 #include <QLabel>
23
24 #include <iostream>
25
26 PaneStack::PaneStack(QWidget *parent, ViewManager *viewManager) :
27 QSplitter(parent),
28 m_currentPane(0),
29 m_viewManager(viewManager)
30 {
31 setOrientation(Qt::Vertical);
32 setOpaqueResize(false);
33 }
34
35 Pane *
36 PaneStack::addPane(bool suppressPropertyBox)
37 {
38 QFrame *frame = new QFrame;
39 QHBoxLayout *layout = new QHBoxLayout;
40 layout->setMargin(0);
41 layout->setSpacing(2);
42
43 QLabel *currentIndicator = new QLabel(frame);
44 currentIndicator->setFixedWidth(QPainter(this).fontMetrics().width("x"));
45 layout->addWidget(currentIndicator);
46 layout->setStretchFactor(currentIndicator, 1);
47 currentIndicator->setScaledContents(true);
48 m_currentIndicators.push_back(currentIndicator);
49
50 Pane *pane = new Pane(frame);
51 pane->setViewManager(m_viewManager);
52 layout->addWidget(pane);
53 layout->setStretchFactor(pane, 10);
54 m_panes.push_back(pane);
55
56 QWidget *properties = 0;
57 if (suppressPropertyBox) {
58 properties = new QFrame();
59 } else {
60 properties = new PropertyStack(frame, pane);
61 connect(properties, SIGNAL(propertyContainerSelected(PropertyContainer *)),
62 this, SLOT(propertyContainerSelected(PropertyContainer *)));
63 }
64 layout->addWidget(properties);
65 layout->setStretchFactor(properties, 1);
66 m_propertyStacks.push_back(properties);
67
68 frame->setLayout(layout);
69 addWidget(frame);
70
71 connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
72 this, SLOT(propertyContainerAdded(PropertyContainer *)));
73 connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
74 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
75 connect(pane, SIGNAL(paneInteractedWith()),
76 this, SLOT(paneInteractedWith()));
77
78 if (!m_currentPane) {
79 setCurrentPane(pane);
80 }
81
82 return pane;
83 }
84
85 Pane *
86 PaneStack::getPane(int n)
87 {
88 return m_panes[n];
89 }
90
91 void
92 PaneStack::deletePane(Pane *pane)
93 {
94 int n = 0;
95 std::vector<Pane *>::iterator i = m_panes.begin();
96 std::vector<QWidget *>::iterator j = m_propertyStacks.begin();
97 std::vector<QLabel *>::iterator k = m_currentIndicators.begin();
98
99 while (i != m_panes.end()) {
100 if (*i == pane) break;
101 ++i;
102 ++j;
103 ++k;
104 ++n;
105 }
106 if (n >= int(m_panes.size())) return;
107
108 m_panes.erase(i);
109 m_propertyStacks.erase(j);
110 m_currentIndicators.erase(k);
111 delete widget(n);
112
113 if (m_currentPane == pane) {
114 if (m_panes.size() > 0) {
115 setCurrentPane(m_panes[0]);
116 } else {
117 setCurrentPane(0);
118 }
119 }
120 }
121
122 int
123 PaneStack::getPaneCount() const
124 {
125 return m_panes.size();
126 }
127
128 void
129 PaneStack::setCurrentPane(Pane *pane) // may be null
130 {
131 if (m_currentPane == pane) return;
132
133 std::vector<Pane *>::iterator i = m_panes.begin();
134 std::vector<QLabel *>::iterator k = m_currentIndicators.begin();
135
136 // We used to do this by setting the foreground and background
137 // role, but it seems the background role is ignored and the
138 // background drawn transparent in Qt 4.1 -- I can't quite see why
139
140 QPixmap selectedMap(1, 1);
141 selectedMap.fill(QApplication::palette().color(QPalette::Foreground));
142
143 QPixmap unselectedMap(1, 1);
144 unselectedMap.fill(QApplication::palette().color(QPalette::Background));
145
146 while (i != m_panes.end()) {
147 if (*i == pane) {
148 (*k)->setPixmap(selectedMap);
149 } else {
150 (*k)->setPixmap(unselectedMap);
151 }
152 ++i;
153 ++k;
154 }
155 m_currentPane = pane;
156
157 emit currentPaneChanged(m_currentPane);
158 }
159
160 Pane *
161 PaneStack::getCurrentPane()
162 {
163 return m_currentPane;
164 }
165
166 void
167 PaneStack::propertyContainerAdded(PropertyContainer *)
168 {
169 sizePropertyStacks();
170 }
171
172 void
173 PaneStack::propertyContainerRemoved(PropertyContainer *)
174 {
175 sizePropertyStacks();
176 }
177
178 void
179 PaneStack::propertyContainerSelected(PropertyContainer *pc)
180 {
181 std::vector<Pane *>::iterator i = m_panes.begin();
182 std::vector<QWidget *>::iterator j = m_propertyStacks.begin();
183
184 while (i != m_panes.end()) {
185 PropertyStack *stack = dynamic_cast<PropertyStack *>(*j);
186 if (stack && stack->containsContainer(pc)) {
187 setCurrentPane(*i);
188 break;
189 }
190 ++i;
191 ++j;
192 }
193 }
194
195 void
196 PaneStack::paneInteractedWith()
197 {
198 Pane *pane = dynamic_cast<Pane *>(sender());
199 if (!pane) return;
200 setCurrentPane(pane);
201 }
202
203 void
204 PaneStack::sizePropertyStacks()
205 {
206 int maxMinWidth = 0;
207
208 for (unsigned int i = 0; i < m_propertyStacks.size(); ++i) {
209 if (!m_propertyStacks[i]) continue;
210 std::cerr << "PaneStack::sizePropertyStacks: " << i << ": min "
211 << m_propertyStacks[i]->minimumSizeHint().width() << ", current "
212 << m_propertyStacks[i]->width() << std::endl;
213
214 if (m_propertyStacks[i]->minimumSizeHint().width() > maxMinWidth) {
215 maxMinWidth = m_propertyStacks[i]->minimumSizeHint().width();
216 }
217 }
218
219 std::cerr << "PaneStack::sizePropertyStacks: max min width " << maxMinWidth << std::endl;
220
221 #ifdef Q_WS_MAC
222 // This is necessary to compensate for cb->setMinimumSize(10, 10)
223 // in PropertyBox in the Mac version (to avoid a mysterious crash)
224 int setWidth = maxMinWidth * 3 / 2;
225 #else
226 int setWidth = maxMinWidth;
227 #endif
228
229 for (unsigned int i = 0; i < m_propertyStacks.size(); ++i) {
230 if (!m_propertyStacks[i]) continue;
231 m_propertyStacks[i]->setMinimumWidth(setWidth);
232 }
233 }
234
235
236 #ifdef INCLUDE_MOCFILES
237 #include "PaneStack.moc.cpp"
238 #endif
239