From 8accd83373236c3a076a3f3a6a6c438abf6023a5 Mon Sep 17 00:00:00 2001 From: "Aaron J. Seigo" Date: Mon, 4 Aug 2008 05:21:52 +0000 Subject: [PATCH] moving tabbar to libplasma svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=841791 --- widgets/tabbar.cpp | 355 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 widgets/tabbar.cpp diff --git a/widgets/tabbar.cpp b/widgets/tabbar.cpp new file mode 100644 index 000000000..509f19ec9 --- /dev/null +++ b/widgets/tabbar.cpp @@ -0,0 +1,355 @@ +/* + * Copyright 2008 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program 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 General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "tabbar.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "nativetabbar.h" + +namespace Plasma +{ + +class TabBarPrivate +{ +public: + TabBarPrivate(TabBar *parent) + : q(parent), + tabBar(0), + currentIndex(0), + oldPage(0), + newPage(0), + oldPageAnimId(-1), + newPageAnimId(-1) + { + } + + ~TabBarPrivate() + { + } + + void slidingCompleted(QGraphicsItem *item); + void shapeChanged(const QTabBar::Shape shape); + + TabBar *q; + NativeTabBar *tabBar; + QList pages; + QGraphicsLinearLayout *mainLayout; + QGraphicsLinearLayout *tabBarLayout; + int currentIndex; + + QGraphicsWidget *oldPage; + QGraphicsWidget *newPage; + int oldPageAnimId; + int newPageAnimId; +}; + + +void TabBarPrivate::slidingCompleted(QGraphicsItem *item) +{ + if (item == oldPage || item == newPage) { + if (item == newPage) { + mainLayout->addItem(newPage); + newPageAnimId = -1; + } else { + oldPageAnimId = -1; + item->hide(); + } + q->setFlags(0); + } +} + +void TabBarPrivate::shapeChanged(const QTabBar::Shape shape) +{ + //FIXME: QGraphicsLinearLayout doesn't have setDirection, so for now + // North is equal to south and East is equal to West + switch (shape) { + case QTabBar::RoundedWest: + case QTabBar::TriangularWest: + + case QTabBar::RoundedEast: + case QTabBar::TriangularEast: + mainLayout->setOrientation(Qt::Horizontal); + mainLayout->itemAt(0)->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + break; + + case QTabBar::RoundedSouth: + case QTabBar::TriangularSouth: + + case QTabBar::RoundedNorth: + case QTabBar::TriangularNorth: + default: + mainLayout->setOrientation(Qt::Vertical); + mainLayout->itemAt(0)->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + } +} + + +TabBar::TabBar(QGraphicsWidget *parent) + : QGraphicsWidget(parent), + d(new TabBarPrivate(this)) +{ + d->tabBar = new NativeTabBar(); + d->tabBar->setAttribute(Qt::WA_NoSystemBackground); + d->mainLayout = new QGraphicsLinearLayout(Qt::Vertical); + d->tabBarLayout = new QGraphicsLinearLayout(Qt::Horizontal); + + setLayout(d->mainLayout); + + d->mainLayout->addItem(d->tabBarLayout); + + QGraphicsProxyWidget *tabProxy = new QGraphicsProxyWidget(this); + tabProxy->setWidget(d->tabBar); + tabProxy->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + //tabBar are centered, so a stretch at begin one at the end + d->tabBarLayout->addStretch(); + d->tabBarLayout->addItem(tabProxy); + d->tabBarLayout->addStretch(); + + connect(d->tabBar, SIGNAL(currentChanged(int)), this, SLOT(setCurrentIndex(int))); + connect(d->tabBar, SIGNAL(shapeChanged(QTabBar::Shape)), this, SLOT(shapeChanged(QTabBar::Shape))); + connect(Plasma::Animator::self(), SIGNAL(movementFinished(QGraphicsItem*)), this, SLOT(slidingCompleted(QGraphicsItem*))); +} + +TabBar::~TabBar() +{ + delete d; +} + +int TabBar::insertTab(int index, const QIcon &icon, const QString &label, QGraphicsLayoutItem *content) +{ + QGraphicsWidget *page = new QGraphicsWidget(this); + page->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + if (content) { + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, page); + layout->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + page->setLayout(layout); + layout->addItem(content); + } else { + page->setMaximumHeight(0); + } + + d->pages.insert(qBound(0, index, d->pages.count()), page); + + if (d->pages.count() == 1) { + d->mainLayout->addItem(page); + page->setVisible(true); + page->setEnabled(true); + } else { + page->setVisible(false); + page->setEnabled(false); + } + + return d->tabBar->insertTab(index, icon, label); +} + +int TabBar::insertTab(int index, const QString &label, QGraphicsLayoutItem *content) +{ + return insertTab(index, QIcon(), label, content); +} + +int TabBar::addTab(const QIcon &icon, const QString &label, QGraphicsLayoutItem *content) +{ + return insertTab(d->pages.count(), icon, label, content); +} + +int TabBar::addTab(const QString &label, QGraphicsLayoutItem *content) +{ + return insertTab(d->pages.count(), QIcon(), label, content); +} + +int TabBar::currentIndex() const +{ + return d->tabBar->currentIndex(); +} + +void TabBar::setCurrentIndex(int index) +{ + if (index > d->tabBar->count() || d->tabBar->count() <= 1) { + return; + } + + if (d->currentIndex != index) { + d->tabBar->setCurrentIndex(index); + } + + d->mainLayout->removeAt(1); + + d->oldPage = d->pages[d->currentIndex]; + d->newPage = d->pages[index]; + +//FIXME: this part should be enabled again once +//http://trolltech.com/developer/task-tracker/index_html?id=220488 +//get fixed +#ifdef USE_SLIDING_ANIMATION + d->newPage->resize(d->oldPage->size()); + + setFlags(QGraphicsItem::ItemClipsChildrenToShape); + + //if an animation was in rogress hide everything to avoid an inconsistent state + if (d->newPageAnimId != -1 || d->oldPageAnimId != -1) { + foreach (QGraphicsWidget *page, d->pages) { + page->hide(); + } + if (d->newPageAnimId != -1) { + Animator::self()->stopItemMovement(d->newPageAnimId); + } + if (d->oldPageAnimId != -1) { + Animator::self()->stopItemMovement(d->oldPageAnimId); + } + } + + d->oldPage->show(); + d->newPage->show(); + d->newPage->setEnabled(true); + + d->oldPage->setEnabled(false); + + QRect beforeCurrentGeom(d->oldPage->geometry().toRect()); + beforeCurrentGeom.moveTopRight(beforeCurrentGeom.topLeft()); + + d->newPageAnimId = Animator::self()->moveItem(d->newPage, Plasma::Animator::SlideOutMovement, d->oldPage->pos().toPoint()); + if (index > d->currentIndex) { + d->newPage->setPos(d->oldPage->geometry().topRight()); + d->oldPageAnimId = Animator::self()->moveItem(d->oldPage, Plasma::Animator::SlideOutMovement, beforeCurrentGeom.topLeft()); + } else { + d->newPage->setPos(beforeCurrentGeom.topLeft()); + d->oldPageAnimId = Animator::self()->moveItem(d->oldPage, Plasma::Animator::SlideOutMovement, d->oldPage->geometry().topRight().toPoint()); + } +#else + d->mainLayout->addItem(d->pages[index]); + d->oldPage->hide(); + d->newPage->show(); + d->newPage->setEnabled(true); + d->oldPage->setEnabled(false); +#endif + d->currentIndex = index; + emit currentChanged(index); +} + +int TabBar::count() const +{ + return d->pages.count(); +} + +void TabBar::removeTab(int index) +{ + if (index > d->pages.count()) { + return; + } + + int currentIndex = d->tabBar->currentIndex(); + + d->tabBar->removeTab(index); + QGraphicsWidget *page = d->pages.takeAt(index); + + if (index == currentIndex) { + setCurrentIndex(currentIndex); + } + + scene()->removeItem(page); + page->deleteLater(); +} + +void TabBar::setTabText(int index, const QString &label) +{ + if (index > d->pages.count()) { + return; + } + + d->tabBar->setTabText(index, label); +} + +QString TabBar::tabText(int index) const +{ + return d->tabBar->tabText(index); +} + +void TabBar::setTabIcon(int index, const QIcon &icon) +{ + d->tabBar->setTabIcon(index, icon); +} + +QIcon TabBar::tabIcon(int index) const +{ + return d->tabBar->tabIcon(index); +} + +void TabBar::setStyleSheet(const QString &stylesheet) +{ + d->tabBar->setStyleSheet(stylesheet); +} + +QString TabBar::styleSheet() const +{ + return d->tabBar->styleSheet(); +} + +QTabBar *TabBar::nativeWidget() const +{ + return d->tabBar; +} + +void TabBar::wheelEvent(QGraphicsSceneWheelEvent * event) +{ + //FIXME: probably this would make more sense in NativeTabBar, but it works only here + + if (d->tabBar->underMouse()) { + //Cycle tabs with the circular array tecnique + if (event->delta() < 0) { + int index = d->tabBar->currentIndex(); + //search for an enabled tab + for (int i = 0; i < d->tabBar->count()-1; ++i) { + index = (index + 1) % d->tabBar->count(); + if (d->tabBar->isTabEnabled(index)) { + break; + } + } + + d->tabBar->setCurrentIndex(index); + } else { + int index = d->tabBar->currentIndex(); + for (int i = 0; i < d->tabBar->count()-1; ++i) { + index = (d->tabBar->count() + index -1) % d->tabBar->count(); + if (d->tabBar->isTabEnabled(index)) { + break; + } + } + + d->tabBar->setCurrentIndex(index); + } + } else { + QGraphicsWidget::wheelEvent(event); + } +} + +} // namespace Plasma + +#include +