Files
Sourcetrail/src/lib_gui/qt/element/QtCodeNavigateable.cpp
T
Eberhard Graether bfa43df491 ui: switch to single file mode with snippet maximize
* switch back to snippet view with snippet button in file title bar
* use new title bar widget in single view as well
* restore view mode on undo, store current view mode for every message id (added id to message)
* treat view mode switch as adapt message on undo stack
* fixed crash after snippet expansion
* fixed hatching in file title not shown
2017-12-20 20:40:38 +01:00

170 lines
3.9 KiB
C++

#include "qt/element/QtCodeNavigateable.h"
#include <QPropertyAnimation>
#include <QScrollArea>
#include <QScrollBar>
#include "settings/ApplicationSettings.h"
QtCodeNavigateable::~QtCodeNavigateable()
{
}
void QtCodeNavigateable::ensureWidgetVisibleAnimated(
const QWidget* parentWidget, const QWidget *childWidget, QRectF rect, bool animated, ScrollTarget target)
{
QAbstractScrollArea* area = getScrollArea();
if (!area || !parentWidget->isAncestorOf(childWidget))
{
return;
}
QRect focusRect = getFocusRectForWidget(childWidget, parentWidget);
const QRect visibleRect(-parentWidget->pos(), area->viewport()->size());
if (rect.height() > 0)
{
focusRect = QRect(childWidget->mapTo(parentWidget, rect.topLeft().toPoint()), rect.size().toSize());
if (focusRect.height() < 100)
{
focusRect.adjust(0, 0, 0, 100);
}
}
// scroll to top if widget is bigger than view
if (focusRect.height() > visibleRect.height())
{
target = SCROLL_TOP;
}
int value = 0;
switch (target)
{
case SCROLL_VISIBLE:
if (focusRect.top() > visibleRect.top() && focusRect.bottom() < visibleRect.bottom())
{
return;
}
case SCROLL_CENTER:
value = focusRect.center().y() - visibleRect.center().y();
if (abs(value) < 50)
{
value = 0;
}
break;
case SCROLL_TOP:
value = focusRect.top() - visibleRect.top() - 50;
break;
}
QScrollBar* scrollBar = area->verticalScrollBar();
if (scrollBar && value)
{
if (animated && ApplicationSettings::getInstance()->getUseAnimations())
{
QPropertyAnimation* anim = new QPropertyAnimation(scrollBar, "value");
anim->setDuration(300);
anim->setStartValue(scrollBar->value());
anim->setEndValue(scrollBar->value() + value);
anim->setEasingCurve(QEasingCurve::InOutQuad);
anim->start();
}
else
{
scrollBar->setValue(scrollBar->value() + value);
}
}
}
void QtCodeNavigateable::ensurePercentVisibleAnimated(double percentA, double percentB, bool animated, ScrollTarget target)
{
QAbstractScrollArea* area = getScrollArea();
if (!area)
{
return;
}
int totalHeight = area->sizeHint().height();
int visibleHeight = area->viewport()->height();
int scrollableHeight = totalHeight - visibleHeight;
if (scrollableHeight < 0)
{
return;
}
QScrollBar* scrollBar = area->verticalScrollBar();
double scrollFactor = double(scrollBar->maximum()) / scrollableHeight;
int visibleY = double(scrollBar->value()) / scrollFactor;
int scrollY = totalHeight * percentA;
int rectHeight = percentB ? (totalHeight * percentB) - scrollY : 0;
if (rectHeight > visibleHeight)
{
target = SCROLL_TOP;
}
switch (target)
{
case SCROLL_VISIBLE:
if (scrollY > visibleY && scrollY + rectHeight < visibleY + scrollableHeight)
{
return;
}
case SCROLL_CENTER:
if (rectHeight < visibleHeight / 2)
{
scrollY -= visibleHeight / 4;
}
else
{
scrollY += rectHeight / 2 - visibleHeight / 2;
}
break;
case SCROLL_TOP:
scrollY -= 20;
break;
}
int value = scrollY * scrollFactor;
int diff = value - scrollBar->value();
if (diff > 5 || diff < -5)
{
if (animated && ApplicationSettings::getInstance()->getUseAnimations())
{
QPropertyAnimation* anim = new QPropertyAnimation(scrollBar, "value");
anim->setDuration(300);
anim->setStartValue(scrollBar->value());
anim->setEndValue(value);
anim->setEasingCurve(QEasingCurve::InOutQuad);
anim->start();
}
else
{
scrollBar->setValue(value);
}
}
}
QRect QtCodeNavigateable::getFocusRectForWidget(const QWidget* childWidget, const QWidget* parentWidget) const
{
const QRect microFocus = childWidget->inputMethodQuery(Qt::ImCursorRectangle).toRect();
const QRect defaultMicroFocus = childWidget->QWidget::inputMethodQuery(Qt::ImCursorRectangle).toRect();
if (microFocus != defaultMicroFocus)
{
return QRect(childWidget->mapTo(parentWidget, microFocus.topLeft()), microFocus.size());
}
else
{
return QRect(childWidget->mapTo(parentWidget, QPoint(0, 0)), childWidget->size());
}
}