mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +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 {
|
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;
|
||||||
BasicRow::~BasicRow() = default;
|
BasicRow::~BasicRow() = default;
|
||||||
|
|
||||||
|
@ -123,28 +180,25 @@ uint64 Row::sortKey(FilterId filterId) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Row::setCornerBadgeShown(
|
void Row::setCornerBadgeShown(
|
||||||
bool shown,
|
CornerLayersManager::Layer nextLayer,
|
||||||
Fn<void()> updateCallback) const {
|
Fn<void()> updateCallback) const {
|
||||||
const auto value = (shown ? 1 : 0);
|
const auto cornerBadgeShown = (nextLayer ? 1 : 0);
|
||||||
if (_cornerBadgeShown == value) {
|
if (_cornerBadgeShown == cornerBadgeShown) {
|
||||||
return;
|
if (!cornerBadgeShown) {
|
||||||
}
|
return;
|
||||||
const_cast<Row*>(this)->_cornerBadgeShown = value;
|
} else if (_cornerBadgeUserpic
|
||||||
if (_cornerBadgeUserpic && _cornerBadgeUserpic->animation.animating()) {
|
&& _cornerBadgeUserpic->layersManager.isSameLayer(nextLayer)) {
|
||||||
_cornerBadgeUserpic->animation.change(
|
return;
|
||||||
_cornerBadgeShown ? 1. : 0.,
|
}
|
||||||
st::dialogsOnlineBadgeDuration);
|
|
||||||
} else if (updateCallback) {
|
|
||||||
ensureCornerBadgeUserpic();
|
|
||||||
_cornerBadgeUserpic->animation.start(
|
|
||||||
std::move(updateCallback),
|
|
||||||
_cornerBadgeShown ? 0. : 1.,
|
|
||||||
_cornerBadgeShown ? 1. : 0.,
|
|
||||||
st::dialogsOnlineBadgeDuration);
|
|
||||||
}
|
}
|
||||||
|
const_cast<Row*>(this)->_cornerBadgeShown = cornerBadgeShown;
|
||||||
|
ensureCornerBadgeUserpic();
|
||||||
|
_cornerBadgeUserpic->layersManager.setLayer(
|
||||||
|
nextLayer,
|
||||||
|
std::move(updateCallback));
|
||||||
if (!_cornerBadgeShown
|
if (!_cornerBadgeShown
|
||||||
&& _cornerBadgeUserpic
|
&& _cornerBadgeUserpic
|
||||||
&& !_cornerBadgeUserpic->animation.animating()) {
|
&& _cornerBadgeUserpic->layersManager.isDisplayedNone()) {
|
||||||
_cornerBadgeUserpic = nullptr;
|
_cornerBadgeUserpic = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,16 +208,17 @@ void Row::updateCornerBadgeShown(
|
||||||
Fn<void()> updateCallback) const {
|
Fn<void()> updateCallback) const {
|
||||||
const auto user = peer->asUser();
|
const auto user = peer->asUser();
|
||||||
const auto now = user ? base::unixtime::now() : TimeId();
|
const auto now = user ? base::unixtime::now() : TimeId();
|
||||||
const auto shown = [&] {
|
const auto nextLayer = [&] {
|
||||||
if (user) {
|
if (user && Data::IsUserOnline(user, now)) {
|
||||||
return Data::IsUserOnline(user, now);
|
return kTopLayer;
|
||||||
} else if (const auto channel = peer->asChannel()) {
|
} else if (peer->isChannel()
|
||||||
return Data::ChannelHasActiveCall(channel);
|
&& Data::ChannelHasActiveCall(peer->asChannel())) {
|
||||||
|
return kTopLayer;
|
||||||
}
|
}
|
||||||
return false;
|
return kNoneLayer;
|
||||||
}();
|
}();
|
||||||
setCornerBadgeShown(shown, std::move(updateCallback));
|
setCornerBadgeShown(nextLayer, std::move(updateCallback));
|
||||||
if (shown && user) {
|
if ((nextLayer == kTopLayer) && user) {
|
||||||
peer->owner().watchForOffline(user, now);
|
peer->owner().watchForOffline(user, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,6 +253,7 @@ void Row::PaintCornerBadgeFrame(
|
||||||
PainterHighQualityEnabler hq(q);
|
PainterHighQualityEnabler hq(q);
|
||||||
q.setCompositionMode(QPainter::CompositionMode_Source);
|
q.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
|
||||||
|
const auto progress = data->layersManager.progressForLayer(kTopLayer);
|
||||||
const auto size = peer->isUser()
|
const auto size = peer->isUser()
|
||||||
? st::dialogsOnlineBadgeSize
|
? st::dialogsOnlineBadgeSize
|
||||||
: st::dialogsCallBadgeSize;
|
: st::dialogsCallBadgeSize;
|
||||||
|
@ -205,10 +261,10 @@ void Row::PaintCornerBadgeFrame(
|
||||||
const auto skip = peer->isUser()
|
const auto skip = peer->isUser()
|
||||||
? st::dialogsOnlineBadgeSkip
|
? st::dialogsOnlineBadgeSkip
|
||||||
: st::dialogsCallBadgeSkip;
|
: st::dialogsCallBadgeSkip;
|
||||||
const auto shrink = (size / 2) * (1. - data->shown);
|
const auto shrink = (size / 2) * (1. - progress);
|
||||||
|
|
||||||
auto pen = QPen(Qt::transparent);
|
auto pen = QPen(Qt::transparent);
|
||||||
pen.setWidthF(stroke * data->shown);
|
pen.setWidthF(stroke * progress);
|
||||||
q.setPen(pen);
|
q.setPen(pen);
|
||||||
q.setBrush(data->active
|
q.setBrush(data->active
|
||||||
? st::dialogsOnlineBadgeFgActive
|
? st::dialogsOnlineBadgeFgActive
|
||||||
|
@ -229,10 +285,10 @@ void Row::paintUserpic(
|
||||||
const Ui::PaintContext &context) const {
|
const Ui::PaintContext &context) const {
|
||||||
updateCornerBadgeShown(peer);
|
updateCornerBadgeShown(peer);
|
||||||
|
|
||||||
const auto shown = _cornerBadgeUserpic
|
const auto cornerBadgeShown = !_cornerBadgeUserpic
|
||||||
? _cornerBadgeUserpic->animation.value(_cornerBadgeShown ? 1. : 0.)
|
? _cornerBadgeShown
|
||||||
: (_cornerBadgeShown ? 1. : 0.);
|
: !_cornerBadgeUserpic->layersManager.isDisplayedNone();
|
||||||
if (!historyForCornerBadge || shown == 0.) {
|
if (!historyForCornerBadge || !cornerBadgeShown) {
|
||||||
BasicRow::paintUserpic(
|
BasicRow::paintUserpic(
|
||||||
p,
|
p,
|
||||||
peer,
|
peer,
|
||||||
|
@ -261,15 +317,15 @@ void Row::paintUserpic(
|
||||||
}
|
}
|
||||||
const auto key = peer->userpicUniqueKey(userpicView());
|
const auto key = peer->userpicUniqueKey(userpicView());
|
||||||
const auto frameIndex = videoUserpic ? videoUserpic->frameIndex() : -1;
|
const auto frameIndex = videoUserpic ? videoUserpic->frameIndex() : -1;
|
||||||
if (_cornerBadgeUserpic->shown != shown
|
if (!_cornerBadgeUserpic->layersManager.isFinished()
|
||||||
|| _cornerBadgeUserpic->key != key
|
|| _cornerBadgeUserpic->key != key
|
||||||
|| _cornerBadgeUserpic->active != context.active
|
|| _cornerBadgeUserpic->active != context.active
|
||||||
|| _cornerBadgeUserpic->frameIndex != frameIndex
|
|| _cornerBadgeUserpic->frameIndex != frameIndex
|
||||||
|| videoUserpic) {
|
|| videoUserpic) {
|
||||||
_cornerBadgeUserpic->shown = shown;
|
|
||||||
_cornerBadgeUserpic->key = key;
|
_cornerBadgeUserpic->key = key;
|
||||||
_cornerBadgeUserpic->active = context.active;
|
_cornerBadgeUserpic->active = context.active;
|
||||||
_cornerBadgeUserpic->frameIndex = frameIndex;
|
_cornerBadgeUserpic->frameIndex = frameIndex;
|
||||||
|
_cornerBadgeUserpic->layersManager.markFrameShown();
|
||||||
PaintCornerBadgeFrame(
|
PaintCornerBadgeFrame(
|
||||||
_cornerBadgeUserpic.get(),
|
_cornerBadgeUserpic.get(),
|
||||||
peer,
|
peer,
|
||||||
|
@ -290,7 +346,8 @@ void Row::paintUserpic(
|
||||||
: st::dialogsBg;
|
: st::dialogsBg;
|
||||||
const auto size = st::dialogsCallBadgeSize;
|
const auto size = st::dialogsCallBadgeSize;
|
||||||
const auto skip = st::dialogsCallBadgeSkip;
|
const auto skip = st::dialogsCallBadgeSkip;
|
||||||
p.setOpacity(shown);
|
p.setOpacity(
|
||||||
|
_cornerBadgeUserpic->layersManager.progressForLayer(kTopLayer));
|
||||||
p.translate(context.st->padding.left(), context.st->padding.top());
|
p.translate(context.st->padding.left(), context.st->padding.top());
|
||||||
actionPainter->paintSpeaking(
|
actionPainter->paintSpeaking(
|
||||||
p,
|
p,
|
||||||
|
|
|
@ -143,17 +143,37 @@ public:
|
||||||
private:
|
private:
|
||||||
friend class List;
|
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 {
|
struct CornerBadgeUserpic {
|
||||||
InMemoryKey key;
|
InMemoryKey key;
|
||||||
float64 shown = 0.;
|
CornerLayersManager layersManager;
|
||||||
int frameIndex = -1;
|
int frameIndex = -1;
|
||||||
bool active = false;
|
bool active = false;
|
||||||
QImage frame;
|
QImage frame;
|
||||||
Ui::Animations::Simple animation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void setCornerBadgeShown(
|
void setCornerBadgeShown(
|
||||||
bool shown,
|
CornerLayersManager::Layer nextLayer,
|
||||||
Fn<void()> updateCallback) const;
|
Fn<void()> updateCallback) const;
|
||||||
void ensureCornerBadgeUserpic() const;
|
void ensureCornerBadgeUserpic() const;
|
||||||
static void PaintCornerBadgeFrame(
|
static void PaintCornerBadgeFrame(
|
||||||
|
|
Loading…
Add table
Reference in a new issue