tdesktop/Telegram/SourceFiles/ui/widgets/input_fields.h

801 lines
20 KiB
C
Raw Normal View History

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
2017-11-03 12:03:00 +00:00
#include "ui/rp_widget.h"
2019-02-04 13:34:50 +00:00
#include "ui/effects/animations.h"
#include "styles/style_widgets.h"
class UserData;
namespace Ui {
const auto kClearFormatSequence = QKeySequence("ctrl+shift+n");
const auto kStrikeOutSequence = QKeySequence("ctrl+shift+x");
const auto kMonospaceSequence = QKeySequence("ctrl+shift+m");
const auto kEditLinkSequence = QKeySequence("ctrl+k");
class PopupMenu;
2018-05-21 21:31:46 +00:00
void InsertEmojiAtCursor(QTextCursor cursor, EmojiPtr emoji);
struct InstantReplaces {
struct Node {
QString text;
std::map<QChar, Node> tail;
};
void add(const QString &what, const QString &with);
static const InstantReplaces &Default();
2019-07-28 13:39:06 +00:00
static const InstantReplaces &TextOnly();
int maxLength = 0;
Node reverseMap;
};
enum class InputSubmitSettings {
Enter,
CtrlEnter,
Both,
None,
};
class FlatInput : public Ui::RpWidgetWrap<QLineEdit>, private base::Subscriber {
2019-01-18 11:26:43 +00:00
// The Q_OBJECT meta info is used for qobject_cast!
Q_OBJECT
using Parent = RpWidgetWrap<QLineEdit>;
public:
FlatInput(
QWidget *parent,
const style::FlatInput &st,
rpl::producer<QString> placeholder = nullptr,
const QString &val = QString());
void updatePlaceholder();
void setPlaceholder(rpl::producer<QString> placeholder);
QRect placeholderRect() const;
2019-04-24 10:15:10 +00:00
void finishAnimations();
void setTextMrg(const QMargins &textMrg);
QRect getTextRect() const;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
void customUpDown(bool isCustom);
2015-10-06 19:49:23 +00:00
const QString &getLastText() const {
return _oldtext;
}
2016-11-24 19:28:23 +00:00
public slots:
void onTextChange(const QString &text);
void onTextEdited();
void onTouchTimer();
signals:
void changed();
void cancelled();
void submitted(Qt::KeyboardModifiers);
void focused();
void blurred();
protected:
bool eventHook(QEvent *e) override;
void touchEvent(QTouchEvent *e);
void paintEvent(QPaintEvent *e) override;
void focusInEvent(QFocusEvent *e) override;
void focusOutEvent(QFocusEvent *e) override;
void keyPressEvent(QKeyEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void inputMethodEvent(QInputMethodEvent *e) override;
2015-10-06 19:49:23 +00:00
virtual void correctValue(const QString &was, QString &now);
style::font phFont() {
return _st.font;
}
2016-12-02 19:16:35 +00:00
void phPrepare(Painter &p, float64 placeholderFocused);
private:
void updatePalette();
void refreshPlaceholder(const QString &text);
QString _oldtext;
rpl::variable<QString> _placeholderFull;
QString _placeholder;
2016-12-02 19:16:35 +00:00
bool _customUpDown = false;
bool _focused = false;
2016-12-02 19:16:35 +00:00
bool _placeholderVisible = true;
2019-04-01 14:53:18 +00:00
Animations::Simple _placeholderFocusedAnimation;
Animations::Simple _placeholderVisibleAnimation;
bool _lastPreEditTextNotEmpty = false;
const style::FlatInput &_st;
QMargins _textMrg;
QTimer _touchTimer;
bool _touchPress, _touchRightButton, _touchMove;
QPoint _touchStart;
};
class InputField : public RpWidget, private base::Subscriber {
2015-10-06 19:49:23 +00:00
Q_OBJECT
public:
enum class Mode {
SingleLine,
NoNewlines,
MultiLine,
};
using TagList = TextWithTags::Tags;
struct MarkdownTag {
2018-06-07 19:00:46 +00:00
// With each emoji being QChar::ObjectReplacementCharacter.
int internalStart = 0;
int internalLength = 0;
// Adjusted by emoji to match _lastTextWithTags.
int adjustedStart = 0;
int adjustedLength = 0;
bool closed = false;
QString tag;
};
static const QString kTagBold;
static const QString kTagItalic;
static const QString kTagUnderline;
static const QString kTagStrikeOut;
static const QString kTagCode;
static const QString kTagPre;
InputField(
2017-11-10 15:45:10 +00:00
QWidget *parent,
const style::InputField &st,
rpl::producer<QString> placeholder,
const QString &value = QString());
InputField(
QWidget *parent,
const style::InputField &st,
Mode mode,
rpl::producer<QString> placeholder,
const QString &value);
InputField(
QWidget *parent,
const style::InputField &st,
Mode mode = Mode::SingleLine,
rpl::producer<QString> placeholder = nullptr,
const TextWithTags &value = TextWithTags());
2015-10-06 19:49:23 +00:00
void showError();
2018-05-21 21:31:46 +00:00
void setMaxLength(int maxLength);
void setMinHeight(int minHeight);
void setMaxHeight(int maxHeight);
2015-10-06 19:49:23 +00:00
2018-05-21 21:31:46 +00:00
const TextWithTags &getTextWithTags() const {
return _lastTextWithTags;
}
const std::vector<MarkdownTag> &getMarkdownTags() const {
return _lastMarkdownTags;
}
2018-05-21 21:31:46 +00:00
TextWithTags getTextWithTagsPart(int start, int end = -1) const;
TextWithTags getTextWithAppliedMarkdown() const;
2018-05-21 21:31:46 +00:00
void insertTag(const QString &text, QString tagId = QString());
bool empty() const {
return _lastTextWithTags.text.isEmpty();
}
enum class HistoryAction {
NewEntry,
MergeEntry,
Clear,
};
void setTextWithTags(
const TextWithTags &textWithTags,
HistoryAction historyAction = HistoryAction::NewEntry);
2018-05-21 21:31:46 +00:00
// If you need to make some preparations of tags before putting them to QMimeData
// (and then to clipboard or to drag-n-drop object), here is a strategy for that.
class TagMimeProcessor {
public:
virtual QString mimeTagFromTag(const QString &tagId) = 0;
virtual QString tagFromMimeTag(const QString &mimeTag) = 0;
virtual ~TagMimeProcessor() {
}
};
void setTagMimeProcessor(std::unique_ptr<TagMimeProcessor> &&processor);
struct EditLinkSelection {
int from = 0;
int till = 0;
};
enum class EditLinkAction {
Check,
Edit,
};
void setEditLinkCallback(
Fn<bool(
EditLinkSelection selection,
QString text,
QString link,
EditLinkAction action)> callback);
void setAdditionalMargin(int margin);
void setInstantReplaces(const InstantReplaces &replaces);
void setInstantReplacesEnabled(rpl::producer<bool> enabled);
void setMarkdownReplacesEnabled(rpl::producer<bool> enabled);
2019-01-21 07:02:20 +00:00
void commitInstantReplacement(int from, int till, const QString &with);
void commitMarkdownLinkEdit(
EditLinkSelection selection,
const QString &text,
const QString &link);
static bool IsValidMarkdownLink(const QString &link);
2015-10-06 19:49:23 +00:00
const QString &getLastText() const {
return _lastTextWithTags.text;
2015-10-06 19:49:23 +00:00
}
2018-05-21 21:31:46 +00:00
void setPlaceholder(
rpl::producer<QString> placeholder,
2018-05-21 21:31:46 +00:00
int afterSymbols = 0);
void setPlaceholderHidden(bool forcePlaceholderHidden);
void setDisplayFocused(bool focused);
void finishAnimating();
void setFocusFast() {
setDisplayFocused(true);
setFocus();
}
2015-10-06 19:49:23 +00:00
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
2015-10-06 19:49:23 +00:00
bool hasText() const;
void selectAll();
2015-10-06 19:49:23 +00:00
bool isUndoAvailable() const;
bool isRedoAvailable() const;
2019-06-10 21:39:58 +00:00
bool isMarkdownEnabled() const {
return _markdownEnabled;
}
using SubmitSettings = InputSubmitSettings;
2018-05-21 21:31:46 +00:00
void setSubmitSettings(SubmitSettings settings);
static bool ShouldSubmit(
SubmitSettings settings,
Qt::KeyboardModifiers modifiers);
2015-10-06 19:49:23 +00:00
void customUpDown(bool isCustom);
void customTab(bool isCustom);
2018-04-10 16:22:27 +00:00
int borderAnimationStart() const;
2015-10-06 19:49:23 +00:00
2018-05-21 21:31:46 +00:00
not_null<QTextDocument*> document();
not_null<const QTextDocument*> document() const;
void setTextCursor(const QTextCursor &cursor);
void setCursorPosition(int position);
QTextCursor textCursor() const;
void setText(const QString &text);
void clear();
bool hasFocus() const;
void setFocus();
void clearFocus();
void ensureCursorVisible();
2018-05-21 21:31:46 +00:00
not_null<QTextEdit*> rawTextEdit();
not_null<const QTextEdit*> rawTextEdit() const;
2015-10-06 19:49:23 +00:00
enum class MimeAction {
Check,
Insert,
};
using MimeDataHook = Fn<bool(
not_null<const QMimeData*> data,
MimeAction action)>;
void setMimeDataHook(MimeDataHook hook) {
_mimeDataHook = std::move(hook);
}
2018-05-21 21:31:46 +00:00
const rpl::variable<int> &scrollTop() const;
int scrollTopMax() const;
void scrollTo(int top);
~InputField();
private slots:
2015-10-06 19:49:23 +00:00
void onTouchTimer();
void onDocumentContentsChange(int position, int charsRemoved, int charsAdded);
void onCursorPositionChanged();
2015-10-06 19:49:23 +00:00
void onUndoAvailable(bool avail);
void onRedoAvailable(bool avail);
void onFocusInner();
2015-10-06 19:49:23 +00:00
signals:
void changed();
void submitted(Qt::KeyboardModifiers);
2015-10-06 19:49:23 +00:00
void cancelled();
void tabbed();
void focused();
void blurred();
void resized();
protected:
void startPlaceholderAnimation();
void startBorderAnimation();
void paintEvent(QPaintEvent *e) override;
void focusInEvent(QFocusEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
2015-10-06 19:49:23 +00:00
private:
class Inner;
2016-10-21 12:28:26 +00:00
friend class Inner;
2015-10-06 19:49:23 +00:00
void handleContentsChanged();
bool viewportEventInner(QEvent *e);
void handleTouchEvent(QTouchEvent *e);
void updatePalette();
void refreshPlaceholder(const QString &text);
2018-05-21 21:31:46 +00:00
int placeholderSkipWidth() const;
bool heightAutoupdated();
void checkContentHeight();
void setErrorShown(bool error);
void focusInEventInner(QFocusEvent *e);
void focusOutEventInner(QFocusEvent *e);
void setFocused(bool focused);
void keyPressEventInner(QKeyEvent *e);
void contextMenuEventInner(QContextMenuEvent *e);
2018-05-21 21:31:46 +00:00
void dropEventInner(QDropEvent *e);
void inputMethodEventInner(QInputMethodEvent *e);
QMimeData *createMimeDataFromSelectionInner() const;
bool canInsertFromMimeDataInner(const QMimeData *source) const;
void insertFromMimeDataInner(const QMimeData *source);
TextWithTags getTextWithTagsSelected() const;
2015-10-06 19:49:23 +00:00
2018-05-21 21:31:46 +00:00
// "start" and "end" are in coordinates of text where emoji are replaced
// by ObjectReplacementCharacter. If "end" = -1 means get text till the end.
QString getTextPart(
int start,
int end,
TagList &outTagsList,
bool &outTagsChanged,
std::vector<MarkdownTag> *outMarkdownTags = nullptr) const;
2018-05-21 21:31:46 +00:00
// After any characters added we must postprocess them. This includes:
// 1. Replacing font family to semibold for ~ characters, if we used Open Sans 13px.
// 2. Replacing font family from semibold for all non-~ characters, if we used ...
// 3. Replacing emoji code sequences by ObjectReplacementCharacters with emoji pics.
// 4. Interrupting tags in which the text was inserted by any char except a letter.
// 5. Applying tags from "_insertedTags" in case we pasted text with tags, not just text.
// Rule 4 applies only if we inserted chars not in the middle of a tag (but at the end).
void processFormatting(int changedPosition, int changedEnd);
void chopByMaxLength(int insertPosition, int insertLength);
2015-10-06 19:49:23 +00:00
bool processMarkdownReplaces(const QString &appended);
//bool processMarkdownReplace(const QString &tag);
void addMarkdownActions(not_null<QMenu*> menu, QContextMenuEvent *e);
void addMarkdownMenuAction(
not_null<QMenu*> menu,
not_null<QAction*> action);
bool handleMarkdownKey(QKeyEvent *e);
// We don't want accidentally detach InstantReplaces map.
// So we access it only by const reference from this method.
const InstantReplaces &instantReplaces() const;
void processInstantReplaces(const QString &appended);
void applyInstantReplace(const QString &what, const QString &with);
struct EditLinkData {
int from = 0;
int till = 0;
QString link;
};
EditLinkData selectionEditLinkData(EditLinkSelection selection) const;
EditLinkSelection editLinkSelection(QContextMenuEvent *e) const;
void editMarkdownLink(EditLinkSelection selection);
2019-01-21 07:02:20 +00:00
void commitInstantReplacement(
int from,
int till,
const QString &with,
std::optional<QString> checkOriginal,
bool checkIfInMonospace);
bool commitMarkdownReplacement(
int from,
int till,
const QString &tag,
const QString &edge = QString());
void toggleSelectionMarkdown(const QString &tag);
void clearSelectionMarkdown();
bool revertFormatReplace();
void highlightMarkdown();
const style::InputField &_st;
2015-10-06 19:49:23 +00:00
Mode _mode = Mode::SingleLine;
int _maxLength = -1;
2018-05-21 21:31:46 +00:00
int _minHeight = -1;
int _maxHeight = -1;
bool _forcePlaceholderHidden = false;
bool _reverseMarkdownReplacement = false;
const std::unique_ptr<Inner> _inner;
2015-10-06 19:49:23 +00:00
TextWithTags _lastTextWithTags;
std::vector<MarkdownTag> _lastMarkdownTags;
QString _lastPreEditText;
Fn<bool(
EditLinkSelection selection,
QString text,
QString link,
EditLinkAction action)> _editLinkCallback;
2015-10-06 19:49:23 +00:00
2018-05-21 21:31:46 +00:00
// Tags list which we should apply while setText() call or insert from mime data.
TagList _insertedTags;
bool _insertedTagsAreFromMime;
// Override insert position and charsAdded from complex text editing
// (like drag-n-drop in the same text edit field).
int _realInsertPosition = -1;
int _realCharsAdded = 0;
std::unique_ptr<TagMimeProcessor> _tagMimeProcessor;
SubmitSettings _submitSettings = SubmitSettings::Enter;
bool _markdownEnabled = false;
bool _undoAvailable = false;
bool _redoAvailable = false;
2018-05-21 21:31:46 +00:00
bool _inDrop = false;
bool _inHeightCheck = false;
int _additionalMargin = 0;
2015-10-06 19:49:23 +00:00
bool _customUpDown = false;
bool _customTab = false;
2015-10-06 19:49:23 +00:00
rpl::variable<QString> _placeholderFull;
QString _placeholder;
2018-05-21 21:31:46 +00:00
int _placeholderAfterSymbols = 0;
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_placeholderShifted;
bool _placeholderShifted = false;
QPainterPath _placeholderPath;
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_borderShown;
int _borderAnimationStart = 0;
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_borderOpacity;
bool _borderVisible = false;
2015-10-06 19:49:23 +00:00
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_focused;
Ui::Animations::Simple _a_error;
2015-10-06 19:49:23 +00:00
bool _focused = false;
bool _error = false;
2015-10-06 19:49:23 +00:00
QTimer _touchTimer;
bool _touchPress = false;
bool _touchRightButton = false;
bool _touchMove = false;
2015-10-06 19:49:23 +00:00
QPoint _touchStart;
bool _correcting = false;
MimeDataHook _mimeDataHook;
base::unique_qptr<Ui::PopupMenu> _contextMenu;
QTextCharFormat _defaultCharFormat;
2015-10-06 19:49:23 +00:00
2018-05-21 21:31:46 +00:00
rpl::variable<int> _scrollTop;
InstantReplaces _mutableInstantReplaces;
bool _instantReplacesEnabled = true;
2015-10-06 19:49:23 +00:00
};
2017-11-10 15:45:10 +00:00
class MaskedInputField
: public RpWidgetWrap<QLineEdit>
, private base::Subscriber {
2019-01-18 11:26:43 +00:00
// The Q_OBJECT meta info is used for qobject_cast!
2015-10-06 19:49:23 +00:00
Q_OBJECT
2017-11-10 15:45:10 +00:00
using Parent = RpWidgetWrap<QLineEdit>;
2015-10-06 19:49:23 +00:00
public:
MaskedInputField(
QWidget *parent,
const style::InputField &st,
rpl::producer<QString> placeholder = nullptr,
const QString &val = QString());
2015-10-06 19:49:23 +00:00
void showError();
QRect getTextRect() const;
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
2015-10-06 19:49:23 +00:00
void customUpDown(bool isCustom);
2018-04-10 16:22:27 +00:00
int borderAnimationStart() const;
2015-10-06 19:49:23 +00:00
const QString &getLastText() const {
return _oldtext;
}
void setPlaceholder(rpl::producer<QString> placeholder);
void setPlaceholderHidden(bool forcePlaceholderHidden);
void setDisplayFocused(bool focused);
void finishAnimating();
void setFocusFast() {
setDisplayFocused(true);
setFocus();
}
2015-10-06 19:49:23 +00:00
void setText(const QString &text) {
QLineEdit::setText(text);
startPlaceholderAnimation();
2015-10-06 19:49:23 +00:00
}
void clear() {
QLineEdit::clear();
startPlaceholderAnimation();
2015-10-06 19:49:23 +00:00
}
2016-11-24 19:28:23 +00:00
public slots:
2015-10-06 19:49:23 +00:00
void onTextChange(const QString &text);
void onCursorPositionChanged(int oldPosition, int position);
void onTextEdited();
void onTouchTimer();
signals:
void changed();
void cancelled();
void submitted(Qt::KeyboardModifiers);
2015-10-06 19:49:23 +00:00
void focused();
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();
2017-11-10 15:45:10 +00:00
bool eventHook(QEvent *e) override;
2016-11-24 19:28:23 +00:00
void touchEvent(QTouchEvent *e);
void paintEvent(QPaintEvent *e) override;
void focusInEvent(QFocusEvent *e) override;
void focusOutEvent(QFocusEvent *e) override;
void keyPressEvent(QKeyEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void inputMethodEvent(QInputMethodEvent *e) override;
2016-11-24 19:28:23 +00:00
virtual void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) {
2016-11-24 19:28:23 +00:00
}
void setCorrectedText(QString &now, int &nowCursor, const QString &newText, int newPos);
2019-04-02 09:13:30 +00:00
virtual void paintAdditionalPlaceholder(Painter &p) {
}
2015-10-06 19:49:23 +00:00
style::font phFont() {
return _st.font;
}
2019-04-02 09:13:30 +00:00
void placeholderAdditionalPrepare(Painter &p);
2015-10-06 19:49:23 +00:00
QRect placeholderRect() const;
void setTextMargins(const QMargins &mrg);
const style::InputField &_st;
private:
void updatePalette();
void refreshPlaceholder(const QString &text);
void setErrorShown(bool error);
void setFocused(bool focused);
2015-10-06 19:49:23 +00:00
int _maxLength = -1;
bool _forcePlaceholderHidden = false;
2015-10-06 19:49:23 +00:00
QString _oldtext;
int _oldcursor = 0;
QString _lastPreEditText;
bool _undoAvailable = false;
bool _redoAvailable = false;
2015-10-06 19:49:23 +00:00
bool _customUpDown = false;
2015-10-06 19:49:23 +00:00
rpl::variable<QString> _placeholderFull;
QString _placeholder;
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_placeholderShifted;
bool _placeholderShifted = false;
QPainterPath _placeholderPath;
2015-10-06 19:49:23 +00:00
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_borderShown;
int _borderAnimationStart = 0;
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_borderOpacity;
bool _borderVisible = false;
2019-04-02 09:13:30 +00:00
Ui::Animations::Simple _a_focused;
Ui::Animations::Simple _a_error;
2015-10-06 19:49:23 +00:00
bool _focused = false;
bool _error = false;
2015-10-06 19:49:23 +00:00
style::margins _textMargins;
QTimer _touchTimer;
bool _touchPress = false;
bool _touchRightButton = false;
bool _touchMove = false;
QPoint _touchStart;
2015-10-06 19:49:23 +00:00
};
2016-11-24 19:28:23 +00:00
class CountryCodeInput : public MaskedInputField {
Q_OBJECT
public:
CountryCodeInput(QWidget *parent, const style::InputField &st);
public slots:
void startErasing(QKeyEvent *e);
void codeSelected(const QString &code);
signals:
void codeChanged(const QString &code);
void addedToNumber(const QString &added);
protected:
void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) override;
2016-11-24 19:28:23 +00:00
private:
bool _nosignal;
};
class PhonePartInput : public MaskedInputField {
Q_OBJECT
public:
PhonePartInput(QWidget *parent, const style::InputField &st);
public slots:
void addedToNumber(const QString &added);
void onChooseCode(const QString &code);
signals:
void voidBackspace(QKeyEvent *e);
protected:
void keyPressEvent(QKeyEvent *e) override;
void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) override;
2019-04-02 09:13:30 +00:00
void paintAdditionalPlaceholder(Painter &p) override;
2016-11-24 19:28:23 +00:00
private:
QVector<int> _pattern;
QString _additionalPlaceholder;
2016-11-24 19:28:23 +00:00
};
class PasswordInput : public MaskedInputField {
2015-10-11 08:37:24 +00:00
public:
PasswordInput(QWidget *parent, const style::InputField &st, rpl::producer<QString> placeholder = nullptr, const QString &val = QString());
2015-10-11 08:37:24 +00:00
};
2015-10-06 19:49:23 +00:00
2015-10-11 08:37:24 +00:00
class PortInput : public MaskedInputField {
2015-10-06 19:49:23 +00:00
public:
PortInput(QWidget *parent, const style::InputField &st, rpl::producer<QString> placeholder, const QString &val);
2015-10-06 19:49:23 +00:00
2018-04-28 15:58:22 +00:00
protected:
void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) override;
};
class HexInput : public MaskedInputField {
public:
HexInput(QWidget *parent, const style::InputField &st, rpl::producer<QString> placeholder, const QString &val);
2018-04-28 15:58:22 +00:00
2015-10-06 19:49:23 +00:00
protected:
void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) override;
2015-10-06 19:49:23 +00:00
};
class UsernameInput : public MaskedInputField {
public:
UsernameInput(
QWidget *parent,
const style::InputField &st,
rpl::producer<QString> placeholder,
const QString &val,
bool isLink);
2015-10-06 19:49:23 +00:00
2017-08-05 20:01:20 +00:00
void setLinkPlaceholder(const QString &placeholder);
2015-10-06 19:49:23 +00:00
protected:
void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) override;
2019-04-02 09:13:30 +00:00
void paintAdditionalPlaceholder(Painter &p) override;
2015-10-06 19:49:23 +00:00
private:
QString _linkPlaceholder;
2015-08-18 16:10:01 +00:00
};
2015-10-11 08:37:24 +00:00
class PhoneInput : public MaskedInputField {
public:
PhoneInput(
QWidget *parent,
const style::InputField &st,
rpl::producer<QString> placeholder,
2019-08-06 16:40:08 +00:00
const QString &defaultValue,
QString value);
2015-10-11 08:37:24 +00:00
void clearText();
protected:
void focusInEvent(QFocusEvent *e) override;
2015-10-11 08:37:24 +00:00
void correctValue(
const QString &was,
int wasCursor,
QString &now,
int &nowCursor) override;
2019-04-02 09:13:30 +00:00
void paintAdditionalPlaceholder(Painter &p) override;
2015-10-11 08:37:24 +00:00
private:
2019-08-06 16:40:08 +00:00
QString _defaultValue;
QVector<int> _pattern;
QString _additionalPlaceholder;
2015-10-11 08:37:24 +00:00
};
} // namespace Ui