mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Added support of switching between corner layers in dialogs list.
This commit is contained in:
parent
34f0aae418
commit
cbbbcd877c
2 changed files with 115 additions and 38 deletions
|
@ -27,6 +27,63 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Dialogs {
|
||||
|
||||
constexpr auto kTopLayer = 1;
|
||||
constexpr auto kNoneLayer = 0;
|
||||
|
||||
Row::CornerLayersManager::CornerLayersManager() = default;
|
||||
|
||||
bool Row::CornerLayersManager::isSameLayer(Layer layer) const {
|
||||
return isFinished() && (_nextLayer == layer);
|
||||
}
|
||||
|
||||
void Row::CornerLayersManager::setLayer(
|
||||
Layer layer,
|
||||
Fn<void()> updateCallback) {
|
||||
if (_nextLayer == layer) {
|
||||
return;
|
||||
}
|
||||
_lastFrameShown = false;
|
||||
_prevLayer = _nextLayer;
|
||||
_nextLayer = layer;
|
||||
if (_animation.animating()) {
|
||||
_animation.change(
|
||||
1.,
|
||||
st::dialogsOnlineBadgeDuration * (1. - _animation.value(1.)));
|
||||
} else if (updateCallback) {
|
||||
_animation.start(
|
||||
std::move(updateCallback),
|
||||
0.,
|
||||
1.,
|
||||
st::dialogsOnlineBadgeDuration);
|
||||
}
|
||||
}
|
||||
|
||||
float64 Row::CornerLayersManager::progressForLayer(Layer layer) const {
|
||||
return (_nextLayer == layer)
|
||||
? progress()
|
||||
: (_prevLayer == layer)
|
||||
? (1. - progress())
|
||||
: 0.;
|
||||
}
|
||||
|
||||
float64 Row::CornerLayersManager::progress() const {
|
||||
return _animation.value(1.);
|
||||
}
|
||||
|
||||
bool Row::CornerLayersManager::isFinished() const {
|
||||
return (progress() == 1.) && _lastFrameShown;
|
||||
}
|
||||
|
||||
void Row::CornerLayersManager::markFrameShown() {
|
||||
if (progress() == 1.) {
|
||||
_lastFrameShown = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Row::CornerLayersManager::isDisplayedNone() const {
|
||||
return (progress() == 1.) && (_nextLayer == 0);
|
||||
}
|
||||
|
||||
BasicRow::BasicRow() = default;
|
||||
BasicRow::~BasicRow() = default;
|
||||
|
||||
|
@ -123,28 +180,25 @@ uint64 Row::sortKey(FilterId filterId) const {
|
|||
}
|
||||
|
||||
void Row::setCornerBadgeShown(
|
||||
bool shown,
|
||||
CornerLayersManager::Layer nextLayer,
|
||||
Fn<void()> updateCallback) const {
|
||||
const auto value = (shown ? 1 : 0);
|
||||
if (_cornerBadgeShown == value) {
|
||||
return;
|
||||
}
|
||||
const_cast<Row*>(this)->_cornerBadgeShown = value;
|
||||
if (_cornerBadgeUserpic && _cornerBadgeUserpic->animation.animating()) {
|
||||
_cornerBadgeUserpic->animation.change(
|
||||
_cornerBadgeShown ? 1. : 0.,
|
||||
st::dialogsOnlineBadgeDuration);
|
||||
} else if (updateCallback) {
|
||||
ensureCornerBadgeUserpic();
|
||||
_cornerBadgeUserpic->animation.start(
|
||||
std::move(updateCallback),
|
||||
_cornerBadgeShown ? 0. : 1.,
|
||||
_cornerBadgeShown ? 1. : 0.,
|
||||
st::dialogsOnlineBadgeDuration);
|
||||
const auto cornerBadgeShown = (nextLayer ? 1 : 0);
|
||||
if (_cornerBadgeShown == cornerBadgeShown) {
|
||||
if (!cornerBadgeShown) {
|
||||
return;
|
||||
} else if (_cornerBadgeUserpic
|
||||
&& _cornerBadgeUserpic->layersManager.isSameLayer(nextLayer)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const_cast<Row*>(this)->_cornerBadgeShown = cornerBadgeShown;
|
||||
ensureCornerBadgeUserpic();
|
||||
_cornerBadgeUserpic->layersManager.setLayer(
|
||||
nextLayer,
|
||||
std::move(updateCallback));
|
||||
if (!_cornerBadgeShown
|
||||
&& _cornerBadgeUserpic
|
||||
&& !_cornerBadgeUserpic->animation.animating()) {
|
||||
&& _cornerBadgeUserpic->layersManager.isDisplayedNone()) {
|
||||
_cornerBadgeUserpic = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -154,16 +208,17 @@ void Row::updateCornerBadgeShown(
|
|||
Fn<void()> updateCallback) const {
|
||||
const auto user = peer->asUser();
|
||||
const auto now = user ? base::unixtime::now() : TimeId();
|
||||
const auto shown = [&] {
|
||||
if (user) {
|
||||
return Data::IsUserOnline(user, now);
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
return Data::ChannelHasActiveCall(channel);
|
||||
const auto nextLayer = [&] {
|
||||
if (user && Data::IsUserOnline(user, now)) {
|
||||
return kTopLayer;
|
||||
} else if (peer->isChannel()
|
||||
&& Data::ChannelHasActiveCall(peer->asChannel())) {
|
||||
return kTopLayer;
|
||||
}
|
||||
return false;
|
||||
return kNoneLayer;
|
||||
}();
|
||||
setCornerBadgeShown(shown, std::move(updateCallback));
|
||||
if (shown && user) {
|
||||
setCornerBadgeShown(nextLayer, std::move(updateCallback));
|
||||
if ((nextLayer == kTopLayer) && user) {
|
||||
peer->owner().watchForOffline(user, now);
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +253,7 @@ void Row::PaintCornerBadgeFrame(
|
|||
PainterHighQualityEnabler hq(q);
|
||||
q.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
|
||||
const auto progress = data->layersManager.progressForLayer(kTopLayer);
|
||||
const auto size = peer->isUser()
|
||||
? st::dialogsOnlineBadgeSize
|
||||
: st::dialogsCallBadgeSize;
|
||||
|
@ -205,10 +261,10 @@ void Row::PaintCornerBadgeFrame(
|
|||
const auto skip = peer->isUser()
|
||||
? st::dialogsOnlineBadgeSkip
|
||||
: st::dialogsCallBadgeSkip;
|
||||
const auto shrink = (size / 2) * (1. - data->shown);
|
||||
const auto shrink = (size / 2) * (1. - progress);
|
||||
|
||||
auto pen = QPen(Qt::transparent);
|
||||
pen.setWidthF(stroke * data->shown);
|
||||
pen.setWidthF(stroke * progress);
|
||||
q.setPen(pen);
|
||||
q.setBrush(data->active
|
||||
? st::dialogsOnlineBadgeFgActive
|
||||
|
@ -229,10 +285,10 @@ void Row::paintUserpic(
|
|||
const Ui::PaintContext &context) const {
|
||||
updateCornerBadgeShown(peer);
|
||||
|
||||
const auto shown = _cornerBadgeUserpic
|
||||
? _cornerBadgeUserpic->animation.value(_cornerBadgeShown ? 1. : 0.)
|
||||
: (_cornerBadgeShown ? 1. : 0.);
|
||||
if (!historyForCornerBadge || shown == 0.) {
|
||||
const auto cornerBadgeShown = !_cornerBadgeUserpic
|
||||
? _cornerBadgeShown
|
||||
: !_cornerBadgeUserpic->layersManager.isDisplayedNone();
|
||||
if (!historyForCornerBadge || !cornerBadgeShown) {
|
||||
BasicRow::paintUserpic(
|
||||
p,
|
||||
peer,
|
||||
|
@ -261,15 +317,15 @@ void Row::paintUserpic(
|
|||
}
|
||||
const auto key = peer->userpicUniqueKey(userpicView());
|
||||
const auto frameIndex = videoUserpic ? videoUserpic->frameIndex() : -1;
|
||||
if (_cornerBadgeUserpic->shown != shown
|
||||
if (!_cornerBadgeUserpic->layersManager.isFinished()
|
||||
|| _cornerBadgeUserpic->key != key
|
||||
|| _cornerBadgeUserpic->active != context.active
|
||||
|| _cornerBadgeUserpic->frameIndex != frameIndex
|
||||
|| videoUserpic) {
|
||||
_cornerBadgeUserpic->shown = shown;
|
||||
_cornerBadgeUserpic->key = key;
|
||||
_cornerBadgeUserpic->active = context.active;
|
||||
_cornerBadgeUserpic->frameIndex = frameIndex;
|
||||
_cornerBadgeUserpic->layersManager.markFrameShown();
|
||||
PaintCornerBadgeFrame(
|
||||
_cornerBadgeUserpic.get(),
|
||||
peer,
|
||||
|
@ -290,7 +346,8 @@ void Row::paintUserpic(
|
|||
: st::dialogsBg;
|
||||
const auto size = st::dialogsCallBadgeSize;
|
||||
const auto skip = st::dialogsCallBadgeSkip;
|
||||
p.setOpacity(shown);
|
||||
p.setOpacity(
|
||||
_cornerBadgeUserpic->layersManager.progressForLayer(kTopLayer));
|
||||
p.translate(context.st->padding.left(), context.st->padding.top());
|
||||
actionPainter->paintSpeaking(
|
||||
p,
|
||||
|
|
|
@ -143,17 +143,37 @@ public:
|
|||
private:
|
||||
friend class List;
|
||||
|
||||
class CornerLayersManager {
|
||||
public:
|
||||
using Layer = int;
|
||||
CornerLayersManager();
|
||||
|
||||
[[nodiscard]] bool isSameLayer(Layer layer) const;
|
||||
[[nodiscard]] bool isDisplayedNone() const;
|
||||
[[nodiscard]] float64 progressForLayer(Layer layer) const;
|
||||
[[nodiscard]] float64 progress() const;
|
||||
[[nodiscard]] bool isFinished() const;
|
||||
void setLayer(Layer layer, Fn<void()> updateCallback);
|
||||
void markFrameShown();
|
||||
|
||||
private:
|
||||
bool _lastFrameShown = false;
|
||||
Layer _prevLayer = 0;
|
||||
Layer _nextLayer = 0;
|
||||
Ui::Animations::Simple _animation;
|
||||
|
||||
};
|
||||
|
||||
struct CornerBadgeUserpic {
|
||||
InMemoryKey key;
|
||||
float64 shown = 0.;
|
||||
CornerLayersManager layersManager;
|
||||
int frameIndex = -1;
|
||||
bool active = false;
|
||||
QImage frame;
|
||||
Ui::Animations::Simple animation;
|
||||
};
|
||||
|
||||
void setCornerBadgeShown(
|
||||
bool shown,
|
||||
CornerLayersManager::Layer nextLayer,
|
||||
Fn<void()> updateCallback) const;
|
||||
void ensureCornerBadgeUserpic() const;
|
||||
static void PaintCornerBadgeFrame(
|
||||
|
|
Loading…
Add table
Reference in a new issue