mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add ripples to top peers.
This commit is contained in:
parent
19ae76d8de
commit
a6c1def6fe
3 changed files with 93 additions and 11 deletions
|
@ -595,8 +595,10 @@ topPeers: DialogsStories(dialogsStoriesFull) {
|
||||||
photo: 46px;
|
photo: 46px;
|
||||||
photoLeft: 10px;
|
photoLeft: 10px;
|
||||||
photoTop: 8px;
|
photoTop: 8px;
|
||||||
nameLeft: 4px;
|
nameLeft: 6px;
|
||||||
}
|
}
|
||||||
|
topPeersRadius: 4px;
|
||||||
|
topPeersMargin: margins(3px, 3px, 3px, 4px);
|
||||||
|
|
||||||
dialogsStoriesList: DialogsStoriesList {
|
dialogsStoriesList: DialogsStoriesList {
|
||||||
small: dialogsStories;
|
small: dialogsStories;
|
||||||
|
|
|
@ -40,7 +40,8 @@ struct TopPeersStrip::Entry {
|
||||||
TopPeersStrip::TopPeersStrip(
|
TopPeersStrip::TopPeersStrip(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
rpl::producer<TopPeersList> content)
|
rpl::producer<TopPeersList> content)
|
||||||
: RpWidget(parent) {
|
: RpWidget(parent)
|
||||||
|
, _selection(st::topPeersRadius, st::windowBgOver) {
|
||||||
resize(0, st::topPeers.height);
|
resize(0, st::topPeers.height);
|
||||||
|
|
||||||
std::move(content) | rpl::start_with_next([=](const TopPeersList &list) {
|
std::move(content) | rpl::start_with_next([=](const TopPeersList &list) {
|
||||||
|
@ -102,6 +103,23 @@ void TopPeersStrip::mousePressEvent(QMouseEvent *e) {
|
||||||
|
|
||||||
_mouseDownPosition = _lastMousePosition;
|
_mouseDownPosition = _lastMousePosition;
|
||||||
_pressed = _selected;
|
_pressed = _selected;
|
||||||
|
|
||||||
|
if (_selected >= 0) {
|
||||||
|
Assert(_selected < _entries.size());
|
||||||
|
auto &entry = _entries[_selected];
|
||||||
|
if (!entry.ripple) {
|
||||||
|
entry.ripple = std::make_unique<Ui::RippleAnimation>(
|
||||||
|
st::defaultRippleAnimation,
|
||||||
|
Ui::RippleAnimation::RoundRectMask(
|
||||||
|
innerRounded().size(),
|
||||||
|
st::topPeersRadius),
|
||||||
|
[=] { update(); });
|
||||||
|
}
|
||||||
|
const auto single = outer().width();
|
||||||
|
entry.ripple->add(e->pos() - QPoint(
|
||||||
|
_selected * single - _scrollLeft + st::topPeersMargin.left(),
|
||||||
|
st::topPeersMargin.top()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopPeersStrip::mouseMoveEvent(QMouseEvent *e) {
|
void TopPeersStrip::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
@ -174,14 +192,20 @@ void TopPeersStrip::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto pressed = std::exchange(_pressed, -1);
|
const auto pressed = std::exchange(_pressed, -1);
|
||||||
|
if (pressed >= 0) {
|
||||||
|
Assert(pressed < _entries.size());
|
||||||
|
auto &entry = _entries[pressed];
|
||||||
|
if (entry.ripple) {
|
||||||
|
entry.ripple->lastStop();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (finishDragging()) {
|
if (finishDragging()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateSelected();
|
updateSelected();
|
||||||
if (_selected == pressed) {
|
if (_selected >= 0 && _selected == pressed) {
|
||||||
if (_selected < _entries.size()) {
|
Assert(_selected < _entries.size());
|
||||||
_clicks.fire_copy(_entries[_selected].id);
|
_clicks.fire_copy(_entries[_selected].id);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +244,14 @@ void TopPeersStrip::removeLocally(uint64 id) {
|
||||||
} else if (i->subscribed) {
|
} else if (i->subscribed) {
|
||||||
i->userpic->subscribeToUpdates(nullptr);
|
i->userpic->subscribeToUpdates(nullptr);
|
||||||
}
|
}
|
||||||
|
const auto index = int(i - begin(_entries));
|
||||||
_entries.erase(i);
|
_entries.erase(i);
|
||||||
|
if (_selected > index) {
|
||||||
|
--_selected;
|
||||||
|
}
|
||||||
|
if (_pressed > index) {
|
||||||
|
--_pressed;
|
||||||
|
}
|
||||||
updateScrollMax();
|
updateScrollMax();
|
||||||
if (_entries.empty()) {
|
if (_entries.empty()) {
|
||||||
_empty = true;
|
_empty = true;
|
||||||
|
@ -231,6 +262,8 @@ void TopPeersStrip::removeLocally(uint64 id) {
|
||||||
void TopPeersStrip::apply(const TopPeersList &list) {
|
void TopPeersStrip::apply(const TopPeersList &list) {
|
||||||
auto now = std::vector<Entry>();
|
auto now = std::vector<Entry>();
|
||||||
|
|
||||||
|
auto selectedId = (_selected >= 0) ? _entries[_selected].id : 0;
|
||||||
|
auto pressedId = (_pressed >= 0) ? _entries[_pressed].id : 0;
|
||||||
for (const auto &entry : list.entries) {
|
for (const auto &entry : list.entries) {
|
||||||
if (_removed.contains(entry.id)) {
|
if (_removed.contains(entry.id)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -253,6 +286,18 @@ void TopPeersStrip::apply(const TopPeersList &list) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_entries = std::move(now);
|
_entries = std::move(now);
|
||||||
|
if (selectedId) {
|
||||||
|
const auto i = ranges::find(_entries, selectedId, &Entry::id);
|
||||||
|
if (i != end(_entries)) {
|
||||||
|
_selected = int(i - begin(_entries));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pressedId) {
|
||||||
|
const auto i = ranges::find(_entries, pressedId, &Entry::id);
|
||||||
|
if (i != end(_entries)) {
|
||||||
|
_pressed = int(i - begin(_entries));
|
||||||
|
}
|
||||||
|
}
|
||||||
updateScrollMax();
|
updateScrollMax();
|
||||||
unsubscribeUserpics();
|
unsubscribeUserpics();
|
||||||
if (!_entries.empty()) {
|
if (!_entries.empty()) {
|
||||||
|
@ -302,10 +347,19 @@ void TopPeersStrip::apply(Entry &entry, const TopPeersEntry &data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect TopPeersStrip::outer() const {
|
||||||
|
const auto &st = st::topPeers;
|
||||||
|
const auto single = st.photoLeft * 2 + st.photo;
|
||||||
|
return QRect(0, 0, single, height());
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect TopPeersStrip::innerRounded() const {
|
||||||
|
return outer().marginsRemoved(st::topPeersMargin);
|
||||||
|
}
|
||||||
|
|
||||||
void TopPeersStrip::paintEvent(QPaintEvent *e) {
|
void TopPeersStrip::paintEvent(QPaintEvent *e) {
|
||||||
auto p = Painter(this);
|
auto p = Painter(this);
|
||||||
const auto &st = st::topPeers;
|
const auto &st = st::topPeers;
|
||||||
const auto line = st.lineTwice / 2;
|
|
||||||
const auto single = st.photoLeft * 2 + st.photo;
|
const auto single = st.photoLeft * 2 + st.photo;
|
||||||
|
|
||||||
const auto from = std::min(_scrollLeft / single, int(_entries.size()));
|
const auto from = std::min(_scrollLeft / single, int(_entries.size()));
|
||||||
|
@ -315,12 +369,28 @@ void TopPeersStrip::paintEvent(QPaintEvent *e) {
|
||||||
int(_entries.size()));
|
int(_entries.size()));
|
||||||
|
|
||||||
auto x = -_scrollLeft + from * single;
|
auto x = -_scrollLeft + from * single;
|
||||||
|
const auto highlighted = (_pressed >= 0) ? _pressed : _selected;
|
||||||
for (auto i = from; i != till; ++i) {
|
for (auto i = from; i != till; ++i) {
|
||||||
auto &entry = _entries[i];
|
auto &entry = _entries[i];
|
||||||
|
const auto selected = (i == highlighted);
|
||||||
|
if (selected) {
|
||||||
|
_selection.paint(p, innerRounded().translated(x, 0));
|
||||||
|
}
|
||||||
|
if (entry.ripple) {
|
||||||
|
entry.ripple->paint(
|
||||||
|
p,
|
||||||
|
x + st::topPeersMargin.left(),
|
||||||
|
st::topPeersMargin.top(),
|
||||||
|
width());
|
||||||
|
if (entry.ripple->empty()) {
|
||||||
|
entry.ripple = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!entry.subscribed) {
|
if (!entry.subscribed) {
|
||||||
subscribeUserpic(entry);
|
subscribeUserpic(entry);
|
||||||
}
|
}
|
||||||
paintUserpic(p, i, x);
|
paintUserpic(p, x, i, selected);
|
||||||
|
|
||||||
const auto nameLeft = x + st.nameLeft;
|
const auto nameLeft = x + st.nameLeft;
|
||||||
const auto nameWidth = single - 2 * st.nameLeft;
|
const auto nameWidth = single - 2 * st.nameLeft;
|
||||||
|
@ -335,7 +405,11 @@ void TopPeersStrip::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopPeersStrip::paintUserpic(Painter &p, int index, int x) {
|
void TopPeersStrip::paintUserpic(
|
||||||
|
Painter &p,
|
||||||
|
int x,
|
||||||
|
int index,
|
||||||
|
bool selected) {
|
||||||
Expects(index >= 0 && index < _entries.size());
|
Expects(index >= 0 && index < _entries.size());
|
||||||
|
|
||||||
auto &entry = _entries[index];
|
auto &entry = _entries[index];
|
||||||
|
@ -401,7 +475,7 @@ void TopPeersStrip::paintUserpic(Painter &p, int index, int x) {
|
||||||
: (QString::number(entry.badge / 1000) + 'K');
|
: (QString::number(entry.badge / 1000) + 'K');
|
||||||
}
|
}
|
||||||
auto st = Ui::UnreadBadgeStyle();
|
auto st = Ui::UnreadBadgeStyle();
|
||||||
st.selected = (_selected == index);
|
st.selected = selected;
|
||||||
st.muted = entry.muted;
|
st.muted = entry.muted;
|
||||||
const auto &counter = entry.badgeString;
|
const auto &counter = entry.badgeString;
|
||||||
const auto badge = PaintUnreadBadge(q, counter, size, 0, st);
|
const auto badge = PaintUnreadBadge(q, counter, size, 0, st);
|
||||||
|
@ -422,6 +496,7 @@ void TopPeersStrip::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
if (_selected < 0 || _entries.empty()) {
|
if (_selected < 0 || _entries.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Assert(_selected < _entries.size());
|
||||||
_menu = base::make_unique_q<Ui::PopupMenu>(
|
_menu = base::make_unique_q<Ui::PopupMenu>(
|
||||||
this,
|
this,
|
||||||
st::popupMenuWithIcons);
|
st::popupMenuWithIcons);
|
||||||
|
@ -476,6 +551,7 @@ void TopPeersStrip::updateSelected() {
|
||||||
setCursor(over ? style::cur_pointer : style::cur_default);
|
setCursor(over ? style::cur_pointer : style::cur_default);
|
||||||
}
|
}
|
||||||
_selected = selected;
|
_selected = selected;
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "base/weak_ptr.h"
|
#include "base/weak_ptr.h"
|
||||||
#include "ui/widgets/menu/menu_add_action_callback.h"
|
#include "ui/widgets/menu/menu_add_action_callback.h"
|
||||||
|
#include "ui/round_rect.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -68,8 +69,10 @@ private:
|
||||||
bool finishDragging();
|
bool finishDragging();
|
||||||
void subscribeUserpic(Entry &entry);
|
void subscribeUserpic(Entry &entry);
|
||||||
void unsubscribeUserpics(bool all = false);
|
void unsubscribeUserpics(bool all = false);
|
||||||
void paintUserpic(Painter &p, int index, int x);
|
void paintUserpic(Painter &p, int x, int index, bool selected);
|
||||||
|
|
||||||
|
[[nodiscard]] QRect outer() const;
|
||||||
|
[[nodiscard]] QRect innerRounded() const;
|
||||||
void apply(const TopPeersList &list);
|
void apply(const TopPeersList &list);
|
||||||
void apply(Entry &entry, const TopPeersEntry &data);
|
void apply(Entry &entry, const TopPeersEntry &data);
|
||||||
|
|
||||||
|
@ -92,6 +95,7 @@ private:
|
||||||
int _selected = -1;
|
int _selected = -1;
|
||||||
int _pressed = -1;
|
int _pressed = -1;
|
||||||
|
|
||||||
|
Ui::RoundRect _selection;
|
||||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||||
base::has_weak_ptr _menuGuard;
|
base::has_weak_ptr _menuGuard;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue