mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 14:45:14 +00:00
Animate inline path thumbnails with sliding gradient.
This commit is contained in:
@@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/effects/path_shift_gradient.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "base/unixtime.h"
|
||||
@@ -125,6 +126,8 @@ private:
|
||||
|
||||
bool _isOneColumn = false;
|
||||
|
||||
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||
|
||||
Fn<SendMenu::Type()> _sendMenuType;
|
||||
|
||||
rpl::event_stream<FieldAutocomplete::MentionChosen> _mentionChosen;
|
||||
@@ -738,6 +741,10 @@ FieldAutocomplete::Inner::Inner(
|
||||
, _hrows(hrows)
|
||||
, _brows(brows)
|
||||
, _srows(srows)
|
||||
, _pathGradient(std::make_unique<Ui::PathShiftGradient>(
|
||||
st::windowBgRipple,
|
||||
st::windowBgOver,
|
||||
[=] { update(); }))
|
||||
, _previewTimer([=] { showPreview(); }) {
|
||||
controller->session().downloaderTaskFinished(
|
||||
) | rpl::start_with_next([=] {
|
||||
@@ -770,6 +777,11 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) {
|
||||
- st::defaultScrollArea.width;
|
||||
|
||||
if (!_srows->empty()) {
|
||||
_pathGradient->startFrame(
|
||||
0,
|
||||
width(),
|
||||
std::min(st::msgMaxWidth / 2, width() / 2));
|
||||
|
||||
int32 rows = rowscount(_srows->size(), _stickersPerRow);
|
||||
int32 fromrow = floorclamp(r.y() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows);
|
||||
int32 torow = ceilclamp(r.y() + r.height() - st::stickerPanPadding, st::stickerPanSize.height(), 0, rows);
|
||||
@@ -815,6 +827,17 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) {
|
||||
w = std::max(qRound(coef * document->dimensions.width()), 1);
|
||||
h = std::max(qRound(coef * document->dimensions.height()), 1);
|
||||
}
|
||||
|
||||
|
||||
QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
|
||||
ChatHelpers::PaintStickerThumbnailPath(
|
||||
p,
|
||||
media.get(),
|
||||
QRect(ppos, QSize(w, h)),
|
||||
_pathGradient.get());
|
||||
continue; AssertIsDebug();
|
||||
|
||||
|
||||
if (sticker.animated && sticker.animated->ready()) {
|
||||
const auto frame = sticker.animated->frame();
|
||||
const auto size = frame.size() / cIntRetinaFactor();
|
||||
@@ -838,7 +861,7 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) {
|
||||
p,
|
||||
media.get(),
|
||||
QRect(ppos, QSize(w, h)),
|
||||
st::windowBgRipple->c);
|
||||
_pathGradient.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/effects/path_shift_gradient.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/cached_round_corners.h"
|
||||
#include "lottie/lottie_multi_player.h"
|
||||
@@ -899,6 +900,10 @@ StickersListWidget::StickersListWidget(
|
||||
: Inner(parent, controller)
|
||||
, _api(&controller->session().mtp())
|
||||
, _section(Section::Stickers)
|
||||
, _pathGradient(std::make_unique<Ui::PathShiftGradient>(
|
||||
st::windowBgRipple,
|
||||
st::windowBgOver,
|
||||
[=] { update(); }))
|
||||
, _megagroupSetAbout(st::columnMinimalWidthThird - st::emojiScroll.width - st::emojiPanHeaderLeft)
|
||||
, _addText(tr::lng_stickers_featured_add(tr::now).toUpper())
|
||||
, _addWidth(st::stickersTrendingAdd.font->width(_addText))
|
||||
@@ -1531,6 +1536,8 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||
toColumn = _columnCount - toColumn;
|
||||
}
|
||||
|
||||
_pathGradient->startFrame(0, width(), width() / 2);
|
||||
|
||||
auto &sets = shownSets();
|
||||
auto selectedSticker = std::get_if<OverSticker>(&_selected);
|
||||
auto selectedButton = std::get_if<OverButton>(!v::is_null(_pressed)
|
||||
@@ -1889,6 +1896,16 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section,
|
||||
h = std::max(qRound(coef * document->dimensions.height()), 1);
|
||||
}
|
||||
auto ppos = pos + QPoint((_singleSize.width() - w) / 2, (_singleSize.height() - h) / 2);
|
||||
|
||||
|
||||
PaintStickerThumbnailPath(
|
||||
p,
|
||||
media.get(),
|
||||
QRect(ppos, QSize{ w, h }),
|
||||
_pathGradient.get());
|
||||
return; AssertIsDebug();
|
||||
|
||||
|
||||
if (sticker.animated && sticker.animated->ready()) {
|
||||
auto request = Lottie::FrameRequest();
|
||||
request.box = boundingBoxSize() * cIntRetinaFactor();
|
||||
@@ -1923,7 +1940,7 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section,
|
||||
p,
|
||||
media.get(),
|
||||
QRect(ppos, QSize{ w, h }),
|
||||
st::windowBgRipple->c);
|
||||
_pathGradient.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -25,6 +25,7 @@ class LinkButton;
|
||||
class PopupMenu;
|
||||
class RippleAnimation;
|
||||
class BoxContent;
|
||||
class PathShiftGradient;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Lottie {
|
||||
@@ -361,6 +362,8 @@ private:
|
||||
OverState _pressed;
|
||||
QPoint _lastMousePosition;
|
||||
|
||||
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||
|
||||
Ui::Text::String _megagroupSetAbout;
|
||||
QString _megagroupSetButtonText;
|
||||
int _megagroupSetButtonTextWidth = 0;
|
||||
|
@@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "storage/cache/storage_cache_database.h"
|
||||
#include "ui/effects/path_shift_gradient.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace ChatHelpers {
|
||||
@@ -192,17 +193,25 @@ bool PaintStickerThumbnailPath(
|
||||
QPainter &p,
|
||||
not_null<Data::DocumentMedia*> media,
|
||||
QRect target,
|
||||
QColor fg) {
|
||||
QLinearGradient *gradient) {
|
||||
const auto &path = media->thumbnailPath();
|
||||
const auto dimensions = media->owner()->dimensions;
|
||||
if (path.isEmpty() || dimensions.isEmpty()) {
|
||||
if (path.isEmpty() || dimensions.isEmpty() || target.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
p.save();
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setBrush(fg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.translate(target.topLeft());
|
||||
if (gradient) {
|
||||
const auto scale = dimensions.width() / float64(target.width());
|
||||
const auto shift = p.worldTransform().dx();
|
||||
gradient->setStart((gradient->start().x() - shift) * scale, 0);
|
||||
gradient->setFinalStop(
|
||||
(gradient->finalStop().x() - shift) * scale,
|
||||
0);
|
||||
p.setBrush(*gradient);
|
||||
}
|
||||
p.scale(
|
||||
target.width() / float64(dimensions.width()),
|
||||
target.height() / float64(dimensions.height()));
|
||||
@@ -211,4 +220,19 @@ bool PaintStickerThumbnailPath(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PaintStickerThumbnailPath(
|
||||
QPainter &p,
|
||||
not_null<Data::DocumentMedia*> media,
|
||||
QRect target,
|
||||
not_null<Ui::PathShiftGradient*> gradient) {
|
||||
return gradient->paint([&](const Ui::PathShiftGradient::Background &bg) {
|
||||
if (const auto color = std::get_if<style::color>(&bg)) {
|
||||
p.setBrush(*color);
|
||||
return PaintStickerThumbnailPath(p, media, target);
|
||||
}
|
||||
const auto gradient = v::get<QLinearGradient*>(bg);
|
||||
return PaintStickerThumbnailPath(p, media, target, gradient);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace ChatHelpers
|
||||
|
@@ -26,6 +26,10 @@ namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
namespace Ui {
|
||||
class PathShiftGradient;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Data {
|
||||
class DocumentMedia;
|
||||
class StickersSetThumbnailView;
|
||||
@@ -75,6 +79,12 @@ bool PaintStickerThumbnailPath(
|
||||
QPainter &p,
|
||||
not_null<Data::DocumentMedia*> media,
|
||||
QRect target,
|
||||
QColor fg);
|
||||
QLinearGradient *gradient = nullptr);
|
||||
|
||||
bool PaintStickerThumbnailPath(
|
||||
QPainter &p,
|
||||
not_null<Data::DocumentMedia*> media,
|
||||
QRect target,
|
||||
not_null<Ui::PathShiftGradient*> gradient);
|
||||
|
||||
} // namespace ChatHelpers
|
||||
|
Reference in New Issue
Block a user