• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Plasma

tabbar.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2008 Marco Martin <notmart@gmail.com>
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU Library General Public License as
00006  *   published by the Free Software Foundation; either version 2, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details
00013  *
00014  *   You should have received a copy of the GNU Library General Public
00015  *   License along with this program; if not, write to the
00016  *   Free Software Foundation, Inc.,
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018  */
00019 
00020 #include "tabbar.h"
00021 
00022 #include <QGraphicsLinearLayout>
00023 #include <QGraphicsLayoutItem>
00024 #include <QString>
00025 #include <QGraphicsScene>
00026 #include <QGraphicsProxyWidget>
00027 #include <QGraphicsSceneWheelEvent>
00028 #include <QIcon>
00029 #include <QStyleOption>
00030 #include <QPainter>
00031 
00032 #include <kdebug.h>
00033 
00034 #include <plasma/animator.h>
00035 
00036 #include "private/nativetabbar_p.h"
00037 
00038 namespace Plasma
00039 {
00040 
00041 class TabBarProxy : public QGraphicsProxyWidget
00042 {
00043 public:
00044     TabBarProxy(QGraphicsWidget *parent)
00045     : QGraphicsProxyWidget(parent)
00046     {
00047         native = new NativeTabBar();
00048         native->setAttribute(Qt::WA_NoSystemBackground);
00049         setWidget(native);
00050         setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
00051     }
00052 
00053     void paint(QPainter *painter,
00054                const QStyleOptionGraphicsItem *option,
00055                QWidget *widget)
00056     {
00057         Q_UNUSED(option);
00058         Q_UNUSED(widget);
00059         //Don't paint the child widgets
00060         static_cast<NativeTabBar *>(QGraphicsProxyWidget::widget())->render(
00061             painter, QPoint(0, 0), QRegion(), 0);
00062     }
00063 
00064     NativeTabBar *native;
00065 };
00066 
00067 class TabBarPrivate
00068 {
00069 public:
00070     TabBarPrivate(TabBar *parent)
00071         : q(parent),
00072           tabProxy(0),
00073           currentIndex(0),
00074           tabWidgetMode(true),
00075           oldPage(0),
00076           newPage(0),
00077           oldPageAnimId(-1),
00078           newPageAnimId(-1)
00079     {
00080     }
00081 
00082     ~TabBarPrivate()
00083     {
00084     }
00085 
00086     void updateTabWidgetMode();
00087     void slidingCompleted(QGraphicsItem *item);
00088     void shapeChanged(const KTabBar::Shape shape);
00089 
00090     TabBar *q;
00091     TabBarProxy *tabProxy;
00092     QList<QGraphicsWidget *> pages;
00093     QGraphicsLinearLayout *mainLayout;
00094     QGraphicsLinearLayout *tabWidgetLayout;
00095     QGraphicsLinearLayout *tabBarLayout;
00096     int currentIndex;
00097     bool tabWidgetMode;
00098 
00099     QGraphicsWidget *oldPage;
00100     QGraphicsWidget *newPage;
00101     int oldPageAnimId;
00102     int newPageAnimId;
00103 };
00104 
00105 void TabBarPrivate::updateTabWidgetMode()
00106 {
00107     bool tabWidget = false;
00108 
00109     foreach (QGraphicsWidget *page, pages) {
00110         if (page->preferredSize() != QSize(0, 0)) {
00111             tabWidget = true;
00112             break;
00113         }
00114     }
00115 
00116     if (tabWidget != tabWidgetMode) {
00117         if (tabWidget) {
00118             mainLayout->removeAt(0);
00119             tabBarLayout->insertItem(1, tabProxy);
00120             mainLayout->addItem(tabWidgetLayout);
00121         } else {
00122             mainLayout->removeAt(0);
00123             tabBarLayout->removeAt(1);
00124             mainLayout->addItem(tabProxy);
00125         }
00126     }
00127 
00128     //always show the tabbar
00129     //FIXME: Qt BUG: calling show on a child of an hidden item it shows it anyways
00130     //so we avoid to call it if the parent is hidden
00131     if (!tabWidget && q->isVisible()) {
00132         q->setTabBarShown(true);
00133     }
00134 
00135     tabWidgetMode = tabWidget;
00136 }
00137 
00138 void TabBarPrivate::slidingCompleted(QGraphicsItem *item)
00139 {
00140     if (item == oldPage || item == newPage) {
00141         if (item == newPage) {
00142             tabWidgetLayout->addItem(newPage);
00143             newPageAnimId = -1;
00144         } else {
00145             oldPageAnimId = -1;
00146             item->hide();
00147         }
00148         q->setFlags(0);
00149     }
00150 }
00151 
00152 void TabBarPrivate::shapeChanged(const QTabBar::Shape shape)
00153 {
00154     //FIXME: QGraphicsLinearLayout doesn't have setDirection, so for now
00155     // North is equal to south and East is equal to West
00156     switch (shape) {
00157     case QTabBar::RoundedWest:
00158     case QTabBar::TriangularWest:
00159 
00160     case QTabBar::RoundedEast:
00161     case QTabBar::TriangularEast:
00162         tabBarLayout->setOrientation(Qt::Vertical);
00163         tabWidgetLayout->setOrientation(Qt::Horizontal);
00164         tabWidgetLayout->itemAt(0)->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
00165         if (tabWidgetLayout->count() > 1) {
00166             tabWidgetLayout->itemAt(1)->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00167         }
00168         tabProxy->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
00169         break;
00170 
00171     case QTabBar::RoundedSouth:
00172     case QTabBar::TriangularSouth:
00173 
00174     case QTabBar::RoundedNorth:
00175     case QTabBar::TriangularNorth:
00176     default:
00177         tabBarLayout->setOrientation(Qt::Horizontal);
00178         tabWidgetLayout->setOrientation(Qt::Vertical);
00179         tabWidgetLayout->itemAt(0)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
00180         if (tabWidgetLayout->count() > 1) {
00181             tabWidgetLayout->itemAt(1)->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00182         }
00183         tabProxy->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
00184     }
00185     tabProxy->setPreferredSize(tabProxy->native->sizeHint());
00186 }
00187 
00188 TabBar::TabBar(QGraphicsWidget *parent)
00189     : QGraphicsWidget(parent),
00190       d(new TabBarPrivate(this))
00191 {
00192     d->tabProxy = new TabBarProxy(this);
00193     d->tabWidgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
00194     d->tabBarLayout = new QGraphicsLinearLayout(Qt::Horizontal);
00195 
00196     d->mainLayout = new QGraphicsLinearLayout(Qt::Horizontal);
00197     d->mainLayout->addItem(d->tabWidgetLayout);
00198 
00199     setLayout(d->mainLayout);
00200     d->mainLayout->setContentsMargins(0,0,0,0);
00201 
00202     d->tabWidgetLayout->addItem(d->tabBarLayout);
00203 
00204     //tabBar is centered, so a stretch at begin one at the end
00205     d->tabBarLayout->addStretch();
00206     d->tabBarLayout->addItem(d->tabProxy);
00207     d->tabBarLayout->addStretch();
00208     //d->tabBarLayout->setStretchFactor(d->tabProxy, 2);
00209 
00210     connect(d->tabProxy->native, SIGNAL(currentChanged(int)),
00211             this, SLOT(setCurrentIndex(int)));
00212     connect(d->tabProxy->native, SIGNAL(shapeChanged(QTabBar::Shape)),
00213             this, SLOT(shapeChanged(QTabBar::Shape)));
00214     connect(Plasma::Animator::self(), SIGNAL(movementFinished(QGraphicsItem*)),
00215             this, SLOT(slidingCompleted(QGraphicsItem*)));
00216 }
00217 
00218 TabBar::~TabBar()
00219 {
00220     delete d;
00221 }
00222 
00223 
00224 int TabBar::insertTab(int index, const QIcon &icon, const QString &label,
00225                       QGraphicsLayoutItem *content)
00226 {
00227     QGraphicsWidget *page = new QGraphicsWidget(this);
00228     page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00229     if (content) {
00230         if (content->isLayout()) {
00231             page->setLayout(static_cast<QGraphicsLayout *>(content));
00232         } else {
00233             QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, page);
00234             layout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00235             layout->addItem(content);
00236             page->setLayout(layout);
00237         }
00238     } else {
00239         page->setPreferredSize(0, 0);
00240     }
00241 
00242     d->pages.insert(qBound(0, index, d->pages.count()), page);
00243 
00244     if (d->pages.count() == 1) {
00245         d->tabWidgetLayout->addItem(page);
00246         page->setVisible(true);
00247         page->setEnabled(true);
00248     } else {
00249         page->setVisible(false);
00250         page->setEnabled(false);
00251     }
00252 
00253     d->tabProxy->setPreferredSize(d->tabProxy->native->sizeHint());
00254     d->updateTabWidgetMode();
00255 
00256     int actualIndex = d->tabProxy->native->insertTab(index, icon, label);
00257     d->currentIndex = d->tabProxy->native->currentIndex();
00258     d->tabProxy->setPreferredSize(d->tabProxy->native->sizeHint());
00259     d->updateTabWidgetMode();
00260     return actualIndex;
00261 }
00262 
00263 int TabBar::insertTab(int index, const QString &label, QGraphicsLayoutItem *content)
00264 {
00265     return insertTab(index, QIcon(), label, content);
00266 }
00267 
00268 int TabBar::addTab(const QIcon &icon, const QString &label, QGraphicsLayoutItem *content)
00269 {
00270     return insertTab(d->pages.count(), icon, label, content);
00271 }
00272 
00273 int TabBar::addTab(const QString &label, QGraphicsLayoutItem *content)
00274 {
00275     return insertTab(d->pages.count(), QIcon(), label, content);
00276 }
00277 
00278 int TabBar::currentIndex() const
00279 {
00280     return d->tabProxy->native->currentIndex();
00281 }
00282 
00283 void TabBar::resizeEvent(QGraphicsSceneResizeEvent * event)
00284 {
00285     if (!d->tabWidgetMode) {
00286         d->tabProxy->setMinimumSize(event->newSize().toSize());
00287         setMinimumSize(QSize(0, 0));
00288         setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
00289     } else {
00290         d->tabProxy->native->setMinimumSize(QSize(0,0));
00291     }
00292 }
00293 
00294 void TabBar::setCurrentIndex(int index)
00295 {
00296     if (index >= d->tabProxy->native->count() ||
00297         d->tabProxy->native->count() <= 1 ||
00298         d->currentIndex == index) {
00299         return;
00300     }
00301 
00302     d->tabWidgetLayout->removeAt(1);
00303 
00304     if (d->currentIndex >= 0) {
00305         d->oldPage = d->pages[d->currentIndex];
00306     } else {
00307         d->oldPage = 0;
00308     }
00309 
00310     if (index >= 0) {
00311         d->newPage = d->pages[index];
00312     } else {
00313         d->newPage = 0;
00314     }
00315 
00316     if (d->newPage && d->oldPage) {
00317         d->newPage->resize(d->oldPage->size());
00318     }
00319 
00320     setFlags(QGraphicsItem::ItemClipsChildrenToShape);
00321 
00322     //if an animation was in rogress hide everything to avoid an inconsistent state
00323     if (d->newPageAnimId != -1 || d->oldPageAnimId != -1) {
00324         foreach (QGraphicsWidget *page, d->pages) {
00325             page->hide();
00326         }
00327         if (d->newPageAnimId != -1) {
00328             Animator::self()->stopItemMovement(d->newPageAnimId);
00329         }
00330         if (d->oldPageAnimId != -1) {
00331             Animator::self()->stopItemMovement(d->oldPageAnimId);
00332         }
00333     }
00334 
00335     if (d->newPage) {
00336         d->newPage->show();
00337         d->newPage->setEnabled(true);
00338     }
00339 
00340     if (d->oldPage) {
00341         d->oldPage->show();
00342         d->oldPage->setEnabled(false);
00343     }
00344 
00345     if (d->newPage && d->oldPage) {
00346         QRect beforeCurrentGeom(d->oldPage->geometry().toRect());
00347         beforeCurrentGeom.moveTopRight(beforeCurrentGeom.topLeft());
00348 
00349         d->newPageAnimId = Animator::self()->moveItem(
00350             d->newPage, Plasma::Animator::SlideOutMovement,
00351             d->oldPage->pos().toPoint());
00352         if (index > d->currentIndex) {
00353             d->newPage->setPos(d->oldPage->geometry().topRight());
00354             d->oldPageAnimId = Animator::self()->moveItem(
00355                 d->oldPage, Plasma::Animator::SlideOutMovement,
00356                 beforeCurrentGeom.topLeft());
00357         } else {
00358             d->newPage->setPos(beforeCurrentGeom.topLeft());
00359             d->oldPageAnimId = Animator::self()->moveItem(
00360                 d->oldPage, Plasma::Animator::SlideOutMovement,
00361                 d->oldPage->geometry().topRight().toPoint());
00362         }
00363     } else {
00364         d->tabWidgetLayout->addItem(d->newPage);
00365     }
00366 
00367     d->currentIndex = index;
00368     emit currentChanged(index);
00369     d->tabProxy->native->setCurrentIndex(index);
00370 }
00371 
00372 int TabBar::count() const
00373 {
00374     return d->pages.count();
00375 }
00376 
00377 void TabBar::removeTab(int index)
00378 {
00379     if (index > d->pages.count()) {
00380         return;
00381     }
00382 
00383     int oldCurrentIndex = d->tabProxy->native->currentIndex();
00384     d->tabProxy->native->removeTab(index);
00385     QGraphicsWidget *page = d->pages.takeAt(index);
00386 
00387     int currentIndex = d->tabProxy->native->currentIndex();
00388 
00389     if (oldCurrentIndex == index) {
00390         d->tabWidgetLayout->removeAt(1);
00391     }
00392 
00393     scene()->removeItem(page);
00394     page->deleteLater();
00395 
00396     if (oldCurrentIndex != currentIndex) {
00397         setCurrentIndex(currentIndex);
00398     }
00399 
00400     d->updateTabWidgetMode();
00401     d->tabProxy->setPreferredSize(d->tabProxy->native->sizeHint());
00402 }
00403 
00404 void TabBar::setTabText(int index, const QString &label)
00405 {
00406     if (index > d->pages.count()) {
00407         return;
00408     }
00409 
00410     d->tabProxy->native->setTabText(index, label);
00411 }
00412 
00413 QString TabBar::tabText(int index) const
00414 {
00415     return d->tabProxy->native->tabText(index);
00416 }
00417 
00418 void TabBar::setTabIcon(int index, const QIcon &icon)
00419 {
00420     d->tabProxy->native->setTabIcon(index, icon);
00421 }
00422 
00423 QIcon TabBar::tabIcon(int index) const
00424 {
00425     return d->tabProxy->native->tabIcon(index);
00426 }
00427 
00428 void TabBar::setTabBarShown(bool show)
00429 {
00430     if (!show && !d->tabWidgetMode) {
00431         return;
00432     }
00433 
00434     if (!show && d->tabProxy->isVisible()) {
00435         d->tabProxy->hide();
00436         d->tabBarLayout->removeItem(d->tabProxy);
00437     } else if (show && !d->tabProxy->isVisible()) {
00438         d->tabProxy->show();
00439         d->tabBarLayout->insertItem(0, d->tabProxy);
00440     }
00441 }
00442 
00443 bool TabBar::isTabBarShown() const
00444 {
00445     return d->tabProxy->isVisible();
00446 }
00447 
00448 void TabBar::setStyleSheet(const QString &stylesheet)
00449 {
00450     d->tabProxy->native->setStyleSheet(stylesheet);
00451 }
00452 
00453 QString TabBar::styleSheet() const
00454 {
00455     return d->tabProxy->native->styleSheet();
00456 }
00457 
00458 KTabBar *TabBar::nativeWidget() const
00459 {
00460     return d->tabProxy->native;
00461 }
00462 
00463 void TabBar::wheelEvent(QGraphicsSceneWheelEvent * event)
00464 {
00465     Q_UNUSED(event)
00466     //Still here for binary compatibility
00467 }
00468 
00469 } // namespace Plasma
00470 
00471 #include <tabbar.moc>
00472 

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal