diff --git a/ui/basic.style b/ui/basic.style index 9d0a66a..6c49f39 100644 --- a/ui/basic.style +++ b/ui/basic.style @@ -268,17 +268,6 @@ inlineRowFileDescriptionTop: 23px; inlineResultsMinWidth: 48px; 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 }}; historyReplyCancelIconOver: icon {{ "box_button_close", historyReplyCancelFgOver }}; boxTitleCloseIcon: icon {{ "box_button_close", boxTitleCloseFg }}; diff --git a/ui/toast/toast.cpp b/ui/toast/toast.cpp index 8c5075b..8bb9879 100644 --- a/ui/toast/toast.cpp +++ b/ui/toast/toast.cpp @@ -8,6 +8,7 @@ #include "ui/toast/toast_manager.h" #include "ui/toast/toast_widget.h" +#include "styles/style_widgets.h" namespace Ui { namespace Toast { @@ -21,13 +22,14 @@ Instance::Instance( const Config &config, not_null widgetParent, const Private &) -: _hideAtMs(crl::now() + config.durationMs) { +: _st(config.st) +, _hideAtMs(crl::now() + config.durationMs) { _widget = std::make_unique(widgetParent, config); _a_opacity.start( [=] { opacityAnimationCallback(); }, 0., 1., - st::toastFadeInDuration); + _st->durationFadeIn); } void SetDefaultParent(not_null parent) { @@ -49,15 +51,11 @@ void Show(const Config &config) { } void Show(not_null parent, const QString &text) { - auto config = Config(); - config.text = { text }; - Show(parent, config); + Show(parent, Config{ .text = { text }, .st = &st::defaultToast }); } void Show(const QString &text) { - auto config = Config(); - config.text = { text }; - Show(config); + Show(Config{ .text = { text }, .st = &st::defaultToast }); } void Instance::opacityAnimationCallback() { @@ -72,7 +70,11 @@ void Instance::opacityAnimationCallback() { void Instance::hideAnimated() { _hiding = true; - _a_opacity.start([this] { opacityAnimationCallback(); }, 1., 0., st::toastFadeOutDuration); + _a_opacity.start( + [=] { opacityAnimationCallback(); }, + 1., + 0., + _st->durationFadeOut); } void Instance::hide() { diff --git a/ui/toast/toast.h b/ui/toast/toast.h index b0e0198..43fef3a 100644 --- a/ui/toast/toast.h +++ b/ui/toast/toast.h @@ -10,6 +10,10 @@ #include "ui/text/text_entity.h" #include "ui/click_handler.h" +namespace style { +struct Toast; +} // namespace style + namespace Ui { namespace Toast { @@ -23,10 +27,8 @@ using ClickHandlerFilter = Fn; inline constexpr auto kDefaultDuration = crl::time(1500); struct Config { TextWithEntities text; - QMargins padding; + not_null st; crl::time durationMs = kDefaultDuration; - int minWidth = 0; - int maxWidth = 0; int maxLines = 16; bool multiline = false; bool dark = false; @@ -56,6 +58,8 @@ public: private: void opacityAnimationCallback(); + const not_null _st; + bool _hiding = false; Ui::Animations::Simple _a_opacity; diff --git a/ui/toast/toast_widget.cpp b/ui/toast/toast_widget.cpp index 933782c..b489cd4 100644 --- a/ui/toast/toast_widget.cpp +++ b/ui/toast/toast_widget.cpp @@ -8,6 +8,7 @@ #include "ui/image/image_prepare.h" #include "styles/palette.h" +#include "styles/style_widgets.h" #include @@ -17,15 +18,14 @@ namespace internal { Widget::Widget(QWidget *parent, const Config &config) : TWidget(parent) +, _st(config.st) , _roundRect(ImageRoundRadius::Large, st::toastBg) , _multiline(config.multiline) , _dark(config.dark) -, _maxWidth((config.maxWidth > 0) ? config.maxWidth : st::toastMaxWidth) -, _padding((config.padding.left() > 0) ? config.padding : st::toastPadding) -, _maxTextWidth(widthWithoutPadding(_maxWidth)) +, _maxTextWidth(widthWithoutPadding(_st->maxWidth)) , _maxTextHeight( - st::toastTextStyle.font->height * (_multiline ? config.maxLines : 1)) -, _text(_multiline ? widthWithoutPadding(config.minWidth) : QFIXED_MAX) + config.st->style.font->height * (_multiline ? config.maxLines : 1)) +, _text(_multiline ? widthWithoutPadding(config.st->minWidth) : QFIXED_MAX) , _clickHandlerFilter(config.filter) { const auto toastOptions = TextParseOptions{ TextParseMultiline, @@ -34,7 +34,7 @@ Widget::Widget(QWidget *parent, const Config &config) Qt::LayoutDirectionAuto }; _text.setMarkedText( - st::toastTextStyle, + _st->style, _multiline ? config.text : TextUtilities::SingleLine(config.text), toastOptions); @@ -49,15 +49,25 @@ Widget::Widget(QWidget *parent, const Config &config) } void Widget::onParentResized() { - auto newWidth = _maxWidth; - accumulate_min(newWidth, _padding.left() + _text.maxWidth() + _padding.right()); - accumulate_min(newWidth, parentWidget()->width() - 2 * st::toastMinMargin); + auto newWidth = _st->maxWidth; + accumulate_min( + newWidth, + _st->padding.left() + _text.maxWidth() + _st->padding.right()); + accumulate_min( + newWidth, + parentWidget()->width() - _st->margin.left() - _st->margin.right()); _textWidth = widthWithoutPadding(newWidth); const auto textHeight = _multiline ? qMin(_text.countHeight(_textWidth), _maxTextHeight) : _text.minHeight(); - const auto newHeight = _padding.top() + textHeight + _padding.bottom(); - setGeometry((parentWidget()->width() - newWidth) / 2, (parentWidget()->height() - newHeight) / 2, newWidth, newHeight); + const auto newHeight = _st->padding.top() + + textHeight + + _st->padding.bottom(); + setGeometry( + (parentWidget()->width() - newWidth) / 2, + (parentWidget()->height() - newHeight) / 2, + newWidth, + newHeight); } void Widget::setShownLevel(float64 shownLevel) { @@ -74,11 +84,16 @@ void Widget::paintEvent(QPaintEvent *e) { _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); - _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) { @@ -96,8 +111,9 @@ 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 point = e->pos() + - 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 was = ClickHandler::getActive(); 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 Toast } // namespace Ui diff --git a/ui/toast/toast_widget.h b/ui/toast/toast_widget.h index 22b6db8..79d91df 100644 --- a/ui/toast/toast_widget.h +++ b/ui/toast/toast_widget.h @@ -33,17 +33,14 @@ protected: void mouseReleaseEvent(QMouseEvent *e) override; private: - int widthWithoutPadding(int w) { - return w - _padding.left() - _padding.right(); - } + [[nodiscard]] int widthWithoutPadding(int w) const; + const not_null _st; RoundRect _roundRect; float64 _shownLevel = 0; bool _multiline = false; bool _dark = false; - int _maxWidth = 0; - QMargins _padding; int _maxTextWidth = 0; int _maxTextHeight = 0; diff --git a/ui/widgets/widgets.style b/ui/widgets/widgets.style index e6e9fae..030af37 100644 --- a/ui/widgets/widgets.style +++ b/ui/widgets/widgets.style @@ -568,6 +568,18 @@ SideBarButton { ripple: RippleAnimation; } +Toast { + style: TextStyle; + palette: TextPalette; + padding: margins; + margin: margins; + minWidth: pixels; + maxWidth: pixels; + durationFadeIn: int; + durationFadeOut: int; + durationSlide: int; +} + defaultLabelSimple: LabelSimple { font: normalFont; 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 windowTitleButton: IconButton {