Support rich text in toasts.

This commit is contained in:
John Preston 2020-04-07 13:58:24 +04:00
parent 14c5da49f9
commit 8d8d561127
7 changed files with 75 additions and 5 deletions

View file

@ -271,6 +271,10 @@ inlineResultsMinWidth: 48px;
inlineDurationMargin: 3px;
toastTextStyle: defaultTextStyle;
toastTextPalette: TextPalette(defaultTextPalette) {
linkFg: mediaviewTextLinkFg;
monoFg: mediaviewCaptionFg;
}
toastMaxWidth: 480px;
toastMinMargin: 13px;
toastPadding: margins(19px, 13px, 19px, 12px);

View file

@ -1321,6 +1321,12 @@ QString SingleLine(const QString &text) {
return result;
}
TextWithEntities SingleLine(const TextWithEntities &text) {
auto copy = text;
Trim(copy);
return { SingleLine(copy.text), std::move(copy.entities) };
}
QString RemoveAccents(const QString &text) {
auto result = text;
auto copying = false;

View file

@ -285,6 +285,7 @@ QString MarkdownPreBadAfter();
QString Clean(const QString &text);
QString EscapeForRichParsing(const QString &text);
QString SingleLine(const QString &text);
TextWithEntities SingleLine(const TextWithEntities &text);
QString RemoveAccents(const QString &text);
QString RemoveEmoji(const QString &text);
QStringList PrepareSearchWords(const QString &query, const QRegularExpression *SplitterOverride = nullptr);

View file

@ -50,13 +50,13 @@ void Show(const Config &config) {
void Show(not_null<QWidget*> parent, const QString &text) {
auto config = Config();
config.text = text;
config.text = { text };
Show(parent, config);
}
void Show(const QString &text) {
auto config = Config();
config.text = text;
config.text = { text };
Show(config);
}

View file

@ -7,6 +7,7 @@
#pragma once
#include "ui/effects/animations.h"
#include "ui/text/text_entity.h"
namespace Ui {
namespace Toast {
@ -18,7 +19,7 @@ class Widget;
inline constexpr auto kDefaultDuration = crl::time(1500);
struct Config {
QString text;
TextWithEntities text;
QMargins padding;
crl::time durationMs = kDefaultDuration;
int minWidth = 0;

View file

@ -9,6 +9,8 @@
#include "ui/image/image_prepare.h"
#include "styles/palette.h"
#include <QtGui/QtEvents>
namespace Ui {
namespace Toast {
namespace internal {
@ -29,12 +31,16 @@ Widget::Widget(QWidget *parent, const Config &config)
_maxTextHeight,
Qt::LayoutDirectionAuto
};
_text.setText(
_text.setMarkedText(
st::toastTextStyle,
_multiline ? config.text : TextUtilities::SingleLine(config.text),
toastOptions);
setAttribute(Qt::WA_TransparentForMouseEvents);
if (_text.hasLinks()) {
setMouseTracking(true);
} else {
setAttribute(Qt::WA_TransparentForMouseEvents);
}
onParentResized();
show();
@ -63,11 +69,58 @@ void Widget::paintEvent(QPaintEvent *e) {
p.setOpacity(_shownLevel);
_roundRect.paint(p, rect());
p.setTextPalette(st::toastTextPalette);
const auto lines = _maxTextHeight / st::toastTextStyle.font->height;
p.setPen(st::toastFg);
_text.drawElided(p, _padding.left(), _padding.top(), _textWidth + 1, lines);
}
void Widget::leaveEventHook(QEvent *e) {
if (!_text.hasLinks()) {
return;
}
if (ClickHandler::getActive()) {
ClickHandler::setActive(nullptr);
setCursor(style::cur_default);
update();
}
}
void Widget::mouseMoveEvent(QMouseEvent *e) {
if (!_text.hasLinks()) {
return;
}
const auto point = e->pos() - QPoint(_padding.left(), _padding.top());
const auto lines = _maxTextHeight / st::toastTextStyle.font->height;
const auto state = _text.getStateElided(point, _textWidth + 1);
const auto was = ClickHandler::getActive();
if (was != state.link) {
ClickHandler::setActive(state.link);
if ((was != nullptr) != (state.link != nullptr)) {
setCursor(was ? style::cur_default : style::cur_pointer);
}
update();
}
}
void Widget::mousePressEvent(QMouseEvent *e) {
if (!_text.hasLinks() || e->button() != Qt::LeftButton) {
return;
}
ClickHandler::pressed();
}
void Widget::mouseReleaseEvent(QMouseEvent *e) {
if (!_text.hasLinks() || e->button() != Qt::LeftButton) {
return;
}
if (const auto handler = ClickHandler::unpressed()) {
handler->onClick({ e->button() });
}
}
} // namespace internal
} // namespace Toast
} // namespace Ui

View file

@ -27,6 +27,11 @@ public:
protected:
void paintEvent(QPaintEvent *e) override;
void leaveEventHook(QEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
private:
int widthWithoutPadding(int w) {
return w - _padding.left() - _padding.right();