Merge pull request #1538 from ada-tv/feature/dark-js-console
Some checks are pending
Master API-docs CI Build and Deploy / Build and deploy API-docs (push) Waiting to run
Master Doxygen CI Build and Deploy / Build and deploy Doxygen documentation (push) Waiting to run

Dark theme for JS console
This commit is contained in:
ksuprynowicz 2025-05-31 14:46:16 +02:00 committed by GitHub
commit 567b66c257
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 82 deletions

View file

@ -1,20 +0,0 @@
* {
font-family: Inconsolata, Lucida Console, Andale Mono, Monaco;
font-size: 14px;
}
#promptTextEdit {
color: #425d72;
}
#promptTextEdit:!enabled {
color: #7f7f7f;
}
#promptGutterLabel {
color: #a9bbc3;
}
#promptGutterLabel:!enabled {
color: #7f7f7f;
}

View file

@ -35,23 +35,10 @@ const int NO_CURRENT_HISTORY_COMMAND = -1;
const int MAX_HISTORY_SIZE = 256; const int MAX_HISTORY_SIZE = 256;
const QString HISTORY_FILENAME = "JSConsole.history.json"; const QString HISTORY_FILENAME = "JSConsole.history.json";
const QString COMMAND_STYLE = "color: #266a9b;";
const QString RESULT_SUCCESS_STYLE = "color: #677373;";
const QString RESULT_INFO_STYLE = "color: #223bd1;";
const QString RESULT_WARNING_STYLE = "color: #999922;";
const QString RESULT_ERROR_STYLE = "color: #d13b22;";
const QString GUTTER_PREVIOUS_COMMAND = "<span style=\"color: #57b8bb;\">&lt;</span>";
const QString GUTTER_ERROR = "<span style=\"color: #d13b22;\">X</span>";
const QString JSDOC_LINE_SEPARATOR = "\r"; const QString JSDOC_LINE_SEPARATOR = "\r";
const QString JSDOC_STYLE = const QString JSDOC_STYLE =
"<style type=\"text/css\"> \ "<style type=\"text/css\"> \
.code { \
font-family: Consolas, Monaco, 'Andale Mono', monospace \
} \
pre, code { \ pre, code { \
display: inline; \ display: inline; \
} \ } \
@ -144,7 +131,11 @@ JSConsole::JSConsole(QWidget* parent, const ScriptManagerPointer& scriptManager)
_currentCommandInHistory(NO_CURRENT_HISTORY_COMMAND), _currentCommandInHistory(NO_CURRENT_HISTORY_COMMAND),
_savedHistoryFilename(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + HISTORY_FILENAME), _savedHistoryFilename(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + HISTORY_FILENAME),
_commandHistory(_readLines(_savedHistoryFilename)), _commandHistory(_readLines(_savedHistoryFilename)),
_completer(new QCompleter(this)) { _completer(new QCompleter(this)),
_monospaceFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)),
// unfortunately we'll just have to use the first theme we get,
// because of the custom colored widgets that can't easily be recolored later
_lightTheme(!qApp->getDarkThemePreference()) {
readAPI(); readAPI();
@ -152,12 +143,14 @@ JSConsole::JSConsole(QWidget* parent, const ScriptManagerPointer& scriptManager)
_ui->promptTextEdit->setLineWrapMode(QTextEdit::NoWrap); _ui->promptTextEdit->setLineWrapMode(QTextEdit::NoWrap);
_ui->promptTextEdit->setWordWrapMode(QTextOption::NoWrap); _ui->promptTextEdit->setWordWrapMode(QTextOption::NoWrap);
_ui->promptTextEdit->installEventFilter(this); _ui->promptTextEdit->installEventFilter(this);
_ui->promptTextEdit->setFont(_monospaceFont);
QFile styleSheet(PathUtils::resourcesPath() + "styles/console.qss"); _ui->promptGutterLabel->setFont(_monospaceFont);
if (styleSheet.open(QIODevice::ReadOnly)) {
QDir::setCurrent(PathUtils::resourcesPath()); // to force the log to have the same background color as a text area
setStyleSheet(styleSheet.readAll()); QString styleSheet = "background-color:" + qApp->palette().base().color().name();
} _ui->scrollAreaWidgetContents->setStyleSheet(styleSheet);
_ui->logArea->setStyleSheet(styleSheet);
connect(_ui->scrollArea->verticalScrollBar(), &QScrollBar::rangeChanged, this, &JSConsole::scrollToBottom); connect(_ui->scrollArea->verticalScrollBar(), &QScrollBar::rangeChanged, this, &JSConsole::scrollToBottom);
connect(_ui->promptTextEdit, &QTextEdit::textChanged, this, &JSConsole::resizeTextInput); connect(_ui->promptTextEdit, &QTextEdit::textChanged, this, &JSConsole::resizeTextInput);
@ -177,6 +170,7 @@ JSConsole::JSConsole(QWidget* parent, const ScriptManagerPointer& scriptManager)
listView->setSelectionBehavior(QAbstractItemView::SelectRows); listView->setSelectionBehavior(QAbstractItemView::SelectRows);
listView->setSelectionMode(QAbstractItemView::SingleSelection); listView->setSelectionMode(QAbstractItemView::SingleSelection);
listView->setModelColumn(_completer->completionColumn()); listView->setModelColumn(_completer->completionColumn());
listView->setFont(_monospaceFont);
_completer->setPopup(listView); _completer->setPopup(listView);
_completer->popup()->installEventFilter(this); _completer->popup()->installEventFilter(this);
@ -350,7 +344,9 @@ void JSConsole::executeCommand(const QString& command) {
_ui->promptTextEdit->setDisabled(true); _ui->promptTextEdit->setDisabled(true);
appendMessage(">", "<span style='" + COMMAND_STYLE + "'>" + command.toHtmlEscaped() + "</span>"); QColor commandColor = _lightTheme ? QColorConstants::Svg::black : QColorConstants::Svg::white;
appendMessage(">", command, commandColor);
std::weak_ptr<ScriptManager> weakScriptManager = _scriptManager; std::weak_ptr<ScriptManager> weakScriptManager = _scriptManager;
auto consoleFileName = _consoleFileName; auto consoleFileName = _consoleFileName;
@ -379,34 +375,46 @@ void JSConsole::commandFinished() {
// V8TODO: // V8TODO:
//bool error = (_scriptManager->engine()->hasUncaughtException() || result.isError()); //bool error = (_scriptManager->engine()->hasUncaughtException() || result.isError());
//QString gutter = error ? GUTTER_ERROR : GUTTER_PREVIOUS_COMMAND;
//QString resultColor = error ? RESULT_ERROR_STYLE : RESULT_SUCCESS_STYLE; QColor color = _lightTheme ? QColorConstants::Svg::gray : QColorConstants::Svg::darkgray;
QString gutter = GUTTER_PREVIOUS_COMMAND;
QString resultColor = RESULT_SUCCESS_STYLE; appendMessage("<", result.toString(), color);
QString resultStr = "<span style='" + resultColor + "'>" + result.toString().toHtmlEscaped() + "</span>";
appendMessage(gutter, resultStr);
resetCurrentCommandHistory(); resetCurrentCommandHistory();
} }
void JSConsole::handleError(const QString& message, const QString& scriptName) { void JSConsole::handleError(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName); Q_UNUSED(scriptName);
appendMessage(GUTTER_ERROR, "<span style='" + RESULT_ERROR_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
QColor color = _lightTheme ? QColorConstants::Svg::maroon : QColorConstants::Svg::lightpink;
QColor bgColor = _lightTheme ? QColorConstants::Svg::lavenderblush : QColorConstants::Svg::darkred;
appendMessage("X", message, color, bgColor);
} }
void JSConsole::handlePrint(const QString& message, const QString& scriptName) { void JSConsole::handlePrint(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName); Q_UNUSED(scriptName);
appendMessage("", message);
QColor color = _lightTheme ? QColorConstants::Svg::black : QColorConstants::Svg::white;
appendMessage("", message, color);
} }
void JSConsole::handleInfo(const QString& message, const QString& scriptName) { void JSConsole::handleInfo(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName); Q_UNUSED(scriptName);
appendMessage("", "<span style='" + RESULT_INFO_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
QColor color = _lightTheme ? QColorConstants::Svg::steelblue : QColorConstants::Svg::paleturquoise;
appendMessage("", message, color);
} }
void JSConsole::handleWarning(const QString& message, const QString& scriptName) { void JSConsole::handleWarning(const QString& message, const QString& scriptName) {
Q_UNUSED(scriptName); Q_UNUSED(scriptName);
appendMessage("", "<span style='" + RESULT_WARNING_STYLE + "'>" + message.toHtmlEscaped() + "</span>");
QColor color = _lightTheme ? QColorConstants::Svg::olive : QColorConstants::Svg::lightyellow;
QColor bgColor = _lightTheme ? QColorConstants::Svg::lemonchiffon : QColorConstants::Svg::olive;
appendMessage("!", message, color, bgColor);
} }
void JSConsole::mouseReleaseEvent(QMouseEvent* event) { void JSConsole::mouseReleaseEvent(QMouseEvent* event) {
@ -580,7 +588,7 @@ void JSConsole::scrollToBottom() {
scrollBar->setValue(scrollBar->maximum()); scrollBar->setValue(scrollBar->maximum());
} }
void JSConsole::appendMessage(const QString& gutter, const QString& message) { void JSConsole::appendMessage(const QString& gutter, const QString& message, const QColor& fgColor, const QColor& bgColor) {
QWidget* logLine = new QWidget(_ui->logArea); QWidget* logLine = new QWidget(_ui->logArea);
QHBoxLayout* layout = new QHBoxLayout(logLine); QHBoxLayout* layout = new QHBoxLayout(logLine);
layout->setMargin(0); layout->setMargin(0);
@ -593,8 +601,8 @@ void JSConsole::appendMessage(const QString& gutter, const QString& message) {
gutterLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); gutterLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
messageLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); messageLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
gutterLabel->setStyleSheet("font-size: 14px; font-family: Inconsolata, Lucida Console, Andale Mono, Monaco;"); gutterLabel->setFont(_monospaceFont);
messageLabel->setStyleSheet("font-size: 14px; font-family: Inconsolata, Lucida Console, Andale Mono, Monaco;"); messageLabel->setFont(_monospaceFont);
gutterLabel->setText(gutter); gutterLabel->setText(gutter);
messageLabel->setText(message); messageLabel->setText(message);
@ -603,6 +611,14 @@ void JSConsole::appendMessage(const QString& gutter, const QString& message) {
layout->addWidget(messageLabel); layout->addWidget(messageLabel);
logLine->setLayout(layout); logLine->setLayout(layout);
QString style = "color:" + fgColor.name();
if (bgColor != Qt::transparent) {
style += ";background-color:" + bgColor.name();
}
logLine->setStyleSheet(style);
logLine->setAutoFillBackground(true);
layout->setAlignment(gutterLabel, Qt::AlignTop); layout->setAlignment(gutterLabel, Qt::AlignTop);
layout->setStretch(0, 0); layout->setStretch(0, 0);

View file

@ -65,7 +65,7 @@ private slots:
void highlightedCompletion(const QModelIndex& completion); void highlightedCompletion(const QModelIndex& completion);
private: private:
void appendMessage(const QString& gutter, const QString& message); void appendMessage(const QString& gutter, const QString& message, const QColor& fgColor, const QColor& bgColor = Qt::transparent);
void setToNextCommandInHistory(); void setToNextCommandInHistory();
void setToPreviousCommandInHistory(); void setToPreviousCommandInHistory();
void resetCurrentCommandHistory(); void resetCurrentCommandHistory();
@ -85,6 +85,8 @@ private:
QJsonArray _apiDocs; QJsonArray _apiDocs;
QCompleter* _completer; QCompleter* _completer;
QString _completerModule {""}; QString _completerModule {""};
QFont _monospaceFont;
bool _lightTheme;
}; };

View file

@ -13,9 +13,6 @@
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Dialog</string>
</property> </property>
<property name="styleSheet">
<string notr="true">QDialog { background: white; color: black }</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
@ -79,9 +76,6 @@
<height>205</height> <height>205</height>
</rect> </rect>
</property> </property>
<property name="styleSheet">
<string notr="true">background-color: white; color: black;</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing"> <property name="spacing">
<number>4</number> <number>4</number>
@ -130,9 +124,6 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="styleSheet">
<string notr="true">background-color: white; color: black;</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing"> <property name="spacing">
<number>4</number> <number>4</number>
@ -196,12 +187,6 @@
<height>23</height> <height>23</height>
</size> </size>
</property> </property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">padding: 0px 0 0 0;</string> <string notr="true">padding: 0px 0 0 0;</string>
</property> </property>
@ -221,15 +206,6 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="font">
<font>
<family>Inconsolata,Lucida Console,Andale Mono,Monaco,Courier New,monospace</family>
<pointsize>-1</pointsize>
</font>
</property>
<property name="textColor">
<color>black</color>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>