From 8eae8881cc6c9f6eb4638fe510e46a2975c66c42 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 6 Nov 2017 15:42:05 +0100 Subject: [PATCH] Improve horizontal scrolling in the navigation views Because of QTBUG-3927 the tree views are scrolled completely to the left when selecting any item because it makes the header column visible. That is very annoying, because it makes items deep in the hierarchy hardly readable, even if you manually scrolled horizontally to see them. Scroll horizontally to make the actual item visible instead. Task-number: QTCREATORBUG-19204 Change-Id: Ic083236feae8892d210b9d2b1238f3c6b80a8cea Reviewed-by: Tobias Hunger --- src/libs/utils/navigationtreeview.cpp | 27 +++++++++++++++++++++++++++ src/libs/utils/navigationtreeview.h | 1 + 2 files changed, 28 insertions(+) diff --git a/src/libs/utils/navigationtreeview.cpp b/src/libs/utils/navigationtreeview.cpp index 87037356cc9..85490a9a17c 100644 --- a/src/libs/utils/navigationtreeview.cpp +++ b/src/libs/utils/navigationtreeview.cpp @@ -27,6 +27,7 @@ #include #include +#include /*! \class Utils::NavigationTreeView @@ -56,6 +57,32 @@ NavigationTreeView::NavigationTreeView(QWidget *parent) header()->setStretchLastSection(false); } +void NavigationTreeView::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint) +{ + // work around QTBUG-3927 + QScrollBar *hBar = horizontalScrollBar(); + int scrollX = hBar->value(); + const int viewportWidth = viewport()->width(); + const QRect itemRect = visualRect(index); + if (itemRect.x() - indentation() < 0) { + // scroll so left edge minus one indent of item is visible + scrollX += itemRect.x() - indentation(); + } else if (itemRect.right() > viewportWidth + && (viewportWidth - itemRect.x() < 3 * viewportWidth / 4)) { + // If right edge of item is not visible and left edge is "too far right", + // then move so it is either fully visible, or to the left edge. + // For this move the left edge one indent to the left, so the parent can potentially + // still be visible. + if (itemRect.width() + indentation() < viewportWidth) + scrollX += itemRect.right() - viewportWidth; + else + scrollX += itemRect.x() - indentation(); + } + scrollX = qBound(hBar->minimum(), scrollX, hBar->maximum()); + TreeView::scrollTo(index, hint); + hBar->setValue(scrollX); +} + // This is a workaround to stop Qt from redrawing the project tree every // time the user opens or closes a menu when it has focus. Would be nicer to // fix it in Qt. diff --git a/src/libs/utils/navigationtreeview.h b/src/libs/utils/navigationtreeview.h index 9a52d9bef50..a99539d51be 100644 --- a/src/libs/utils/navigationtreeview.h +++ b/src/libs/utils/navigationtreeview.h @@ -36,6 +36,7 @@ class QTCREATOR_UTILS_EXPORT NavigationTreeView : public TreeView Q_OBJECT public: explicit NavigationTreeView(QWidget *parent = 0); + void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override; protected: void focusInEvent(QFocusEvent *event) override;