]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinviewautoscroller.cpp
assure that the current index stays visible, when the user explicitly changed it...
[dolphin.git] / src / dolphinviewautoscroller.cpp
index 45abc1e9294bfc9727df164d973637531bed1400..67bc696cc63e319fda7d63eccca2255b5c62f2fc 100644 (file)
@@ -36,6 +36,7 @@ DolphinViewAutoScroller::DolphinViewAutoScroller(QAbstractItemView* parent) :
 {
     m_itemView->setAutoScroll(false);
     m_itemView->viewport()->installEventFilter(this);
+    m_itemView->installEventFilter(this);
     
     m_timer = new QTimer(this);
     m_timer->setSingleShot(false);
@@ -52,7 +53,9 @@ bool DolphinViewAutoScroller::eventFilter(QObject* watched, QEvent* event)
     if (watched == m_itemView->viewport()) {
         switch (event->type()) {
         case QEvent::MouseButtonPress:
-            m_rubberBandSelection = true;
+            if (static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton) {
+                m_rubberBandSelection = true;
+            }
             break;
             
         case QEvent::MouseMove:
@@ -72,6 +75,7 @@ bool DolphinViewAutoScroller::eventFilter(QObject* watched, QEvent* event)
             triggerAutoScroll();
             break;
             
+        case QEvent::Drop:
         case QEvent::DragLeave:
             m_rubberBandSelection = false;
             stopAutoScroll();
@@ -80,58 +84,69 @@ bool DolphinViewAutoScroller::eventFilter(QObject* watched, QEvent* event)
         default:
             break;
         }
-    }
+    } else if ((watched == m_itemView) && (event->type() == QEvent::KeyPress)) {
+        const int key = static_cast<QKeyEvent*>(event)->key();
+        const bool arrowKeyPressed = (key == Qt::Key_Up)   || (key == Qt::Key_Down) ||
+                                     (key == Qt::Key_Left) || (key == Qt::Key_Right);
+        if (arrowKeyPressed) {
+            QMetaObject::invokeMethod(this, "scrollToCurrentIndex", Qt::QueuedConnection);
+        }
+    } 
+    
 
     return QObject::eventFilter(watched, event);
 }
 
 void DolphinViewAutoScroller::scrollViewport()
 {
-    // TODO: implement horizontal scrolling
     QScrollBar* verticalScrollBar = m_itemView->verticalScrollBar();
     if (verticalScrollBar != 0) {
         const int value = verticalScrollBar->value();
         verticalScrollBar->setValue(value + m_scrollInc);
         
-        if (m_rubberBandSelection) {
-            // The scrolling does not lead to an update of the rubberband
-            // selection. Fake a mouse move event to let the QAbstractItemView
-            // update the rubberband.
-            QWidget* viewport = m_itemView->viewport();
-            const QPoint pos = viewport->mapFromGlobal(QCursor::pos());
-            QMouseEvent event(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
-            QCoreApplication::sendEvent(viewport, &event);
-        }
+    }
+    QScrollBar* horizontalScrollBar = m_itemView->horizontalScrollBar();
+    if (horizontalScrollBar != 0) {
+        const int value = horizontalScrollBar->value();
+        horizontalScrollBar->setValue(value + m_scrollInc);
+        
+    }
+    
+    if (m_rubberBandSelection) {
+        // The scrolling does not lead to an update of the rubberband
+        // selection. Fake a mouse move event to let the QAbstractItemView
+        // update the rubberband.
+        QWidget* viewport = m_itemView->viewport();
+        const QPoint pos = viewport->mapFromGlobal(QCursor::pos());
+        QMouseEvent event(QEvent::MouseMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+        QCoreApplication::sendEvent(viewport, &event);
     }
 }
 
+void DolphinViewAutoScroller::scrollToCurrentIndex()
+{
+     const QModelIndex index = m_itemView->currentIndex();
+     m_itemView->scrollTo(index);
+}
+
 void DolphinViewAutoScroller::triggerAutoScroll()
 {
-    // TODO: implement horizontal scrolling
-    
-    const int startSpeed = 2;
-    const int speedLimiter = 8;
-    const int scrollIncMax = 32;
-    
-    const int autoScrollBorder = 32;
+    const bool verticalScrolling = (m_itemView->verticalScrollBar() != 0) &&
+                                    m_itemView->verticalScrollBar()->isVisible();
+    const bool horizontalScrolling = (m_itemView->horizontalScrollBar() != 0) &&
+                                     m_itemView->horizontalScrollBar()->isVisible();
+    if (!verticalScrolling && !horizontalScrolling) {
+        // no scrollbars are shown at all, so no autoscrolling is necessary
+        return;
+    }
     
     QWidget* viewport = m_itemView->viewport();
     const QPoint pos = viewport->mapFromGlobal(QCursor::pos());
-    if (pos.y() < autoScrollBorder) {
-        // scroll up
-        m_scrollInc = -startSpeed + (pos.y() - autoScrollBorder) / speedLimiter;
-        if (m_scrollInc < -scrollIncMax) {
-            m_scrollInc = -scrollIncMax;
-        }
-    } else if (pos.y() > viewport->height() - autoScrollBorder) {
-        // scroll down
-        m_scrollInc = startSpeed + (pos.y() - viewport->height() + autoScrollBorder) / speedLimiter;
-        if (m_scrollInc > scrollIncMax) {
-            m_scrollInc = scrollIncMax;
-        }
-    } else {
-        // no scrolling
-        m_scrollInc = 0;
+    if (verticalScrolling) {
+        calculateScrollIncrement(pos.y(), viewport->height());
+    }
+    if (horizontalScrolling) {
+        calculateScrollIncrement(pos.x(), viewport->width());
     }
     
     if (m_timer->isActive()) {
@@ -149,4 +164,26 @@ void DolphinViewAutoScroller::stopAutoScroll()
     m_scrollInc = 0;
 }
 
+void DolphinViewAutoScroller::calculateScrollIncrement(int cursorPos, int rangeSize)
+{
+    const int minSpeed = 2;
+    const int maxSpeed = 32;
+    const int speedLimiter = 8;
+    const int autoScrollBorder = 32;
+    
+    if (cursorPos < autoScrollBorder) {
+        m_scrollInc = -minSpeed + (cursorPos - autoScrollBorder) / speedLimiter;
+        if (m_scrollInc < -maxSpeed) {
+            m_scrollInc = -maxSpeed;
+        }
+    } else if (cursorPos > rangeSize - autoScrollBorder) {
+        m_scrollInc = minSpeed + (cursorPos - rangeSize + autoScrollBorder) / speedLimiter;
+        if (m_scrollInc > maxSpeed) {
+            m_scrollInc = maxSpeed;
+        }
+    } else {
+        m_scrollInc = 0;
+    }
+}
+
 #include "dolphinviewautoscroller.moc"