pgLab/pglab/codeeditor/GutterPainter.cpp

73 lines
2.3 KiB
C++
Raw Permalink Normal View History

2022-04-10 10:29:40 +02:00
#include "GutterPainter.h"
#include "CodeEditor.h"
GutterPainter::GutterPainter(CodeEditor *editor, QPaintEvent *event)
: editor(editor)
, painter(editor->gutterArea)
, event(event)
, fontMetrics(editor->fontMetrics())
, colorTheme(GetColorTheme())
{
}
2022-04-10 10:29:40 +02:00
void GutterPainter::Paint()
{
painter.fillRect(event->rect(), colorTheme.gutterBackground);
2022-04-10 10:29:40 +02:00
LoopState loopState(editor);
// We will now loop through all visible lines and paint the line numbers in the
// extra area for each line. Notice that in a plain text edit each line will
// consist of one QTextBlock; though, if line wrapping is enabled, a line may span
// several rows in the text edit's viewport.
//
// We get the top and bottom y-coordinate of the first text block, and adjust these
// values by the height of the current text block in each iteration in the loop.
while (loopState.block.isValid() && loopState.top <= event->rect().bottom())
{
if (loopState.block.isVisible() && loopState.bottom >= event->rect().top())
{
drawLineNumber(loopState);
if (editor->lineHasError(loopState.blockNumber()))
drawGutterErrorMarker(loopState);
}
loopState.advanceToNextLine();
}
}
void GutterPainter::drawLineNumber(const LoopState &loopState)
{
QString number = QString::number(loopState.blockNumber() + 1);
painter.setPen(colorTheme.lineNumber);
2022-04-10 10:29:40 +02:00
painter.drawText(0, loopState.top, editor->gutterArea->width(), fontMetrics.height(),
Qt::AlignRight, number);
}
void GutterPainter::drawGutterErrorMarker(const LoopState &loopState)
{
int s = fontMetrics.height() - 8;
painter.setBrush(QBrush(Qt::red));
painter.drawEllipse(4, loopState.top + 4, s, s);
}
GutterPainter::LoopState::LoopState(CodeEditor *editor)
: editor(editor)
, block(editor->firstVisibleBlock())
, top((int) editor->blockBoundingGeometry(block).translated(editor->contentOffset()).top())
, bottom(top + (int) editor->blockBoundingRect(block).height())
{}
int GutterPainter::LoopState::blockNumber() const
{
return block.blockNumber();
}
void GutterPainter::LoopState::advanceToNextLine()
{
block = block.next();
top = bottom;
bottom = top + (int) editor->blockBoundingRect(block).height();
}