┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Penz <[email protected]>2011-08-27 20:12:03 +0200
committerPeter Penz <[email protected]>2011-08-27 20:13:22 +0200
commitd99d5fbea76a79346761c0d8ce98a0719e5790d2 (patch)
tree50b944a3adf3e4533003d91df16f3b19bb636412
parent4905667ada4ddd0aee3d2bb077e401a4262804b9 (diff)
Improve the autoscrolling for the rubberband selection
This modifications will also allow to do an autoscrolling in an easy way for drag and drop operations (not fully implemented yet).
-rw-r--r--src/kitemviews/kitemlistcontainer.cpp7
-rw-r--r--src/kitemviews/kitemlistcontroller.cpp2
-rw-r--r--src/kitemviews/kitemlistview.cpp82
-rw-r--r--src/kitemviews/kitemlistview.h20
4 files changed, 83 insertions, 28 deletions
diff --git a/src/kitemviews/kitemlistcontainer.cpp b/src/kitemviews/kitemlistcontainer.cpp
index ec759bdb3..0d2637da6 100644
--- a/src/kitemviews/kitemlistcontainer.cpp
+++ b/src/kitemviews/kitemlistcontainer.cpp
@@ -120,7 +120,14 @@ void KItemListContainer::scrollContentsBy(int dx, int dy)
return;
}
+ const QScrollBar* scrollBar = (view->scrollOrientation() == Qt::Vertical)
+ ? verticalScrollBar() : horizontalScrollBar();
const qreal currentOffset = view->offset();
+ if (static_cast<int>(currentOffset) == scrollBar->value()) {
+ // The current offset is already synchronous to the scrollbar
+ return;
+ }
+
qreal offsetDiff = (view->scrollOrientation() == Qt::Vertical) ? dy : dx;
const bool animRunning = (m_smoothScrollingAnimation->state() == QAbstractAnimation::Running);
diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
index ddae06c17..78c0a3594 100644
--- a/src/kitemviews/kitemlistcontroller.cpp
+++ b/src/kitemviews/kitemlistcontroller.cpp
@@ -306,6 +306,7 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const
rubberBand->setEndPosition(startPos);
rubberBand->setActive(true);
connect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
+ m_view->setAutoScroll(true);
}
return false;
@@ -365,6 +366,7 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con
disconnect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged()));
rubberBand->setActive(false);
m_oldSelection.clear();
+ m_view->setAutoScroll(false);
if (rubberBand->startPosition() != rubberBand->endPosition()) {
clearSelection = false;
diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp
index 3435e3f65..a35752a47 100644
--- a/src/kitemviews/kitemlistview.cpp
+++ b/src/kitemviews/kitemlistview.cpp
@@ -43,7 +43,6 @@
KItemListView::KItemListView(QGraphicsWidget* parent) :
QGraphicsWidget(parent),
- m_autoScrollMarginEnabled(false),
m_grouped(false),
m_activeTransactions(0),
m_itemSize(),
@@ -62,8 +61,10 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
m_layoutTimer(0),
m_oldOffset(0),
m_oldMaximumOffset(0),
+ m_skipAutoScrollForRubberBand(false),
m_rubberBand(0),
- m_mousePos()
+ m_mousePos(),
+ m_autoScrollTimer(0)
{
setAcceptHoverEvents(true);
@@ -193,6 +194,26 @@ QHash<QByteArray, int> KItemListView::visibleRoles() const
return m_visibleRoles;
}
+void KItemListView::setAutoScroll(bool enabled)
+{
+ if (enabled && !m_autoScrollTimer) {
+ m_autoScrollTimer = new QTimer(this);
+ m_autoScrollTimer->setInterval(1000 / 60); // 60 frames per second
+ m_autoScrollTimer->setSingleShot(false);
+ connect(m_autoScrollTimer, SIGNAL(timeout()), this, SLOT(triggerAutoScrolling()));
+ m_autoScrollTimer->start();
+ } else if (!enabled && m_autoScrollTimer) {
+ delete m_autoScrollTimer;
+ m_autoScrollTimer = 0;
+ }
+
+}
+
+bool KItemListView::autoScroll() const
+{
+ return m_autoScrollTimer != 0;
+}
+
KItemListController* KItemListView::controller() const
{
return m_controller;
@@ -463,6 +484,10 @@ void KItemListView::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
m_mousePos = transform().map(event->pos());
QGraphicsWidget::mouseMoveEvent(event);
+
+ if (m_autoScrollTimer && !m_autoScrollTimer->isActive()) {
+ m_autoScrollTimer->start();
+ }
}
void KItemListView::dragEnterEvent(QGraphicsSceneDragDropEvent* event)
@@ -755,29 +780,21 @@ void KItemListView::slotLayoutTimerFinished()
doLayout(Animation, 0, 0);
}
-void KItemListView::slotRubberBandStartPosChanged()
+void KItemListView::slotRubberBandPosChanged()
{
update();
}
-void KItemListView::slotRubberBandEndPosChanged()
-{
- // The autoscrolling is triggered asynchronously otherwise it
- // might be possible to have an endless recursion: The autoscrolling
- // might adjust the position which might result in updating the
- // rubberband end-position.
- QTimer::singleShot(0, this, SLOT(triggerAutoScrolling()));
- update();
-}
-
void KItemListView::slotRubberBandActivationChanged(bool active)
{
if (active) {
- connect(m_rubberBand, SIGNAL(startPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandStartPosChanged()));
- connect(m_rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandEndPosChanged()));
+ connect(m_rubberBand, SIGNAL(startPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandPosChanged()));
+ connect(m_rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandPosChanged()));
+ m_skipAutoScrollForRubberBand = true;
} else {
- disconnect(m_rubberBand, SIGNAL(startPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandStartPosChanged()));
- disconnect(m_rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandEndPosChanged()));
+ disconnect(m_rubberBand, SIGNAL(startPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandPosChanged()));
+ disconnect(m_rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandPosChanged()));
+ m_skipAutoScrollForRubberBand = false;
}
update();
@@ -785,6 +802,10 @@ void KItemListView::slotRubberBandActivationChanged(bool active)
void KItemListView::triggerAutoScrolling()
{
+ if (!m_autoScrollTimer) {
+ return;
+ }
+
int pos = 0;
int visibleSize = 0;
if (scrollOrientation() == Qt::Vertical) {
@@ -797,13 +818,17 @@ void KItemListView::triggerAutoScrolling()
const int inc = calculateAutoScrollingIncrement(pos, visibleSize);
if (inc == 0) {
- // The mouse position is not above an autoscroll margin
+ // The mouse position is not above an autoscroll margin (the autoscroll timer
+ // will be restarted in mouseMoveEvent())
+ m_autoScrollTimer->stop();
return;
}
- if (m_rubberBand->isActive()) {
+ if (m_rubberBand->isActive() && m_skipAutoScrollForRubberBand) {
// If a rubberband selection is ongoing the autoscrolling may only get triggered
- // if the direction of the rubberband is similar to the autoscroll direction.
+ // if the direction of the rubberband is similar to the autoscroll direction. This
+ // prevents that starting to create a rubberband within the autoscroll margins starts
+ // an autoscrolling.
const qreal minDiff = 4; // Ignore any autoscrolling if the rubberband is very small
const qreal diff = (scrollOrientation() == Qt::Vertical)
@@ -812,11 +837,22 @@ void KItemListView::triggerAutoScrolling()
if (qAbs(diff) < minDiff || (inc < 0 && diff > 0) || (inc > 0 && diff < 0)) {
// The rubberband direction is different from the scroll direction (e.g. the rubberband has
// been moved up although the autoscroll direction might be down)
+ m_autoScrollTimer->stop();
return;
}
}
- emit scrollTo(offset() + inc);
+ // As soon as the autoscrolling has been triggered at least once despite having an active rubberband,
+ // the autoscrolling may not get skipped anymore until a new rubberband is created
+ m_skipAutoScrollForRubberBand = false;
+
+ setOffset(offset() + inc);
+
+ if (!m_autoScrollTimer->isActive()) {
+ // Trigger the autoscroll timer which will periodically call
+ // triggerAutoScrolling()
+ m_autoScrollTimer->start();
+ }
}
void KItemListView::setController(KItemListController* controller)
@@ -1230,8 +1266,8 @@ int KItemListView::calculateAutoScrollingIncrement(int pos, int size)
int inc = 0;
const int minSpeed = 4;
- const int maxSpeed = 768;
- const int speedLimiter = 48;
+ const int maxSpeed = 128;
+ const int speedLimiter = 96;
const int autoScrollBorder = 64;
if (pos < autoScrollBorder) {
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
index 344221e40..9977e3639 100644
--- a/src/kitemviews/kitemlistview.h
+++ b/src/kitemviews/kitemlistview.h
@@ -90,6 +90,14 @@ public:
QHash<QByteArray, int> visibleRoles() const;
/**
+ * If set to true an automatic scrolling is done as soon as the
+ * mouse is moved near the borders of the view. Per default
+ * the automatic scrolling is turned off.
+ */
+ void setAutoScroll(bool enabled);
+ bool autoScroll() const;
+
+ /**
* @return Controller of the item-list. The controller gets
* initialized by KItemListController::setView() and will
* result in calling KItemListController::onControllerChanged().
@@ -124,6 +132,7 @@ public:
void setStyleOption(const KItemListStyleOption& option);
const KItemListStyleOption& styleOption() const;
+ /** @reimp */
virtual void setGeometry(const QRectF& rect);
int itemAt(const QPointF& pos) const;
@@ -207,13 +216,13 @@ private slots:
KItemListViewAnimation::AnimationType type);
void slotLayoutTimerFinished();
- void slotRubberBandStartPosChanged();
- void slotRubberBandEndPosChanged();
+ void slotRubberBandPosChanged();
void slotRubberBandActivationChanged(bool active);
/**
- * Emits the signal scrollTo() with the corresponding target offset if the current
- * mouse position is above the autoscroll-margin.
+ * Triggers the autoscrolling if autoScroll() is enabled by checking the
+ * current mouse position. If the mouse position is within the autoscroll
+ * margins a timer will be started that periodically triggers the autoscrolling.
*/
void triggerAutoScrolling();
@@ -289,7 +298,6 @@ private:
static int calculateAutoScrollingIncrement(int pos, int size);
private:
- bool m_autoScrollMarginEnabled;
bool m_grouped;
int m_activeTransactions; // Counter for beginTransaction()/endTransaction()
@@ -314,9 +322,11 @@ private:
qreal m_oldOffset;
qreal m_oldMaximumOffset;
+ bool m_skipAutoScrollForRubberBand;
KItemListRubberBand* m_rubberBand;
QPointF m_mousePos;
+ QTimer* m_autoScrollTimer;
friend class KItemListController;
};