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

Plasma

scrollwidget.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2009 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 "scrollwidget.h"
00021 
00022 //Qt
00023 #include <QGraphicsSceneResizeEvent>
00024 #include <QGraphicsGridLayout>
00025 #include <QApplication>
00026 #include <QWidget>
00027 
00028 //KDE
00029 #include <kmimetype.h>
00030 #include <kdebug.h>
00031 
00032 //Plasma
00033 #include <plasma/widgets/scrollbar.h>
00034 
00035 namespace Plasma
00036 {
00037 
00038 class ScrollWidgetPrivate
00039 {
00040 public:
00041     ScrollWidgetPrivate(ScrollWidget *parent)
00042         : q(parent),
00043           widget(0),
00044           dragging(false)
00045     {
00046     }
00047 
00048     ~ScrollWidgetPrivate()
00049     {
00050     }
00051 
00052     void adjustScrollbars()
00053     {
00054         verticalScrollBar->nativeWidget()->setMaximum(qMax(0, int((widget->size().height() - scrollingWidget->size().height())/10)));
00055 
00056         if (verticalScrollBarPolicy == Qt::ScrollBarAlwaysOff ||
00057             verticalScrollBar->nativeWidget()->maximum() == 0) {
00058             if (layout->itemAt(2) == verticalScrollBar) {
00059                 layout->removeAt(2);
00060             } else if (layout->itemAt(1) == verticalScrollBar) {
00061                 layout->removeAt(1);
00062             }
00063             verticalScrollBar->hide();
00064         } else if (!verticalScrollBar->isVisible()) {
00065             layout->addItem(verticalScrollBar, 0, 1);
00066             verticalScrollBar->show();
00067         }
00068 
00069 
00070         horizontalScrollBar->nativeWidget()->setMaximum(qMax(0, int((widget->size().width() - scrollingWidget->size().width())/10)));
00071 
00072         if (horizontalScrollBarPolicy == Qt::ScrollBarAlwaysOff ||
00073             horizontalScrollBar->nativeWidget()->maximum() == 0) {
00074             if (layout->itemAt(2) == horizontalScrollBar) {
00075                 layout->removeAt(2);
00076             } else if (layout->itemAt(1) == horizontalScrollBar) {
00077                 layout->removeAt(1);
00078             }
00079             horizontalScrollBar->hide();
00080         } else if (!horizontalScrollBar->isVisible()) {
00081             layout->addItem(horizontalScrollBar, 1, 0);
00082             horizontalScrollBar->show();
00083         }
00084 
00085         layout->activate();
00086         widget->resize(scrollingWidget->size().width(), widget->size().height());
00087     }
00088 
00089     void verticalScroll(int value)
00090     {
00091         if (!dragging) {
00092             widget->setPos(QPoint(0, -value*10));
00093         }
00094     }
00095 
00096     void horizontalScroll(int value)
00097     {
00098         if (!dragging) {
00099             widget->setPos(QPoint(-value*10, 0));
00100         }
00101     }
00102 
00103     void adjustClipping()
00104     {
00105         const bool clip = widget->size().width() > scrollingWidget->size().width() ||
00106                           widget->size().height() > scrollingWidget->size().height();
00107 
00108         /* WORKAROUND: it should really be like this:
00109          *
00110          * scrollingWidget->setFlag(QGraphicsItem::ItemClipsChildrenToShape, clip);
00111          *
00112          * however, a qt bug prevents this to work properly when toggling this flag,
00113          * so we have to keep the children items always clipped (performance--)
00114          * The bug appears to be fixed in Qt 4.6 but it is unclear if it will ever be in the 4.5 branch
00115          */
00116 
00117         scrollingWidget->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
00118     }
00119 
00120     ScrollWidget *q;
00121     QGraphicsWidget *scrollingWidget;
00122     QGraphicsWidget *widget;
00123     QGraphicsGridLayout *layout;
00124     ScrollBar *verticalScrollBar;
00125     Qt::ScrollBarPolicy verticalScrollBarPolicy;
00126     ScrollBar *horizontalScrollBar;
00127     Qt::ScrollBarPolicy horizontalScrollBarPolicy;
00128     QString styleSheet;
00129     bool dragging;
00130 };
00131 
00132 
00133 ScrollWidget::ScrollWidget(QGraphicsWidget *parent)
00134     : QGraphicsWidget(parent),
00135       d(new ScrollWidgetPrivate(this))
00136 {
00137     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00138     d->layout = new QGraphicsGridLayout(this);
00139     d->scrollingWidget = new QGraphicsWidget(this);
00140     d->layout->addItem(d->scrollingWidget, 0, 0);
00141 
00142     d->verticalScrollBarPolicy = Qt::ScrollBarAsNeeded;
00143     d->verticalScrollBar = new Plasma::ScrollBar(this);
00144     d->layout->addItem(d->verticalScrollBar, 0, 1);
00145     d->verticalScrollBar->nativeWidget()->setMinimum(0);
00146     d->verticalScrollBar->nativeWidget()->setMaximum(100);
00147     connect(d->verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(verticalScroll(int)));
00148 
00149     d->horizontalScrollBarPolicy = Qt::ScrollBarAsNeeded;
00150     d->horizontalScrollBar = new Plasma::ScrollBar(this);
00151     d->horizontalScrollBar->setOrientation(Qt::Horizontal);
00152     d->layout->addItem(d->horizontalScrollBar, 1, 0);
00153     d->horizontalScrollBar->nativeWidget()->setMinimum(0);
00154     d->horizontalScrollBar->nativeWidget()->setMaximum(100);
00155     connect(d->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(horizontalScroll(int)));
00156 }
00157 
00158 ScrollWidget::~ScrollWidget()
00159 {
00160     delete d;
00161 }
00162 
00163 
00164 void ScrollWidget::setWidget(QGraphicsWidget *widget)
00165 {
00166     if (d->widget && d->widget != widget) {
00167         d->widget->removeEventFilter(this);
00168         delete d->widget;
00169     }
00170 
00171     d->widget = widget;
00172     widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00173     widget->setParentItem(d->scrollingWidget);
00174     widget->setPos(QPoint(0,0));
00175     widget->installEventFilter(this);
00176     d->adjustScrollbars();
00177 }
00178 
00179 QGraphicsWidget *ScrollWidget::widget() const
00180 {
00181     return d->widget;
00182 }
00183 
00184 
00185 void ScrollWidget::setHorizontalScrollBarPolicy(const Qt::ScrollBarPolicy policy)
00186 {
00187     d->horizontalScrollBarPolicy = policy;
00188 }
00189 
00190 
00191 Qt::ScrollBarPolicy ScrollWidget::horizontalScrollBarPolicy() const
00192 {
00193     return d->horizontalScrollBarPolicy;
00194 }
00195 
00196 
00197 void ScrollWidget::setVerticalScrollBarPolicy(const Qt::ScrollBarPolicy policy)
00198 {
00199     d->verticalScrollBarPolicy = policy;
00200 }
00201 
00202 Qt::ScrollBarPolicy ScrollWidget::verticalScrollBarPolicy() const
00203 {
00204     return d->verticalScrollBarPolicy;
00205 }
00206 
00207 
00208 void ScrollWidget::setStyleSheet(const QString &styleSheet)
00209 {
00210     d->styleSheet = styleSheet;
00211     d->verticalScrollBar->setStyleSheet(styleSheet);
00212     d->horizontalScrollBar->setStyleSheet(styleSheet);
00213 }
00214 
00215 QString ScrollWidget::styleSheet() const
00216 {
00217     return d->styleSheet;
00218 }
00219 
00220 QWidget *ScrollWidget::nativeWidget() const
00221 {
00222     return 0;
00223 }
00224 
00225 
00226 void ScrollWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
00227 {
00228     if (!d->widget) {
00229         return;
00230     }
00231 
00232     d->adjustScrollbars();
00233 
00234     d->adjustClipping();
00235 
00236     QGraphicsWidget::resizeEvent(event);
00237 }
00238 
00239 void ScrollWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00240 {
00241     if (!d->widget) {
00242         return;
00243     }
00244 
00245     QPointF deltaPos = event->pos() - event->lastPos();
00246 
00247     d->widget->setPos(qBound(qMin((qreal)0,-d->widget->size().width()+d->scrollingWidget->size().width()), d->widget->pos().x()+deltaPos.x(), (qreal)0),
00248                       qBound(qMin((qreal)0,-d->widget->size().height()+d->scrollingWidget->size().height()), d->widget->pos().y()+deltaPos.y(), (qreal)0));
00249 
00250     d->dragging = true;
00251     d->horizontalScrollBar->setValue(-d->widget->pos().x()/10);
00252     d->verticalScrollBar->setValue(-d->widget->pos().y()/10);
00253     d->dragging = false;
00254 
00255     QGraphicsWidget::mouseMoveEvent(event);
00256 }
00257 
00258 void ScrollWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
00259 {
00260     event->accept();
00261 }
00262 
00263 void ScrollWidget::wheelEvent(QGraphicsSceneWheelEvent *event)
00264 {
00265     if (event->delta() < 0) {
00266         d->verticalScrollBar->setValue(d->verticalScrollBar->value()+10);
00267     } else {
00268         d->verticalScrollBar->setValue(d->verticalScrollBar->value()-10);
00269     }
00270     QGraphicsWidget::wheelEvent(event);
00271 }
00272 
00273 bool ScrollWidget::eventFilter(QObject *watched, QEvent *event)
00274 {
00275     if (!d->widget) {
00276         return false;
00277     }
00278 
00279     if (watched == d->widget && event->type() == QEvent::GraphicsSceneResize) {
00280         d->adjustScrollbars();
00281         d->adjustClipping();
00282     } else if (watched == d->widget && event->type() == QEvent::GraphicsSceneMove) {
00283         d->horizontalScrollBar->blockSignals(true);
00284         d->verticalScrollBar->blockSignals(true);
00285         d->horizontalScrollBar->setValue(-d->widget->pos().x()/10);
00286         d->verticalScrollBar->setValue(-d->widget->pos().y()/10);
00287         d->horizontalScrollBar->blockSignals(false);
00288         d->verticalScrollBar->blockSignals(false);
00289     }
00290 
00291     return false;
00292 }
00293 
00294 } // namespace Plasma
00295 
00296 #include <scrollwidget.moc>
00297 

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