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. 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;