#include "GutterPainter.h" #include "CodeEditor.h" GutterPainter::GutterPainter(CodeEditor *editor, QPaintEvent *event) : editor(editor) , painter(editor->gutterArea) , event(event) , fontMetrics(editor->fontMetrics()) , colorTheme(GetColorTheme()) { } void GutterPainter::Paint() { painter.fillRect(event->rect(), colorTheme.gutterBackground); 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); 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(); }