mirror of https://github.com/procxx/kepka.git
Use toasts from lib_ui.
This commit is contained in:
parent
2d3f683003
commit
959901d599
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
#include "ui/toast/toast.h"
|
|
||||||
|
|
||||||
#include "ui/toast/toast_manager.h"
|
|
||||||
#include "ui/toast/toast_widget.h"
|
|
||||||
#include "mainwindow.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
namespace Toast {
|
|
||||||
|
|
||||||
Instance::Instance(const Config &config, QWidget *widgetParent, const Private &)
|
|
||||||
: _hideAtMs(crl::now() + config.durationMs) {
|
|
||||||
_widget = std::make_unique<internal::Widget>(widgetParent, config);
|
|
||||||
_a_opacity.start([this] { opacityAnimationCallback(); }, 0., 1., st::toastFadeInDuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Show(QWidget *parent, const Config &config) {
|
|
||||||
if (auto manager = internal::Manager::instance(parent)) {
|
|
||||||
auto toast = std::make_unique<Instance>(config, parent, Instance::Private());
|
|
||||||
manager->addToast(std::move(toast));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Show(const Config &config) {
|
|
||||||
if (auto window = App::wnd()) {
|
|
||||||
Show(window->bodyWidget(), config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Show(const QString &text) {
|
|
||||||
Config toast;
|
|
||||||
toast.text = text;
|
|
||||||
Show(toast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::opacityAnimationCallback() {
|
|
||||||
_widget->setShownLevel(_a_opacity.value(_hiding ? 0. : 1.));
|
|
||||||
_widget->update();
|
|
||||||
if (!_a_opacity.animating()) {
|
|
||||||
if (_hiding) {
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::hideAnimated() {
|
|
||||||
_hiding = true;
|
|
||||||
_a_opacity.start([this] { opacityAnimationCallback(); }, 1., 0., st::toastFadeOutDuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::hide() {
|
|
||||||
_widget->hide();
|
|
||||||
_widget->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Toast
|
|
||||||
} // namespace Ui
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
|
|
||||||
#include "ui/effects/animations.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
namespace Toast {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
class Manager;
|
|
||||||
class Widget;
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
static constexpr const int DefaultDuration = 1500;
|
|
||||||
struct Config {
|
|
||||||
QString text;
|
|
||||||
QMargins padding;
|
|
||||||
int durationMs = DefaultDuration;
|
|
||||||
int minWidth = 0;
|
|
||||||
int maxWidth = 0;
|
|
||||||
int maxLines = 16;
|
|
||||||
bool multiline = false;
|
|
||||||
};
|
|
||||||
void Show(QWidget *parent, const Config &config);
|
|
||||||
void Show(const Config &config);
|
|
||||||
void Show(const QString &text);
|
|
||||||
|
|
||||||
class Instance {
|
|
||||||
struct Private {
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Instance(const Config &config, QWidget *widgetParent, const Private &);
|
|
||||||
Instance(const Instance &other) = delete;
|
|
||||||
Instance &operator=(const Instance &other) = delete;
|
|
||||||
|
|
||||||
void hideAnimated();
|
|
||||||
void hide();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void opacityAnimationCallback();
|
|
||||||
|
|
||||||
bool _hiding = false;
|
|
||||||
Ui::Animations::Simple _a_opacity;
|
|
||||||
|
|
||||||
const crl::time _hideAtMs;
|
|
||||||
|
|
||||||
// ToastManager should reset _widget pointer if _widget is destroyed.
|
|
||||||
friend class internal::Manager;
|
|
||||||
friend void Show(QWidget *parent, const Config &config);
|
|
||||||
std::unique_ptr<internal::Widget> _widget;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Toast
|
|
||||||
} // namespace Ui
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
#include "ui/toast/toast_manager.h"
|
|
||||||
|
|
||||||
#include "ui/toast/toast_widget.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
namespace Toast {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
NeverFreedPointer<QMap<QObject*, Manager*>> _managers;
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
Manager::Manager(QWidget *parent) : QObject(parent)
|
|
||||||
, _hideTimer([=] { hideByTimer(); }) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::eventFilter(QObject *o, QEvent *e) {
|
|
||||||
if (e->type() == QEvent::Resize) {
|
|
||||||
for (auto i = _toastByWidget.cbegin(), e = _toastByWidget.cend(); i != e; ++i) {
|
|
||||||
if (i.key()->parentWidget() == o) {
|
|
||||||
i.key()->onParentResized();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QObject::eventFilter(o, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Manager *Manager::instance(QWidget *parent) {
|
|
||||||
if (!parent) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
_managers.createIfNull();
|
|
||||||
auto i = _managers->constFind(parent);
|
|
||||||
if (i == _managers->cend()) {
|
|
||||||
i = _managers->insert(parent, new Manager(parent));
|
|
||||||
}
|
|
||||||
return i.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::addToast(std::unique_ptr<Instance> &&toast) {
|
|
||||||
_toasts.push_back(toast.release());
|
|
||||||
Instance *t = _toasts.back();
|
|
||||||
Widget *widget = t->_widget.get();
|
|
||||||
|
|
||||||
_toastByWidget.insert(widget, t);
|
|
||||||
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onToastWidgetDestroyed(QObject*)));
|
|
||||||
if (auto parent = widget->parentWidget()) {
|
|
||||||
auto found = false;
|
|
||||||
for (auto i = _toastParents.begin(); i != _toastParents.cend();) {
|
|
||||||
if (*i == parent) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
} else if (!*i) {
|
|
||||||
i = _toastParents.erase(i);
|
|
||||||
} else {
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
_toastParents.insert(parent);
|
|
||||||
parent->installEventFilter(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto oldHideNearestMs = _toastByHideTime.isEmpty() ? 0LL : _toastByHideTime.firstKey();
|
|
||||||
_toastByHideTime.insert(t->_hideAtMs, t);
|
|
||||||
if (!oldHideNearestMs || _toastByHideTime.firstKey() < oldHideNearestMs) {
|
|
||||||
startNextHideTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::hideByTimer() {
|
|
||||||
auto now = crl::now();
|
|
||||||
for (auto i = _toastByHideTime.begin(); i != _toastByHideTime.cend();) {
|
|
||||||
if (i.key() <= now) {
|
|
||||||
auto toast = i.value();
|
|
||||||
i = _toastByHideTime.erase(i);
|
|
||||||
toast->hideAnimated();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startNextHideTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::onToastWidgetDestroyed(QObject *widget) {
|
|
||||||
auto i = _toastByWidget.find(static_cast<Widget*>(widget));
|
|
||||||
if (i != _toastByWidget.cend()) {
|
|
||||||
auto toast = i.value();
|
|
||||||
_toastByWidget.erase(i);
|
|
||||||
toast->_widget.release();
|
|
||||||
|
|
||||||
int index = _toasts.indexOf(toast);
|
|
||||||
if (index >= 0) {
|
|
||||||
_toasts.removeAt(index);
|
|
||||||
delete toast;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::startNextHideTimer() {
|
|
||||||
if (_toastByHideTime.isEmpty()) return;
|
|
||||||
|
|
||||||
auto ms = crl::now();
|
|
||||||
if (ms >= _toastByHideTime.firstKey()) {
|
|
||||||
crl::on_main(this, [=] {
|
|
||||||
hideByTimer();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_hideTimer.callOnce(_toastByHideTime.firstKey() - ms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Manager::~Manager() {
|
|
||||||
_managers->remove(parent());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Toast
|
|
||||||
} // namespace Ui
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
|
|
||||||
#include "ui/toast/toast.h"
|
|
||||||
#include "base/timer.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
namespace Toast {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class Widget;
|
|
||||||
class Manager : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
Manager(const Manager &other) = delete;
|
|
||||||
Manager &operator=(const Manager &other) = delete;
|
|
||||||
|
|
||||||
static Manager *instance(QWidget *parent);
|
|
||||||
|
|
||||||
void addToast(std::unique_ptr<Instance> &&toast);
|
|
||||||
|
|
||||||
~Manager();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool eventFilter(QObject *o, QEvent *e);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onToastWidgetDestroyed(QObject *widget);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Manager(QWidget *parent);
|
|
||||||
void startNextHideTimer();
|
|
||||||
void hideByTimer();
|
|
||||||
|
|
||||||
base::Timer _hideTimer;
|
|
||||||
crl::time _nextHide = 0;
|
|
||||||
|
|
||||||
QMultiMap<crl::time, Instance*> _toastByHideTime;
|
|
||||||
QMap<Widget*, Instance*> _toastByWidget;
|
|
||||||
QList<Instance*> _toasts;
|
|
||||||
OrderedSet<QPointer<QWidget>> _toastParents;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Toast
|
|
||||||
} // namespace Ui
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
*/
|
|
||||||
#include "ui/toast/toast_widget.h"
|
|
||||||
|
|
||||||
#include "ui/image/image_prepare.h"
|
|
||||||
#include "app.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
namespace Toast {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
Widget::Widget(QWidget *parent, const Config &config) : TWidget(parent)
|
|
||||||
, _multiline(config.multiline)
|
|
||||||
, _maxWidth((config.maxWidth > 0) ? config.maxWidth : st::toastMaxWidth)
|
|
||||||
, _padding((config.padding.left() > 0) ? config.padding : st::toastPadding)
|
|
||||||
, _maxTextWidth(widthWithoutPadding(_maxWidth))
|
|
||||||
, _maxTextHeight(
|
|
||||||
st::toastTextStyle.font->height * (_multiline ? config.maxLines : 1))
|
|
||||||
, _text(_multiline ? widthWithoutPadding(config.minWidth) : QFIXED_MAX) {
|
|
||||||
const auto toastOptions = TextParseOptions{
|
|
||||||
TextParseMultiline,
|
|
||||||
_maxTextWidth,
|
|
||||||
_maxTextHeight,
|
|
||||||
Qt::LayoutDirectionAuto
|
|
||||||
};
|
|
||||||
_text.setText(
|
|
||||||
st::toastTextStyle,
|
|
||||||
_multiline ? config.text : TextUtilities::SingleLine(config.text),
|
|
||||||
toastOptions);
|
|
||||||
|
|
||||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
|
|
||||||
onParentResized();
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::onParentResized() {
|
|
||||||
auto newWidth = _maxWidth;
|
|
||||||
accumulate_min(newWidth, _padding.left() + _text.maxWidth() + _padding.right());
|
|
||||||
accumulate_min(newWidth, parentWidget()->width() - 2 * st::toastMinMargin);
|
|
||||||
_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setShownLevel(float64 shownLevel) {
|
|
||||||
_shownLevel = shownLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::paintEvent(QPaintEvent *e) {
|
|
||||||
Painter p(this);
|
|
||||||
PainterHighQualityEnabler hq(p);
|
|
||||||
|
|
||||||
p.setOpacity(_shownLevel);
|
|
||||||
App::roundRect(p, rect(), st::toastBg, ImageRoundRadius::Large);
|
|
||||||
|
|
||||||
const auto lines = _maxTextHeight / st::toastTextStyle.font->height;
|
|
||||||
p.setPen(st::toastFg);
|
|
||||||
_text.drawElided(p, _padding.left(), _padding.top(), _textWidth + 1, lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Toast
|
|
||||||
} // namespace Ui
|
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
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
|
|
||||||
|
|
||||||
#include "ui/toast/toast.h"
|
|
||||||
#include "ui/rp_widget.h"
|
|
||||||
#include "ui/text/text.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
namespace Toast {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class Widget : public TWidget {
|
|
||||||
public:
|
|
||||||
Widget(QWidget *parent, const Config &config);
|
|
||||||
|
|
||||||
// shownLevel=1 completely visible, shownLevel=0 completely invisible
|
|
||||||
void setShownLevel(float64 shownLevel);
|
|
||||||
|
|
||||||
void onParentResized();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline int widthWithoutPadding(int w) {
|
|
||||||
return w - _padding.left() - _padding.right();
|
|
||||||
}
|
|
||||||
|
|
||||||
float64 _shownLevel = 0;
|
|
||||||
bool _multiline = false;
|
|
||||||
int _maxWidth = 0;
|
|
||||||
QMargins _padding;
|
|
||||||
|
|
||||||
int _maxTextWidth = 0;
|
|
||||||
int _maxTextHeight = 0;
|
|
||||||
int _textWidth = 0;
|
|
||||||
Text::String _text;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace Toast
|
|
||||||
} // namespace Ui
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "base/crc32hash.h"
|
#include "base/crc32hash.h"
|
||||||
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
@ -145,6 +146,8 @@ MainWindow::MainWindow(not_null<Controller*> controller)
|
||||||
checkLockByTerms();
|
checkLockByTerms();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
Ui::Toast::SetDefaultParent(_body.data());
|
||||||
|
|
||||||
if (_outdated) {
|
if (_outdated) {
|
||||||
_outdated->heightValue(
|
_outdated->heightValue(
|
||||||
) | rpl::filter([=] {
|
) | rpl::filter([=] {
|
||||||
|
|
|
@ -736,12 +736,6 @@
|
||||||
<(src_loc)/ui/image/image_location.h
|
<(src_loc)/ui/image/image_location.h
|
||||||
<(src_loc)/ui/image/image_source.cpp
|
<(src_loc)/ui/image/image_source.cpp
|
||||||
<(src_loc)/ui/image/image_source.h
|
<(src_loc)/ui/image/image_source.h
|
||||||
<(src_loc)/ui/toast/toast.cpp
|
|
||||||
<(src_loc)/ui/toast/toast.h
|
|
||||||
<(src_loc)/ui/toast/toast_manager.cpp
|
|
||||||
<(src_loc)/ui/toast/toast_manager.h
|
|
||||||
<(src_loc)/ui/toast/toast_widget.cpp
|
|
||||||
<(src_loc)/ui/toast/toast_widget.h
|
|
||||||
<(src_loc)/ui/widgets/continuous_sliders.cpp
|
<(src_loc)/ui/widgets/continuous_sliders.cpp
|
||||||
<(src_loc)/ui/widgets/continuous_sliders.h
|
<(src_loc)/ui/widgets/continuous_sliders.h
|
||||||
<(src_loc)/ui/widgets/discrete_sliders.cpp
|
<(src_loc)/ui/widgets/discrete_sliders.cpp
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 34b05c25fc5e0642506fc59f3d791973632d4248
|
Subproject commit d22f5f405f18b6983b7ae19c5c8caff1c88c8098
|
Loading…
Reference in New Issue