95 lines
2.8 KiB
C++
95 lines
2.8 KiB
C++
// QCodeEditor
|
|
#include "QLineNumberArea.hpp"
|
|
#include "QCodeEditor.hpp"
|
|
#include "QSyntaxStyle.hpp"
|
|
|
|
// Qt
|
|
#include <QAbstractTextDocumentLayout>
|
|
#include <QPaintEvent>
|
|
#include <QPainter>
|
|
#include <QScrollBar>
|
|
#include <QTextBlock>
|
|
#include <QTextEdit>
|
|
|
|
QLineNumberArea::QLineNumberArea(QCodeEditor *parent)
|
|
: QWidget(parent), m_syntaxStyle(nullptr), m_codeEditParent(parent) {}
|
|
|
|
QSize QLineNumberArea::sizeHint() const {
|
|
if (m_codeEditParent == nullptr) {
|
|
return QWidget::sizeHint();
|
|
}
|
|
|
|
// Calculating width
|
|
int digits = 1;
|
|
int max = qMax(1, m_codeEditParent->document()->blockCount());
|
|
while (max >= 10) {
|
|
max /= 10;
|
|
++digits;
|
|
}
|
|
|
|
#if QT_VERSION >= 0x050B00
|
|
int space =
|
|
13 + m_codeEditParent->fontMetrics().horizontalAdvance(QLatin1Char('9')) *
|
|
digits;
|
|
#else
|
|
int space =
|
|
13 + m_codeEditParent->fontMetrics().width(QLatin1Char('9')) * digits;
|
|
#endif
|
|
|
|
return {space, 0};
|
|
}
|
|
|
|
void QLineNumberArea::setSyntaxStyle(QSyntaxStyle *style) {
|
|
m_syntaxStyle = style;
|
|
}
|
|
|
|
QSyntaxStyle *QLineNumberArea::syntaxStyle() const { return m_syntaxStyle; }
|
|
|
|
void QLineNumberArea::paintEvent(QPaintEvent *event) {
|
|
QPainter painter(this);
|
|
|
|
// Clearing rect to update
|
|
painter.fillRect(event->rect(),
|
|
m_syntaxStyle->getFormat("Text").background().color());
|
|
|
|
auto blockNumber = m_codeEditParent->getFirstVisibleBlock();
|
|
auto block = m_codeEditParent->document()->findBlockByNumber(blockNumber);
|
|
auto top = (int)m_codeEditParent->document()
|
|
->documentLayout()
|
|
->blockBoundingRect(block)
|
|
.translated(0, -m_codeEditParent->verticalScrollBar()->value())
|
|
.top();
|
|
auto bottom = top + (int)m_codeEditParent->document()
|
|
->documentLayout()
|
|
->blockBoundingRect(block)
|
|
.height();
|
|
|
|
auto currentLine =
|
|
m_syntaxStyle->getFormat("CurrentLineNumber").foreground().color();
|
|
auto otherLines = m_syntaxStyle->getFormat("LineNumber").foreground().color();
|
|
|
|
painter.setFont(m_codeEditParent->font());
|
|
|
|
while (block.isValid() && top <= event->rect().bottom()) {
|
|
if (block.isVisible() && bottom >= event->rect().top()) {
|
|
QString number = QString::number(blockNumber + 1);
|
|
|
|
auto isCurrentLine =
|
|
m_codeEditParent->textCursor().blockNumber() == blockNumber;
|
|
painter.setPen(isCurrentLine ? currentLine : otherLines);
|
|
|
|
painter.drawText(-5, top, sizeHint().width(),
|
|
m_codeEditParent->fontMetrics().height(), Qt::AlignRight,
|
|
number);
|
|
}
|
|
|
|
block = block.next();
|
|
top = bottom;
|
|
bottom = top + (int)m_codeEditParent->document()
|
|
->documentLayout()
|
|
->blockBoundingRect(block)
|
|
.height();
|
|
++blockNumber;
|
|
}
|
|
}
|