From 405d8c327d81903b3809309294fe3c129f073a19 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 29 Sep 2022 14:33:17 +0400 Subject: [PATCH] Support different row styles in chats list. --- Telegram/SourceFiles/data/data_folder.cpp | 19 +- Telegram/SourceFiles/data/data_folder.h | 6 +- .../SourceFiles/data/data_forum_topic.cpp | 20 +- Telegram/SourceFiles/data/data_forum_topic.h | 4 +- Telegram/SourceFiles/dialogs/dialogs.style | 36 ++- Telegram/SourceFiles/dialogs/dialogs_entry.h | 21 +- .../dialogs/dialogs_inner_widget.cpp | 238 ++++++++++-------- .../dialogs/dialogs_inner_widget.h | 27 +- Telegram/SourceFiles/dialogs/dialogs_row.cpp | 71 +++--- Telegram/SourceFiles/dialogs/dialogs_row.h | 13 +- .../SourceFiles/dialogs/dialogs_widget.cpp | 6 +- .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 125 ++++----- .../SourceFiles/dialogs/ui/dialogs_layout.h | 15 +- Telegram/SourceFiles/history/history.cpp | 31 ++- Telegram/SourceFiles/history/history.h | 4 +- .../SourceFiles/history/history_service.cpp | 17 -- .../controls/history_view_compose_search.cpp | 1 + Telegram/SourceFiles/ui/empty_userpic.cpp | 2 +- .../window/themes/window_theme_preview.cpp | 33 ++- .../window/window_session_controller.cpp | 4 +- 20 files changed, 369 insertions(+), 324 deletions(-) diff --git a/Telegram/SourceFiles/data/data_folder.cpp b/Telegram/SourceFiles/data/data_folder.cpp index 0c9aa0fb78..6c2c7a8ebe 100644 --- a/Telegram/SourceFiles/data/data_folder.cpp +++ b/Telegram/SourceFiles/data/data_folder.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_histories.h" #include "data/data_changes.h" #include "dialogs/dialogs_key.h" +#include "dialogs/ui/dialogs_layout.h" #include "history/history.h" #include "history/history_item.h" #include "ui/painter.h" @@ -225,9 +226,15 @@ void Folder::loadUserpic() { void Folder::paintUserpic( Painter &p, std::shared_ptr &view, - int x, - int y, - int size) const { + const Dialogs::Ui::PaintContext &context) const { + paintUserpic( + p, + context.st->padding.left(), + context.st->padding.top(), + context.st->photoSize); +} + +void Folder::paintUserpic(Painter &p, int x, int y, int size) const { paintUserpic(p, x, y, size, nullptr, nullptr); } @@ -254,7 +261,7 @@ void Folder::paintUserpic( PainterHighQualityEnabler hq(p); p.drawEllipse(x, y, size, size); } - if (size == st::dialogsPhotoSize) { + if (size == st::defaultDialogRow.photoSize) { const auto rect = QRect{ x, y, size, size }; if (overrideFg) { st::dialogsArchiveUserpic.paintInCenter( @@ -266,10 +273,10 @@ void Folder::paintUserpic( } } else { p.save(); - const auto ratio = size / float64(st::dialogsPhotoSize); + const auto ratio = size / float64(st::defaultDialogRow.photoSize); p.translate(x + size / 2., y + size / 2.); p.scale(ratio, ratio); - const auto skip = st::dialogsPhotoSize; + const auto skip = st::defaultDialogRow.photoSize; const auto rect = QRect{ -skip, -skip, 2 * skip, 2 * skip }; if (overrideFg) { st::dialogsArchiveUserpic.paintInCenter( diff --git a/Telegram/SourceFiles/data/data_folder.h b/Telegram/SourceFiles/data/data_folder.h index c589dd762b..97d46f7105 100644 --- a/Telegram/SourceFiles/data/data_folder.h +++ b/Telegram/SourceFiles/data/data_folder.h @@ -60,10 +60,8 @@ public: void paintUserpic( Painter &p, std::shared_ptr &view, - int x, - int y, - int size) const override; - + const Dialogs::Ui::PaintContext &context) const override; + void paintUserpic(Painter &p, int x, int y, int size) const; void paintUserpic( Painter &p, int x, diff --git a/Telegram/SourceFiles/data/data_forum_topic.cpp b/Telegram/SourceFiles/data/data_forum_topic.cpp index 9ca85be8cc..d5edabe41b 100644 --- a/Telegram/SourceFiles/data/data_forum_topic.cpp +++ b/Telegram/SourceFiles/data/data_forum_topic.cpp @@ -12,11 +12,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/stickers/data_custom_emoji.h" #include "dialogs/dialogs_main_list.h" +#include "dialogs/ui/dialogs_layout.h" #include "core/application.h" #include "core/core_settings.h" #include "history/history.h" #include "history/history_item.h" #include "ui/painter.h" +#include "styles/style_dialogs.h" namespace Data { @@ -207,20 +209,14 @@ void ForumTopic::loadUserpic() { void ForumTopic::paintUserpic( Painter &p, std::shared_ptr &view, - int x, - int y, - int size) const { + const Dialogs::Ui::PaintContext &context) const { if (_icon) { - const auto emoji = Data::FrameSizeFromTag( - Data::CustomEmojiManager::SizeTag::Isolated - ) / style::DevicePixelRatio(); + const auto &st = context.st; _icon->paint(p, { .preview = st::windowBgOver->c, - .now = crl::now(), - .position = QPoint( - x + (size - emoji) / 2, - y + (size - emoji) / 2), - .paused = false, + .now = context.now, + .position = QPoint(st->padding.left(), st->padding.top()), + .paused = context.paused, }); } } @@ -297,7 +293,7 @@ void ForumTopic::applyIconId(DocumentId iconId) { ? _history->owner().customEmojiManager().create( _iconId, [=] { updateChatListEntry(); }, - Data::CustomEmojiManager::SizeTag::Isolated) + Data::CustomEmojiManager::SizeTag::Normal) : nullptr; } updateChatListEntry(); diff --git a/Telegram/SourceFiles/data/data_forum_topic.h b/Telegram/SourceFiles/data/data_forum_topic.h index 8f36d87b65..7928782813 100644 --- a/Telegram/SourceFiles/data/data_forum_topic.h +++ b/Telegram/SourceFiles/data/data_forum_topic.h @@ -76,9 +76,7 @@ public: void paintUserpic( Painter &p, std::shared_ptr &view, - int x, - int y, - int size) const override; + const Dialogs::Ui::PaintContext &context) const override; [[nodiscard]] int unreadCount() const; [[nodiscard]] bool unreadCountKnown() const; diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index dc2883f85d..ddfd5f2f38 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -9,6 +9,16 @@ using "ui/basic.style"; using "ui/widgets/widgets.style"; +DialogRow { + height: pixels; + padding: margins; + photoSize: pixels; + nameLeft: pixels; + nameTop: pixels; + textLeft: pixels; + textTop: pixels; +} + dialogsUnreadFont: font(12px bold); dialogsUnreadHeight: 19px; dialogsUnreadPadding: 5px; @@ -25,14 +35,20 @@ dialogsTextStyle: TextStyle(defaultTextStyle) { } dialogsDateFont: font(13px); dialogsDateSkip: 5px; -dialogsNameTop: 2px; dialogsRowHeight: 62px; dialogsFilterPadding: point(7px, 7px); dialogsFilterSkip: 4px; -dialogsPhotoSize: 46px; -dialogsPhotoPadding: 12px; -dialogsPadding: point(10px, 8px); + +defaultDialogRow: DialogRow { + height: dialogsRowHeight; + padding: margins(10px, 8px, 10px, 8px); + photoSize: 46px; + nameLeft: 68px; + nameTop: 10px; + textLeft: 68px; + textTop: 35px; +} dialogsOnlineBadgeStroke: 2px; dialogsOnlineBadgeSize: 10px; @@ -47,8 +63,6 @@ dialogsSpeakingDenominator: 8.; dialogsImportantBarHeight: 37px; -dialogsSkip: 8px; - dialogsWidthDuration: 120; dialogsTextWidthMin: 150px; @@ -371,3 +385,13 @@ downloadLoadedSize: 30px; downloadIconDocument: icon {{ "dialogs/dialogs_downloads", windowFgActive }}; downloadIconSize: 16px; downloadIconSizeDone: 20px; + +forumTopicRow: DialogRow(defaultDialogRow) { + height: 54px; + padding: margins(8px, 7px, 8px, 7px); + photoSize: 20px; + nameLeft: 39px; + nameTop: 7px; + textLeft: 68px; + textTop: 29px; +} diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 24d3557423..6d9ba5b860 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -23,6 +23,14 @@ class ForumTopic; class CloudImageView; } // namespace Data +namespace Ui { +} // namespace Ui + +namespace Dialogs::Ui { +using namespace ::Ui; +struct PaintContext; +} // namespace Dialogs::Ui + namespace Dialogs { class Row; @@ -174,18 +182,7 @@ public: virtual void paintUserpic( Painter &p, std::shared_ptr &view, - int x, - int y, - int size) const = 0; - void paintUserpicLeft( - Painter &p, - std::shared_ptr &view, - int x, - int y, - int w, - int size) const { - paintUserpic(p, view, rtl() ? (w - x - size) : x, y, size); - } + const Ui::PaintContext &context) const = 0; [[nodiscard]] TimeId chatListTimeId() const { return _timeId; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 894255e9f7..37c99e4dc5 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -121,7 +121,7 @@ struct InnerWidget::HashtagResult { }; struct InnerWidget::PeerSearchResult { - PeerSearchResult(not_null peer) : peer(peer) { + explicit PeerSearchResult(not_null peer) : peer(peer) { } not_null peer; mutable Ui::Text::String name; @@ -134,6 +134,7 @@ InnerWidget::InnerWidget( not_null controller) : RpWidget(parent) , _controller(controller) +, _st(&st::defaultDialogRow) , _pinnedShiftAnimation([=](crl::time now) { return pinnedShiftAnimationCallback(now); }) @@ -177,6 +178,7 @@ InnerWidget::InnerWidget( ) | rpl::start_with_next([=]( const Data::SendActionManager::AnimationUpdate &update) { const auto updateRect = Ui::RowPainter::SendActionAnimationRect( + _st, update.left, update.width, update.height, @@ -348,7 +350,7 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) { int InnerWidget::dialogsOffset() const { return _collapsedRows.size() * st::dialogsImportantBarHeight - - _skipTopDialogs * st::dialogsRowHeight; + - _skipTopDialogs * _st->height; } int InnerWidget::fixedOnTopCount() const { @@ -364,7 +366,7 @@ int InnerWidget::fixedOnTopCount() const { } int InnerWidget::pinnedOffset() const { - return dialogsOffset() + fixedOnTopCount() * st::dialogsRowHeight; + return dialogsOffset() + fixedOnTopCount() * _st->height; } int InnerWidget::filteredOffset() const { @@ -372,11 +374,17 @@ int InnerWidget::filteredOffset() const { } int InnerWidget::peerSearchOffset() const { - return filteredOffset() + (_filterResults.size() * st::dialogsRowHeight) + st::searchedBarHeight; + return filteredOffset() + + (_filterResults.size() * _st->height) + + st::searchedBarHeight; } int InnerWidget::searchedOffset() const { - auto result = peerSearchOffset() + (_peerSearchResults.empty() ? 0 : ((_peerSearchResults.size() * st::dialogsRowHeight) + st::searchedBarHeight)); + auto result = peerSearchOffset(); + if (!_peerSearchResults.empty()) { + result += (_peerSearchResults.size() * st::dialogsRowHeight) + + st::searchedBarHeight; + } if (_searchInChat) { result += searchInChatSkip(); } @@ -412,6 +420,7 @@ void InnerWidget::changeOpenedForum(ChannelData *forum) { stopReorderPinned(); clearSelection(); _openedForum = forum ? forum->forum() : nullptr; + _st = forum ? &st::forumTopicRow : &st::defaultDialogRow; _openedForumLifetime.destroy(); if (forum) { @@ -449,7 +458,8 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto rows = shownDialogs(); const auto &list = rows->all(); - const auto otherStart = std::max(int(rows->size()) - _skipTopDialogs, 0) * st::dialogsRowHeight; + const auto shownCount = int(rows->size()) - _skipTopDialogs; + const auto otherStart = std::max(shownCount, 0) * _st->height; const auto active = activeEntry.key; const auto selected = _menuRow.key ? _menuRow.key @@ -464,7 +474,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto skip = dialogsOffset(); auto reorderingPinned = (_aboveIndex >= 0 && !_pinnedRows.empty()); if (reorderingPinned) { - dialogsClip = dialogsClip.marginsAdded(QMargins(0, st::dialogsRowHeight, 0, st::dialogsRowHeight)); + dialogsClip = dialogsClip.marginsAdded(QMargins(0, _st->height, 0, _st->height)); } const auto promoted = fixedOnTopCount(); @@ -482,6 +492,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto isActive = (key == active); const auto isSelected = (key == selected); Ui::RowPainter::Paint(p, row, validateVideoUserpic(row), { + .st = _st, .folder = _openedFolder, .forum = _openedForum, .filter = _filterId, @@ -497,7 +508,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } }; - auto i = list.cfind(dialogsClip.top() - skip, st::dialogsRowHeight); + auto i = list.cfind(dialogsClip.top() - skip, _st->height); while (i != list.cend() && (*i)->pos() < _skipTopDialogs) { ++i; } @@ -506,13 +517,13 @@ void InnerWidget::paintEvent(QPaintEvent *e) { // If we're reordering pinned chats we need to fill this area background first. if (reorderingPinned) { - p.fillRect(0, (promoted - _skipTopDialogs) * st::dialogsRowHeight, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg); + p.fillRect(0, (promoted - _skipTopDialogs) * _st->height, fullWidth, st::dialogsRowHeight * _pinnedRows.size(), st::dialogsBg); } - p.translate(0, (lastPaintedPos - _skipTopDialogs) * st::dialogsRowHeight); + p.translate(0, (lastPaintedPos - _skipTopDialogs) * _st->height); for (auto e = list.cend(); i != e; ++i) { auto row = (*i); - if ((lastPaintedPos - _skipTopDialogs) * st::dialogsRowHeight >= dialogsClip.top() - skip + dialogsClip.height()) { + if ((lastPaintedPos - _skipTopDialogs) * _st->height >= dialogsClip.top() - skip + dialogsClip.height()) { break; } @@ -522,7 +533,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { paintDialog(row); } - p.translate(0, st::dialogsRowHeight); + p.translate(0, _st->height); ++lastPaintedPos; } @@ -531,9 +542,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { auto i = list.cfind(promoted + _aboveIndex, 1); auto pos = (i == list.cend()) ? -1 : (*i)->pos(); if (pos == promoted + _aboveIndex) { - p.translate(0, (pos - lastPaintedPos) * st::dialogsRowHeight); + p.translate(0, (pos - lastPaintedPos) * _st->height); paintDialog(*i); - p.translate(0, (lastPaintedPos - pos) * st::dialogsRowHeight); + p.translate(0, (lastPaintedPos - pos) * _st->height); } } } @@ -547,7 +558,10 @@ void InnerWidget::paintEvent(QPaintEvent *e) { auto to = ceilclamp(r.y() + r.height(), st::mentionHeight, 0, _hashtagResults.size()); p.translate(0, from * st::mentionHeight); if (from < _hashtagResults.size()) { - auto htagwidth = fullWidth - st::dialogsPadding.x() * 2; + const auto htagleft = st::defaultDialogRow.padding.left(); + auto htagwidth = fullWidth + - htagleft + - st::defaultDialogRow.padding.right(); p.setFont(st::mentionFont); for (; from < to; ++from) { @@ -576,11 +590,11 @@ void InnerWidget::paintEvent(QPaintEvent *e) { p.setFont(st::mentionFont); if (!first.isEmpty()) { p.setPen(selected ? st::mentionFgOverActive : st::mentionFgActive); - p.drawText(st::dialogsPadding.x(), st::mentionTop + st::mentionFont->ascent, first); + p.drawText(htagleft, st::mentionTop + st::mentionFont->ascent, first); } if (!second.isEmpty()) { p.setPen(selected ? st::mentionFgOver : st::mentionFg); - p.drawText(st::dialogsPadding.x() + firstwidth, st::mentionTop + st::mentionFont->ascent, second); + p.drawText(htagleft + firstwidth, st::mentionTop + st::mentionFont->ascent, second); } p.translate(0, st::mentionHeight); } @@ -588,9 +602,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } if (!_filterResults.empty()) { auto skip = filteredOffset(); - auto from = floorclamp(r.y() - skip, st::dialogsRowHeight, 0, _filterResults.size()); - auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _filterResults.size()); - p.translate(0, from * st::dialogsRowHeight); + auto from = floorclamp(r.y() - skip, _st->height, 0, _filterResults.size()); + auto to = ceilclamp(r.y() + r.height() - skip, _st->height, 0, _filterResults.size()); + p.translate(0, from * _st->height); if (from < _filterResults.size()) { for (; from < to; ++from) { const auto row = _filterResults[from]; @@ -603,6 +617,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { ? _filteredPressed : _filteredSelected)); Ui::RowPainter::Paint(p, row, validateVideoUserpic(row), { + .st = _st, .folder = _openedFolder, .forum = _openedForum, .filter = _filterId, @@ -613,7 +628,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { .paused = videoPaused, .narrow = (fullWidth < st::columnMinimalWidthLeft), }); - p.translate(0, st::dialogsRowHeight); + p.translate(0, _st->height); } } } @@ -642,6 +657,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { ? _peerSearchPressed : _peerSearchSelected)); paintPeerSearchResult(p, result.get(), { + .st = &st::defaultDialogRow, .now = ms, .width = fullWidth, .active = active, @@ -704,6 +720,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { ? _searchedPressed : _searchedSelected)); Ui::RowPainter::Paint(p, result.get(), { + .st = &st::defaultDialogRow, .folder = _openedFolder, .forum = _openedForum, .filter = _filterId, @@ -778,14 +795,11 @@ void InnerWidget::paintCollapsedRow( const auto text = row->folder->chatListName(); const auto unread = row->folder->chatListUnreadCount(); - Ui::PaintCollapsedRow( - p, - row->row, - row->folder, - text, - unread, - width(), - selected); + Ui::PaintCollapsedRow(p, row->row, row->folder, text, unread, { + .st = _st, + .width = width(), + .selected = selected, + }); } bool InnerWidget::isSearchResultActive( @@ -818,11 +832,17 @@ void InnerWidget::paintPeerSearchResult( auto peer = result->peer; auto userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer); - userpicPeer->paintUserpicLeft(p, result->row.userpicView(), st::dialogsPadding.x(), st::dialogsPadding.y(), width(), st::dialogsPhotoSize); + userpicPeer->paintUserpicLeft( + p, + result->row.userpicView(), + context.st->padding.left(), + context.st->padding.top(), + width(), + context.st->photoSize); - auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; - auto namewidth = context.width - nameleft - st::dialogsPadding.x(); - QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height); + auto nameleft = context.st->nameLeft; + auto namewidth = context.width - nameleft - context.st->padding.right(); + QRect rectForName(nameleft, context.st->nameTop, namewidth, st::msgNameFont->height); if (result->name.isEmpty()) { result->name.setText( @@ -874,7 +894,7 @@ void InnerWidget::paintPeerSearchResult( }); rectForName.setWidth(rectForName.width() - badgeWidth); - QRect tr(nameleft, st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip, namewidth, st::dialogsTextFont->height); + QRect tr(context.st->textLeft, context.st->textTop, namewidth, st::dialogsTextFont->height); p.setFont(st::dialogsTextFont); QString username = peer->userName(); if (!context.active && username.startsWith(_peerSearchQuery, Qt::CaseInsensitive)) { @@ -942,17 +962,18 @@ void InnerWidget::paintSearchInFilter( const style::icon *icon, const Ui::Text::String &text) const { const auto savedPen = p.pen(); - const auto userpicLeft = st::dialogsPadding.x(); + const auto userpicLeft = st::defaultDialogRow.padding.left(); const auto userpicTop = top + (st::dialogsSearchInHeight - st::dialogsSearchInPhotoSize) / 2; paintUserpic(p, userpicLeft, userpicTop, st::dialogsSearchInPhotoSize); - const auto nameleft = st::dialogsPadding.x() + const auto nameleft = st::defaultDialogRow.padding.left() + st::dialogsSearchInPhotoSize + st::dialogsSearchInPhotoPadding; const auto namewidth = width() - nameleft - - st::dialogsPadding.x() * 2 + - st::defaultDialogRow.padding.left() + - st::defaultDialogRow.padding.right() - st::dialogsCancelSearch.width; auto rectForName = QRect( nameleft, @@ -1056,9 +1077,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { const auto selected = (collapsedSelected >= 0) ? nullptr : (mouseY >= offset) - ? shownDialogs()->rowAtY( - mouseY - offset, - st::dialogsRowHeight) + ? shownDialogs()->rowAtY(mouseY - offset, _st->height) : nullptr; if (_selected != selected || _collapsedSelected != collapsedSelected) { updateSelectedRow(); @@ -1089,7 +1108,7 @@ void InnerWidget::selectByMouse(QPoint globalPosition) { } if (!_filterResults.empty()) { auto skip = filteredOffset(); - auto filteredSelected = (mouseY >= skip) ? ((mouseY - skip) / st::dialogsRowHeight) : -1; + auto filteredSelected = (mouseY >= skip) ? ((mouseY - skip) / _st->height) : -1; if (filteredSelected < 0 || filteredSelected >= _filterResults.size()) { filteredSelected = -1; } @@ -1147,11 +1166,14 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { }); } else if (_pressed) { auto row = _pressed; - row->addRipple(e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * st::dialogsRowHeight), QSize(width(), st::dialogsRowHeight), [this, row] { - if (!_pinnedShiftAnimation.animating()) { - row->entry()->updateChatListEntry(); - } - }); + row->addRipple( + e->pos() - QPoint(0, dialogsOffset() + _pressed->pos() * _st->height), + QSize(width(), _st->height), + [this, row] { + if (!_pinnedShiftAnimation.animating()) { + row->entry()->updateChatListEntry(); + } + }); _dragStart = e->pos(); } else if (base::in_range(_hashtagPressed, 0, _hashtagResults.size()) && !_hashtagDeletePressed) { auto row = &_hashtagResults[_hashtagPressed]->row; @@ -1162,8 +1184,8 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { const auto row = _filterResults[_filteredPressed]; const auto filterId = _filterId; row->addRipple( - e->pos() - QPoint(0, filteredOffset() + _filteredPressed * st::dialogsRowHeight), - QSize(width(), st::dialogsRowHeight), + e->pos() - QPoint(0, filteredOffset() + _filteredPressed * _st->height), + QSize(width(), _st->height), [=] { repaintDialogRow(filterId, row); }); } else if (base::in_range(_peerSearchPressed, 0, _peerSearchResults.size())) { auto &result = _peerSearchResults[_peerSearchPressed]; @@ -1303,36 +1325,35 @@ bool InnerWidget::updateReorderPinned(QPoint localPosition) { auto yaddWas = _pinnedRows[_draggingIndex].yadd.current(); auto shift = 0; auto now = crl::now(); - auto rowHeight = st::dialogsRowHeight; if (_dragStart.y() > localPosition.y() && _draggingIndex > 0) { - shift = -floorclamp(_dragStart.y() - localPosition.y() + (rowHeight / 2), rowHeight, 0, _draggingIndex); + shift = -floorclamp(_dragStart.y() - localPosition.y() + (_st->height / 2), _st->height, 0, _draggingIndex); for (auto from = _draggingIndex, to = _draggingIndex + shift; from > to; --from) { list->movePinned(_dragging, -1); std::swap(_pinnedRows[from], _pinnedRows[from - 1]); - _pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() - rowHeight, 0); + _pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() - _st->height, 0); _pinnedRows[from].animStartTime = now; } } else if (_dragStart.y() < localPosition.y() && _draggingIndex + 1 < pinnedCount) { - shift = floorclamp(localPosition.y() - _dragStart.y() + (rowHeight / 2), rowHeight, 0, pinnedCount - _draggingIndex - 1); + shift = floorclamp(localPosition.y() - _dragStart.y() + (_st->height / 2), _st->height, 0, pinnedCount - _draggingIndex - 1); for (auto from = _draggingIndex, to = _draggingIndex + shift; from < to; ++from) { list->movePinned(_dragging, 1); std::swap(_pinnedRows[from], _pinnedRows[from + 1]); - _pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() + rowHeight, 0); + _pinnedRows[from].yadd = anim::value(_pinnedRows[from].yadd.current() + _st->height, 0); _pinnedRows[from].animStartTime = now; } } if (shift) { _draggingIndex += shift; _aboveIndex = _draggingIndex; - _dragStart.setY(_dragStart.y() + shift * rowHeight); + _dragStart.setY(_dragStart.y() + shift * _st->height); if (!_pinnedShiftAnimation.animating()) { _pinnedShiftAnimation.start(); } } _aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current()); - _pinnedRows[_draggingIndex].yadd = anim::value(yaddWas - shift * rowHeight, localPosition.y() - _dragStart.y()); + _pinnedRows[_draggingIndex].yadd = anim::value(yaddWas - shift * _st->height, localPosition.y() - _dragStart.y()); if (!_pinnedRows[_draggingIndex].animStartTime) { _pinnedRows[_draggingIndex].yadd.finish(); } @@ -1383,11 +1404,11 @@ bool InnerWidget::pinnedShiftAnimationCallback(crl::time now) { } if (updateMin >= 0) { auto top = pinnedOffset(); - auto updateFrom = top + st::dialogsRowHeight * (updateMin - 1); - auto updateHeight = st::dialogsRowHeight * (updateMax - updateMin + 3); + auto updateFrom = top + _st->height * (updateMin - 1); + auto updateHeight = _st->height * (updateMax - updateMin + 3); if (base::in_range(_aboveIndex, 0, _pinnedRows.size())) { // Always include currently dragged chat in its current and old positions. - auto aboveRowBottom = top + (_aboveIndex + 1) * st::dialogsRowHeight; + auto aboveRowBottom = top + (_aboveIndex + 1) * _st->height; auto aboveTopShift = qCeil(_pinnedRows[_aboveIndex].yadd.current()); accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + _aboveTopShift); accumulate_max(updateHeight, (aboveRowBottom - updateFrom) + aboveTopShift); @@ -1549,9 +1570,9 @@ void InnerWidget::handleChatListEntryRefreshes() { ) | rpl::filter([=](const Event &event) { return (event.filterId == _filterId); }) | rpl::start_with_next([=](const Event &event) { - const auto rowHeight = st::dialogsRowHeight; - const auto from = dialogsOffset() + event.moved.from * rowHeight; - const auto to = dialogsOffset() + event.moved.to * rowHeight; + const auto offset = dialogsOffset(); + const auto from = offset + event.moved.from * _st->height; + const auto to = offset + event.moved.to * _st->height; const auto &key = event.key; const auto entry = key.entry(); @@ -1590,7 +1611,7 @@ void InnerWidget::handleChatListEntryRefreshes() { 0, std::min(from, to), width(), - std::abs(from - to) + rowHeight); + std::abs(from - to) + _st->height); } }, lifetime()); } @@ -1610,7 +1631,7 @@ int InnerWidget::defaultRowTop(not_null row) const { if (base::in_range(position, 0, _pinnedRows.size())) { top += qRound(_pinnedRows[position].yadd.current()); } - return top + position * st::dialogsRowHeight; + return top + position * _st->height; } void InnerWidget::repaintDialogRow( @@ -1621,7 +1642,7 @@ void InnerWidget::repaintDialogRow( if (const auto folder = row->folder()) { repaintCollapsedFolderRow(folder); } - update(0, defaultRowTop(row), width(), st::dialogsRowHeight); + update(0, defaultRowTop(row), width(), _st->height); } } else if (_state == WidgetState::Filtered) { if (!filterId) { @@ -1629,9 +1650,9 @@ void InnerWidget::repaintDialogRow( if (_filterResults[i]->key() == row->key()) { update( 0, - filteredOffset() + i * st::dialogsRowHeight, + filteredOffset() + i * _st->height, width(), - st::dialogsRowHeight); + _st->height); break; } } @@ -1677,7 +1698,7 @@ void InnerWidget::updateDialogRow( QRect updateRect, UpdateRowSections sections) { if (updateRect.isEmpty()) { - updateRect = QRect(0, 0, width(), st::dialogsRowHeight); + updateRect = QRect(0, 0, width(), _st->height); } if (IsServerMsgId(-row.fullId.msg)) { if (const auto peer = row.key.peer()) { @@ -1691,12 +1712,12 @@ void InnerWidget::updateDialogRow( } } - const auto updateRow = [&](int rowTop) { + const auto updateRow = [&](int rowTop, int rowHeight = 0) { rtlupdate( updateRect.x(), rowTop + updateRect.y(), updateRect.width(), - updateRect.height()); + rowHeight ? rowHeight : updateRect.height()); }; if (_state == WidgetState::Default) { if (sections & UpdateRowSection::Default) { @@ -1709,7 +1730,7 @@ void InnerWidget::updateDialogRow( if (base::in_range(position, 0, _pinnedRows.size())) { top += qRound(_pinnedRows[position].yadd.current()); } - updateRow(top + position * st::dialogsRowHeight); + updateRow(top + position * _st->height); } } } else if (_state == WidgetState::Filtered) { @@ -1719,7 +1740,7 @@ void InnerWidget::updateDialogRow( auto index = 0; for (const auto result : _filterResults) { if (result->key() == row.key) { - updateRow(add + index * st::dialogsRowHeight); + updateRow(add + index * _st->height); break; } ++index; @@ -1732,7 +1753,9 @@ void InnerWidget::updateDialogRow( auto index = 0; for (const auto &result : _peerSearchResults) { if (result->peer == peer) { - updateRow(add + index * st::dialogsRowHeight); + updateRow( + add + index * st::dialogsRowHeight, + st::dialogsRowHeight); break; } ++index; @@ -1745,7 +1768,9 @@ void InnerWidget::updateDialogRow( auto index = 0; for (const auto &result : _searchResults) { if (isSearchResultActive(result.get(), row)) { - updateRow(add + index * st::dialogsRowHeight); + updateRow( + add + index * st::dialogsRowHeight, + st::dialogsRowHeight); break; } ++index; @@ -1770,9 +1795,9 @@ void InnerWidget::updateSelectedRow(Key key) { if (base::in_range(position, 0, _pinnedRows.size())) { top += qRound(_pinnedRows[position].yadd.current()); } - update(0, top + position * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, top + position * _st->height, width(), _st->height); } else if (_selected) { - update(0, dialogsOffset() + _selected->pos() * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, dialogsOffset() + _selected->pos() * _st->height, width(), _st->height); } else if (_collapsedSelected >= 0) { update(0, _collapsedSelected * st::dialogsImportantBarHeight, width(), st::dialogsImportantBarHeight); } @@ -1780,14 +1805,14 @@ void InnerWidget::updateSelectedRow(Key key) { if (key) { for (auto i = 0, l = int(_filterResults.size()); i != l; ++i) { if (_filterResults[i]->key() == key) { - update(0, filteredOffset() + i * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, filteredOffset() + i * _st->height, width(), _st->height); break; } } } else if (_hashtagSelected >= 0) { update(0, _hashtagSelected * st::mentionHeight, width(), st::mentionHeight); } else if (_filteredSelected >= 0) { - update(0, filteredOffset() + _filteredSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight); + update(0, filteredOffset() + _filteredSelected * _st->height, width(), _st->height); } else if (_peerSearchSelected >= 0) { update(0, peerSearchOffset() + _peerSearchSelected * st::dialogsRowHeight, width(), st::dialogsRowHeight); } else if (_searchedSelected >= 0) { @@ -2344,7 +2369,7 @@ void InnerWidget::refresh(bool toTop) { if (list->empty()) { h = st::dialogsEmptyHeight; } else { - h = dialogsOffset() + list->size() * st::dialogsRowHeight; + h = dialogsOffset() + list->size() * _st->height; } } else if (_state == WidgetState::Filtered) { if (_waitingForSearch) { @@ -2537,8 +2562,8 @@ void InnerWidget::repaintSearchResult(int index) { rtlupdate( 0, searchedOffset() + index * st::dialogsRowHeight, - - width(), st::dialogsRowHeight); + width(), + st::dialogsRowHeight); } void InnerWidget::clearFilter() { @@ -2598,8 +2623,8 @@ void InnerWidget::selectSkip(int32 direction) { if (_collapsedSelected >= 0 || _selected) { const auto fromY = (_collapsedSelected >= 0) ? (_collapsedSelected * st::dialogsImportantBarHeight) - : (dialogsOffset() + _selected->pos() * st::dialogsRowHeight); - _mustScrollTo.fire({ fromY, fromY + st::dialogsRowHeight }); + : (dialogsOffset() + _selected->pos() * _st->height); + _mustScrollTo.fire({ fromY, fromY + _st->height }); } } else if (_state == WidgetState::Filtered) { if (_hashtagResults.empty() && _filterResults.empty() && _peerSearchResults.empty() && _searchResults.empty()) { @@ -2654,9 +2679,9 @@ void InnerWidget::selectSkip(int32 direction) { }); } else if (base::in_range(_filteredSelected, 0, _filterResults.size())) { _mustScrollTo.fire({ - filteredOffset() + _filteredSelected * st::dialogsRowHeight, + filteredOffset() + _filteredSelected * _st->height, filteredOffset() - + (_filteredSelected + 1) * st::dialogsRowHeight, + + (_filteredSelected + 1) * _st->height, }); } else if (base::in_range(_peerSearchSelected, 0, _peerSearchResults.size())) { _mustScrollTo.fire({ @@ -2680,36 +2705,38 @@ void InnerWidget::selectSkip(int32 direction) { } void InnerWidget::scrollToEntry(const RowDescriptor &entry) { - int32 fromY = -1; + auto fromY = -1; + auto rowHeight = _st->height; if (_state == WidgetState::Default) { if (auto row = shownDialogs()->getRow(entry.key)) { - fromY = dialogsOffset() + row->pos() * st::dialogsRowHeight; + fromY = dialogsOffset() + row->pos() * _st->height; } } else if (_state == WidgetState::Filtered) { for (int32 i = 0, c = _searchResults.size(); i < c; ++i) { if (isSearchResultActive(_searchResults[i].get(), entry)) { fromY = searchedOffset() + i * st::dialogsRowHeight; + rowHeight = st::dialogsRowHeight; break; } } if (fromY < 0) { for (auto i = 0, c = int(_filterResults.size()); i != c; ++i) { if (_filterResults[i]->key() == entry.key) { - fromY = filteredOffset() + (i * st::dialogsRowHeight); + fromY = filteredOffset() + (i * _st->height); break; } } } } if (fromY >= 0) { - _mustScrollTo.fire({ fromY, fromY + st::dialogsRowHeight }); + _mustScrollTo.fire({ fromY, fromY + rowHeight }); } } void InnerWidget::selectSkipPage(int32 pixels, int32 direction) { clearMouseSelection(); const auto list = shownDialogs(); - int toSkip = pixels / int(st::dialogsRowHeight); + int toSkip = pixels / _st->height; if (_state == WidgetState::Default) { if (!_selected) { if (direction > 0 && list->size() > _skipTopDialogs) { @@ -2735,8 +2762,8 @@ void InnerWidget::selectSkipPage(int32 pixels, int32 direction) { if (_collapsedSelected >= 0 || _selected) { const auto fromY = (_collapsedSelected >= 0) ? (_collapsedSelected * st::dialogsImportantBarHeight) - : (dialogsOffset() + _selected->pos() * st::dialogsRowHeight); - _mustScrollTo.fire({ fromY, fromY + st::dialogsRowHeight }); + : (dialogsOffset() + _selected->pos() * _st->height); + _mustScrollTo.fire({ fromY, fromY + _st->height }); } } else { return selectSkip(direction * toSkip); @@ -2751,10 +2778,10 @@ void InnerWidget::loadPeerPhotos() { auto yFrom = _visibleTop; auto yTo = _visibleTop + (_visibleBottom - _visibleTop) * (PreloadHeightsCount + 1); if (_state == WidgetState::Default) { - auto otherStart = list->size() * st::dialogsRowHeight; + auto otherStart = list->size() * _st->height; if (yFrom < otherStart) { - for (auto i = list->cfind(yFrom, st::dialogsRowHeight), end = list->cend(); i != end; ++i) { - if (((*i)->pos() * st::dialogsRowHeight) >= yTo) { + for (auto i = list->cfind(yFrom, _st->height), end = list->cend(); i != end; ++i) { + if (((*i)->pos() * _st->height) >= yTo) { break; } (*i)->entry()->loadUserpic(); @@ -2765,10 +2792,10 @@ void InnerWidget::loadPeerPhotos() { } yTo -= otherStart; } else if (_state == WidgetState::Filtered) { - int32 from = (yFrom - filteredOffset()) / st::dialogsRowHeight; + int32 from = (yFrom - filteredOffset()) / _st->height; if (from < 0) from = 0; if (from < _filterResults.size()) { - int32 to = (yTo / int32(st::dialogsRowHeight)) + 1; + int32 to = (yTo / _st->height) + 1; if (to > _filterResults.size()) to = _filterResults.size(); for (; from < to; ++from) { @@ -2776,20 +2803,20 @@ void InnerWidget::loadPeerPhotos() { } } - from = (yFrom > filteredOffset() + st::searchedBarHeight ? ((yFrom - filteredOffset() - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size(); + from = (yFrom > filteredOffset() + st::searchedBarHeight ? ((yFrom - filteredOffset() - st::searchedBarHeight) / st::dialogsRowHeight) : 0) - _filterResults.size(); if (from < 0) from = 0; if (from < _peerSearchResults.size()) { - int32 to = (yTo > filteredOffset() + st::searchedBarHeight ? ((yTo - filteredOffset() - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() + 1; + int32 to = (yTo > filteredOffset() + st::searchedBarHeight ? ((yTo - filteredOffset() - st::searchedBarHeight) / st::dialogsRowHeight) : 0) - _filterResults.size() + 1; if (to > _peerSearchResults.size()) to = _peerSearchResults.size(); for (; from < to; ++from) { _peerSearchResults[from]->peer->loadUserpic(); } } - from = (yFrom > filteredOffset() + ((_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() - _peerSearchResults.size(); + from = (yFrom > filteredOffset() + ((_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight) ? ((yFrom - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / st::dialogsRowHeight) : 0) - _filterResults.size() - _peerSearchResults.size(); if (from < 0) from = 0; if (from < _searchResults.size()) { - int32 to = (yTo > filteredOffset() + (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight ? ((yTo - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / int32(st::dialogsRowHeight)) : 0) - _filterResults.size() - _peerSearchResults.size() + 1; + int32 to = (yTo > filteredOffset() + (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) + st::searchedBarHeight ? ((yTo - filteredOffset() - (_peerSearchResults.empty() ? 0 : st::searchedBarHeight) - st::searchedBarHeight) / st::dialogsRowHeight) : 0) - _filterResults.size() - _peerSearchResults.size() + 1; if (to > _searchResults.size()) to = _searchResults.size(); for (; from < to; ++from) { @@ -3156,14 +3183,15 @@ void InnerWidget::updateDialogRowCornerStatus(not_null history) { ? st::dialogsOnlineBadgeSkip : st::dialogsCallBadgeSkip; const auto updateRect = QRect( - st::dialogsPhotoSize - skip.x() - size, - st::dialogsPhotoSize - skip.y() - size, + _st->photoSize - skip.x() - size, + _st->photoSize - skip.y() - size, size, size ).marginsAdded( { stroke, stroke, stroke, stroke } ).translated( - st::dialogsPadding + st::defaultDialogRow.padding.left(), + st::defaultDialogRow.padding.top() ); updateDialogRow( RowDescriptor( @@ -3217,11 +3245,11 @@ void InnerWidget::updateRowCornerStatusShown( [](not_null row) { return row->history(); }); const auto index = (i - begin(_filterResults)); const auto row = (i == end(_filterResults)) ? nullptr : i->get(); - return { row, filteredOffset() + index * st::dialogsRowHeight }; + return { row, filteredOffset() + index * _st->height }; }; if (const auto &[row, top] = findRow(history); row != nullptr) { const auto visible = (top < _visibleBottom) - && (top + st::dialogsRowHeight > _visibleTop); + && (top + _st->height > _visibleTop); row->updateCornerBadgeShown( history->peer, visible ? Fn(crl::guard(this, repaint)) : nullptr); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 248f7e9ce4..2ece123572 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -15,6 +15,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/flags.h" #include "base/object_ptr.h" +namespace style { +struct DialogRow; +} // namespace style + namespace MTP { class Error; } // namespace MTP @@ -76,7 +80,6 @@ enum class WidgetState { }; class InnerWidget final : public Ui::RpWidget { - public: InnerWidget( QWidget *parent, @@ -112,18 +115,21 @@ public: void scrollToEntry(const RowDescriptor &entry); - Data::Folder *shownFolder() const; - Data::Forum *shownForum() const; - int32 lastSearchDate() const; - PeerData *lastSearchPeer() const; - MsgId lastSearchId() const; - MsgId lastSearchMigratedId() const; + [[nodiscard]] Data::Folder *shownFolder() const; + [[nodiscard]] Data::Forum *shownForum() const; + [[nodiscard]] int32 lastSearchDate() const; + [[nodiscard]] PeerData *lastSearchPeer() const; + [[nodiscard]] MsgId lastSearchId() const; + [[nodiscard]] MsgId lastSearchMigratedId() const; - WidgetState state() const; - bool waitingForSearch() const { + [[nodiscard]] WidgetState state() const; + [[nodiscard]] const style::DialogRow *st() const { + return _st; + } + [[nodiscard]] bool waitingForSearch() const { return _waitingForSearch; } - bool hasFilteredResults() const; + [[nodiscard]] bool hasFilteredResults() const; void searchInChat(Key key, PeerData *from); @@ -354,6 +360,7 @@ private: rpl::lifetime _openedForumLifetime; std::vector> _collapsedRows; + not_null _st; int _collapsedSelected = -1; int _collapsedPressed = -1; int _skipTopDialogs = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.cpp b/Telegram/SourceFiles/dialogs/dialogs_row.cpp index 0a03281e7b..462db2f63b 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_row.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/painter.h" #include "dialogs/dialogs_entry.h" #include "dialogs/ui/dialogs_video_userpic.h" +#include "dialogs/ui/dialogs_layout.h" #include "data/data_folder.h" #include "data/data_peer_values.h" #include "history/history.h" @@ -126,20 +127,17 @@ void BasicRow::paintUserpic( not_null peer, Ui::VideoUserpic *videoUserpic, History *historyForCornerBadge, - crl::time now, - bool active, - int fullWidth, - bool paused) const { + const Ui::PaintContext &context) const { PaintUserpic( p, peer, videoUserpic, _userpic, - st::dialogsPadding.x(), - st::dialogsPadding.y(), - fullWidth, - st::dialogsPhotoSize, - paused); + context.st->padding.left(), + context.st->padding.top(), + context.width, + context.st->photoSize, + context.paused); } Row::Row(Key key, int pos) : _id(key), _pos(pos) { @@ -221,7 +219,7 @@ void Row::PaintCornerBadgeFrame( not_null peer, Ui::VideoUserpic *videoUserpic, std::shared_ptr &view, - bool paused) { + const Ui::PaintContext &context) { data->frame.fill(Qt::transparent); Painter q(&data->frame); @@ -233,8 +231,8 @@ void Row::PaintCornerBadgeFrame( 0, 0, data->frame.width() / data->frame.devicePixelRatio(), - st::dialogsPhotoSize, - paused); + context.st->photoSize, + context.paused); PainterHighQualityEnabler hq(q); q.setCompositionMode(QPainter::CompositionMode_Source); @@ -255,8 +253,8 @@ void Row::PaintCornerBadgeFrame( ? st::dialogsOnlineBadgeFgActive : st::dialogsOnlineBadgeFg); q.drawEllipse(QRectF( - st::dialogsPhotoSize - skip.x() - size, - st::dialogsPhotoSize - skip.y() - size, + context.st->photoSize - skip.x() - size, + context.st->photoSize - skip.y() - size, size, size ).marginsRemoved({ shrink, shrink, shrink, shrink })); @@ -267,10 +265,7 @@ void Row::paintUserpic( not_null peer, Ui::VideoUserpic *videoUserpic, History *historyForCornerBadge, - crl::time now, - bool active, - int fullWidth, - bool paused) const { + const Ui::PaintContext &context) const { updateCornerBadgeShown(peer); const auto shown = _cornerBadgeUserpic @@ -282,61 +277,63 @@ void Row::paintUserpic( peer, videoUserpic, historyForCornerBadge, - now, - active, - fullWidth, - paused); + context); if (!historyForCornerBadge || !_cornerBadgeShown) { _cornerBadgeUserpic = nullptr; } return; } ensureCornerBadgeUserpic(); - if (_cornerBadgeUserpic->frame.isNull()) { + const auto ratio = style::DevicePixelRatio(); + const auto frameSide = context.st->photoSize * style::DevicePixelRatio(); + const auto frameSize = QSize(frameSide, frameSide); + if (_cornerBadgeUserpic->frame.size() != frameSize) { _cornerBadgeUserpic->frame = QImage( - st::dialogsPhotoSize * cRetinaFactor(), - st::dialogsPhotoSize * cRetinaFactor(), + frameSize, QImage::Format_ARGB32_Premultiplied); - _cornerBadgeUserpic->frame.setDevicePixelRatio(cRetinaFactor()); + _cornerBadgeUserpic->frame.setDevicePixelRatio(ratio); } const auto key = peer->userpicUniqueKey(userpicView()); const auto frameIndex = videoUserpic ? videoUserpic->frameIndex() : -1; if (_cornerBadgeUserpic->shown != shown || _cornerBadgeUserpic->key != key - || _cornerBadgeUserpic->active != active + || _cornerBadgeUserpic->active != context.active || _cornerBadgeUserpic->frameIndex != frameIndex || videoUserpic) { _cornerBadgeUserpic->shown = shown; _cornerBadgeUserpic->key = key; - _cornerBadgeUserpic->active = active; + _cornerBadgeUserpic->active = context.active; _cornerBadgeUserpic->frameIndex = frameIndex; PaintCornerBadgeFrame( _cornerBadgeUserpic.get(), peer, videoUserpic, userpicView(), - paused); + context); } - p.drawImage(st::dialogsPadding, _cornerBadgeUserpic->frame); + p.drawImage( + context.st->padding.left(), + context.st->padding.top(), + _cornerBadgeUserpic->frame); if (historyForCornerBadge->peer->isUser()) { return; } const auto actionPainter = historyForCornerBadge->sendActionPainter(); - const auto bg = active + const auto bg = context.active ? st::dialogsBgActive : st::dialogsBg; const auto size = st::dialogsCallBadgeSize; const auto skip = st::dialogsCallBadgeSkip; p.setOpacity(shown); - p.translate(st::dialogsPadding); + p.translate(context.st->padding.left(), context.st->padding.top()); actionPainter->paintSpeaking( p, - st::dialogsPhotoSize - skip.x() - size, - st::dialogsPhotoSize - skip.y() - size, - fullWidth, + context.st->photoSize - skip.x() - size, + context.st->photoSize - skip.y() - size, + context.width, bg, - now); - p.translate(-st::dialogsPadding); + context.now); + p.translate(-context.st->padding.left(), -context.st->padding.top()); p.setOpacity(1.); } diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.h b/Telegram/SourceFiles/dialogs/dialogs_row.h index 60d36ecd1a..31f781fea6 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.h +++ b/Telegram/SourceFiles/dialogs/dialogs_row.h @@ -28,6 +28,7 @@ namespace Dialogs::Ui { using namespace ::Ui; class RowPainter; class VideoUserpic; +struct PaintContext; } // namespace Dialogs::Ui namespace Dialogs { @@ -44,10 +45,7 @@ public: not_null peer, Ui::VideoUserpic *videoUserpic, History *historyForCornerBadge, - crl::time now, - bool active, - int fullWidth, - bool paused) const; + const Ui::PaintContext &context) const; void addRipple(QPoint origin, QSize size, Fn updateCallback); void stopLastRipple(); @@ -84,10 +82,7 @@ public: not_null peer, Ui::VideoUserpic *videoUserpic, History *historyForCornerBadge, - crl::time now, - bool active, - int fullWidth, - bool paused) const final override; + const Ui::PaintContext &context) const final override; [[nodiscard]] Key key() const { return _id; @@ -138,7 +133,7 @@ private: not_null peer, Ui::VideoUserpic *videoUserpic, std::shared_ptr &view, - bool paused); + const Ui::PaintContext &context); Key _id; int _pos = 0; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 4263a43bdb..85b9deb449 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -232,9 +232,9 @@ Widget::Widget( ) | rpl::start_with_next([=](const Ui::ScrollToRequest &data) { const auto movedFrom = data.ymin; const auto movedTo = data.ymax; - const auto st = int32(_scroll->scrollTop()); + const auto st = _scroll->scrollTop(); if (st > movedTo && st < movedFrom) { - _scroll->scrollToY(st + st::dialogsRowHeight); + _scroll->scrollToY(st + _inner->st()->height); } }, lifetime()); _inner->searchMessages( @@ -1723,7 +1723,7 @@ void Widget::updateControlsGeometry() { _forwardCancel->moveToLeft(0, filterAreaTop); filterAreaTop += st::dialogsForwardHeight; } - auto smallLayoutWidth = (st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x()); + auto smallLayoutWidth = (st::defaultDialogRow.padding.left() + st::defaultDialogRow.photoSize + st::defaultDialogRow.padding.left()); auto smallLayoutRatio = (width() < st::columnMinimalWidthLeft) ? (st::columnMinimalWidthLeft - width()) / float64(st::columnMinimalWidthLeft - smallLayoutWidth) : 0.; auto filterLeft = (controller()->filtersWidth() ? st::dialogsFilterSkip : st::dialogsFilterPadding.x() + _mainMenuToggle->width()) + st::dialogsFilterPadding.x(); auto filterRight = (session().domain().local().hasLocalPasscode() ? (st::dialogsFilterPadding.x() + _lockUnlock->width()) : st::dialogsFilterSkip) + st::dialogsFilterPadding.x(); diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index 5a4b218915..8b0b6c27b7 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -118,10 +118,10 @@ void PaintNarrowCounter( || displayReactionBadge) ? 1 : 3; - const auto unreadRight = st::dialogsPadding.x() - + st::dialogsPhotoSize; - const auto unreadTop = st::dialogsPadding.y() - + st::dialogsPhotoSize + const auto unreadRight = context.st->padding.left() + + context.st->photoSize; + const auto unreadTop = context.st->padding.top() + + context.st->photoSize - st::dialogsUnreadHeight; UnreadBadgeStyle st; @@ -139,11 +139,11 @@ void PaintNarrowCounter( } if (displayMentionBadge || displayReactionBadge) { const auto counter = QString(); - const auto unreadRight = st::dialogsPadding.x() - + st::dialogsPhotoSize + const auto unreadRight = context.st->padding.left() + + context.st->photoSize - skipBeforeMention; - const auto unreadTop = st::dialogsPadding.y() - + st::dialogsPhotoSize + const auto unreadTop = context.st->padding.top() + + context.st->photoSize - st::dialogsUnreadHeight; UnreadBadgeStyle st; @@ -193,8 +193,7 @@ int PaintWideCounter( const auto counter = (unreadCount > 0) ? QString::number(unreadCount) : QString(); - const auto unreadRight = context.width - - st::dialogsPadding.x(); + const auto unreadRight = context.width - context.st->padding.right(); const auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent @@ -219,7 +218,7 @@ int PaintWideCounter( : st::dialogsPinnedIcon; icon.paint( p, - context.width - st::dialogsPadding.x() - icon.width(), + context.width - context.st->padding.right() - icon.width(), texttop, context.width); availableWidth -= icon.width() + st::dialogsUnreadPadding; @@ -227,7 +226,7 @@ int PaintWideCounter( if (displayMentionBadge || displayReactionBadge) { const auto counter = QString(); const auto unreadRight = context.width - - st::dialogsPadding.x() + - context.st->padding.right() - (initial - availableWidth); const auto unreadTop = texttop + st::dialogsTextFont->ascent @@ -334,7 +333,7 @@ void PaintRow( draft = nullptr; } - auto fullRect = QRect(0, 0, context.width, st::dialogsRowHeight); + auto fullRect = QRect(0, 0, context.width, context.st->height); auto bg = context.active ? st::dialogsBgActive : context.selected @@ -351,47 +350,36 @@ void PaintRow( if (flags & Flag::SavedMessages) { EmptyUserpic::PaintSavedMessages( p, - st::dialogsPadding.x(), - st::dialogsPadding.y(), + context.st->padding.left(), + context.st->padding.top(), context.width, - st::dialogsPhotoSize); + context.st->photoSize); } else if (flags & Flag::RepliesMessages) { EmptyUserpic::PaintRepliesMessages( p, - st::dialogsPadding.x(), - st::dialogsPadding.y(), + context.st->padding.left(), + context.st->padding.top(), context.width, - st::dialogsPhotoSize); + context.st->photoSize); } else if (from) { row->paintUserpic( p, from, videoUserpic, (flags & Flag::AllowUserOnline) ? history : nullptr, - context.now, - context.active, - context.width, - context.paused); + context); } else if (hiddenSenderInfo) { hiddenSenderInfo->emptyUserpic.paint( p, - st::dialogsPadding.x(), - st::dialogsPadding.y(), + context.st->padding.left(), + context.st->padding.top(), context.width, - st::dialogsPhotoSize); + context.st->photoSize); } else { - entry->paintUserpicLeft( - p, - row->userpicView(), - st::dialogsPadding.x(), - st::dialogsPadding.y(), - context.width, - st::dialogsPhotoSize); + entry->paintUserpic(p, row->userpicView(), context); } - auto nameleft = st::dialogsPadding.x() - + st::dialogsPhotoSize - + st::dialogsPhotoPadding; + auto nameleft = context.st->nameLeft; if (context.width <= nameleft) { if (!draft && item && !item->isEmpty()) { paintCounterCallback(); @@ -399,10 +387,10 @@ void PaintRow( return; } - auto namewidth = context.width - nameleft - st::dialogsPadding.x(); + auto namewidth = context.width - nameleft - context.st->padding.right(); auto rectForName = QRect( nameleft, - st::dialogsPadding.y() + st::dialogsNameTop, + context.st->nameTop, namewidth, st::msgNameFont->height); @@ -425,9 +413,7 @@ void PaintRow( rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); } } - auto texttop = st::dialogsPadding.y() - + st::msgNameFont->height - + st::dialogsSkip; + auto texttop = context.st->textTop; if (promoted && !history->topPromotionMessage().isEmpty()) { auto availableWidth = namewidth; p.setFont(st::dialogsTextFont); @@ -467,7 +453,7 @@ void PaintRow( : st::dialogsPinnedIcon; icon.paint( p, - context.width - st::dialogsPadding.x() - icon.width(), + context.width - context.st->padding.right() - icon.width(), texttop, context.width); availableWidth -= icon.width() + st::dialogsUnreadPadding; @@ -553,7 +539,7 @@ void PaintRow( : context.selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon; - icon.paint(p, context.width - st::dialogsPadding.x() - icon.width(), texttop, context.width); + icon.paint(p, context.width - context.st->padding.right() - icon.width(), texttop, context.width); availableWidth -= icon.width() + st::dialogsUnreadPadding; } @@ -587,7 +573,7 @@ void PaintRow( : context.selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon; - icon.paint(p, context.width - st::dialogsPadding.x() - icon.width(), texttop, context.width); + icon.paint(p, context.width - context.st->padding.right() - icon.width(), texttop, context.width); } auto sendStateIcon = [&]() -> const style::icon* { if (draft) { @@ -967,9 +953,7 @@ void RowPainter::Paint( | (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0)) | (peer && peer->isRepliesChat() ? Flag::RepliesMessages : Flag(0)); const auto paintItemCallback = [&](int nameleft, int namewidth) { - const auto texttop = st::dialogsPadding.y() - + st::msgNameFont->height - + st::dialogsSkip; + const auto texttop = context.st->textTop; const auto availableWidth = PaintWideCounter( p, context, @@ -1111,9 +1095,7 @@ void RowPainter::Paint( const auto displayPinnedIcon = false; const auto paintItemCallback = [&](int nameleft, int namewidth) { - const auto texttop = st::dialogsPadding.y() - + st::msgNameFont->height - + st::dialogsSkip; + const auto texttop = context.st->textTop; const auto availableWidth = PaintWideCounter( p, context, @@ -1178,18 +1160,15 @@ void RowPainter::Paint( } QRect RowPainter::SendActionAnimationRect( + not_null st, int animationLeft, int animationWidth, int animationHeight, int fullWidth, bool textUpdated) { - const auto nameleft = st::dialogsPadding.x() - + st::dialogsPhotoSize - + st::dialogsPhotoPadding; - const auto namewidth = fullWidth - nameleft - st::dialogsPadding.x(); - const auto texttop = st::dialogsPadding.y() - + st::msgNameFont->height - + st::dialogsSkip; + const auto nameleft = st->nameLeft; + const auto namewidth = fullWidth - nameleft - st->padding.right(); + const auto texttop = st->textTop; return QRect( nameleft + (textUpdated ? 0 : animationLeft), texttop, @@ -1203,40 +1182,34 @@ void PaintCollapsedRow( Data::Folder *folder, const QString &text, int unread, - int fullWidth, - bool selected) { - p.fillRect(0, 0, fullWidth, st::dialogsImportantBarHeight, selected ? st::dialogsBgOver : st::dialogsBg); + const PaintContext &context) { + p.fillRect( + QRect{ 0, 0, context.width, st::dialogsImportantBarHeight }, + context.selected ? st::dialogsBgOver : st::dialogsBg); - row.paintRipple(p, 0, 0, fullWidth); - - const auto smallWidth = st::dialogsPadding.x() - + st::dialogsPhotoSize - + st::dialogsPhotoPadding; - const auto narrow = (fullWidth <= smallWidth); + row.paintRipple(p, 0, 0, context.width); const auto unreadTop = (st::dialogsImportantBarHeight - st::dialogsUnreadHeight) / 2; - if (!narrow || !folder) { + if (!context.narrow || !folder) { p.setFont(st::semiboldFont); p.setPen(st::dialogsNameFg); const auto textBaseline = unreadTop + (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2 + st::dialogsUnreadFont->ascent; - const auto left = narrow - ? ((fullWidth - st::semiboldFont->width(text)) / 2) - : st::dialogsPadding.x(); + const auto left = context.narrow + ? ((context.width - st::semiboldFont->width(text)) / 2) + : context.st->padding.left(); p.drawText(left, textBaseline, text); } else { - folder->paintUserpicLeft( + folder->paintUserpic( p, - row.userpicView(), - (fullWidth - st::dialogsUnreadHeight) / 2, + (context.width - st::dialogsUnreadHeight) / 2, unreadTop, - fullWidth, st::dialogsUnreadHeight); } - if (!narrow && unread) { - const auto unreadRight = fullWidth - st::dialogsPadding.x(); + if (!context.narrow && unread) { + const auto unreadRight = context.width - context.st->padding.right(); UnreadBadgeStyle st; st.muted = true; PaintUnreadBadge( diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h index d28540365e..1968729216 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h @@ -7,6 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +namespace style { +struct DialogRow; +} // namespace style + +namespace st { +extern const style::DialogRow &defaultDialogRow; +} // namespace st + namespace Ui { } // namespace Ui @@ -28,6 +36,7 @@ using namespace ::Ui; class VideoUserpic; struct PaintContext { + not_null st; Data::Folder *folder = nullptr; Data::Forum *forum = nullptr; FilterId filter = 0; @@ -43,7 +52,7 @@ struct PaintContext { const style::icon *ChatTypeIcon( not_null peer, - const PaintContext &context = {}); + const PaintContext &context = { .st = &st::defaultDialogRow }); class RowPainter { public: @@ -57,6 +66,7 @@ public: not_null row, const PaintContext &context); static QRect SendActionAnimationRect( + not_null st, int animationLeft, int animationWidth, int animationHeight, @@ -70,8 +80,7 @@ void PaintCollapsedRow( Data::Folder *folder, const QString &text, int unread, - int fullWidth, - bool selected); + const PaintContext &context); enum class UnreadBadgeSize { Dialogs, diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 06b68b0661..5ccb0253a9 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history_inner_widget.h" #include "history/history_unread_things.h" #include "dialogs/dialogs_indexed_list.h" +#include "dialogs/ui/dialogs_layout.h" #include "data/notify/data_notify_settings.h" #include "data/stickers/data_stickers.h" #include "data/data_drafts.h" @@ -1074,6 +1075,25 @@ void History::applyServiceChanges( peer->setThemeEmoji(qs(data.vemoticon())); }, [&](const MTPDmessageActionChatJoinedByRequest &data) { processJoinedPeer(item->from()); + }, [&](const MTPDmessageActionTopicCreate &data) { + if (const auto forum = peer->forum()) { + forum->applyTopicAdded( + item->id, + qs(data.vtitle()), + data.vicon_emoji_id().value_or(DocumentId())); + } + }, [&](const MTPDmessageActionTopicEditTitle &data) { + if (const auto forum = peer->forum()) { + if (const auto topic = forum->topicFor(item)) { + topic->applyTitle(qs(data.vtitle())); + } + } + }, [&](const MTPDmessageActionTopicEditIcon &data) { + if (const auto forum = peer->forum()) { + if (const auto topic = forum->topicFor(item)) { + topic->applyIconId(data.vemoji_document_id().v); + } + } }, [](const auto &) { }); } @@ -2081,10 +2101,13 @@ void History::loadUserpic() { void History::paintUserpic( Painter &p, std::shared_ptr &view, - int x, - int y, - int size) const { - peer->paintUserpic(p, view, x, y, size); + const Dialogs::Ui::PaintContext &context) const { + peer->paintUserpic( + p, + view, + context.st->padding.left(), + context.st->padding.top(), + context.st->photoSize); } void History::startBuildingFrontBlock(int expectedItemsCount) { diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 948ccf2d99..2c778017c7 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -415,9 +415,7 @@ public: void paintUserpic( Painter &p, std::shared_ptr &view, - int x, - int y, - int size) const override; + const Dialogs::Ui::PaintContext &context) const override; void refreshChatListNameSortKey(); diff --git a/Telegram/SourceFiles/history/history_service.cpp b/Telegram/SourceFiles/history/history_service.cpp index 0c416cf8b6..bf900f5800 100644 --- a/Telegram/SourceFiles/history/history_service.cpp +++ b/Telegram/SourceFiles/history/history_service.cpp @@ -802,23 +802,6 @@ void HistoryService::applyAction(const MTPMessageAction &action) { this, _from, data.vmonths().v); - }, [&](const MTPDmessageActionTopicCreate &data) { - if (const auto forum = history()->peer->forum()) { - const auto iconId = DocumentId(0); // #TODO forum icon - forum->applyTopicAdded(id, qs(data.vtitle()), iconId); - } - }, [&](const MTPDmessageActionTopicEditTitle &data) { - if (const auto forum = history()->peer->forum()) { - if (const auto topic = forum->topicFor(this)) { - topic->applyTitle(qs(data.vtitle())); - } - } - }, [&](const MTPDmessageActionTopicEditIcon &data) { - if (const auto forum = history()->peer->forum()) { - if (const auto topic = forum->topicFor(this)) { - topic->applyIconId(data.vemoji_document_id().v); - } - } }, [](const auto &) { }); } diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp index 72e30d22fc..a4812fccdb 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_search.cpp @@ -100,6 +100,7 @@ void Row::elementsPaint( int selectedElement) { _outerWidth = outerWidth; Dialogs::Ui::RowPainter::Paint(p, _fakeRow.get(), { + .st = &st::defaultDialogRow, .now = crl::now(), .width = outerWidth, .selected = selected, diff --git a/Telegram/SourceFiles/ui/empty_userpic.cpp b/Telegram/SourceFiles/ui/empty_userpic.cpp index 5cf75e78f8..992e186480 100644 --- a/Telegram/SourceFiles/ui/empty_userpic.cpp +++ b/Telegram/SourceFiles/ui/empty_userpic.cpp @@ -140,7 +140,7 @@ void PaintRepliesMessagesInner( x, y, size, - st::dialogsPhotoSize, + st::defaultDialogRow.photoSize, st::dialogsRepliesUserpic, fg); } diff --git a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp index 958af993b0..b5194748a9 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp @@ -214,7 +214,7 @@ void Generator::prepare() { _inner = extended() ? _rect.marginsRemoved(st::themePreviewMargin) : _rect; _body = extended() ? _inner.marginsRemoved(QMargins(0, Platform::PreviewTitleHeight(), 0, 0)) : _inner; _dialogs = QRect(_body.x(), _body.y(), st::themePreviewDialogsWidth, _body.height()); - _dialogsList = _dialogs.marginsRemoved(QMargins(0, st::dialogsFilterPadding.y() + st::dialogsMenuToggle.height + st::dialogsFilterPadding.y(), 0, st::dialogsPadding.y())); + _dialogsList = _dialogs.marginsRemoved(QMargins(0, st::dialogsFilterPadding.y() + st::dialogsMenuToggle.height + st::dialogsFilterPadding.y(), 0, st::defaultDialogRow.padding.bottom())); _topBar = QRect(_dialogs.x() + _dialogs.width(), _dialogs.y(), _body.width() - _dialogs.width(), st::topBarHeight); _composeArea = QRect(_topBar.x(), _body.y() + _body.height() - st::historySendSize.height(), _topBar.width(), st::historySendSize.height()); _history = QRect(_topBar.x(), _topBar.y() + _topBar.height(), _topBar.width(), _body.height() - _topBar.height() - _composeArea.height()); @@ -666,11 +666,17 @@ void Generator::paintRow(const Row &row) { if (row.active || row.selected) { _p->fillRect(fullRect, row.active ? st::dialogsBgActive[_palette] : st::dialogsBgOver[_palette]); } - paintUserpic(x + st::dialogsPadding.x(), y + st::dialogsPadding.y(), row.type, row.peerIndex, row.letters); + const auto &st = st::defaultDialogRow; + paintUserpic( + x + st.padding.left(), + y + st.padding.top(), + row.type, + row.peerIndex, + row.letters); - auto nameleft = x + st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding; - auto namewidth = x + fullWidth - nameleft - st::dialogsPadding.x(); - auto rectForName = QRect(nameleft, y + st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height); + auto nameleft = x + st.nameLeft; + auto namewidth = x + fullWidth - nameleft - st.padding.right(); + auto rectForName = QRect(nameleft, y + st.nameTop, namewidth, st::msgNameFont->height); auto chatTypeIcon = ([&row]() -> const style::icon * { if (row.type == Row::Type::Group) { @@ -685,7 +691,7 @@ void Generator::paintRow(const Row &row) { rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); } - auto texttop = y + st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip; + auto texttop = st.textTop; auto dateWidth = st::dialogsDateFont->width(row.date); rectForName.setWidth(rectForName.width() - dateWidth - st::dialogsDateSkip); @@ -696,7 +702,7 @@ void Generator::paintRow(const Row &row) { auto availableWidth = namewidth; if (row.unreadCounter) { auto counter = QString::number(row.unreadCounter); - auto unreadRight = x + fullWidth - st::dialogsPadding.x(); + auto unreadRight = x + fullWidth - st.padding.right(); auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2; auto unreadWidth = st::dialogsUnreadFont->width(counter); @@ -728,7 +734,7 @@ void Generator::paintRow(const Row &row) { _p->drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + textTop + st::dialogsUnreadFont->ascent, counter); } else if (row.pinned) { auto icon = (row.active ? st::dialogsPinnedIconActive[_palette] : (row.selected ? st::dialogsPinnedIconOver[_palette] : st::dialogsPinnedIcon[_palette])); - icon.paint(*_p, x + fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth); + icon.paint(*_p, x + fullWidth - st.padding.right() - icon.width(), texttop, fullWidth); availableWidth -= icon.width() + st::dialogsUnreadPadding; } auto textRect = QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height); @@ -955,22 +961,25 @@ void Generator::paintUserpic(int x, int y, Row::Type type, int index, QString le }; auto color = colors[index % base::array_size(colors)]; - auto image = QImage(st::dialogsPhotoSize * cIntRetinaFactor(), st::dialogsPhotoSize * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + const auto size = st::defaultDialogRow.photoSize; + auto image = QImage( + QSize(size, size) * cIntRetinaFactor(), + QImage::Format_ARGB32_Premultiplied); image.setDevicePixelRatio(cRetinaFactor()); image.fill(color[_palette]->c); { Painter p(&image); - auto fontsize = (st::dialogsPhotoSize * 13) / 33; + auto fontsize = (size * 13) / 33; auto font = st::historyPeerUserpicFont->f; font.setPixelSize(fontsize); p.setFont(font); p.setBrush(Qt::NoBrush); p.setPen(st::historyPeerUserpicFg[_palette]); - p.drawText(QRect(0, 0, st::dialogsPhotoSize, st::dialogsPhotoSize), letters, QTextOption(style::al_center)); + p.drawText(QRect(0, 0, size, size), letters, QTextOption(style::al_center)); } image = Images::Circle(std::move(image)); - _p->drawImage(rtl() ? (_rect.width() - x - st::dialogsPhotoSize) : x, y, image); + _p->drawImage(rtl() ? (_rect.width() - x - size) : x, y, image); } void Generator::paintHistoryShadows() { diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 8be9e9f5d1..f1d20d33aa 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -1092,7 +1092,9 @@ void SessionController::floatPlayerAreaUpdated() { } int SessionController::dialogsSmallColumnWidth() const { - return st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPadding.x(); + return st::defaultDialogRow.padding.left() + + st::defaultDialogRow.photoSize + + st::defaultDialogRow.padding.left(); } int SessionController::minimalThreeColumnWidth() const {