Skip to content

Commit cce9994

Browse files
committed
Improve LBM/QML output buffer scroll behavior
Improves the LBM REPL and QMl output buffers in two ways: 1. Makes them only snap to the bottom when the view was already scrolled to the bottom. This makes is far easier to read output when connected to a device which prints stuff often. 2. Changes how the LBM REPL output is trimmed so that maintains the scroll position how you'd expect. The lack of this feature only became apparent after the first change.
1 parent 2ba978e commit cce9994

File tree

4 files changed

+57
-27
lines changed

4 files changed

+57
-27
lines changed

pages/pagelisp.cpp

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -202,29 +202,12 @@ void PageLisp::setVesc(VescInterface *vesc)
202202
ui->experimentPlot->setVesc(vesc);
203203

204204
connect(mVesc->commands(), &Commands::lispPrintReceived, [this](QString str) {
205-
ui->debugEdit->moveCursor(QTextCursor::End);
206-
ui->debugEdit->insertPlainText(str + "\n");
207-
ui->debugEdit->moveCursor(QTextCursor::End);
208-
205+
ui->debugEdit->doAtEndWithScroll([this, str](QTextCursor cursor) {
206+
cursor.insertText(str + "\n");
207+
});
208+
209209
int maxLines = QSettings().value("scripting/replMaxLines", 5000).toInt();
210-
int removeLines = maxLines / 5;
211-
212-
if (ui->debugEdit->document()->lineCount() > maxLines) {
213-
QString txt = ui->debugEdit->toPlainText();
214-
auto lines = txt.split("\n");
215-
if (lines.length() >= removeLines) {
216-
QString shorter;
217-
for (int i = removeLines;i < lines.length();i++) {
218-
shorter.append(lines.at(i));
219-
220-
if (i != (lines.length() - 1)) {
221-
shorter.append("\n");
222-
}
223-
}
224-
ui->debugEdit->setText(shorter);
225-
ui->debugEdit->moveCursor(QTextCursor::End);
226-
}
227-
}
210+
ui->debugEdit->trimKeepingLastLines(maxLines);
228211
});
229212

230213
connect(mVesc->commands(), &Commands::lispRunningResRx, [this](bool ok) {

pages/pagescripting.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,11 @@ void PageScripting::debugMsgRx(QtMsgType type, const QString msg)
226226
str = msg + "<br>";
227227
}
228228

229-
ui->debugEdit->moveCursor(QTextCursor::End);
230-
ui->debugEdit->insertHtml("<font color=\"#4d7fc4\">" +
231-
QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss: ") +
232-
"</font>" + str);
233-
ui->debugEdit->moveCursor(QTextCursor::End);
229+
ui->debugEdit->doAtEndWithScroll([this, str](QTextCursor cursor) {
230+
cursor.insertHtml("<font color=\"#4d7fc4\">" +
231+
QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss: ") +
232+
"</font>" + str);
233+
});
234234
}
235235

236236
void PageScripting::on_runButton_clicked()

widgets/vtextbrowser.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "vtextbrowser.h"
2121
#include <QDesktopServices>
2222
#include <QMouseEvent>
23+
#include <QScrollBar>
2324

2425
VTextBrowser::VTextBrowser(QWidget *parent)
2526
: QTextEdit(parent)
@@ -59,3 +60,21 @@ void VTextBrowser::mouseMoveEvent(QMouseEvent *e)
5960

6061
QTextEdit::mouseMoveEvent(e);
6162
}
63+
64+
void VTextBrowser::trimKeepingLastLines(int maxAmount)
65+
{
66+
int lines = document()->lineCount();
67+
int lines_to_remove = lines - maxAmount;
68+
if (lines_to_remove > 0) {
69+
int scroll_before = verticalScrollBar()->value();
70+
int scroll_max_before = verticalScrollBar()->maximum();
71+
72+
auto cursor = textCursor();
73+
cursor.movePosition(QTextCursor::Start);
74+
cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, lines_to_remove);
75+
cursor.removeSelectedText();
76+
77+
int scroll_max_delta = scroll_max_before - verticalScrollBar()->maximum();
78+
verticalScrollBar()->setValue(scroll_before - scroll_max_delta);
79+
}
80+
}

widgets/vtextbrowser.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define VTEXTBROWSER_H
2222

2323
#include <QTextEdit>
24+
#include <QScrollBar>
2425

2526
class VTextBrowser : public QTextEdit
2627
{
@@ -32,6 +33,33 @@ class VTextBrowser : public QTextEdit
3233
void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
3334
void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
3435
void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
36+
// Run `operation` with a cursor moved to the end of the document, making
37+
// sure to scroll to the bottom if the operation changed the content's
38+
// length and the view was at the bottom before.
39+
// `operation` should be a callable taking a single `QTextCursor`.
40+
template<typename F>
41+
void doAtEndWithScroll(const F operation) {
42+
// How far in pixels the scroll bar is allowed to be from the bottom
43+
// while still being snapped to the bottom.
44+
static const int bottom_margin = 30;
45+
46+
int scroll_before = verticalScrollBar()->value();
47+
bool was_at_end = scroll_before >= verticalScrollBar()->maximum() - bottom_margin;
48+
49+
auto cursor = textCursor();
50+
cursor.movePosition(QTextCursor::End);
51+
operation(cursor);
52+
53+
if (was_at_end) {
54+
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
55+
} else {
56+
verticalScrollBar()->setValue(scroll_before);
57+
}
58+
};
59+
// Remove the first lines so that only the last `maxAmount` of lines remain.
60+
// The scroll position is maintained so that the user doesn't perceive the
61+
// change.
62+
void trimKeepingLastLines(int maxAmount);
3563

3664
private:
3765
QString mLastAnchor;

0 commit comments

Comments
 (0)