HAL
code_editor_minimap.cpp
Go to the documentation of this file.
2 
5 
6 #include <QPainter>
7 #include <QStyleOption>
8 #include <QTextBlock>
9 
10 #include <cmath>
11 #include <math.h>
12 
13 #include <QDebug>
14 namespace hal
15 {
17  : QWidget(editor), mEditor(editor), mDocument(new QTextDocument()), mScrollbar(new MinimapScrollbar(this)), mDocumentHeight(0), mOffset(0)
18  {
21 
22  mDocument->setDocumentMargin(0);
23  mScrollbar->show();
24 
25  repolish();
26  }
27 
29  {
30  return mScrollbar;
31  }
32 
34  {
35  return mDocument;
36  }
37 
38  void CodeEditorMinimap::adjustSliderHeight(int viewport_height)
39  {
40  Q_UNUSED(viewport_height);
41 
42  qDebug() << "editor " << mEditor->document()->documentLayout()->documentSize().height();
43  qDebug() << "mini " << mDocument->documentLayout()->documentSize().height();
44 
45  qreal ratio = mEditor->document()->documentLayout()->documentSize().height() / mDocument->documentLayout()->documentSize().height(); // UNEXPECTED RESULT, MAKES NO SENSE
46 
47  mScrollbar->setSliderHeight(std::round(mEditor->viewport()->contentsRect().height() * ratio));
48  }
49 
51  {
52  mScrollbar->setSliderHeight(std::round(ratio * mDocument->documentLayout()->blockBoundingRect(mDocument->firstBlock()).height()));
53  resizeScrollbar();
54  }
55 
56  void CodeEditorMinimap::adjustSliderHeight(int first_visible_block, int last_visible_block)
57  {
58  qDebug() << "first block: " + QString::number(first_visible_block);
59  qDebug() << "last block: " + QString::number(last_visible_block);
60 
61  qreal top = mDocument->documentLayout()->blockBoundingRect(mDocument->findBlockByNumber(first_visible_block)).top();
62  qreal bottom = mDocument->documentLayout()->blockBoundingRect(mDocument->findBlockByNumber(last_visible_block)).bottom();
63 
64  qDebug() << "top: " + QString::number(top);
65  qDebug() << "bottom: " + QString::number(bottom);
66 
67  mScrollbar->setSliderHeight(std::round(bottom - top));
68  }
69 
71  {
72  mDocumentHeight = std::ceil(new_size.height());
73  resizeScrollbar();
74  }
75 
76  void CodeEditorMinimap::handleContentsChange(int position, int chars_removed, int chars_added)
77  {
78  QTextCursor cursor = QTextCursor(mDocument);
79  cursor.setPosition(position);
80 
81  if (chars_removed)
82  {
83  cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, chars_removed);
84  cursor.removeSelectedText();
85  }
86 
87  if (chars_added)
88  cursor.insertText(mEditor->document()->toPlainText().mid(position, chars_added));
89  }
90 
92  {
93  Q_UNUSED(event)
94 
95  QStyleOption opt;
96  opt.init(this);
97  QPainter painter(this);
98  style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
99 
100  painter.setClipping(true);
101  painter.setClipRect(rect());
102 
104  ctx.palette.setColor(QPalette::Text, palette().text().color());
105 
106  if (mDocumentHeight > height())
107  {
108  int block_number = mEditor->first_visible_block();
109  int sliderPosition = mScrollbar->sliderPosition();
110  mOffset = mDocument->documentLayout()->blockBoundingRect(mDocument->findBlockByNumber(block_number)).top() - sliderPosition;
111  painter.translate(0, -mOffset);
112 
113  ctx.clip = QRectF(0, mOffset, width(), height());
114  }
115 
116  mDocument->documentLayout()->draw(&painter, ctx);
117  }
118 
120  {
121  Q_UNUSED(event)
122 
123  resizeScrollbar();
124  }
125 
127  {
128  int position = mDocument->documentLayout()->hitTest(QPointF(event->pos().x(), event->pos().y() + mOffset), Qt::FuzzyHit);
129  QTextCursor cursor(mDocument);
130  cursor.setPosition(position);
131  mEditor->centerOnLine(cursor.blockNumber());
132  }
133 
135  {
136  mEditor->handleWheelEvent(event);
137  }
138 
139  void CodeEditorMinimap::resizeScrollbar()
140  {
141  if (mDocumentHeight < height())
142  mScrollbar->resize(width(), std::max(mScrollbar->sliderHeight(), mDocumentHeight));
143  else
144  mScrollbar->resize(width(), height());
145  }
146 
148  {
149  QStyle* s = style();
150 
151  s->unpolish(this);
152  s->polish(this);
153 
154  mDocument->setDefaultFont(font());
155  }
156 }
A plain text edit widget that is intended for editing code.
Definition: code_editor.h:52
void centerOnLine(const int number)
int first_visible_block()
void handleWheelEvent(QWheelEvent *event)
void mousePressEvent(QMouseEvent *event) override
void handleContentsChange(int position, int chars_removed, int chars_added)
void adjustSliderHeight(int viewport_height)
void wheelEvent(QWheelEvent *event) override
void handleDocumentSizeChanged(const QSizeF &new_size)
void paintEvent(QPaintEvent *event) override
MinimapScrollbar * scrollbar()
CodeEditorMinimap(CodeEditor *editor)
void resizeEvent(QResizeEvent *event) override
The scrollbar of the CodeEditorMinimap.
void setSliderHeight(const int height)
QWidget * viewport() const const
virtual QRectF blockBoundingRect(const QTextBlock &block) const const=0
virtual QSizeF documentSize() const const=0
void documentSizeChanged(const QSizeF &newSize)
virtual void draw(QPainter *painter, const QAbstractTextDocumentLayout::PaintContext &context)=0
virtual int hitTest(const QPointF &point, Qt::HitTestAccuracy accuracy) const const=0
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
void setClipping(bool enable)
void translate(const QPointF &offset)
QTextDocument * document() const const
int height() const const
qreal bottom() const const
qreal height() const const
qreal top() const const
qreal height() const const
QString mid(int position, int n) const const
QString number(int n, int base)
virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
virtual void polish(QWidget *widget)
virtual void unpolish(QWidget *widget)
void init(const QWidget *widget)
FuzzyHit
void contentsChange(int position, int charsRemoved, int charsAdded)
QAbstractTextDocumentLayout * documentLayout() const const
void setDocumentMargin(qreal margin)
QTextBlock findBlockByNumber(int blockNumber) const const
QTextBlock firstBlock() const const
void setDefaultFont(const QFont &font)
QString toPlainText() const const
QRect contentsRect() const const
virtual bool event(QEvent *event) override
void resize(int w, int h)
void show()
QStyle * style() const const