Mercurial > hg > svgui
diff widgets/PaneStack.cpp @ 0:2a4f26e85b4c
initial import
author | Chris Cannam |
---|---|
date | Tue, 10 Jan 2006 16:33:16 +0000 |
parents | |
children | 37b110168acf |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/PaneStack.cpp Tue Jan 10 16:33:16 2006 +0000 @@ -0,0 +1,239 @@ + +/* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ + +/* + A waveform viewer and audio annotation editor. + Chris Cannam, Queen Mary University of London, 2005 + + This is experimental software. Not for distribution. +*/ + +#include "PaneStack.h" + +#include "widgets/Pane.h" +#include "widgets/PropertyStack.h" +#include "base/Layer.h" +#include "base/ViewManager.h" + +#include <QApplication> +#include <QHBoxLayout> +#include <QPainter> +#include <QPalette> +#include <QLabel> + +#include <iostream> + +PaneStack::PaneStack(QWidget *parent, ViewManager *viewManager) : + QSplitter(parent), + m_currentPane(0), + m_viewManager(viewManager) +{ + setOrientation(Qt::Vertical); + setOpaqueResize(false); +} + +Pane * +PaneStack::addPane(bool suppressPropertyBox) +{ + QFrame *frame = new QFrame; + QHBoxLayout *layout = new QHBoxLayout; + layout->setMargin(0); + layout->setSpacing(2); + + QLabel *currentIndicator = new QLabel(frame); + currentIndicator->setFixedWidth(QPainter(this).fontMetrics().width("x")); + layout->addWidget(currentIndicator); + layout->setStretchFactor(currentIndicator, 1); + currentIndicator->setScaledContents(true); + m_currentIndicators.push_back(currentIndicator); + + Pane *pane = new Pane(frame); + pane->setViewManager(m_viewManager); + layout->addWidget(pane); + layout->setStretchFactor(pane, 10); + m_panes.push_back(pane); + + QWidget *properties = 0; + if (suppressPropertyBox) { + properties = new QFrame(); + } else { + properties = new PropertyStack(frame, pane); + connect(properties, SIGNAL(propertyContainerSelected(PropertyContainer *)), + this, SLOT(propertyContainerSelected(PropertyContainer *))); + } + layout->addWidget(properties); + layout->setStretchFactor(properties, 1); + m_propertyStacks.push_back(properties); + + frame->setLayout(layout); + addWidget(frame); + + connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)), + this, SLOT(propertyContainerAdded(PropertyContainer *))); + connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)), + this, SLOT(propertyContainerRemoved(PropertyContainer *))); + connect(pane, SIGNAL(paneInteractedWith()), + this, SLOT(paneInteractedWith())); + + if (!m_currentPane) { + setCurrentPane(pane); + } + + return pane; +} + +Pane * +PaneStack::getPane(int n) +{ + return m_panes[n]; +} + +void +PaneStack::deletePane(Pane *pane) +{ + int n = 0; + std::vector<Pane *>::iterator i = m_panes.begin(); + std::vector<QWidget *>::iterator j = m_propertyStacks.begin(); + std::vector<QLabel *>::iterator k = m_currentIndicators.begin(); + + while (i != m_panes.end()) { + if (*i == pane) break; + ++i; + ++j; + ++k; + ++n; + } + if (n >= int(m_panes.size())) return; + + m_panes.erase(i); + m_propertyStacks.erase(j); + m_currentIndicators.erase(k); + delete widget(n); + + if (m_currentPane == pane) { + if (m_panes.size() > 0) { + setCurrentPane(m_panes[0]); + } else { + setCurrentPane(0); + } + } +} + +int +PaneStack::getPaneCount() const +{ + return m_panes.size(); +} + +void +PaneStack::setCurrentPane(Pane *pane) // may be null +{ + if (m_currentPane == pane) return; + + std::vector<Pane *>::iterator i = m_panes.begin(); + std::vector<QLabel *>::iterator k = m_currentIndicators.begin(); + + // We used to do this by setting the foreground and background + // role, but it seems the background role is ignored and the + // background drawn transparent in Qt 4.1 -- I can't quite see why + + QPixmap selectedMap(1, 1); + selectedMap.fill(QApplication::palette().color(QPalette::Foreground)); + + QPixmap unselectedMap(1, 1); + unselectedMap.fill(QApplication::palette().color(QPalette::Background)); + + while (i != m_panes.end()) { + if (*i == pane) { + (*k)->setPixmap(selectedMap); + } else { + (*k)->setPixmap(unselectedMap); + } + ++i; + ++k; + } + m_currentPane = pane; + + emit currentPaneChanged(m_currentPane); +} + +Pane * +PaneStack::getCurrentPane() +{ + return m_currentPane; +} + +void +PaneStack::propertyContainerAdded(PropertyContainer *) +{ + sizePropertyStacks(); +} + +void +PaneStack::propertyContainerRemoved(PropertyContainer *) +{ + sizePropertyStacks(); +} + +void +PaneStack::propertyContainerSelected(PropertyContainer *pc) +{ + std::vector<Pane *>::iterator i = m_panes.begin(); + std::vector<QWidget *>::iterator j = m_propertyStacks.begin(); + + while (i != m_panes.end()) { + PropertyStack *stack = dynamic_cast<PropertyStack *>(*j); + if (stack && stack->containsContainer(pc)) { + setCurrentPane(*i); + break; + } + ++i; + ++j; + } +} + +void +PaneStack::paneInteractedWith() +{ + Pane *pane = dynamic_cast<Pane *>(sender()); + if (!pane) return; + setCurrentPane(pane); +} + +void +PaneStack::sizePropertyStacks() +{ + int maxMinWidth = 0; + + for (unsigned int i = 0; i < m_propertyStacks.size(); ++i) { + if (!m_propertyStacks[i]) continue; + std::cerr << "PaneStack::sizePropertyStacks: " << i << ": min " + << m_propertyStacks[i]->minimumSizeHint().width() << ", current " + << m_propertyStacks[i]->width() << std::endl; + + if (m_propertyStacks[i]->minimumSizeHint().width() > maxMinWidth) { + maxMinWidth = m_propertyStacks[i]->minimumSizeHint().width(); + } + } + + std::cerr << "PaneStack::sizePropertyStacks: max min width " << maxMinWidth << std::endl; + +#ifdef Q_WS_MAC + // This is necessary to compensate for cb->setMinimumSize(10, 10) + // in PropertyBox in the Mac version (to avoid a mysterious crash) + int setWidth = maxMinWidth * 3 / 2; +#else + int setWidth = maxMinWidth; +#endif + + for (unsigned int i = 0; i < m_propertyStacks.size(); ++i) { + if (!m_propertyStacks[i]) continue; + m_propertyStacks[i]->setMinimumWidth(setWidth); + } +} + + +#ifdef INCLUDE_MOCFILES +#include "PaneStack.moc.cpp" +#endif +