Improve terminal theming, cursor UX, and size negotiation
This commit is contained in:
@@ -3,7 +3,11 @@
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QColor>
|
||||
#include <QFocusEvent>
|
||||
#include <QFontMetrics>
|
||||
#include <QKeyEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QTimer>
|
||||
#include <QTextCursor>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -21,13 +25,21 @@ TerminalView::TerminalView(QWidget* parent)
|
||||
m_hasFgColor(false),
|
||||
m_hasBgColor(false)
|
||||
{
|
||||
setReadOnly(true);
|
||||
setReadOnly(false);
|
||||
setUndoRedoEnabled(false);
|
||||
document()->setMaximumBlockCount(4000);
|
||||
setAcceptRichText(false);
|
||||
setLineWrapMode(QTextEdit::NoWrap);
|
||||
setContextMenuPolicy(Qt::NoContextMenu);
|
||||
setCursorWidth(2);
|
||||
document()->setMaximumBlockCount(4000);
|
||||
|
||||
applyThemePalette(paletteByName(QStringLiteral("Dark")));
|
||||
resetSgrState();
|
||||
|
||||
QTimer::singleShot(0, this, [this]() {
|
||||
moveCursor(QTextCursor::End);
|
||||
emitTerminalSize();
|
||||
});
|
||||
}
|
||||
|
||||
QStringList TerminalView::themeNames()
|
||||
@@ -123,8 +135,19 @@ void TerminalView::keyPressEvent(QKeyEvent* event)
|
||||
return;
|
||||
}
|
||||
|
||||
moveCursor(QTextCursor::End);
|
||||
|
||||
const Qt::KeyboardModifiers modifiers = event->modifiers();
|
||||
|
||||
if (modifiers == (Qt::ControlModifier | Qt::ShiftModifier)
|
||||
&& event->key() == Qt::Key_C) {
|
||||
const QString selected = textCursor().selectedText();
|
||||
if (!selected.isEmpty()) {
|
||||
QApplication::clipboard()->setText(selected);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (modifiers == Qt::ControlModifier) {
|
||||
switch (event->key()) {
|
||||
case Qt::Key_C:
|
||||
@@ -180,8 +203,18 @@ void TerminalView::keyPressEvent(QKeyEvent* event)
|
||||
emit inputGenerated(text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QTextEdit::keyPressEvent(event);
|
||||
void TerminalView::focusInEvent(QFocusEvent* event)
|
||||
{
|
||||
QTextEdit::focusInEvent(event);
|
||||
moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
void TerminalView::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QTextEdit::resizeEvent(event);
|
||||
emitTerminalSize();
|
||||
}
|
||||
|
||||
TerminalView::ThemePalette TerminalView::paletteByName(const QString& themeName)
|
||||
@@ -190,23 +223,23 @@ TerminalView::ThemePalette TerminalView::paletteByName(const QString& themeName)
|
||||
|
||||
if (theme == QStringLiteral("light")) {
|
||||
return ThemePalette{QStringLiteral("Light"),
|
||||
QColor(QStringLiteral("#fafafa")),
|
||||
QColor(QStringLiteral("#202124")),
|
||||
QColor(QStringLiteral("#ececec")),
|
||||
QColor(QStringLiteral("#000000")),
|
||||
{QColor(QStringLiteral("#000000")),
|
||||
QColor(QStringLiteral("#a31515")),
|
||||
QColor(QStringLiteral("#aa0000")),
|
||||
QColor(QStringLiteral("#008000")),
|
||||
QColor(QStringLiteral("#795e26")),
|
||||
QColor(QStringLiteral("#0000ff")),
|
||||
QColor(QStringLiteral("#af00db")),
|
||||
QColor(QStringLiteral("#0451a5")),
|
||||
QColor(QStringLiteral("#666666"))},
|
||||
{QColor(QStringLiteral("#7f7f7f")),
|
||||
QColor(QStringLiteral("#cd3131")),
|
||||
QColor(QStringLiteral("#14a10e")),
|
||||
QColor(QStringLiteral("#b5ba00")),
|
||||
QColor(QStringLiteral("#0451a5")),
|
||||
QColor(QStringLiteral("#bc05bc")),
|
||||
QColor(QStringLiteral("#0598bc")),
|
||||
QColor(QStringLiteral("#7a5f00")),
|
||||
QColor(QStringLiteral("#0033cc")),
|
||||
QColor(QStringLiteral("#8a00a8")),
|
||||
QColor(QStringLiteral("#005f87")),
|
||||
QColor(QStringLiteral("#333333"))},
|
||||
{QColor(QStringLiteral("#5c5c5c")),
|
||||
QColor(QStringLiteral("#d30000")),
|
||||
QColor(QStringLiteral("#00a000")),
|
||||
QColor(QStringLiteral("#9a7700")),
|
||||
QColor(QStringLiteral("#0055ff")),
|
||||
QColor(QStringLiteral("#b300db")),
|
||||
QColor(QStringLiteral("#007ea7")),
|
||||
QColor(QStringLiteral("#111111"))}};
|
||||
}
|
||||
|
||||
@@ -338,7 +371,7 @@ void TerminalView::handleSgrSequence(const QString& params)
|
||||
for (int i = 0; i < parts.size(); ++i) {
|
||||
const QString part = parts.at(i).trimmed();
|
||||
bool ok = false;
|
||||
int code = part.isEmpty() ? 0 : part.toInt(&ok);
|
||||
const int code = part.isEmpty() ? 0 : part.toInt(&ok);
|
||||
if (!ok && !part.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -399,7 +432,7 @@ void TerminalView::handleSgrSequence(const QString& params)
|
||||
if (mode == 5 && i + 2 < parts.size()) {
|
||||
const int index = parts.at(i + 2).toInt(&ok);
|
||||
if (ok) {
|
||||
QColor color = colorFrom256Index(index);
|
||||
const QColor color = colorFrom256Index(index);
|
||||
if (background) {
|
||||
m_bgColor = color;
|
||||
m_hasBgColor = true;
|
||||
@@ -466,3 +499,22 @@ QColor TerminalView::paletteColor(bool, int index, bool bright) const
|
||||
return bright ? m_palette.bright.at(static_cast<size_t>(safeIndex))
|
||||
: m_palette.normal.at(static_cast<size_t>(safeIndex));
|
||||
}
|
||||
|
||||
int TerminalView::terminalColumns() const
|
||||
{
|
||||
const QFontMetrics metrics(font());
|
||||
const int cellWidth = std::max(1, metrics.horizontalAdvance(QChar::fromLatin1('M')));
|
||||
return std::max(1, viewport()->width() / cellWidth);
|
||||
}
|
||||
|
||||
int TerminalView::terminalRows() const
|
||||
{
|
||||
const QFontMetrics metrics(font());
|
||||
const int cellHeight = std::max(1, metrics.lineSpacing());
|
||||
return std::max(1, viewport()->height() / cellHeight);
|
||||
}
|
||||
|
||||
void TerminalView::emitTerminalSize()
|
||||
{
|
||||
emit terminalSizeChanged(terminalColumns(), terminalRows());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user