Introduce a toast style structure.

This commit is contained in:
John Preston 2020-04-29 18:52:18 +04:00
parent 1647b0b76a
commit 48a8315740
6 changed files with 82 additions and 44 deletions

View file

@ -268,17 +268,6 @@ inlineRowFileDescriptionTop: 23px;
inlineResultsMinWidth: 48px; inlineResultsMinWidth: 48px;
inlineDurationMargin: 3px; inlineDurationMargin: 3px;
toastTextStyle: defaultTextStyle;
toastTextPalette: TextPalette(defaultTextPalette) {
linkFg: mediaviewTextLinkFg;
monoFg: mediaviewCaptionFg;
}
toastMaxWidth: 480px;
toastMinMargin: 13px;
toastPadding: margins(19px, 13px, 19px, 12px);
toastFadeInDuration: 200;
toastFadeOutDuration: 1000;
historyReplyCancelIcon: icon {{ "box_button_close", historyReplyCancelFg }}; historyReplyCancelIcon: icon {{ "box_button_close", historyReplyCancelFg }};
historyReplyCancelIconOver: icon {{ "box_button_close", historyReplyCancelFgOver }}; historyReplyCancelIconOver: icon {{ "box_button_close", historyReplyCancelFgOver }};
boxTitleCloseIcon: icon {{ "box_button_close", boxTitleCloseFg }}; boxTitleCloseIcon: icon {{ "box_button_close", boxTitleCloseFg }};

View file

@ -8,6 +8,7 @@
#include "ui/toast/toast_manager.h" #include "ui/toast/toast_manager.h"
#include "ui/toast/toast_widget.h" #include "ui/toast/toast_widget.h"
#include "styles/style_widgets.h"
namespace Ui { namespace Ui {
namespace Toast { namespace Toast {
@ -21,13 +22,14 @@ Instance::Instance(
const Config &config, const Config &config,
not_null<QWidget*> widgetParent, not_null<QWidget*> widgetParent,
const Private &) const Private &)
: _hideAtMs(crl::now() + config.durationMs) { : _st(config.st)
, _hideAtMs(crl::now() + config.durationMs) {
_widget = std::make_unique<internal::Widget>(widgetParent, config); _widget = std::make_unique<internal::Widget>(widgetParent, config);
_a_opacity.start( _a_opacity.start(
[=] { opacityAnimationCallback(); }, [=] { opacityAnimationCallback(); },
0., 0.,
1., 1.,
st::toastFadeInDuration); _st->durationFadeIn);
} }
void SetDefaultParent(not_null<QWidget*> parent) { void SetDefaultParent(not_null<QWidget*> parent) {
@ -49,15 +51,11 @@ void Show(const Config &config) {
} }
void Show(not_null<QWidget*> parent, const QString &text) { void Show(not_null<QWidget*> parent, const QString &text) {
auto config = Config(); Show(parent, Config{ .text = { text }, .st = &st::defaultToast });
config.text = { text };
Show(parent, config);
} }
void Show(const QString &text) { void Show(const QString &text) {
auto config = Config(); Show(Config{ .text = { text }, .st = &st::defaultToast });
config.text = { text };
Show(config);
} }
void Instance::opacityAnimationCallback() { void Instance::opacityAnimationCallback() {
@ -72,7 +70,11 @@ void Instance::opacityAnimationCallback() {
void Instance::hideAnimated() { void Instance::hideAnimated() {
_hiding = true; _hiding = true;
_a_opacity.start([this] { opacityAnimationCallback(); }, 1., 0., st::toastFadeOutDuration); _a_opacity.start(
[=] { opacityAnimationCallback(); },
1.,
0.,
_st->durationFadeOut);
} }
void Instance::hide() { void Instance::hide() {

View file

@ -10,6 +10,10 @@
#include "ui/text/text_entity.h" #include "ui/text/text_entity.h"
#include "ui/click_handler.h" #include "ui/click_handler.h"
namespace style {
struct Toast;
} // namespace style
namespace Ui { namespace Ui {
namespace Toast { namespace Toast {
@ -23,10 +27,8 @@ using ClickHandlerFilter = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>;
inline constexpr auto kDefaultDuration = crl::time(1500); inline constexpr auto kDefaultDuration = crl::time(1500);
struct Config { struct Config {
TextWithEntities text; TextWithEntities text;
QMargins padding; not_null<const style::Toast*> st;
crl::time durationMs = kDefaultDuration; crl::time durationMs = kDefaultDuration;
int minWidth = 0;
int maxWidth = 0;
int maxLines = 16; int maxLines = 16;
bool multiline = false; bool multiline = false;
bool dark = false; bool dark = false;
@ -56,6 +58,8 @@ public:
private: private:
void opacityAnimationCallback(); void opacityAnimationCallback();
const not_null<const style::Toast*> _st;
bool _hiding = false; bool _hiding = false;
Ui::Animations::Simple _a_opacity; Ui::Animations::Simple _a_opacity;

View file

@ -8,6 +8,7 @@
#include "ui/image/image_prepare.h" #include "ui/image/image_prepare.h"
#include "styles/palette.h" #include "styles/palette.h"
#include "styles/style_widgets.h"
#include <QtGui/QtEvents> #include <QtGui/QtEvents>
@ -17,15 +18,14 @@ namespace internal {
Widget::Widget(QWidget *parent, const Config &config) Widget::Widget(QWidget *parent, const Config &config)
: TWidget(parent) : TWidget(parent)
, _st(config.st)
, _roundRect(ImageRoundRadius::Large, st::toastBg) , _roundRect(ImageRoundRadius::Large, st::toastBg)
, _multiline(config.multiline) , _multiline(config.multiline)
, _dark(config.dark) , _dark(config.dark)
, _maxWidth((config.maxWidth > 0) ? config.maxWidth : st::toastMaxWidth) , _maxTextWidth(widthWithoutPadding(_st->maxWidth))
, _padding((config.padding.left() > 0) ? config.padding : st::toastPadding)
, _maxTextWidth(widthWithoutPadding(_maxWidth))
, _maxTextHeight( , _maxTextHeight(
st::toastTextStyle.font->height * (_multiline ? config.maxLines : 1)) config.st->style.font->height * (_multiline ? config.maxLines : 1))
, _text(_multiline ? widthWithoutPadding(config.minWidth) : QFIXED_MAX) , _text(_multiline ? widthWithoutPadding(config.st->minWidth) : QFIXED_MAX)
, _clickHandlerFilter(config.filter) { , _clickHandlerFilter(config.filter) {
const auto toastOptions = TextParseOptions{ const auto toastOptions = TextParseOptions{
TextParseMultiline, TextParseMultiline,
@ -34,7 +34,7 @@ Widget::Widget(QWidget *parent, const Config &config)
Qt::LayoutDirectionAuto Qt::LayoutDirectionAuto
}; };
_text.setMarkedText( _text.setMarkedText(
st::toastTextStyle, _st->style,
_multiline ? config.text : TextUtilities::SingleLine(config.text), _multiline ? config.text : TextUtilities::SingleLine(config.text),
toastOptions); toastOptions);
@ -49,15 +49,25 @@ Widget::Widget(QWidget *parent, const Config &config)
} }
void Widget::onParentResized() { void Widget::onParentResized() {
auto newWidth = _maxWidth; auto newWidth = _st->maxWidth;
accumulate_min(newWidth, _padding.left() + _text.maxWidth() + _padding.right()); accumulate_min(
accumulate_min(newWidth, parentWidget()->width() - 2 * st::toastMinMargin); newWidth,
_st->padding.left() + _text.maxWidth() + _st->padding.right());
accumulate_min(
newWidth,
parentWidget()->width() - _st->margin.left() - _st->margin.right());
_textWidth = widthWithoutPadding(newWidth); _textWidth = widthWithoutPadding(newWidth);
const auto textHeight = _multiline const auto textHeight = _multiline
? qMin(_text.countHeight(_textWidth), _maxTextHeight) ? qMin(_text.countHeight(_textWidth), _maxTextHeight)
: _text.minHeight(); : _text.minHeight();
const auto newHeight = _padding.top() + textHeight + _padding.bottom(); const auto newHeight = _st->padding.top()
setGeometry((parentWidget()->width() - newWidth) / 2, (parentWidget()->height() - newHeight) / 2, newWidth, newHeight); + textHeight
+ _st->padding.bottom();
setGeometry(
(parentWidget()->width() - newWidth) / 2,
(parentWidget()->height() - newHeight) / 2,
newWidth,
newHeight);
} }
void Widget::setShownLevel(float64 shownLevel) { void Widget::setShownLevel(float64 shownLevel) {
@ -74,11 +84,16 @@ void Widget::paintEvent(QPaintEvent *e) {
_roundRect.paint(p, rect()); _roundRect.paint(p, rect());
} }
p.setTextPalette(st::toastTextPalette); p.setTextPalette(_st->palette);
const auto lines = _maxTextHeight / st::toastTextStyle.font->height; const auto lines = _maxTextHeight / _st->style.font->height;
p.setPen(st::toastFg); p.setPen(st::toastFg);
_text.drawElided(p, _padding.left(), _padding.top(), _textWidth + 1, lines); _text.drawElided(
p,
_st->padding.left(),
_st->padding.top(),
_textWidth + 1,
lines);
} }
void Widget::leaveEventHook(QEvent *e) { void Widget::leaveEventHook(QEvent *e) {
@ -96,8 +111,9 @@ void Widget::mouseMoveEvent(QMouseEvent *e) {
if (!_text.hasLinks()) { if (!_text.hasLinks()) {
return; return;
} }
const auto point = e->pos() - QPoint(_padding.left(), _padding.top()); const auto point = e->pos()
const auto lines = _maxTextHeight / st::toastTextStyle.font->height; - QPoint(_st->padding.left(), _st->padding.top());
const auto lines = _maxTextHeight / _st->style.font->height;
const auto state = _text.getStateElided(point, _textWidth + 1); const auto state = _text.getStateElided(point, _textWidth + 1);
const auto was = ClickHandler::getActive(); const auto was = ClickHandler::getActive();
if (was != state.link) { if (was != state.link) {
@ -129,6 +145,10 @@ void Widget::mouseReleaseEvent(QMouseEvent *e) {
} }
} }
int Widget::widthWithoutPadding(int w) const {
return w - _st->padding.left() - _st->padding.right();
}
} // namespace internal } // namespace internal
} // namespace Toast } // namespace Toast
} // namespace Ui } // namespace Ui

View file

@ -33,17 +33,14 @@ protected:
void mouseReleaseEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override;
private: private:
int widthWithoutPadding(int w) { [[nodiscard]] int widthWithoutPadding(int w) const;
return w - _padding.left() - _padding.right();
}
const not_null<const style::Toast*> _st;
RoundRect _roundRect; RoundRect _roundRect;
float64 _shownLevel = 0; float64 _shownLevel = 0;
bool _multiline = false; bool _multiline = false;
bool _dark = false; bool _dark = false;
int _maxWidth = 0;
QMargins _padding;
int _maxTextWidth = 0; int _maxTextWidth = 0;
int _maxTextHeight = 0; int _maxTextHeight = 0;

View file

@ -568,6 +568,18 @@ SideBarButton {
ripple: RippleAnimation; ripple: RippleAnimation;
} }
Toast {
style: TextStyle;
palette: TextPalette;
padding: margins;
margin: margins;
minWidth: pixels;
maxWidth: pixels;
durationFadeIn: int;
durationFadeOut: int;
durationSlide: int;
}
defaultLabelSimple: LabelSimple { defaultLabelSimple: LabelSimple {
font: normalFont; font: normalFont;
maxWidth: 0px; maxWidth: 0px;
@ -1266,6 +1278,20 @@ defaultSideBarButton: SideBarButton {
} }
} }
defaultToast: Toast {
style: defaultTextStyle;
palette: TextPalette(defaultTextPalette) {
linkFg: mediaviewTextLinkFg;
monoFg: mediaviewCaptionFg;
}
padding: margins(19px, 13px, 19px, 12px);
margin: margins(13px, 13px, 13px, 13px);
maxWidth: 480px;
durationFadeIn: 200;
durationFadeOut: 1000;
durationSlide: 400;
}
// Windows specific title // Windows specific title
windowTitleButton: IconButton { windowTitleButton: IconButton {