mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-17 22:57:11 +02:00
Added initial implementation of right button for bots in dialogs list.
This commit is contained in:
parent
14cc7789d9
commit
8a3aa660cb
9 changed files with 259 additions and 39 deletions
|
@ -1475,6 +1475,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_profile_enable_notifications" = "Notifications";
|
||||
"lng_profile_send_message" = "Send Message";
|
||||
"lng_profile_open_app" = "Open App";
|
||||
"lng_profile_open_app_short" = "Open";
|
||||
"lng_profile_open_app_about" = "By launching this mini app, you agree to the {terms}.";
|
||||
"lng_profile_open_app_terms" = "Terms of Service for Mini Apps";
|
||||
"lng_profile_bot_permissions_title" = "Allow access to";
|
||||
|
|
|
@ -1826,8 +1826,8 @@ void StickersBox::Inner::setPressed(SelectedRow pressed) {
|
|||
if (_megagroupSet && pressedIndex >= 0 && pressedIndex < _rows.size()) {
|
||||
update(0, _itemsTop + pressedIndex * _rowHeight, width(), _rowHeight);
|
||||
auto &set = _rows[pressedIndex];
|
||||
auto rippleMask = Ui::RippleAnimation::RectMask(QSize(width(), _rowHeight));
|
||||
if (!set->ripple) {
|
||||
auto rippleMask = Ui::RippleAnimation::RectMask(QSize(width(), _rowHeight));
|
||||
set->ripple = std::make_unique<Ui::RippleAnimation>(st::defaultRippleAnimation, std::move(rippleMask), [this, pressedIndex] {
|
||||
update(0, _itemsTop + pressedIndex * _rowHeight, width(), _rowHeight);
|
||||
});
|
||||
|
|
|
@ -108,6 +108,10 @@ taggedForumDialogRow: DialogRow(forumDialogRow) {
|
|||
}
|
||||
dialogRowFilterTagSkip : 4px;
|
||||
dialogRowFilterTagFont : font(10px);
|
||||
dialogRowOpenBotTextStyle: semiboldTextStyle;
|
||||
dialogRowOpenBotHeight: 20px;
|
||||
dialogRowOpenBotRight: 10px;
|
||||
dialogRowOpenBotTop: 32px;
|
||||
|
||||
forumDialogJumpArrow: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFg }};
|
||||
forumDialogJumpArrowOver: icon{{ "dialogs/dialogs_topic_arrow", dialogsTextFgOver }};
|
||||
|
|
|
@ -29,6 +29,7 @@ class SavedSublist;
|
|||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class RippleAnimation;
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
|
@ -43,6 +44,14 @@ class Row;
|
|||
class IndexedList;
|
||||
class MainList;
|
||||
|
||||
struct RightButton final {
|
||||
QImage bg;
|
||||
QImage selectedBg;
|
||||
QImage activeBg;
|
||||
Ui::Text::String text;
|
||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||
};
|
||||
|
||||
struct RowsByLetter {
|
||||
not_null<Row*> main;
|
||||
base::flat_map<QChar, not_null<Row*>> letters;
|
||||
|
|
|
@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text_options.h"
|
||||
#include "ui/dynamic_thumbnails.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/rect.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_folder.h"
|
||||
|
@ -62,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/window_controller.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_peer_menu.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/effects/loading_element.h"
|
||||
#include "ui/widgets/multi_select.h"
|
||||
#include "ui/widgets/menu/menu_add_action_callback_factory.h"
|
||||
|
@ -122,6 +124,19 @@ constexpr auto kPreviewPostsLimit = 3;
|
|||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] UserData *MaybeBotWithApp(Row *row) {
|
||||
if (row) {
|
||||
if (const auto history = row->key().history()) {
|
||||
if (const auto user = history->peer->asUser()) {
|
||||
if (user->botInfo && user->botInfo->hasMainApp) {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<SearchEmpty> MakeSearchEmpty(
|
||||
QWidget *parent,
|
||||
SearchState state) {
|
||||
|
@ -773,7 +788,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
not_null<Row*> row,
|
||||
bool selected,
|
||||
bool mayBeActive) {
|
||||
const auto key = row->key();
|
||||
const auto &key = row->key();
|
||||
const auto active = mayBeActive && isRowActive(row, activeEntry);
|
||||
const auto forum = key.history() && key.history()->isForum();
|
||||
if (forum && !_topicJumpCache) {
|
||||
|
@ -781,6 +796,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
const auto expanding = forum
|
||||
&& (key.history()->peer->id == childListShown.peerId);
|
||||
context.rightButton = maybeCacheRightButton(row);
|
||||
|
||||
context.st = (forum ? &st::forumDialogRow : _st.get());
|
||||
|
||||
|
@ -1195,6 +1211,47 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] RightButton *InnerWidget::maybeCacheRightButton(Row *row) {
|
||||
if (const auto user = MaybeBotWithApp(row)) {
|
||||
const auto it = _rightButtons.find(user->id);
|
||||
if (it == _rightButtons.end()) {
|
||||
auto rightButton = RightButton();
|
||||
const auto text
|
||||
= tr::lng_profile_open_app_short(tr::now).toUpper();
|
||||
rightButton.text.setText(st::dialogRowOpenBotTextStyle, text);
|
||||
const auto size = QSize(
|
||||
rightButton.text.maxWidth()
|
||||
+ rightButton.text.minHeight(),
|
||||
st::dialogRowOpenBotHeight);
|
||||
const auto generateBg = [&](const style::color &c) {
|
||||
auto bg = QImage(
|
||||
style::DevicePixelRatio() * size,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
bg.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
bg.fill(Qt::transparent);
|
||||
{
|
||||
auto p = QPainter(&bg);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(c);
|
||||
const auto r = size.height() / 2;
|
||||
p.drawRoundedRect(Rect(size), r, r);
|
||||
}
|
||||
return bg;
|
||||
};
|
||||
rightButton.bg = generateBg(st::activeButtonBg);
|
||||
rightButton.selectedBg = generateBg(st::activeButtonBgOver);
|
||||
rightButton.activeBg = generateBg(st::activeButtonFg);
|
||||
return &(_rightButtons.emplace(
|
||||
user->id,
|
||||
std::move(rightButton)).first->second);
|
||||
} else {
|
||||
return &(it->second);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Ui::VideoUserpic *InnerWidget::validateVideoUserpic(not_null<Row*> row) {
|
||||
const auto history = row->history();
|
||||
return history ? validateVideoUserpic(history) : nullptr;
|
||||
|
@ -1554,6 +1611,26 @@ void InnerWidget::clearIrrelevantState() {
|
|||
}
|
||||
}
|
||||
|
||||
bool InnerWidget::lookupIsInBotAppButton(
|
||||
Row *row,
|
||||
QPoint localPosition) {
|
||||
if (const auto user = MaybeBotWithApp(row)) {
|
||||
const auto it = _rightButtons.find(user->id);
|
||||
if (it != _rightButtons.end()) {
|
||||
const auto s = it->second.bg.size() / style::DevicePixelRatio();
|
||||
const auto r = QRect(
|
||||
width() - s.width() - st::dialogRowOpenBotRight,
|
||||
st::dialogRowOpenBotTop,
|
||||
s.width(),
|
||||
s.height());
|
||||
if (r.contains(localPosition)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InnerWidget::selectByMouse(QPoint globalPosition) {
|
||||
const auto local = mapFromGlobal(globalPosition);
|
||||
if (updateReorderPinned(local)) {
|
||||
|
@ -1594,16 +1671,19 @@ void InnerWidget::selectByMouse(QPoint globalPosition) {
|
|||
: (mouseY >= offset)
|
||||
? _shownList->rowAtY(mouseY - offset)
|
||||
: nullptr;
|
||||
const auto mappedY = selected ? mouseY - offset - selected->top() : 0;
|
||||
const auto selectedTopicJump = selected
|
||||
&& selected->lookupIsInTopicJump(
|
||||
local.x(),
|
||||
mouseY - offset - selected->top());
|
||||
&& selected->lookupIsInTopicJump(local.x(), mappedY);
|
||||
const auto selectedBotApp = selected
|
||||
&& lookupIsInBotAppButton(selected, QPoint(local.x(), mappedY));
|
||||
if (_collapsedSelected != collapsedSelected
|
||||
|| _selected != selected
|
||||
|| _selectedTopicJump != selectedTopicJump) {
|
||||
|| _selectedTopicJump != selectedTopicJump
|
||||
|| _selectedBotApp != selectedBotApp) {
|
||||
updateSelectedRow();
|
||||
_selected = selected;
|
||||
_selectedTopicJump = selectedTopicJump;
|
||||
_selectedBotApp = selectedBotApp;
|
||||
_collapsedSelected = collapsedSelected;
|
||||
updateSelectedRow();
|
||||
setCursor((_selected || _collapsedSelected >= 0)
|
||||
|
@ -1729,7 +1809,7 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
|||
selectByMouse(e->globalPos());
|
||||
|
||||
_pressButton = e->button();
|
||||
setPressed(_selected, _selectedTopicJump);
|
||||
setPressed(_selected, _selectedTopicJump, _selectedBotApp);
|
||||
setCollapsedPressed(_collapsedSelected);
|
||||
setHashtagPressed(_hashtagSelected);
|
||||
_hashtagDeletePressed = _hashtagDeleteSelected;
|
||||
|
@ -1762,7 +1842,22 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) {
|
|||
};
|
||||
const auto origin = e->pos()
|
||||
- QPoint(0, dialogsOffset() + _pressed->top());
|
||||
if (_pressedTopicJump) {
|
||||
if (_pressedBotApp && _pressedBotAppData) {
|
||||
const auto size = _pressedBotAppData->bg.size()
|
||||
/ style::DevicePixelRatio();
|
||||
if (!_pressedBotAppData->ripple) {
|
||||
const auto r = size.height() / 2;
|
||||
_pressedBotAppData->ripple
|
||||
= std::make_unique<Ui::RippleAnimation>(
|
||||
st::defaultRippleAnimation,
|
||||
Ui::RippleAnimation::RoundRectMask(size, r),
|
||||
updateCallback);
|
||||
}
|
||||
const auto shift = QPoint(
|
||||
width() - size.width() - st::dialogRowOpenBotRight,
|
||||
st::dialogRowOpenBotTop);
|
||||
_pressedBotAppData->ripple->add(origin - shift);
|
||||
} else if (_pressedTopicJump) {
|
||||
row->addTopicJumpRipple(
|
||||
origin,
|
||||
_topicJumpCache.get(),
|
||||
|
@ -2094,6 +2189,7 @@ void InnerWidget::mousePressReleased(
|
|||
setCollapsedPressed(-1);
|
||||
const auto pressedTopicRootId = _pressedTopicJumpRootId;
|
||||
const auto pressedTopicJump = _pressedTopicJump;
|
||||
const auto pressedBotApp = _pressedBotApp;
|
||||
auto pressed = _pressed;
|
||||
clearPressed();
|
||||
auto hashtagPressed = _hashtagPressed;
|
||||
|
@ -2113,12 +2209,16 @@ void InnerWidget::mousePressReleased(
|
|||
if (wasDragging) {
|
||||
selectByMouse(globalPosition);
|
||||
}
|
||||
if (_pressedBotAppData && _pressedBotAppData->ripple) {
|
||||
_pressedBotAppData->ripple->lastStop();
|
||||
}
|
||||
updateSelectedRow();
|
||||
if (!wasDragging && button == Qt::LeftButton) {
|
||||
if ((collapsedPressed >= 0 && collapsedPressed == _collapsedSelected)
|
||||
|| (pressed
|
||||
&& pressed == _selected
|
||||
&& pressedTopicJump == _selectedTopicJump)
|
||||
&& pressedTopicJump == _selectedTopicJump
|
||||
&& pressedBotApp == _selectedBotApp)
|
||||
|| (hashtagPressed >= 0
|
||||
&& hashtagPressed == _hashtagSelected
|
||||
&& hashtagDeletePressed == _hashtagDeleteSelected)
|
||||
|
@ -2131,7 +2231,13 @@ void InnerWidget::mousePressReleased(
|
|||
&& searchedPressed == _searchedSelected)
|
||||
|| (pressedMorePosts
|
||||
&& pressedMorePosts == _selectedMorePosts)) {
|
||||
chooseRow(modifiers, pressedTopicRootId);
|
||||
if (pressedBotApp) {
|
||||
if (const auto user = MaybeBotWithApp(pressed)) {
|
||||
_openBotMainAppRequests.fire(peerToUser(user->id));
|
||||
}
|
||||
} else {
|
||||
chooseRow(modifiers, pressedTopicRootId);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (auto activated = ClickHandler::unpressed()) {
|
||||
|
@ -2152,14 +2258,31 @@ void InnerWidget::setCollapsedPressed(int pressed) {
|
|||
}
|
||||
}
|
||||
|
||||
void InnerWidget::setPressed(Row *pressed, bool pressedTopicJump) {
|
||||
if (_pressed != pressed || (pressed && _pressedTopicJump != pressedTopicJump)) {
|
||||
void InnerWidget::setPressed(
|
||||
Row *pressed,
|
||||
bool pressedTopicJump,
|
||||
bool pressedBotApp) {
|
||||
if ((_pressed != pressed)
|
||||
|| (pressed && _pressedTopicJump != pressedTopicJump)
|
||||
|| (pressed && _pressedBotApp != pressedBotApp)) {
|
||||
if (_pressed) {
|
||||
_pressed->stopLastRipple();
|
||||
}
|
||||
if (_pressedBotAppData && _pressedBotAppData->ripple) {
|
||||
_pressedBotAppData->ripple->lastStop();
|
||||
}
|
||||
_pressed = pressed;
|
||||
if (pressed || !pressedTopicJump) {
|
||||
if (pressed || !pressedTopicJump || !pressedBotApp) {
|
||||
_pressedTopicJump = pressedTopicJump;
|
||||
_pressedBotApp = pressedBotApp;
|
||||
if (pressedBotApp) {
|
||||
if (const auto user = MaybeBotWithApp(pressed)) {
|
||||
const auto it = _rightButtons.find(user->id);
|
||||
if (it != _rightButtons.end()) {
|
||||
_pressedBotAppData = &(it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto history = pressedTopicJump
|
||||
? pressed->history()
|
||||
: nullptr;
|
||||
|
@ -2170,7 +2293,7 @@ void InnerWidget::setPressed(Row *pressed, bool pressedTopicJump) {
|
|||
}
|
||||
|
||||
void InnerWidget::clearPressed() {
|
||||
setPressed(nullptr, false);
|
||||
setPressed(nullptr, false, false);
|
||||
}
|
||||
|
||||
void InnerWidget::setHashtagPressed(int pressed) {
|
||||
|
@ -2265,7 +2388,7 @@ void InnerWidget::dialogRowReplaced(
|
|||
_selected = newRow;
|
||||
}
|
||||
if (_pressed == oldRow) {
|
||||
setPressed(newRow, _pressedTopicJump);
|
||||
setPressed(newRow, _pressedTopicJump, _pressedBotApp);
|
||||
}
|
||||
if (_dragging == oldRow) {
|
||||
if (newRow) {
|
||||
|
@ -4822,4 +4945,8 @@ bool InnerWidget::jumpToDialogRow(RowDescriptor to) {
|
|||
return _controller->jumpToChatListEntry(to);
|
||||
}
|
||||
|
||||
rpl::producer<UserId> InnerWidget::openBotMainAppRequests() const {
|
||||
return _openBotMainAppRequests.events();
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
||||
|
|
|
@ -64,6 +64,7 @@ class SearchTags;
|
|||
class SearchEmpty;
|
||||
class ChatSearchIn;
|
||||
enum class HashOrCashtag : uchar;
|
||||
struct RightButton;
|
||||
|
||||
struct ChosenRow {
|
||||
Key key;
|
||||
|
@ -200,6 +201,8 @@ public:
|
|||
return _touchCancelRequests.events();
|
||||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<UserId> openBotMainAppRequests() const;
|
||||
|
||||
protected:
|
||||
void visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
|
@ -286,7 +289,7 @@ private:
|
|||
void scrollToItem(int top, int height);
|
||||
void scrollToDefaultSelected();
|
||||
void setCollapsedPressed(int pressed);
|
||||
void setPressed(Row *pressed, bool pressedTopicJump);
|
||||
void setPressed(Row *pressed, bool pressedTopicJump, bool pressedBotApp);
|
||||
void clearPressed();
|
||||
void setHashtagPressed(int pressed);
|
||||
void setFilteredPressed(int pressed, bool pressedTopicJump);
|
||||
|
@ -451,6 +454,11 @@ private:
|
|||
void saveChatsFilterScrollState(FilterId filterId);
|
||||
void restoreChatsFilterScrollState(FilterId filterId);
|
||||
|
||||
[[nodiscard]] bool lookupIsInBotAppButton(
|
||||
Row *row,
|
||||
QPoint localPosition);
|
||||
[[nodiscard]] RightButton *maybeCacheRightButton(Row *row);
|
||||
|
||||
[[nodiscard]] QImage *cacheChatsFilterTag(
|
||||
const Data::ChatFilter &filter,
|
||||
uint8 more,
|
||||
|
@ -483,6 +491,10 @@ private:
|
|||
bool _selectedTopicJump = false;
|
||||
bool _pressedTopicJump = false;
|
||||
|
||||
RightButton *_pressedBotAppData = nullptr;
|
||||
bool _selectedBotApp = false;
|
||||
bool _pressedBotApp = false;
|
||||
|
||||
Row *_dragging = nullptr;
|
||||
int _draggingIndex = -1;
|
||||
int _aboveIndex = -1;
|
||||
|
@ -566,6 +578,8 @@ private:
|
|||
bool _waitingAllChatListEntryRefreshesForTags = false;
|
||||
rpl::lifetime _handleChatListEntryTagRefreshesLifetime;
|
||||
|
||||
std::unordered_map<PeerId, RightButton> _rightButtons;
|
||||
|
||||
Fn<void()> _loadMoreCallback;
|
||||
Fn<void()> _loadMoreFilteredCallback;
|
||||
rpl::event_stream<> _listBottomReached;
|
||||
|
@ -577,6 +591,7 @@ private:
|
|||
rpl::event_stream<SearchRequestDelay> _searchRequests;
|
||||
rpl::event_stream<QString> _completeHashtagRequests;
|
||||
rpl::event_stream<> _refreshHashtagsRequests;
|
||||
rpl::event_stream<UserId> _openBotMainAppRequests;
|
||||
|
||||
RowDescriptor _chatPreviewRow;
|
||||
bool _chatPreviewScheduled = false;
|
||||
|
|
|
@ -478,6 +478,12 @@ Widget::Widget(
|
|||
) | rpl::start_with_next([=](const ChosenRow &row) {
|
||||
chosenRow(row);
|
||||
}, lifetime());
|
||||
_inner->openBotMainAppRequests(
|
||||
) | rpl::start_with_next([=](UserId userId) {
|
||||
if (const auto user = session().data().user(userId)) {
|
||||
openBotMainApp(user);
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
_scroll->geometryChanged(
|
||||
) | rpl::start_with_next(crl::guard(_inner, [=] {
|
||||
|
|
|
@ -7,41 +7,42 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "dialogs/ui/dialogs_layout.h"
|
||||
|
||||
#include "base/unixtime.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "dialogs/dialogs_list.h"
|
||||
#include "dialogs/dialogs_three_state_icon.h"
|
||||
#include "dialogs/ui/dialogs_video_userpic.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/history_unread_things.h"
|
||||
#include "history/view/history_view_item_preview.h"
|
||||
#include "history/view/history_view_send_action.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "support/support_helper.h"
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/power_saving.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/unread_badge.h"
|
||||
#include "ui/unread_badge_paint.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/power_saving.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "support/support_helper.h"
|
||||
#include "main/main_session.h"
|
||||
#include "history/view/history_view_send_action.h"
|
||||
#include "history/view/history_view_item_preview.h"
|
||||
#include "history/history_unread_things.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/history.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
namespace Dialogs::Ui {
|
||||
namespace {
|
||||
|
@ -84,6 +85,55 @@ void PaintRowTopRight(
|
|||
text);
|
||||
}
|
||||
|
||||
int PaintRightButton(QPainter &p, const PaintContext &context) {
|
||||
if (context.width < st::columnMinimalWidthLeft) {
|
||||
return 0;
|
||||
}
|
||||
if (const auto rightButton = context.rightButton) {
|
||||
const auto size = rightButton->bg.size() / style::DevicePixelRatio();
|
||||
const auto left = context.width
|
||||
- size.width()
|
||||
- st::dialogRowOpenBotRight;
|
||||
const auto top = st::dialogRowOpenBotTop;
|
||||
p.drawImage(
|
||||
left,
|
||||
top,
|
||||
context.active
|
||||
? rightButton->activeBg
|
||||
: context.selected
|
||||
? rightButton->selectedBg
|
||||
: rightButton->bg);
|
||||
if (rightButton->ripple) {
|
||||
rightButton->ripple->paint(
|
||||
p,
|
||||
left,
|
||||
top,
|
||||
size.width() - size.height() / 2,
|
||||
context.active
|
||||
? &st::universalRippleAnimation.color->c
|
||||
: &st::activeButtonBgRipple->c);
|
||||
if (rightButton->ripple->empty()) {
|
||||
rightButton->ripple.reset();
|
||||
}
|
||||
}
|
||||
p.setPen(context.active
|
||||
? st::activeButtonBg
|
||||
: context.selected
|
||||
? st::activeButtonFgOver
|
||||
: st::activeButtonFg);
|
||||
rightButton->text.draw(p, {
|
||||
.position = QPoint(
|
||||
left + size.height() / 2,
|
||||
top + (st::dialogRowOpenBotHeight - rightButton->text.minHeight()) / 2),
|
||||
.availableWidth = size.width() - size.height() / 2,
|
||||
.outerWidth = size.width() - size.height() / 2,
|
||||
.elisionLines = 1,
|
||||
});
|
||||
return size.width() + st::dialogsUnreadPadding;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PaintBadges(
|
||||
QPainter &p,
|
||||
const PaintContext &context,
|
||||
|
@ -93,7 +143,9 @@ int PaintBadges(
|
|||
bool displayPinnedIcon = false,
|
||||
int pinnedIconTop = 0) {
|
||||
auto initial = right;
|
||||
if (badgesState.unread
|
||||
if (const auto used = PaintRightButton(p, context)) {
|
||||
return used - st::dialogsUnreadPadding;
|
||||
} else if (badgesState.unread
|
||||
&& !badgesState.unreadCounter
|
||||
&& context.st->unreadMarkDiameter > 0) {
|
||||
const auto d = context.st->unreadMarkDiameter;
|
||||
|
@ -430,7 +482,9 @@ void PaintRow(
|
|||
}
|
||||
|
||||
auto availableWidth = namewidth;
|
||||
if (entry->isPinnedDialog(context.filter)
|
||||
if (const auto used = PaintRightButton(p, context)) {
|
||||
availableWidth -= used;
|
||||
} else if (entry->isPinnedDialog(context.filter)
|
||||
&& (context.filter || !entry->fixedOnTopIndex())) {
|
||||
auto &icon = ThreeStateIcon(
|
||||
st::dialogsPinnedIcon,
|
||||
|
@ -528,7 +582,9 @@ void PaintRow(
|
|||
}
|
||||
} else if (!item) {
|
||||
auto availableWidth = namewidth;
|
||||
if (entry->isPinnedDialog(context.filter)
|
||||
if (const auto used = PaintRightButton(p, context)) {
|
||||
availableWidth -= used;
|
||||
} else if (entry->isPinnedDialog(context.filter)
|
||||
&& (context.filter || !entry->fixedOnTopIndex())) {
|
||||
auto &icon = ThreeStateIcon(
|
||||
st::dialogsPinnedIcon,
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace Dialogs {
|
|||
class Row;
|
||||
class FakeRow;
|
||||
class BasicRow;
|
||||
struct RightButton;
|
||||
} // namespace Dialogs
|
||||
|
||||
namespace Dialogs::Ui {
|
||||
|
@ -53,6 +54,7 @@ struct TopicJumpCache {
|
|||
};
|
||||
|
||||
struct PaintContext {
|
||||
RightButton *rightButton = nullptr;
|
||||
std::vector<QImage*> *chatsFilterTags = nullptr;
|
||||
not_null<const style::DialogRow*> st;
|
||||
TopicJumpCache *topicJumpCache = nullptr;
|
||||
|
|
Loading…
Add table
Reference in a new issue