Fix ResizingPlainTextEdit hiding text in some circumstances

In some scenarios - the exact reason is not known - the widget would
scroll to the very last row, which is always empty, and result in the
text cursor and the already entered text being moved above the displayed
edit area.

It could be fixed by manually scrolling back up (e.g. by attempting to
highlight text with the mouse), but the problem would reappear as soon
as new existing text was modified.

To work around this issue text wrapping was disabled and additional
height will be added for the horizontal scroll bar, if they are visible.

There are still some issues of the height randomly flickering in the
scenarios, which would previously result in the text no longer being
visible.
This commit is contained in:
WarmUpTill 2023-12-27 02:12:25 +01:00 committed by WarmUpTill
parent 4f0c8c4ab5
commit a412f2fd5e
2 changed files with 46 additions and 4 deletions

View File

@ -1,6 +1,7 @@
#include "resizing-text-edit.hpp"
#include <obs-module.h>
#include <obs-module-helper.hpp>
#include <QScrollBar>
#include <utility.hpp>
namespace advss {
@ -14,10 +15,12 @@ ResizingPlainTextEdit::ResizingPlainTextEdit(QWidget *parent,
_minLines(minLines),
_paddingLines(paddingLines)
{
setWordWrapMode(QTextOption::NoWrap);
QWidget::connect(this, SIGNAL(textChanged()), this,
SLOT(ResizeTexteditArea()));
QWidget::connect(this, SIGNAL(textChanged()), this,
SLOT(PreventExceedingMaxLength()));
verticalScrollBar()->installEventFilter(this);
}
int ResizingPlainTextEdit::maxLength()
@ -30,19 +33,35 @@ void ResizingPlainTextEdit::setMaxLength(int maxLength)
_maxLength = maxLength;
}
bool ResizingPlainTextEdit::eventFilter(QObject *obj, QEvent *event)
{
if (obj == horizontalScrollBar()) {
if (event->type() == QEvent::Show) {
AddHeightForScrollBar(true);
} else if (event->type() == QEvent::Hide) {
AddHeightForScrollBar(false);
}
}
return QPlainTextEdit::eventFilter(obj, event);
}
void ResizingPlainTextEdit::ResizeTexteditArea()
{
QFontMetrics f(font());
int rowHeight = f.lineSpacing();
int numLines = document()->blockCount();
int height = 0;
if (numLines + _paddingLines < _minLines) {
setFixedHeight(_minLines * rowHeight);
height = _minLines * rowHeight;
} else if (numLines + _paddingLines < _scrollAt) {
setFixedHeight((numLines + _paddingLines) * rowHeight);
height = (numLines + _paddingLines) * rowHeight;
} else {
setFixedHeight(_scrollAt * rowHeight);
height = _scrollAt * rowHeight;
}
setFixedHeight(height + _hScrollBarAddedHeight);
adjustSize();
updateGeometry();
}
@ -62,4 +81,21 @@ void ResizingPlainTextEdit::PreventExceedingMaxLength()
}
}
void ResizingPlainTextEdit::AddHeightForScrollBar(bool addHeight)
{
if (!addHeight) {
setFixedHeight(height() - _hScrollBarAddedHeight);
_hScrollBarAddedHeight = 0;
return;
}
// Check if we have already added space for the scroll bar
if (_hScrollBarAddedHeight > 0) {
return;
}
_hScrollBarAddedHeight = verticalScrollBar()->height();
setFixedHeight(height() + _hScrollBarAddedHeight);
}
} // namespace advss

View File

@ -13,15 +13,21 @@ public:
int maxLength();
void setMaxLength(int maxLength);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
private slots:
void ResizeTexteditArea();
void PreventExceedingMaxLength();
private:
void AddHeightForScrollBar(bool addHeight);
const int _scrollAt;
const int _minLines;
const int _paddingLines;
int _maxLength = -1;
int _hScrollBarAddedHeight = 0;
};
} // namespace advss