An attempt to improve input fields touch-screen support.
This commit is contained in:
parent
13e59e27eb
commit
e72b521618
2 changed files with 234 additions and 64 deletions
|
|
@ -976,6 +976,16 @@ protected:
|
|||
return outer()->paintEventInner(e);
|
||||
}
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override {
|
||||
return outer()->mousePressEventInner(e);
|
||||
}
|
||||
void mouseReleaseEvent(QMouseEvent *e) override {
|
||||
return outer()->mouseReleaseEventInner(e);
|
||||
}
|
||||
void mouseMoveEvent(QMouseEvent *e) override {
|
||||
return outer()->mouseMoveEventInner(e);
|
||||
}
|
||||
|
||||
bool canInsertFromMimeData(const QMimeData *source) const override {
|
||||
return outer()->canInsertFromMimeDataInner(source);
|
||||
}
|
||||
|
|
@ -1147,41 +1157,27 @@ bool FlatInput::eventHook(QEvent *e) {
|
|||
void FlatInput::touchEvent(QTouchEvent *e) {
|
||||
switch (e->type()) {
|
||||
case QEvent::TouchBegin: {
|
||||
if (_touchPress || e->touchPoints().isEmpty()) return;
|
||||
if (_touchPress || e->touchPoints().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
_touchTimer.start(QApplication::startDragTime());
|
||||
_touchPress = true;
|
||||
_touchMove = _touchRightButton = false;
|
||||
_touchMove = _touchRightButton = _mousePressedInTouch = false;
|
||||
_touchStart = e->touchPoints().cbegin()->screenPos().toPoint();
|
||||
} break;
|
||||
|
||||
case QEvent::TouchUpdate: {
|
||||
if (!_touchPress || e->touchPoints().isEmpty()) return;
|
||||
if (!_touchMove && (e->touchPoints().cbegin()->screenPos().toPoint() - _touchStart).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
_touchMove = true;
|
||||
if (!e->touchPoints().isEmpty()) {
|
||||
touchUpdate(e->touchPoints().cbegin()->screenPos().toPoint());
|
||||
}
|
||||
} break;
|
||||
|
||||
case QEvent::TouchEnd: {
|
||||
if (!_touchPress) return;
|
||||
auto weak = MakeWeak(this);
|
||||
if (!_touchMove && window()) {
|
||||
QPoint mapped(mapFromGlobal(_touchStart));
|
||||
|
||||
if (_touchRightButton) {
|
||||
QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart);
|
||||
contextMenuEvent(&contextEvent);
|
||||
} else {
|
||||
QGuiApplication::inputMethod()->show();
|
||||
}
|
||||
}
|
||||
if (weak) {
|
||||
_touchTimer.stop();
|
||||
_touchPress = _touchMove = _touchRightButton = false;
|
||||
}
|
||||
touchFinish();
|
||||
} break;
|
||||
|
||||
case QEvent::TouchCancel: {
|
||||
_touchPress = false;
|
||||
_touchPress = _mousePressedInTouch = false;
|
||||
_touchTimer.stop();
|
||||
} break;
|
||||
}
|
||||
|
|
@ -1323,6 +1319,64 @@ void FlatInput::inputMethodEvent(QInputMethodEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
void FlatInput::mousePressEvent(QMouseEvent *e) {
|
||||
if (_touchPress && e->button() == Qt::LeftButton) {
|
||||
_mousePressedInTouch = true;
|
||||
_touchStart = e->globalPos();
|
||||
}
|
||||
return QLineEdit::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void FlatInput::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (_mousePressedInTouch) {
|
||||
touchFinish();
|
||||
}
|
||||
return QLineEdit::mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
void FlatInput::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (_mousePressedInTouch) {
|
||||
touchUpdate(e->globalPos());
|
||||
}
|
||||
return QLineEdit::mouseMoveEvent(e);
|
||||
}
|
||||
|
||||
void FlatInput::touchUpdate(QPoint globalPosition) {
|
||||
if (_touchPress
|
||||
&& !_touchMove
|
||||
&& ((globalPosition - _touchStart).manhattanLength()
|
||||
>= QApplication::startDragDistance())) {
|
||||
_touchMove = true;
|
||||
}
|
||||
}
|
||||
|
||||
void FlatInput::touchFinish() {
|
||||
if (!_touchPress) {
|
||||
return;
|
||||
}
|
||||
const auto weak = MakeWeak(this);
|
||||
if (!_touchMove && window()) {
|
||||
QPoint mapped(mapFromGlobal(_touchStart));
|
||||
|
||||
if (_touchRightButton) {
|
||||
QContextMenuEvent contextEvent(
|
||||
QContextMenuEvent::Mouse,
|
||||
mapped,
|
||||
_touchStart);
|
||||
contextMenuEvent(&contextEvent);
|
||||
} else {
|
||||
QGuiApplication::inputMethod()->show();
|
||||
}
|
||||
}
|
||||
if (weak) {
|
||||
_touchTimer.stop();
|
||||
_touchPress
|
||||
= _touchMove
|
||||
= _touchRightButton
|
||||
= _mousePressedInTouch = false;
|
||||
}
|
||||
}
|
||||
|
||||
QRect FlatInput::placeholderRect() const {
|
||||
return QRect(_textMrg.left() + _st.phPos.x(), _textMrg.top() + _st.phPos.y(), width() - _textMrg.left() - _textMrg.right(), height() - _textMrg.top() - _textMrg.bottom());
|
||||
}
|
||||
|
|
@ -1572,6 +1626,7 @@ bool InputField::viewportEventInner(QEvent *e) {
|
|||
const auto ev = static_cast<QTouchEvent*>(e);
|
||||
if (ev->device()->type() == base::TouchDevice::TouchScreen) {
|
||||
handleTouchEvent(ev);
|
||||
return false;
|
||||
}
|
||||
} else if (e->type() == QEvent::Paint && _customEmojiObject) {
|
||||
_customEmojiObject->setNow(crl::now());
|
||||
|
|
@ -1846,7 +1901,9 @@ void InputField::checkContentHeight() {
|
|||
void InputField::handleTouchEvent(QTouchEvent *e) {
|
||||
switch (e->type()) {
|
||||
case QEvent::TouchBegin: {
|
||||
if (_touchPress || e->touchPoints().isEmpty()) return;
|
||||
if (_touchPress || e->touchPoints().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
_touchTimer.start(QApplication::startDragTime());
|
||||
_touchPress = true;
|
||||
_touchMove = _touchRightButton = false;
|
||||
|
|
@ -1854,29 +1911,13 @@ void InputField::handleTouchEvent(QTouchEvent *e) {
|
|||
} break;
|
||||
|
||||
case QEvent::TouchUpdate: {
|
||||
if (!_touchPress || e->touchPoints().isEmpty()) return;
|
||||
if (!_touchMove && (e->touchPoints().cbegin()->screenPos().toPoint() - _touchStart).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
_touchMove = true;
|
||||
if (!e->touchPoints().isEmpty()) {
|
||||
touchUpdate(e->touchPoints().cbegin()->screenPos().toPoint());
|
||||
}
|
||||
} break;
|
||||
|
||||
case QEvent::TouchEnd: {
|
||||
if (!_touchPress) return;
|
||||
auto weak = MakeWeak(this);
|
||||
if (!_touchMove && window()) {
|
||||
QPoint mapped(mapFromGlobal(_touchStart));
|
||||
|
||||
if (_touchRightButton) {
|
||||
QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart);
|
||||
contextMenuEvent(&contextEvent);
|
||||
} else {
|
||||
QGuiApplication::inputMethod()->show();
|
||||
}
|
||||
}
|
||||
if (weak) {
|
||||
_touchTimer.stop();
|
||||
_touchPress = _touchMove = _touchRightButton = false;
|
||||
}
|
||||
touchFinish();
|
||||
} break;
|
||||
|
||||
case QEvent::TouchCancel: {
|
||||
|
|
@ -1886,6 +1927,42 @@ void InputField::handleTouchEvent(QTouchEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
void InputField::touchUpdate(QPoint globalPosition) {
|
||||
if (_touchPress
|
||||
&& !_touchMove
|
||||
&& ((globalPosition - _touchStart).manhattanLength()
|
||||
>= QApplication::startDragDistance())) {
|
||||
_touchMove = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InputField::touchFinish() {
|
||||
if (!_touchPress) {
|
||||
return;
|
||||
}
|
||||
const auto weak = MakeWeak(this);
|
||||
if (!_touchMove && window()) {
|
||||
QPoint mapped(mapFromGlobal(_touchStart));
|
||||
|
||||
if (_touchRightButton) {
|
||||
QContextMenuEvent contextEvent(
|
||||
QContextMenuEvent::Mouse,
|
||||
mapped,
|
||||
_touchStart);
|
||||
contextMenuEvent(&contextEvent);
|
||||
} else {
|
||||
QGuiApplication::inputMethod()->show();
|
||||
}
|
||||
}
|
||||
if (weak) {
|
||||
_touchTimer.stop();
|
||||
_touchPress
|
||||
= _touchMove
|
||||
= _touchRightButton
|
||||
= _mousePressedInTouch = false;
|
||||
}
|
||||
}
|
||||
|
||||
void InputField::paintEvent(QPaintEvent *e) {
|
||||
auto p = QPainter(this);
|
||||
|
||||
|
|
@ -2006,6 +2083,29 @@ void InputField::mousePressEvent(QMouseEvent *e) {
|
|||
InvokeQueued(this, [=] { onFocusInner(); });
|
||||
}
|
||||
|
||||
void InputField::mousePressEventInner(QMouseEvent *e) {
|
||||
if (_touchPress && e->button() == Qt::LeftButton) {
|
||||
_mousePressedInTouch = true;
|
||||
_touchStart = e->globalPos();
|
||||
}
|
||||
_inner->QTextEdit::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void InputField::mouseReleaseEventInner(QMouseEvent *e) {
|
||||
if (_mousePressedInTouch) {
|
||||
touchFinish();
|
||||
} else {
|
||||
_inner->QTextEdit::mouseReleaseEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void InputField::mouseMoveEventInner(QMouseEvent *e) {
|
||||
if (_mousePressedInTouch) {
|
||||
touchUpdate(e->globalPos());
|
||||
}
|
||||
_inner->QTextEdit::mouseMoveEvent(e);
|
||||
}
|
||||
|
||||
void InputField::onFocusInner() {
|
||||
auto borderStart = _borderAnimationStart;
|
||||
_inner->setFocus();
|
||||
|
|
@ -4165,37 +4265,23 @@ bool MaskedInputField::eventHook(QEvent *e) {
|
|||
void MaskedInputField::touchEvent(QTouchEvent *e) {
|
||||
switch (e->type()) {
|
||||
case QEvent::TouchBegin: {
|
||||
if (_touchPress || e->touchPoints().isEmpty()) return;
|
||||
if (_touchPress || e->touchPoints().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
_touchTimer.start(QApplication::startDragTime());
|
||||
_touchPress = true;
|
||||
_touchMove = _touchRightButton = false;
|
||||
_touchMove = _touchRightButton = _mousePressedInTouch = false;
|
||||
_touchStart = e->touchPoints().cbegin()->screenPos().toPoint();
|
||||
} break;
|
||||
|
||||
case QEvent::TouchUpdate: {
|
||||
if (!_touchPress || e->touchPoints().isEmpty()) return;
|
||||
if (!_touchMove && (e->touchPoints().cbegin()->screenPos().toPoint() - _touchStart).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
_touchMove = true;
|
||||
if (!e->touchPoints().isEmpty()) {
|
||||
touchUpdate(e->touchPoints().cbegin()->screenPos().toPoint());
|
||||
}
|
||||
} break;
|
||||
|
||||
case QEvent::TouchEnd: {
|
||||
if (!_touchPress) return;
|
||||
auto weak = MakeWeak(this);
|
||||
if (!_touchMove && window()) {
|
||||
QPoint mapped(mapFromGlobal(_touchStart));
|
||||
|
||||
if (_touchRightButton) {
|
||||
QContextMenuEvent contextEvent(QContextMenuEvent::Mouse, mapped, _touchStart);
|
||||
contextMenuEvent(&contextEvent);
|
||||
} else {
|
||||
QGuiApplication::inputMethod()->show();
|
||||
}
|
||||
}
|
||||
if (weak) {
|
||||
_touchTimer.stop();
|
||||
_touchPress = _touchMove = _touchRightButton = false;
|
||||
}
|
||||
touchFinish();
|
||||
} break;
|
||||
|
||||
case QEvent::TouchCancel: {
|
||||
|
|
@ -4205,6 +4291,42 @@ void MaskedInputField::touchEvent(QTouchEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
void MaskedInputField::touchUpdate(QPoint globalPosition) {
|
||||
if (_touchPress
|
||||
&& !_touchMove
|
||||
&& ((globalPosition - _touchStart).manhattanLength()
|
||||
>= QApplication::startDragDistance())) {
|
||||
_touchMove = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MaskedInputField::touchFinish() {
|
||||
if (!_touchPress) {
|
||||
return;
|
||||
}
|
||||
const auto weak = MakeWeak(this);
|
||||
if (!_touchMove && window()) {
|
||||
QPoint mapped(mapFromGlobal(_touchStart));
|
||||
|
||||
if (_touchRightButton) {
|
||||
QContextMenuEvent contextEvent(
|
||||
QContextMenuEvent::Mouse,
|
||||
mapped,
|
||||
_touchStart);
|
||||
contextMenuEvent(&contextEvent);
|
||||
} else {
|
||||
QGuiApplication::inputMethod()->show();
|
||||
}
|
||||
}
|
||||
if (weak) {
|
||||
_touchTimer.stop();
|
||||
_touchPress
|
||||
= _touchMove
|
||||
= _touchRightButton
|
||||
= _mousePressedInTouch = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MaskedInputField::paintEvent(QPaintEvent *e) {
|
||||
auto p = QPainter(this);
|
||||
|
||||
|
|
@ -4279,6 +4401,28 @@ void MaskedInputField::paintEvent(QPaintEvent *e) {
|
|||
QLineEdit::paintEvent(e);
|
||||
}
|
||||
|
||||
void MaskedInputField::mousePressEvent(QMouseEvent *e) {
|
||||
if (_touchPress && e->button() == Qt::LeftButton) {
|
||||
_mousePressedInTouch = true;
|
||||
_touchStart = e->globalPos();
|
||||
}
|
||||
return QLineEdit::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void MaskedInputField::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (_mousePressedInTouch) {
|
||||
touchFinish();
|
||||
}
|
||||
return QLineEdit::mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
void MaskedInputField::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (_mousePressedInTouch) {
|
||||
touchUpdate(e->globalPos());
|
||||
}
|
||||
return QLineEdit::mouseMoveEvent(e);
|
||||
}
|
||||
|
||||
void MaskedInputField::startBorderAnimation() {
|
||||
auto borderVisible = (_error || _focused);
|
||||
if (_borderVisible != borderVisible) {
|
||||
|
|
|
|||
|
|
@ -118,6 +118,10 @@ protected:
|
|||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
void inputMethodEvent(QInputMethodEvent *e) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
|
||||
virtual void correctValue(const QString &was, QString &now);
|
||||
|
||||
style::font phFont() {
|
||||
|
|
@ -130,6 +134,9 @@ private:
|
|||
void updatePalette();
|
||||
void refreshPlaceholder(const QString &text);
|
||||
|
||||
void touchUpdate(QPoint globalPosition);
|
||||
void touchFinish();
|
||||
|
||||
QString _oldtext;
|
||||
rpl::variable<QString> _placeholderFull;
|
||||
QString _placeholder;
|
||||
|
|
@ -146,7 +153,10 @@ private:
|
|||
QMargins _textMrg;
|
||||
|
||||
QTimer _touchTimer;
|
||||
bool _touchPress, _touchRightButton, _touchMove;
|
||||
bool _touchPress = false;
|
||||
bool _touchRightButton = false;
|
||||
bool _touchMove = false;
|
||||
bool _mousePressedInTouch = false;
|
||||
QPoint _touchStart;
|
||||
|
||||
base::unique_qptr<PopupMenu> _contextMenu;
|
||||
|
|
@ -448,6 +458,10 @@ private:
|
|||
void inputMethodEventInner(QInputMethodEvent *e);
|
||||
void paintEventInner(QPaintEvent *e);
|
||||
|
||||
void mousePressEventInner(QMouseEvent *e);
|
||||
void mouseReleaseEventInner(QMouseEvent *e);
|
||||
void mouseMoveEventInner(QMouseEvent *e);
|
||||
|
||||
QMimeData *createMimeDataFromSelectionInner() const;
|
||||
bool canInsertFromMimeDataInner(const QMimeData *source) const;
|
||||
void insertFromMimeDataInner(const QMimeData *source);
|
||||
|
|
@ -522,6 +536,9 @@ private:
|
|||
void customEmojiRepaint();
|
||||
void highlightMarkdown();
|
||||
|
||||
void touchUpdate(QPoint globalPosition);
|
||||
void touchFinish();
|
||||
|
||||
const style::InputField &_st;
|
||||
|
||||
Mode _mode = Mode::SingleLine;
|
||||
|
|
@ -594,6 +611,7 @@ private:
|
|||
bool _touchPress = false;
|
||||
bool _touchRightButton = false;
|
||||
bool _touchMove = false;
|
||||
bool _mousePressedInTouch = false;
|
||||
QPoint _touchStart;
|
||||
|
||||
bool _correcting = false;
|
||||
|
|
@ -690,6 +708,10 @@ protected:
|
|||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
void inputMethodEvent(QInputMethodEvent *e) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
|
||||
virtual void correctValue(
|
||||
const QString &was,
|
||||
int wasCursor,
|
||||
|
|
@ -716,6 +738,9 @@ private:
|
|||
void refreshPlaceholder(const QString &text);
|
||||
void setErrorShown(bool error);
|
||||
|
||||
void touchUpdate(QPoint globalPosition);
|
||||
void touchFinish();
|
||||
|
||||
void setFocused(bool focused);
|
||||
|
||||
int _maxLength = -1;
|
||||
|
|
@ -753,6 +778,7 @@ private:
|
|||
bool _touchPress = false;
|
||||
bool _touchRightButton = false;
|
||||
bool _touchMove = false;
|
||||
bool _mousePressedInTouch = false;
|
||||
QPoint _touchStart;
|
||||
|
||||
base::unique_qptr<PopupMenu> _contextMenu;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue