Improve toasts: adaptive, with a title.
This commit is contained in:
parent
91d43ea4b5
commit
ad356135e4
5 changed files with 60 additions and 14 deletions
|
|
@ -33,10 +33,12 @@ 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 {
|
||||||
|
QString title;
|
||||||
TextWithEntities text;
|
TextWithEntities text;
|
||||||
not_null<const style::Toast*> st = &st::defaultMultilineToast;
|
not_null<const style::Toast*> st = &st::defaultMultilineToast;
|
||||||
crl::time duration = kDefaultDuration;
|
crl::time duration = kDefaultDuration;
|
||||||
int maxLines = 16;
|
int maxLines = 16;
|
||||||
|
bool adaptive = false;
|
||||||
bool multiline = true;
|
bool multiline = true;
|
||||||
bool dark = false;
|
bool dark = false;
|
||||||
RectPart slideSide = RectPart::None;
|
RectPart slideSide = RectPart::None;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include "ui/toast/toast_widget.h"
|
#include "ui/toast/toast_widget.h"
|
||||||
|
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "styles/palette.h"
|
#include "styles/palette.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
|
@ -16,6 +18,21 @@
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
namespace Toast {
|
namespace Toast {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] TextWithEntities ComputeText(const Config &config) {
|
||||||
|
auto result = config.text;
|
||||||
|
if (!config.title.isEmpty()) {
|
||||||
|
result = Text::Bold(
|
||||||
|
config.title
|
||||||
|
).append('\n').append(std::move(result));
|
||||||
|
}
|
||||||
|
return config.multiline
|
||||||
|
? result
|
||||||
|
: TextUtilities::SingleLine(std::move(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
Widget::Widget(QWidget *parent, const Config &config)
|
Widget::Widget(QWidget *parent, const Config &config)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
|
|
@ -24,6 +41,7 @@ Widget::Widget(QWidget *parent, const Config &config)
|
||||||
, _slideSide(config.slideSide)
|
, _slideSide(config.slideSide)
|
||||||
, _multiline(config.multiline)
|
, _multiline(config.multiline)
|
||||||
, _dark(config.dark)
|
, _dark(config.dark)
|
||||||
|
, _adaptive(config.adaptive)
|
||||||
, _maxTextWidth(widthWithoutPadding(_st->maxWidth))
|
, _maxTextWidth(widthWithoutPadding(_st->maxWidth))
|
||||||
, _maxTextHeight(
|
, _maxTextHeight(
|
||||||
config.st->style.font->height * (_multiline ? config.maxLines : 1))
|
config.st->style.font->height * (_multiline ? config.maxLines : 1))
|
||||||
|
|
@ -37,7 +55,7 @@ Widget::Widget(QWidget *parent, const Config &config)
|
||||||
};
|
};
|
||||||
_text.setMarkedText(
|
_text.setMarkedText(
|
||||||
_st->style,
|
_st->style,
|
||||||
_multiline ? config.text : TextUtilities::SingleLine(config.text),
|
ComputeText(config),
|
||||||
toastOptions,
|
toastOptions,
|
||||||
config.textContext ? config.textContext(this) : std::any());
|
config.textContext ? config.textContext(this) : std::any());
|
||||||
if (_text.hasSpoilers()) {
|
if (_text.hasSpoilers()) {
|
||||||
|
|
@ -74,6 +92,12 @@ void Widget::updateGeometry() {
|
||||||
accumulate_min(
|
accumulate_min(
|
||||||
width,
|
width,
|
||||||
parentWidget()->width() - _st->margin.left() - _st->margin.right());
|
parentWidget()->width() - _st->margin.left() - _st->margin.right());
|
||||||
|
if (_adaptive) {
|
||||||
|
const auto added = _st->padding.left() + _st->padding.right();
|
||||||
|
width = FindNiceTooltipWidth(0, width - added, [&](int width) {
|
||||||
|
return _text.countHeight(width);
|
||||||
|
}) + added;
|
||||||
|
}
|
||||||
_textWidth = widthWithoutPadding(width);
|
_textWidth = widthWithoutPadding(width);
|
||||||
_textHeight = _multiline
|
_textHeight = _multiline
|
||||||
? qMin(_text.countHeight(_textWidth), _maxTextHeight)
|
? qMin(_text.countHeight(_textWidth), _maxTextHeight)
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ private:
|
||||||
bool _multiline = false;
|
bool _multiline = false;
|
||||||
bool _dark = false;
|
bool _dark = false;
|
||||||
bool _processMouse = false;
|
bool _processMouse = false;
|
||||||
|
bool _adaptive = false;
|
||||||
|
|
||||||
int _maxTextWidth = 0;
|
int _maxTextWidth = 0;
|
||||||
int _maxTextHeight = 0;
|
int _maxTextHeight = 0;
|
||||||
|
|
|
||||||
|
|
@ -411,6 +411,25 @@ void ImportantTooltip::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] int FindNiceTooltipWidth(
|
||||||
|
int minWidth,
|
||||||
|
int maxWidth,
|
||||||
|
Fn<int(int width)> heightForWidth) {
|
||||||
|
Expects(minWidth >= 0);
|
||||||
|
Expects(maxWidth > minWidth);
|
||||||
|
|
||||||
|
const auto desired = heightForWidth(maxWidth);
|
||||||
|
while (maxWidth - minWidth > 1) {
|
||||||
|
const auto middle = (minWidth + maxWidth) / 2;
|
||||||
|
if (heightForWidth(middle) > desired) {
|
||||||
|
minWidth = middle;
|
||||||
|
} else {
|
||||||
|
maxWidth = middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxWidth;
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<FlatLabel> MakeNiceTooltipLabel(
|
object_ptr<FlatLabel> MakeNiceTooltipLabel(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<TextWithEntities> &&text,
|
rpl::producer<TextWithEntities> &&text,
|
||||||
|
|
@ -431,19 +450,14 @@ object_ptr<FlatLabel> MakeNiceTooltipLabel(
|
||||||
if (raw->naturalWidth() <= maxWidth) {
|
if (raw->naturalWidth() <= maxWidth) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto desired = raw->heightNoMargins();
|
const auto niceWidth = FindNiceTooltipWidth(
|
||||||
auto from = st.minWidth;
|
st.minWidth,
|
||||||
auto till = maxWidth;
|
maxWidth,
|
||||||
while (till - from > 1) {
|
[&](int width) {
|
||||||
const auto middle = (from + till) / 2;
|
raw->resizeToWidth(width);
|
||||||
raw->resizeToWidth(middle);
|
return raw->heightNoMargins();
|
||||||
if (raw->heightNoMargins() > desired) {
|
});
|
||||||
from = middle;
|
raw->resizeToWidth(niceWidth);
|
||||||
} else {
|
|
||||||
till = middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
raw->resizeToWidth(till);
|
|
||||||
}, raw->lifetime());
|
}, raw->lifetime());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,11 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] int FindNiceTooltipWidth(
|
||||||
|
int minWidth,
|
||||||
|
int maxWidth,
|
||||||
|
Fn<int(int width)> heightForWidth);
|
||||||
|
|
||||||
[[nodiscard]] object_ptr<FlatLabel> MakeNiceTooltipLabel(
|
[[nodiscard]] object_ptr<FlatLabel> MakeNiceTooltipLabel(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<TextWithEntities> &&text,
|
rpl::producer<TextWithEntities> &&text,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue