mirror of https://github.com/procxx/kepka.git
Ui::FadeAnimation now supports scaling.
Ui::WidgetScaledFadeWrap<> wrapper added for fading widgets out and fading them in with a scale effect similar to Ui::SendButton.
This commit is contained in:
parent
6456a83a22
commit
b80dd99172
|
@ -21,8 +21,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|||
#include "ui/effects/widget_fade_wrap.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
FadeAnimation::FadeAnimation(TWidget *widget) : _widget(widget) {
|
||||
constexpr int kWideScale = 5;
|
||||
|
||||
} // namespace
|
||||
|
||||
FadeAnimation::FadeAnimation(TWidget *widget, bool scaled)
|
||||
: _widget(widget)
|
||||
, _scaled(scaled) {
|
||||
}
|
||||
|
||||
bool FadeAnimation::paint(Painter &p) {
|
||||
|
@ -30,17 +37,44 @@ bool FadeAnimation::paint(Painter &p) {
|
|||
|
||||
auto opacity = _animation.current(getms(), _visible ? 1. : 0.);
|
||||
p.setOpacity(opacity);
|
||||
p.drawPixmap(0, 0, _cache);
|
||||
if (_scaled) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
auto targetRect = QRect((1 - kWideScale) / 2 * _size.width(), (1 - kWideScale) / 2 * _size.height(), kWideScale * _size.width(), kWideScale * _size.height());
|
||||
auto scale = opacity;
|
||||
auto shownWidth = anim::interpolate((1 - kWideScale) / 2 * _size.width(), 0, scale);
|
||||
auto shownHeight = anim::interpolate((1 - kWideScale) / 2 * _size.height(), 0, scale);
|
||||
p.drawPixmap(targetRect.marginsAdded(QMargins(shownWidth, shownHeight, shownWidth, shownHeight)), _cache);
|
||||
} else {
|
||||
p.drawPixmap(0, 0, _cache);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FadeAnimation::refreshCache() {
|
||||
if (!_cache.isNull()) {
|
||||
_cache = QPixmap();
|
||||
_cache = myGrab(_widget);
|
||||
_cache = grabContent();
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap FadeAnimation::grabContent() {
|
||||
myEnsureResized(_widget);
|
||||
_size = _widget->size();
|
||||
auto widgetContent = myGrab(_widget);
|
||||
if (!_scaled) {
|
||||
return widgetContent;
|
||||
}
|
||||
|
||||
auto result = QImage(kWideScale * _size * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||
result.setDevicePixelRatio(cRetinaFactor());
|
||||
result.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&result);
|
||||
p.drawPixmap((kWideScale - 1) / 2 * _size.width(), (kWideScale - 1) / 2 * _size.height(), widgetContent);
|
||||
}
|
||||
return App::pixmapFromImageInPlace(std::move(result));
|
||||
}
|
||||
|
||||
void FadeAnimation::setFinishedCallback(FinishedCallback &&callback) {
|
||||
_finishedCallback = std::move(callback);
|
||||
}
|
||||
|
@ -93,7 +127,7 @@ void FadeAnimation::fadeOut(int duration) {
|
|||
void FadeAnimation::startAnimation(int duration) {
|
||||
if (_cache.isNull()) {
|
||||
_widget->showChildren();
|
||||
_cache = myGrab(_widget);
|
||||
_cache = grabContent();
|
||||
_widget->hideChildren();
|
||||
}
|
||||
auto from = _visible ? 0. : 1.;
|
||||
|
@ -119,11 +153,12 @@ void FadeAnimation::updateCallback() {
|
|||
WidgetFadeWrap<TWidget>::WidgetFadeWrap(QWidget *parent
|
||||
, object_ptr<TWidget> entity
|
||||
, int duration
|
||||
, base::lambda<void()> updateCallback) : TWidget(parent)
|
||||
, base::lambda<void()> updateCallback
|
||||
, bool scaled) : TWidget(parent)
|
||||
, _entity(std::move(entity))
|
||||
, _duration(duration)
|
||||
, _updateCallback(std::move(updateCallback))
|
||||
, _animation(this) {
|
||||
, _animation(this, scaled) {
|
||||
_animation.show();
|
||||
if (_updateCallback) {
|
||||
_animation.setFinishedCallback([this] { _updateCallback(); });
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Ui {
|
|||
|
||||
class FadeAnimation {
|
||||
public:
|
||||
FadeAnimation(TWidget *widget);
|
||||
FadeAnimation(TWidget *widget, bool scaled = false);
|
||||
|
||||
bool paint(Painter &p);
|
||||
void refreshCache();
|
||||
|
@ -58,9 +58,13 @@ private:
|
|||
void stopAnimation();
|
||||
|
||||
void updateCallback();
|
||||
QPixmap grabContent();
|
||||
|
||||
TWidget *_widget = nullptr;
|
||||
bool _scaled = false;
|
||||
|
||||
TWidget *_widget;
|
||||
Animation _animation;
|
||||
QSize _size;
|
||||
QPixmap _cache;
|
||||
bool _visible = false;
|
||||
|
||||
|
@ -78,7 +82,8 @@ public:
|
|||
WidgetFadeWrap(QWidget *parent
|
||||
, object_ptr<TWidget> entity
|
||||
, int duration = st::widgetFadeDuration
|
||||
, base::lambda<void()> updateCallback = base::lambda<void()>());
|
||||
, base::lambda<void()> updateCallback = base::lambda<void()>()
|
||||
, bool scaled = false);
|
||||
|
||||
void showAnimated() {
|
||||
_animation.fadeIn(_duration);
|
||||
|
@ -140,10 +145,12 @@ public:
|
|||
WidgetFadeWrap(QWidget *parent
|
||||
, object_ptr<Widget> entity
|
||||
, int duration = st::widgetFadeDuration
|
||||
, base::lambda<void()> updateCallback = base::lambda<void()>()) : WidgetFadeWrap<TWidget>(parent
|
||||
, base::lambda<void()> updateCallback = base::lambda<void()>()
|
||||
, bool scaled = false) : WidgetFadeWrap<TWidget>(parent
|
||||
, std::move(entity)
|
||||
, duration
|
||||
, std::move(updateCallback)) {
|
||||
, std::move(updateCallback)
|
||||
, scaled) {
|
||||
}
|
||||
Widget *entity() {
|
||||
return static_cast<Widget*>(WidgetFadeWrap<TWidget>::entity());
|
||||
|
@ -154,4 +161,19 @@ public:
|
|||
|
||||
};
|
||||
|
||||
template <typename Widget>
|
||||
class WidgetScaledFadeWrap : public WidgetFadeWrap<Widget> {
|
||||
public:
|
||||
WidgetScaledFadeWrap(QWidget *parent
|
||||
, object_ptr<Widget> entity
|
||||
, int duration = st::widgetFadeDuration
|
||||
, base::lambda<void()> updateCallback = base::lambda<void()>()) : WidgetFadeWrap<Widget>(parent
|
||||
, std::move(entity)
|
||||
, duration
|
||||
, std::move(updateCallback)
|
||||
, true) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
|
Loading…
Reference in New Issue