ui: scroll code horizontally to active sourcelocations

This commit is contained in:
Eberhard Graether
2018-07-22 19:40:01 +02:00
parent ad6f5c8727
commit 1db248a34e
7 changed files with 116 additions and 8 deletions
+95
View File
@@ -7,6 +7,7 @@
#include <QHBoxLayout>
#include <QMenu>
#include <QPainter>
#include <QPropertyAnimation>
#include <QPushButton>
#include <QScrollBar>
#include <QTextBlock>
@@ -372,6 +373,21 @@ Id QtCodeArea::getLocationIdOfFirstActiveScopeLocation(Id tokenId) const
return 0;
}
Id QtCodeArea::getLocationIdOfFirstHighlightedLocation() const
{
for (const Annotation& annotation : m_annotations)
{
if ((annotation.locationType == LocationType::LOCATION_TOKEN && annotation.isActive) ||
annotation.locationType == LocationType::LOCATION_FULLTEXT_SEARCH ||
annotation.locationType == LocationType::LOCATION_ERROR)
{
return annotation.locationId;
}
}
return 0;
}
size_t QtCodeArea::getActiveLocationCount() const
{
uint count = 0;
@@ -475,6 +491,85 @@ void QtCodeArea::clearScreenMatches()
}
}
void QtCodeArea::ensureLocationIdVisible(Id locationId, int parentWidth, bool animated)
{
QScrollBar* scrollBar = horizontalScrollBar();
if (!scrollBar || scrollBar->minimum() == scrollBar->maximum())
{
return;
}
const int oldValue = scrollBar->value();
scrollBar->setValue(scrollBar->minimum());
const Annotation* annotationPtr = nullptr;
for (const Annotation& annotation : m_annotations)
{
if (annotation.locationId == locationId)
{
annotationPtr = &annotation;
break;
}
}
if (!annotationPtr)
{
return;
}
std::vector<QRect> rects = getCursorRectsForAnnotation(*annotationPtr);
QRect boundingRect;
for (QRect rect : rects)
{
if (boundingRect.width())
{
boundingRect = boundingRect.united(rect);
}
else
{
boundingRect = rect;
}
}
if (!boundingRect.width())
{
return;
}
boundingRect.adjust(-50, 0, 50, 0);
int totalWidth = sizeHint().width() - lineNumberAreaWidth();
int visibleWidth = parentWidth - lineNumberAreaWidth();
int targetWidth = 0;
if (boundingRect.right() > visibleWidth)
{
targetWidth = boundingRect.right() - visibleWidth;
if (targetWidth > boundingRect.left())
{
targetWidth = boundingRect.left();
}
}
const double percentTarget = double(targetWidth) / (totalWidth - visibleWidth);
const int newValue = (scrollBar->maximum() - scrollBar->minimum()) * percentTarget + scrollBar->minimum();
if (animated && ApplicationSettings::getInstance()->getUseAnimations())
{
QPropertyAnimation* anim = new QPropertyAnimation(scrollBar, "value");
anim->setDuration(300);
anim->setStartValue(oldValue);
anim->setEndValue(newValue);
anim->setEasingCurve(QEasingCurve::InOutQuad);
anim->start();
}
else
{
scrollBar->setValue(newValue);
}
}
void QtCodeArea::resizeEvent(QResizeEvent *e)
{
QPlainTextEdit::resizeEvent(e);
+3
View File
@@ -79,6 +79,7 @@ public:
Id getLocationIdOfFirstActiveLocation(Id tokenId) const;
Id getLocationIdOfFirstActiveScopeLocation(Id tokenId) const;
Id getLocationIdOfFirstHighlightedLocation() const;
size_t getActiveLocationCount() const;
@@ -87,6 +88,8 @@ public:
void findScreenMatches(const std::wstring& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches);
void clearScreenMatches();
void ensureLocationIdVisible(Id locationId, int parentWidth, bool animated);
protected:
virtual void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
+4 -8
View File
@@ -101,20 +101,16 @@ QSize QtCodeField::sizeHint() const
int width = 0;
QFontMetrics fm = fontMetrics();
int maxTextSize = 0;
for (QTextBlock block = document()->firstBlock(); block.isValid(); block = block.next())
{
QRectF rect = blockBoundingGeometry(block);
height += rect.height();
{
int blockWidth = fm.boundingRect(
0, 0, 1000000, 1000000,
Qt::AlignLeft | Qt::AlignTop | Qt::TextExpandTabs, block.text(), tabStopWidth()).width();
int blockWidth = fm.boundingRect(
0, 0, 1000000, 1000000,
Qt::AlignLeft | Qt::AlignTop | Qt::TextExpandTabs, block.text(), tabStopWidth()).width();
width = std::max(blockWidth, width);
maxTextSize = block.text().size();
}
width = std::max(blockWidth, width);
}
return QSize(width + 1, height + 5);
@@ -228,6 +228,9 @@ bool QtCodeFileList::requestScroll(const FilePath& filePath, uint lineNumber, Id
}
ensureWidgetVisibleAnimated(m_filesArea, snippet, lineRect, animated, target);
snippet->ensureLocationIdVisible(locationId, animated);
return true;
}
@@ -197,6 +197,8 @@ bool QtCodeFileSingle::requestScroll(
double percentB = endLineNumber ? double(endLineNumber - 1) / m_area->getEndLineNumber() : 0.0f;
ensurePercentVisibleAnimated(percentA, percentB, animated, target);
m_area->ensureLocationIdVisible(locationId, width(), animated);
m_scrollRequested = true;
return true;
+7
View File
@@ -142,6 +142,8 @@ int QtCodeSnippet::lineNumberDigits() const
void QtCodeSnippet::updateCodeSnippet(const CodeSnippetParams& params)
{
m_codeArea->updateSourceLocations(params.locationFile);
ensureLocationIdVisible(m_codeArea->getLocationIdOfFirstHighlightedLocation(), false);
}
void QtCodeSnippet::updateLineNumberAreaWidthForDigits(int digits)
@@ -197,6 +199,11 @@ void QtCodeSnippet::findScreenMatches(const std::wstring& query, std::vector<std
m_codeArea->findScreenMatches(query, screenMatches);
}
void QtCodeSnippet::ensureLocationIdVisible(Id locationId, bool animated)
{
m_codeArea->ensureLocationIdVisible(locationId, width(), animated);
}
void QtCodeSnippet::clickedTitle()
{
if (m_titleId > 0)
+2
View File
@@ -54,6 +54,8 @@ public:
void findScreenMatches(const std::wstring& query, std::vector<std::pair<QtCodeArea*, Id>>* screenMatches);
void ensureLocationIdVisible(Id locationId, bool animated);
private slots:
void clickedTitle();
void clickedFooter();