From 2ba978ea41f88d7ae2bf03b1dfe9b7e90391d577 Mon Sep 17 00:00:00 2001 From: laxsjo Date: Tue, 29 Jul 2025 18:42:33 +0200 Subject: [PATCH 1/2] Add build instructions to README.md --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index fa1d3178c..211d4e088 100644 --- a/README.md +++ b/README.md @@ -31,3 +31,46 @@ If you have custom hardware and you want to add support for it in the official r 1) Go to https://github.com/vedderb/bldc and use the github fork function. 2) Make your changes, test them and make a pull request to the main repository. 3) If the pull request gets accepted your hardware will become part of the next official release. It will show up in the binary beta typically after a few days and in the stable version the next time a stable release is made. + +## Development + +**Note:** These instructions build VESC Tool without the BLDC firmwares bundled. + +### Linux + +Make sure that the required dependencies are installed. There is some advice in the [build_lin](./build_lin) file's comments. If you have Nix installed see below. + +```shell +qmake -config release "CONFIG += release_lin build_original exclude_fw" +make -j8 +./build/lin/vesc_tool_6.06 +``` + +### Nix + +The most easy way to build and run VESC Tool is to just run the provided program: + +```shell +nix run +``` + +This will rebuild the program from scratch on each invokation. To enter a build environment with the dependencies installed for building it manually with QMake, run + +```shell +nix develop +``` + +Then follow the normal build instructions for Linux. + +**Note:** The Nix flake's outputs currently only supports x86 Linux. + +### Starting QT Creator in Nix + +QT Creator allows you to easily build and run the project. It also allows you to edit the page UIs with it's graphical editor. To run it using Nix simply start QT Creator from a shell with the build dependencies: + +```shell +nix develop +nix run nixpkgs#qtcreator +``` + +This makes sure that QT Creator has access to the required dependencies. From cce999478f7f697c07be930bfc6b714ab2405f34 Mon Sep 17 00:00:00 2001 From: laxsjo Date: Tue, 29 Jul 2025 18:50:41 +0200 Subject: [PATCH 2/2] 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. --- pages/pagelisp.cpp | 27 +++++---------------------- pages/pagescripting.cpp | 10 +++++----- widgets/vtextbrowser.cpp | 19 +++++++++++++++++++ widgets/vtextbrowser.h | 28 ++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/pages/pagelisp.cpp b/pages/pagelisp.cpp index 70ec9e713..31156d0be 100644 --- a/pages/pagelisp.cpp +++ b/pages/pagelisp.cpp @@ -202,29 +202,12 @@ void PageLisp::setVesc(VescInterface *vesc) ui->experimentPlot->setVesc(vesc); connect(mVesc->commands(), &Commands::lispPrintReceived, [this](QString str) { - ui->debugEdit->moveCursor(QTextCursor::End); - ui->debugEdit->insertPlainText(str + "\n"); - ui->debugEdit->moveCursor(QTextCursor::End); - + ui->debugEdit->doAtEndWithScroll([this, str](QTextCursor cursor) { + cursor.insertText(str + "\n"); + }); + int maxLines = QSettings().value("scripting/replMaxLines", 5000).toInt(); - int removeLines = maxLines / 5; - - if (ui->debugEdit->document()->lineCount() > maxLines) { - QString txt = ui->debugEdit->toPlainText(); - auto lines = txt.split("\n"); - if (lines.length() >= removeLines) { - QString shorter; - for (int i = removeLines;i < lines.length();i++) { - shorter.append(lines.at(i)); - - if (i != (lines.length() - 1)) { - shorter.append("\n"); - } - } - ui->debugEdit->setText(shorter); - ui->debugEdit->moveCursor(QTextCursor::End); - } - } + ui->debugEdit->trimKeepingLastLines(maxLines); }); connect(mVesc->commands(), &Commands::lispRunningResRx, [this](bool ok) { diff --git a/pages/pagescripting.cpp b/pages/pagescripting.cpp index 1b08b82c7..6f9d79a28 100755 --- a/pages/pagescripting.cpp +++ b/pages/pagescripting.cpp @@ -226,11 +226,11 @@ void PageScripting::debugMsgRx(QtMsgType type, const QString msg) str = msg + "
"; } - ui->debugEdit->moveCursor(QTextCursor::End); - ui->debugEdit->insertHtml("" + - QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss: ") + - "" + str); - ui->debugEdit->moveCursor(QTextCursor::End); + ui->debugEdit->doAtEndWithScroll([this, str](QTextCursor cursor) { + cursor.insertHtml("" + + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss: ") + + "" + str); + }); } void PageScripting::on_runButton_clicked() diff --git a/widgets/vtextbrowser.cpp b/widgets/vtextbrowser.cpp index 0f183fed5..2240008ad 100644 --- a/widgets/vtextbrowser.cpp +++ b/widgets/vtextbrowser.cpp @@ -20,6 +20,7 @@ #include "vtextbrowser.h" #include #include +#include VTextBrowser::VTextBrowser(QWidget *parent) : QTextEdit(parent) @@ -59,3 +60,21 @@ void VTextBrowser::mouseMoveEvent(QMouseEvent *e) QTextEdit::mouseMoveEvent(e); } + +void VTextBrowser::trimKeepingLastLines(int maxAmount) +{ + int lines = document()->lineCount(); + int lines_to_remove = lines - maxAmount; + if (lines_to_remove > 0) { + int scroll_before = verticalScrollBar()->value(); + int scroll_max_before = verticalScrollBar()->maximum(); + + auto cursor = textCursor(); + cursor.movePosition(QTextCursor::Start); + cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, lines_to_remove); + cursor.removeSelectedText(); + + int scroll_max_delta = scroll_max_before - verticalScrollBar()->maximum(); + verticalScrollBar()->setValue(scroll_before - scroll_max_delta); + } +} diff --git a/widgets/vtextbrowser.h b/widgets/vtextbrowser.h index 3860dd814..eeb800b2a 100644 --- a/widgets/vtextbrowser.h +++ b/widgets/vtextbrowser.h @@ -21,6 +21,7 @@ #define VTEXTBROWSER_H #include +#include class VTextBrowser : public QTextEdit { @@ -32,6 +33,33 @@ class VTextBrowser : public QTextEdit void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; + // Run `operation` with a cursor moved to the end of the document, making + // sure to scroll to the bottom if the operation changed the content's + // length and the view was at the bottom before. + // `operation` should be a callable taking a single `QTextCursor`. + template + void doAtEndWithScroll(const F operation) { + // How far in pixels the scroll bar is allowed to be from the bottom + // while still being snapped to the bottom. + static const int bottom_margin = 30; + + int scroll_before = verticalScrollBar()->value(); + bool was_at_end = scroll_before >= verticalScrollBar()->maximum() - bottom_margin; + + auto cursor = textCursor(); + cursor.movePosition(QTextCursor::End); + operation(cursor); + + if (was_at_end) { + verticalScrollBar()->setValue(verticalScrollBar()->maximum()); + } else { + verticalScrollBar()->setValue(scroll_before); + } + }; + // Remove the first lines so that only the last `maxAmount` of lines remain. + // The scroll position is maintained so that the user doesn't perceive the + // change. + void trimKeepingLastLines(int maxAmount); private: QString mLastAnchor;