/* This file is part of the KDE libraries Copyright (C) 2005 Daniel Molkentin This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include /****************************************************************** * Helper classes *****************************************************************/ ClickableLabel::ClickableLabel( QWidget* parent ) : QLabel( parent ) { } ClickableLabel::~ClickableLabel() { } void ClickableLabel::mouseReleaseEvent( QMouseEvent *e ) { Q_UNUSED( e ); emit clicked(); } ArrowButton::ArrowButton( QWidget *parent ) : QAbstractButton( parent ) { } ArrowButton::~ArrowButton() { } void ArrowButton::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QPainter p(this); QStyleOption opt; int h = sizeHint().height(); opt.rect = QRect(0,( height()- h )/2, h, h); opt.palette = palette(); opt.state = QStyle::State_Children; if (isChecked()) { opt.state |= QStyle::State_Open; } style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, &p); p.end(); } /****************************************************************** * Private classes *****************************************************************/ class CollapsibleWidget::Private { public: QGridLayout *gridLayout; QWidget *innerWidget; ClickableLabel *label; ArrowButton *colButton; QTimeLine *timeline; QWidget *expander; QVBoxLayout *expanderLayout; }; class SettingsContainer::Private { public: QVBoxLayout *layout; }; /****************************************************************** * Implementation *****************************************************************/ SettingsContainer::SettingsContainer(QWidget *parent) : QScrollArea(parent), d(new SettingsContainer::Private()) { QWidget *w = new QWidget; QVBoxLayout *helperLay = new QVBoxLayout(w); helperLay->setMargin(0); d->layout = new QVBoxLayout; helperLay->addLayout( d->layout); helperLay->addStretch(1); setWidget(w); setWidgetResizable(true); } SettingsContainer::~SettingsContainer() { delete d; } CollapsibleWidget* SettingsContainer::insertWidget(QWidget *w, const QString& name) { if (w && w->layout()) { QLayout *lay = w->layout(); lay->setMargin(2); lay->setSpacing(2); } CollapsibleWidget *cw = new CollapsibleWidget(name); d->layout->addWidget(cw); cw->setInnerWidget(w); return cw; } CollapsibleWidget::CollapsibleWidget(QWidget *parent) : QWidget(parent), d(new CollapsibleWidget::Private()) { init(); } CollapsibleWidget::CollapsibleWidget(const QString& caption, QWidget *parent) : QWidget(parent), d(new CollapsibleWidget::Private()) { init(); setCaption(caption); } void CollapsibleWidget::init() { d->expander = 0; d->expanderLayout = 0; d->timeline = new QTimeLine(150, this); d->timeline->setEasingCurve(QEasingCurve(QEasingCurve::InOutSine)); connect(d->timeline, SIGNAL(valueChanged(qreal)), this, SLOT(animateCollapse(qreal))); d->innerWidget = 0; d->gridLayout = new QGridLayout(this); d->gridLayout->setMargin(0); d->colButton = new ArrowButton; d->colButton->setCheckable(true); d->label = new ClickableLabel; d->label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); d->gridLayout->addWidget(d->colButton, 1, 1); d->gridLayout->addWidget(d->label, 1, 2); connect(d->label, SIGNAL(clicked()), d->colButton, SLOT(click())); connect(d->colButton, SIGNAL(toggled(bool)), SLOT(setExpanded(bool))); setExpanded(false); setEnabled(false); } CollapsibleWidget::~CollapsibleWidget() { delete d; } QWidget* CollapsibleWidget::innerWidget() const { return d->innerWidget; } #define SIMPLE void CollapsibleWidget::setInnerWidget(QWidget *w) { if (!w) { return; } d->innerWidget = w; #ifdef SIMPLE if (!isExpanded()) { d->innerWidget->hide(); } d->gridLayout->addWidget(d->innerWidget, 2, 2); d->gridLayout->setRowStretch(2, 1); #else if ( !d->expander ) { d->expander = new QWidget(this); d->gridLayout->addWidget(d->expander, 2, 2); d->gridLayout->setRowStretch( 2, 1 ); d->expanderLayout = new QVBoxLayout(d->expander); d->expanderLayout->setMargin(0); d->expanderLayout->setSpacing(0); d->expander->setFixedHeight(0); } d->innerWidget->setParent(d->expander); d->innerWidget->show(); d->expanderLayout->addWidget(d->innerWidget); #endif setEnabled(true); if (isExpanded()) { setExpanded(true); } } void CollapsibleWidget::setCaption(const QString& caption) { d->label->setText(QString("%1").arg(caption)); } QString CollapsibleWidget::caption() const { return d->label->text(); } void CollapsibleWidget::setExpanded(bool expanded) { if (!d->innerWidget) { return; } #ifdef SIMPLE if (!expanded) { d->innerWidget->setVisible(false); } #else if (expanded) { d->expander->setVisible(true); } d->innerWidget->setVisible(expanded); #endif d->colButton->setChecked(expanded); d->timeline->setDirection(expanded ? QTimeLine::Forward : QTimeLine::Backward ); if (d->timeline->state() != QTimeLine::Running) { d->timeline->start(); } } void CollapsibleWidget::animateCollapse( qreal showAmount ) { int pixels = d->innerWidget->sizeHint().height() * showAmount; d->gridLayout->setRowMinimumHeight(2, pixels); #ifdef SIMPLE d->gridLayout->setRowMinimumHeight(2, pixels); if (showAmount == 1) { d->innerWidget->setVisible(true); } #else d->expander->setFixedHeight(pixels); #endif } bool CollapsibleWidget::isExpanded() const { return d->colButton->isChecked(); } #include "moc_collapsiblewidget.cpp"