┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/kitemviews/kitemlistcontainer.cpp
diff options
context:
space:
mode:
authorPeter Penz <[email protected]>2011-08-08 23:41:18 +0200
committerPeter Penz <[email protected]>2011-08-09 16:22:36 +0200
commit3957884bf2e44619a4ed35ba0ffead519988885b (patch)
treed8a5bf1a015cc6001adb4afc5f0f1da721908a22 /src/kitemviews/kitemlistcontainer.cpp
parent4692eb7c96f57328479862c0d17d7945b4e87188 (diff)
Improvements for selections, smooth scrolling, tooltips and info-panel
Diffstat (limited to 'src/kitemviews/kitemlistcontainer.cpp')
-rw-r--r--src/kitemviews/kitemlistcontainer.cpp151
1 files changed, 129 insertions, 22 deletions
diff --git a/src/kitemviews/kitemlistcontainer.cpp b/src/kitemviews/kitemlistcontainer.cpp
index 09fb505d6..e247df0c7 100644
--- a/src/kitemviews/kitemlistcontainer.cpp
+++ b/src/kitemviews/kitemlistcontainer.cpp
@@ -28,6 +28,7 @@
#include <QGraphicsScene>
#include <QGraphicsView>
+#include <QPropertyAnimation>
#include <QScrollBar>
#include <QStyle>
@@ -56,7 +57,9 @@ public:
KItemListContainer::KItemListContainer(KItemListController* controller, QWidget* parent) :
QAbstractScrollArea(parent),
- m_controller(controller)
+ m_controller(controller),
+ m_sliderMovedByUser(false),
+ m_viewOffsetAnimation(0)
{
Q_ASSERT(controller);
controller->setParent(this);
@@ -99,8 +102,86 @@ void KItemListContainer::scrollContentsBy(int dx, int dy)
}
const qreal currentOffset = view->offset();
- const qreal offsetDiff = (view->scrollOrientation() == Qt::Vertical) ? dy : dx;
- view->setOffset(currentOffset - offsetDiff);
+ qreal offsetDiff = (view->scrollOrientation() == Qt::Vertical) ? dy : dx;
+
+ const bool animRunning = (m_viewOffsetAnimation->state() == QAbstractAnimation::Running);
+ if (animRunning) {
+ // Stopping a running animation means skipping the range from the current offset
+ // until the target offset. To prevent skipping of the range the difference
+ // is added to the new target offset.
+ m_viewOffsetAnimation->stop();
+ const qreal targetOffset = m_viewOffsetAnimation->endValue().toReal();
+ offsetDiff += (currentOffset - targetOffset);
+ }
+
+ const qreal newOffset = currentOffset - offsetDiff;
+
+ if (m_sliderMovedByUser || animRunning) {
+ m_viewOffsetAnimation->stop();
+ m_viewOffsetAnimation->setStartValue(currentOffset);
+ m_viewOffsetAnimation->setEndValue(newOffset);
+ m_viewOffsetAnimation->setEasingCurve(animRunning ? QEasingCurve::OutQuad : QEasingCurve::InOutQuad);
+ m_viewOffsetAnimation->start();
+ } else {
+ view->setOffset(newOffset);
+ }
+}
+
+bool KItemListContainer::eventFilter(QObject* obj, QEvent* event)
+{
+ Q_ASSERT(obj == horizontalScrollBar() || obj == verticalScrollBar());
+
+ // Check whether the scrollbar has been adjusted by a mouse-event
+ // triggered by the user and remember this in m_sliderMovedByUser.
+ // The smooth scrolling will only get active if m_sliderMovedByUser
+ // is true (see scrollContentsBy()).
+ const bool scrollVertical = (m_controller->view()->scrollOrientation() == Qt::Vertical);
+ const bool checkEvent = ( scrollVertical && obj == verticalScrollBar()) ||
+ (!scrollVertical && obj == horizontalScrollBar());
+ if (checkEvent) {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ m_sliderMovedByUser = true;
+ break;
+
+ case QEvent::MouseButtonRelease:
+ m_sliderMovedByUser = false;
+ break;
+
+ case QEvent::Wheel:
+ wheelEvent(static_cast<QWheelEvent*>(event));
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return QAbstractScrollArea::eventFilter(obj, event);
+}
+
+void KItemListContainer::wheelEvent(QWheelEvent* event)
+{
+ KItemListView* view = m_controller->view();
+ if (!view || event->orientation() != view->scrollOrientation()) {
+ return;
+ }
+
+ const int numDegrees = event->delta() / 8;
+ const int numSteps = numDegrees / 15;
+
+ const bool previous = m_sliderMovedByUser;
+ m_sliderMovedByUser = true;
+ if (view->scrollOrientation() == Qt::Vertical) {
+ const int value = verticalScrollBar()->value();
+ verticalScrollBar()->setValue(value - numSteps * view->size().height());
+ } else {
+ const int value = horizontalScrollBar()->value();
+ horizontalScrollBar()->setValue(value - numSteps * view->size().width());
+ }
+ m_sliderMovedByUser = previous;
+
+ event->accept();
}
void KItemListContainer::slotModelChanged(KItemModelBase* current, KItemModelBase* previous)
@@ -116,37 +197,57 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView*
scene->removeItem(previous);
disconnect(previous, SIGNAL(offsetChanged(int,int)), this, SLOT(updateScrollBars()));
disconnect(previous, SIGNAL(maximumOffsetChanged(int,int)), this, SLOT(updateScrollBars()));
+ m_viewOffsetAnimation->setTargetObject(0);
}
if (current) {
scene->addItem(current);
- connect(previous, SIGNAL(offsetChanged(int,int)), this, SLOT(updateScrollBars()));
+ connect(current, SIGNAL(offsetChanged(int,int)), this, SLOT(updateScrollBars()));
connect(current, SIGNAL(maximumOffsetChanged(int,int)), this, SLOT(updateScrollBars()));
+ m_viewOffsetAnimation->setTargetObject(current);
}
}
void KItemListContainer::updateScrollBars()
{
- const QSizeF size = m_controller->view()->size();
+ const KItemListView* view = m_controller->view();
+ if (!view) {
+ return;
+ }
- if (m_controller->view()->scrollOrientation() == Qt::Vertical) {
- QScrollBar* scrollBar = verticalScrollBar();
- const int value = m_controller->view()->offset();
- const int maximum = qMax(0, int(m_controller->view()->maximumOffset() - size.height()));
- scrollBar->setPageStep(size.height());
- scrollBar->setMinimum(0);
- scrollBar->setMaximum(maximum);
- scrollBar->setValue(value);
- horizontalScrollBar()->setMaximum(0);
+ QScrollBar* scrollBar = 0;
+ int singleStep = 0;
+ int pageStep = 0;
+ if (view->scrollOrientation() == Qt::Vertical) {
+ scrollBar = verticalScrollBar();
+ singleStep = view->itemSize().height();
+ pageStep = view->size().height();
} else {
- QScrollBar* scrollBar = horizontalScrollBar();
- const int value = m_controller->view()->offset();
- const int maximum = qMax(0, int(m_controller->view()->maximumOffset() - size.width()));
- scrollBar->setPageStep(size.width());
- scrollBar->setMinimum(0);
- scrollBar->setMaximum(maximum);
- scrollBar->setValue(value);
- verticalScrollBar()->setMaximum(0);
+ scrollBar = horizontalScrollBar();
+ singleStep = view->itemSize().width();
+ pageStep = view->size().width();
+ }
+
+ const int value = view->offset();
+ const int maximum = qMax(0, int(view->maximumOffset() - pageStep));
+ if (m_viewOffsetAnimation->state() == QAbstractAnimation::Running) {
+ if (maximum == scrollBar->maximum()) {
+ // The value has been changed by the animation, no update
+ // of the scrollbars is required as their target state will be
+ // reached with the end of the animation.
+ return;
+ }
+
+ // The maximum has been changed which indicates that the content
+ // of the view has been changed. Stop the animation in any case and
+ // update the scrollbars immediately.
+ m_viewOffsetAnimation->stop();
}
+
+ scrollBar->setSingleStep(singleStep);
+ scrollBar->setPageStep(pageStep);
+ scrollBar->setMinimum(0);
+ scrollBar->setMaximum(maximum);
+ scrollBar->setValue(value);
}
void KItemListContainer::updateGeometries()
@@ -186,6 +287,12 @@ void KItemListContainer::initialize()
QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
setViewport(graphicsView);
+
+ m_viewOffsetAnimation = new QPropertyAnimation(this, "offset");
+ m_viewOffsetAnimation->setDuration(500);
+
+ horizontalScrollBar()->installEventFilter(this);
+ verticalScrollBar()->installEventFilter(this);
}
#include "kitemlistcontainer.moc"