mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 13:47:05 +02:00
Added support of locked sections to chats filters tabs slider.
This commit is contained in:
parent
dc49c788a8
commit
4d9112283d
3 changed files with 102 additions and 1 deletions
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/chat_filters_tabs_slider.h"
|
||||
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/widgets/side_bar_button.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
#include <QScrollBar>
|
||||
|
@ -57,6 +58,7 @@ int ChatsFiltersTabs::centerOfSection(int section) const {
|
|||
void ChatsFiltersTabs::fitWidthToSections() {
|
||||
const auto widths = countSectionsWidths(0);
|
||||
resizeToWidth(ranges::accumulate(widths, .0));
|
||||
_lockedFromX = calculateLockedFromX();
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::setUnreadCount(int index, int unreadCount) {
|
||||
|
@ -90,6 +92,37 @@ void ChatsFiltersTabs::setUnreadCount(int index, int unreadCount) {
|
|||
}
|
||||
}
|
||||
|
||||
int ChatsFiltersTabs::calculateLockedFromX() const {
|
||||
if (!_lockedFrom) {
|
||||
return std::numeric_limits<int>::max();
|
||||
}
|
||||
auto left = 0;
|
||||
auto index = 0;
|
||||
enumerateSections([&](const Section §ion) {
|
||||
const auto currentRight = section.left + section.width;
|
||||
if (index == _lockedFrom) {
|
||||
return false;
|
||||
}
|
||||
left = currentRight;
|
||||
index++;
|
||||
return true;
|
||||
});
|
||||
return left ? left : std::numeric_limits<int>::max();
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::setLockedFrom(int index) {
|
||||
_lockedFrom = index;
|
||||
_lockedFromX = calculateLockedFromX();
|
||||
if (!index) {
|
||||
_paletteLifetime.destroy();
|
||||
return;
|
||||
}
|
||||
_paletteLifetime = style::PaletteChanged(
|
||||
) | rpl::start_with_next([this] {
|
||||
_lockCache.emplace(Ui::SideBarLockIcon(_st.labelFg));
|
||||
});
|
||||
}
|
||||
|
||||
QImage ChatsFiltersTabs::cacheUnreadCount(int count) const {
|
||||
const auto widthIndex = (count < 10) ? 0 : (count < 100) ? 1 : 2;
|
||||
auto image = QImage(
|
||||
|
@ -144,6 +177,11 @@ void ChatsFiltersTabs::paintEvent(QPaintEvent *e) {
|
|||
section.contentWidth,
|
||||
_st.labelStyle.font->height);
|
||||
if (rect.intersects(clip)) {
|
||||
const auto locked = (_lockedFrom && (index >= _lockedFrom));
|
||||
if (locked) {
|
||||
constexpr auto kPremiumLockedOpacity = 0.6;
|
||||
p.setOpacity(kPremiumLockedOpacity);
|
||||
}
|
||||
p.setPen(anim::pen(_st.labelFg, _st.labelFgActive, active));
|
||||
section.label.draw(p, {
|
||||
.position = QPoint(labelLeft, _st.labelTop),
|
||||
|
@ -161,6 +199,18 @@ void ChatsFiltersTabs::paintEvent(QPaintEvent *e) {
|
|||
it->second.cache);
|
||||
}
|
||||
}
|
||||
if (locked) {
|
||||
if (!_lockCache) {
|
||||
_lockCache.emplace(Ui::SideBarLockIcon(_st.labelFg));
|
||||
}
|
||||
const auto size = _lockCache->size()
|
||||
/ style::DevicePixelRatio();
|
||||
p.drawImage(
|
||||
labelLeft + (section.label.maxWidth() - size.width()) / 2,
|
||||
height() - size.height() - st::lineWidth,
|
||||
*_lockCache);
|
||||
p.setOpacity(1.0);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
return true;
|
||||
|
@ -188,14 +238,36 @@ void ChatsFiltersTabs::paintEvent(QPaintEvent *e) {
|
|||
void ChatsFiltersTabs::mousePressEvent(QMouseEvent *e) {
|
||||
const auto mouseButton = e->button();
|
||||
if (mouseButton == Qt::MouseButton::LeftButton) {
|
||||
Ui::SettingsSlider::mousePressEvent(e);
|
||||
_lockedPressed = (e->pos().x() >= _lockedFromX);
|
||||
if (_lockedPressed) {
|
||||
Ui::RpWidget::mousePressEvent(e);
|
||||
} else {
|
||||
Ui::SettingsSlider::mousePressEvent(e);
|
||||
}
|
||||
} else {
|
||||
Ui::RpWidget::mousePressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::mouseReleaseEvent(QMouseEvent *e) {
|
||||
const auto mouseButton = e->button();
|
||||
if (mouseButton == Qt::MouseButton::LeftButton) {
|
||||
if (base::take(_lockedPressed)) {
|
||||
_lockedPressed = false;
|
||||
_lockedClicked.fire({});
|
||||
} else {
|
||||
Ui::SettingsSlider::mouseReleaseEvent(e);
|
||||
}
|
||||
} else {
|
||||
Ui::RpWidget::mouseReleaseEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::contextMenuEvent(QContextMenuEvent *e) {
|
||||
const auto pos = e->pos();
|
||||
if (pos.x() >= _lockedFromX) {
|
||||
return;
|
||||
}
|
||||
auto left = 0;
|
||||
auto index = 0;
|
||||
enumerateSections([&](const Section §ion) {
|
||||
|
@ -214,4 +286,8 @@ rpl::producer<int> ChatsFiltersTabs::contextMenuRequested() const {
|
|||
return _contextMenuRequested.events();
|
||||
}
|
||||
|
||||
rpl::producer<> ChatsFiltersTabs::lockedClicked() const {
|
||||
return _lockedClicked.events();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -28,16 +28,20 @@ public:
|
|||
[[nodiscard]] int centerOfSection(int section) const;
|
||||
void fitWidthToSections();
|
||||
void setUnreadCount(int index, int unreadCount);
|
||||
void setLockedFrom(int index);
|
||||
|
||||
[[nodiscard]] rpl::producer<int> contextMenuRequested() const;
|
||||
[[nodiscard]] rpl::producer<> lockedClicked() const;
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
|
||||
private:
|
||||
[[nodiscard]] QImage cacheUnreadCount(int count) const;
|
||||
[[nodiscard]] int calculateLockedFromX() const;
|
||||
|
||||
using Index = int;
|
||||
struct Unread final {
|
||||
|
@ -51,10 +55,16 @@ private:
|
|||
const int _unreadSkip;
|
||||
std::vector<int> _cachedBadgeWidths;
|
||||
int _cachedBadgeHeight = 0;
|
||||
int _lockedFrom = 0;
|
||||
int _lockedFromX = 0;
|
||||
bool _lockedPressed = false;
|
||||
std::optional<Ui::RoundRect> _bar;
|
||||
std::optional<Ui::RoundRect> _barActive;
|
||||
std::optional<QImage> _lockCache;
|
||||
|
||||
rpl::lifetime _paletteLifetime;
|
||||
rpl::event_stream<int> _contextMenuRequested;
|
||||
rpl::event_stream<> _lockedClicked;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -9,10 +9,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "api/api_chat_filters_remove_manager.h"
|
||||
#include "boxes/filters/edit_filter_box.h"
|
||||
#include "boxes/premium_limits_box.h"
|
||||
#include "core/application.h"
|
||||
#include "data/data_chat_filters.h"
|
||||
#include "data/data_premium_limits.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_unread_value.h"
|
||||
#include "data/data_user.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "settings/settings_folders.h"
|
||||
|
@ -205,6 +208,18 @@ not_null<Ui::RpWidget*> AddChatFiltersTabsStrip(
|
|||
}) | ranges::to_vector;
|
||||
slider->setSections(std::move(sections));
|
||||
slider->fitWidthToSections();
|
||||
{
|
||||
const auto reorderAll = session->user()->isPremium();
|
||||
const auto maxLimit = (reorderAll ? 1 : 0)
|
||||
+ Data::PremiumLimits(session).dialogFiltersCurrent();
|
||||
const auto premiumFrom = (reorderAll ? 0 : 1) + maxLimit;
|
||||
slider->setLockedFrom((premiumFrom >= list.size())
|
||||
? 0
|
||||
: premiumFrom);
|
||||
slider->lockedClicked() | rpl::start_with_next([=] {
|
||||
controller->show(Box(FiltersLimitBox, session, std::nullopt));
|
||||
}, slider->lifetime());
|
||||
}
|
||||
{
|
||||
auto includeMuted = Data::IncludeMutedCounterFoldersValue();
|
||||
state->unreadLifetime.destroy();
|
||||
|
|
Loading…
Add table
Reference in a new issue