From 7cea6ede1ad50cb68a908412de89cc087a59f124 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 26 May 2017 18:50:25 +0300 Subject: [PATCH] Improve input field placeholders with IME. Respect the IME preedit string when toggling the placeholder. --- .../SourceFiles/ui/widgets/input_fields.cpp | 34 +++++++++++++++---- .../SourceFiles/ui/widgets/input_fields.h | 11 ++++++ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.cpp b/Telegram/SourceFiles/ui/widgets/input_fields.cpp index 265651572..57cb1f59c 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.cpp +++ b/Telegram/SourceFiles/ui/widgets/input_fields.cpp @@ -1331,7 +1331,8 @@ void FlatTextarea::setPlaceholder(const QString &ph, int32 afterSymbols) { } void FlatTextarea::updatePlaceholder() { - auto placeholderVisible = (getTextWithTags().text.size() <= _phAfter); + auto textSize = (getTextWithTags().text.size() + textCursor().block().layout()->preeditAreaText().size()); + auto placeholderVisible = (textSize <= _phAfter); if (_placeholderVisible != placeholderVisible) { _placeholderVisible = placeholderVisible; _a_placeholderVisible.start([this] { update(); }, _placeholderVisible ? 0. : 1., _placeholderVisible ? 1. : 0., _st.phDuration); @@ -1645,13 +1646,28 @@ QSize FlatInput::minimumSizeHint() const { } void FlatInput::updatePlaceholder() { - auto placeholderVisible = text().isEmpty(); + auto hasText = !text().isEmpty(); + if (!hasText) { + hasText = _lastPreEditTextNotEmpty; + } else { + _lastPreEditTextNotEmpty = false; + } + auto placeholderVisible = !hasText; if (_placeholderVisible != placeholderVisible) { _placeholderVisible = placeholderVisible; _a_placeholderVisible.start([this] { update(); }, _placeholderVisible ? 0. : 1., _placeholderVisible ? 1. : 0., _st.phDuration); } } +void FlatInput::inputMethodEvent(QInputMethodEvent *e) { + QLineEdit::inputMethodEvent(e); + auto lastPreEditTextNotEmpty = !e->preeditString().isEmpty(); + if (_lastPreEditTextNotEmpty != lastPreEditTextNotEmpty) { + _lastPreEditTextNotEmpty = lastPreEditTextNotEmpty; + updatePlaceholder(); + } +} + const QString &FlatInput::placeholder() const { return _fullph; } @@ -2707,7 +2723,7 @@ void InputField::setFocused(bool focused) { } void InputField::startPlaceholderAnimation() { - auto placeholderShifted = (_focused && _st.placeholderScale > 0.) || !getLastText().isEmpty() || _forcePlaceholderHidden; + auto placeholderShifted = _forcePlaceholderHidden || (_focused && _st.placeholderScale > 0.) || !getLastText().isEmpty(); if (_placeholderShifted != placeholderShifted) { _placeholderShifted = placeholderShifted; _a_placeholderShifted.start([this] { update(); }, _placeholderShifted ? 0. : 1., _placeholderShifted ? 1. : 0., _st.duration); @@ -3495,6 +3511,12 @@ void MaskedInputField::contextMenuEvent(QContextMenuEvent *e) { } } +void MaskedInputField::inputMethodEvent(QInputMethodEvent *e) { + QLineEdit::inputMethodEvent(e); + _lastPreEditText = e->preeditString(); + update(); +} + void MaskedInputField::showError() { setErrorShown(true); if (!hasFocus()) { @@ -3538,7 +3560,7 @@ void MaskedInputField::setPlaceholderHidden(bool forcePlaceholderHidden) { } void MaskedInputField::startPlaceholderAnimation() { - auto placeholderShifted = (_focused && _st.placeholderScale > 0.) || !getLastText().isEmpty() || _forcePlaceholderHidden; + auto placeholderShifted = _forcePlaceholderHidden || (_focused && _st.placeholderScale > 0.) || !getLastText().isEmpty(); if (_placeholderShifted != placeholderShifted) { _placeholderShifted = placeholderShifted; _a_placeholderShifted.start([this] { update(); }, _placeholderShifted ? 0. : 1., _placeholderShifted ? 1. : 0., _st.duration); @@ -3681,8 +3703,8 @@ PhonePartInput::PhonePartInput(QWidget *parent, const style::InputField &st) : M } void PhonePartInput::paintAdditionalPlaceholder(Painter &p, TimeMs ms) { - auto t = getLastText(); if (!_pattern.isEmpty()) { + auto t = getDisplayedText(); auto ph = _additionalPlaceholder.mid(t.size()); if (!ph.isEmpty()) { p.setClipRect(rect()); @@ -3901,7 +3923,7 @@ void PhoneInput::clearText() { void PhoneInput::paintAdditionalPlaceholder(Painter &p, TimeMs ms) { if (!_pattern.isEmpty()) { - auto t = getLastText(); + auto t = getDisplayedText(); auto ph = _additionalPlaceholder.mid(t.size()); if (!ph.isEmpty()) { p.setClipRect(rect()); diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.h b/Telegram/SourceFiles/ui/widgets/input_fields.h index ab2cbc739..e4012d328 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.h +++ b/Telegram/SourceFiles/ui/widgets/input_fields.h @@ -273,6 +273,7 @@ protected: void keyPressEvent(QKeyEvent *e) override; void resizeEvent(QResizeEvent *e) override; void contextMenuEvent(QContextMenuEvent *e) override; + void inputMethodEvent(QInputMethodEvent *e) override; virtual void correctValue(const QString &was, QString &now); @@ -294,6 +295,7 @@ private: bool _placeholderVisible = true; Animation _a_placeholderFocused; Animation _a_placeholderVisible; + bool _lastPreEditTextNotEmpty = false; const style::FlatInput &_st; @@ -720,6 +722,13 @@ signals: void blurred(); protected: + QString getDisplayedText() const { + auto result = getLastText(); + if (!_lastPreEditText.isEmpty()) { + result = result.mid(0, _oldcursor) + _lastPreEditText + result.mid(_oldcursor); + } + return result; + } void startBorderAnimation(); void startPlaceholderAnimation(); @@ -731,6 +740,7 @@ protected: void keyPressEvent(QKeyEvent *e) override; void resizeEvent(QResizeEvent *e) override; void contextMenuEvent(QContextMenuEvent *e) override; + void inputMethodEvent(QInputMethodEvent *e) override; virtual void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) { } @@ -762,6 +772,7 @@ private: QString _oldtext; int _oldcursor = 0; + QString _lastPreEditText; bool _undoAvailable = false; bool _redoAvailable = false;