From 263d6a30f28803a4560282df9ca93c4eb55c0ba7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 19 Oct 2020 18:37:59 +0300 Subject: [PATCH] Improve grouped files layout in chat. --- Telegram/Resources/langs/lang.strings | 5 +- Telegram/SourceFiles/boxes/boxes.style | 6 +- .../SourceFiles/boxes/edit_caption_box.cpp | 51 +++--- Telegram/SourceFiles/boxes/send_files_box.cpp | 14 +- .../chat_helpers/chat_helpers.style | 3 + .../SourceFiles/history/history_widget.cpp | 2 +- .../view/history_view_replies_section.cpp | 2 +- .../view/history_view_scheduled_section.cpp | 2 +- .../history/view/media/history_view_call.cpp | 2 +- .../view/media/history_view_contact.cpp | 53 +++--- .../view/media/history_view_document.cpp | 163 ++++++++---------- .../view/media/history_view_document.h | 5 +- .../history/view/media/history_view_gif.cpp | 3 +- .../view/media/history_view_media_grouped.cpp | 39 ++++- .../view/media/history_view_media_grouped.h | 1 + .../history/view/media/history_view_photo.cpp | 6 +- .../media/history_view_theme_document.cpp | 3 +- .../inline_bot_layout_internal.cpp | 33 ++-- .../ui/chat/attach/attach_album_preview.cpp | 19 +- .../ui/chat/attach/attach_album_thumbnail.cpp | 33 ++-- .../ui/chat/attach/attach_prepare.cpp | 28 +++ .../ui/chat/attach/attach_prepare.h | 3 + .../attach/attach_single_file_preview.cpp | 50 +++--- .../attach/attach_single_media_preview.cpp | 3 +- Telegram/SourceFiles/ui/chat/chat.style | 56 ++++-- .../window/themes/window_theme_preview.cpp | 22 +-- 26 files changed, 343 insertions(+), 264 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 556f2fd35..6a939ec7e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1525,9 +1525,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_send_files_selected#other" = "{count} files selected"; "lng_send_files#one" = "Send {count} file"; "lng_send_files#other" = "Send {count} files"; -"lng_send_album" = "Send as an album"; -"lng_send_photo" = "Send as a photo"; -"lng_send_file" = "Send as a file"; +"lng_send_grouped" = "Group items"; +"lng_send_compressed" = "Compress images"; "lng_send_media_invalid_files" = "Sorry, no valid files found."; "lng_forward_choose" = "Choose recipient..."; diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 87929ede4..2269c450d 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -713,11 +713,7 @@ groupStickersSubTitleHeight: 36px; sendMediaPreviewSize: 308px; sendMediaPreviewHeightMax: 1280; -sendMediaPreviewPhotoSkip: 10px; -sendMediaFileThumbSize: 64px; -sendMediaFileThumbSkip: 10px; -sendMediaFileNameTop: 7px; -sendMediaFileStatusTop: 37px; +sendMediaRowSkip: 10px; proxyUsePadding: margins(22px, 6px, 22px, 5px); proxyTryIPv6Padding: margins(22px, 8px, 22px, 5px); diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 99cf59946..19e044b44 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -158,11 +158,12 @@ EditCaptionBox::EditCaptionBox( _thumbw = 0; _thumbnailImageLoaded = true; } else { + const auto thumbSize = st::msgFileThumbLayout.thumbSize; const auto tw = dimensions.width(), th = dimensions.height(); if (tw > th) { - _thumbw = (tw * st::msgFileThumbSize) / th; + _thumbw = (tw * thumbSize) / th; } else { - _thumbw = st::msgFileThumbSize; + _thumbw = thumbSize; } _refreshThumbnail = [=] { const auto image = computeImage(); @@ -180,8 +181,8 @@ EditCaptionBox::EditCaptionBox( _thumbw * cIntRetinaFactor(), 0, options, - st::msgFileThumbSize, - st::msgFileThumbSize)); + thumbSize, + thumbSize)); _thumbnailImageLoaded = true; }; _refreshThumbnail(); @@ -355,8 +356,8 @@ EditCaptionBox::EditCaptionBox( this, object_ptr( this, - tr::lng_send_file(tr::now), - false, + tr::lng_send_compressed(tr::now), + true, st::defaultBoxCheckbox), st::editMediaCheckboxMargins); _wayWrap = r.data(); @@ -364,7 +365,7 @@ EditCaptionBox::EditCaptionBox( r->entity()->checkedChanges( ) | rpl::start_with_next([&](bool checked) { - _asFile = checked; + _asFile = !checked; }, _wayWrap->lifetime()); _controller->session().data().itemRemoved( @@ -813,12 +814,11 @@ void EditCaptionBox::updateBoxSize() { if (_photo) { newHeight += _wayWrap->height() / 2; } + const auto &st = _thumbw ? st::msgFileThumbLayout : st::msgFileLayout; if (_photo || _animated) { newHeight += std::max(_thumbh, _gifh); - } else if (_thumbw) { - newHeight += 0 + st::msgFileThumbSize + 0; - } else if (_doc) { - newHeight += 0 + st::msgFileSize + 0; + } else if (_thumbw || _doc) { + newHeight += 0 + st.thumbSize + 0; } else { newHeight += st::boxTitleFont->height; } @@ -887,7 +887,8 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) { p.drawPixmap(_thumbx, st::boxPhotoPadding.top() + offset, _thumb); } if (_animated && !_streamed) { - QRect inner(_thumbx + (_thumbw - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (th - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + const auto &st = st::msgFileLayout; + QRect inner(_thumbx + (_thumbw - st.thumbSize) / 2, st::boxPhotoPadding.top() + (th - st.thumbSize) / 2, st.thumbSize, st.thumbSize); p.setPen(Qt::NoPen); p.setBrush(st::msgDateImgBg); @@ -900,20 +901,13 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) { icon->paintInCenter(p, inner); } } else if (_doc) { + const auto &st = _thumbw ? st::msgFileThumbLayout : st::msgFileLayout; const auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(); - const auto h = _thumbw ? (0 + st::msgFileThumbSize + 0) : (0 + st::msgFileSize + 0); - auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0; - if (_thumbw) { - nameleft = 0 + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - nametop = st::msgFileThumbNameTop - st::msgFileThumbPadding.top(); - nameright = 0; - statustop = st::msgFileThumbStatusTop - st::msgFileThumbPadding.top(); - } else { - nameleft = 0 + st::msgFileSize + st::msgFilePadding.right(); - nametop = st::msgFileNameTop - st::msgFilePadding.top(); - nameright = 0; - statustop = st::msgFileStatusTop - st::msgFilePadding.top(); - } + const auto h = 0 + st.thumbSize + 0; + const auto nameleft = 0 + st.thumbSize + st.padding.right(); + const auto nametop = st.nameTop - st.padding.top(); + const auto nameright = 0; + const auto statustop = st.statusTop - st.padding.top(); const auto editButton = _isAllowedEditMedia ? _editMedia->width() + st::editMediaButtonSkip : 0; @@ -922,21 +916,20 @@ void EditCaptionBox::paintEvent(QPaintEvent *e) { // Ui::FillRoundCorner(p, x, y, w, h, st::msgInBg, Ui::MessageInCorners, &st::msgInShadow); + const auto rthumb = style::rtlrect(x + 0, y + 0, st.thumbSize, st.thumbSize, width()); if (_thumbw) { - QRect rthumb(style::rtlrect(x + 0, y + 0, st::msgFileThumbSize, st::msgFileThumbSize, width())); p.drawPixmap(rthumb.topLeft(), _thumb); } else { - const QRect inner(style::rtlrect(x + 0, y + 0, st::msgFileSize, st::msgFileSize, width())); p.setPen(Qt::NoPen); p.setBrush(st::msgFileInBg); { PainterHighQualityEnabler hq(p); - p.drawEllipse(inner); + p.drawEllipse(rthumb); } const auto icon = &(_isAudio ? st::historyFileInPlay : _isImage ? st::historyFileInImage : st::historyFileInDocument); - icon->paintInCenter(p, inner); + icon->paintInCenter(p, rthumb); } p.setFont(st::semiboldFont); p.setPen(st::historyFileNameInFg); diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 6ce610629..bca75480a 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -527,7 +527,7 @@ void SendFilesBox::pushBlock(int from, int till) { auto &block = _blocks.back(); const auto widget = _inner->add( block.takeWidget(), - QMargins(0, _inner->count() ? st::sendMediaFileThumbSkip : 0, 0, 0)); + QMargins(0, _inner->count() ? st::sendMediaRowSkip : 0, 0, 0)); block.itemDeleteRequest( ) | rpl::filter([=] { @@ -590,15 +590,14 @@ void SendFilesBox::refreshControls() { } void SendFilesBox::setupSendWayControls() { - // #TODO files _groupFiles.create( this, - "Group items", + tr::lng_send_grouped(tr::now), _sendWay.current().groupFiles(), st::defaultBoxCheckbox); _sendImagesAsPhotos.create( this, - "Compress images", + tr::lng_send_compressed(tr::now), _sendWay.current().sendImagesAsPhotos(), st::defaultBoxCheckbox); @@ -628,8 +627,9 @@ void SendFilesBox::updateSendWayControlsVisibility() { return; } const auto onlyOne = (_sendLimit == SendLimit::One); - _groupFiles->setVisible(!onlyOne); - _sendImagesAsPhotos->setVisible(/*_list.hasImagesForCompression()*/true); // #TODO files + _groupFiles->setVisible(_list.hasGroupOption(onlyOne)); + _sendImagesAsPhotos->setVisible( + _list.hasSendImagesAsPhotosOption(onlyOne)); } void SendFilesBox::setupCaption() { @@ -821,7 +821,7 @@ void SendFilesBox::refreshTitleText() { _titleHeight = st::boxTitleHeight; } else { _titleText = QString(); - _titleHeight = st::boxPhotoPadding.top(); + _titleHeight = count ? st::boxPhotoPadding.top() : 0; } } diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index ac5b74139..7c3cf0494 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -278,3 +278,6 @@ manageEmojiPreviewPadding: margins(22px, 9px, 19px, 9px); manageEmojiMarginRight: 21px; manageEmojiNameTop: 3px; manageEmojiStatusTop: 25px; + +inlineRadialSize: 44px; +inlineFileSize: 44px; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c77a230b0..161b13678 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -4226,7 +4226,7 @@ void HistoryWidget::sendingFilesConfirmed( action.replyTo = replyToId(); action.options = options; action.clearDraft = false; - if (groups.size() > 1 && !caption.text.isEmpty()) { + if ((groups.empty() || groups.size() > 1) && !caption.text.isEmpty()) { auto message = Api::MessageToSend(_history); message.textWithTags = base::take(caption); message.action = action; diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 7c534f7b9..cd58947de 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -671,7 +671,7 @@ void RepliesWidget::sendingFilesConfirmed( action.replyTo = replyTo ? replyTo : _rootId; action.options = options; action.clearDraft = false; - if (groups.size() > 1 && !caption.text.isEmpty()) { + if ((groups.empty() || groups.size() > 1) && !caption.text.isEmpty()) { auto message = Api::MessageToSend(_history); message.textWithTags = base::take(caption); message.action = action; diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 8afba643f..37843d188 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -407,7 +407,7 @@ void ScheduledWidget::sendingFilesConfirmed( auto action = Api::SendAction(_history); action.options = options; action.clearDraft = false; - if (groups.size() > 1 && !caption.text.isEmpty()) { + if ((groups.empty() || groups.size() > 1) && !caption.text.isEmpty()) { auto message = Api::MessageToSend(_history); message.textWithTags = base::take(caption); message.action = action; diff --git a/Telegram/SourceFiles/history/view/media/history_view_call.cpp b/Telegram/SourceFiles/history/view/media/history_view_call.cpp index 982e7c459..aa2881aeb 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_call.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_call.cpp @@ -86,7 +86,7 @@ void Call::draw(Painter &p, const QRect &r, TextSelection selection, crl::time m nameleft = st::historyCallLeft; nametop = st::historyCallTop - topMinus; - nameright = st::msgFilePadding.left(); + nameright = st::msgFileLayout.padding.left(); statustop = st::historyCallStatusTop - topMinus; auto namewidth = paintw - nameleft - nameright; diff --git a/Telegram/SourceFiles/history/view/media/history_view_contact.cpp b/Telegram/SourceFiles/history/view/media/history_view_contact.cpp index eb8a5ca37..ff87a9b05 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_contact.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_contact.cpp @@ -120,30 +120,25 @@ QSize Contact::countOptimalSize() { } _linkw = _link.isEmpty() ? 0 : st::semiboldFont->width(_link); - auto tleft = 0; - auto tright = 0; + const auto &st = _userId ? st::msgFileThumbLayout : st::msgFileLayout; + + const auto tleft = st.padding.left() + st.thumbSize + st.padding.right(); + const auto tright = st.padding.left(); if (_userId) { - tleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - tright = st::msgFileThumbPadding.left(); accumulate_max(maxWidth, tleft + _phonew + tright); } else { - tleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - tright = st::msgFileThumbPadding.left(); accumulate_max(maxWidth, tleft + _phonew + _parent->skipBlockWidth() + st::msgPadding.right()); } accumulate_max(maxWidth, tleft + _name.maxWidth() + tright); accumulate_min(maxWidth, st::msgMaxWidth); - auto minHeight = 0; + auto minHeight = st.padding.top() + st.thumbSize + st.padding.bottom(); if (_userId) { - minHeight = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); const auto msgsigned = item->Get(); if ((msgsigned && !msgsigned->isAnonymousRank) || item->Has()) { minHeight += st::msgDateFont->height - st::msgDateDelta.y(); } - } else { - minHeight = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); } if (!isBubbleTop()) { minHeight -= st::msgFileTopMinus; @@ -160,24 +155,23 @@ void Contact::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim accumulate_min(paintw, maxWidth()); - auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; - auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto &st = _userId ? st::msgFileThumbLayout : st::msgFileLayout; + const auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto nameleft = st.padding.left() + st.thumbSize + st.padding.right(); + const auto nametop = st.nameTop - topMinus; + const auto nameright = st.padding.left(); + const auto statustop = st.statusTop - topMinus; + const auto linktop = st.linkTop - topMinus; if (_userId) { - nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - nametop = st::msgFileThumbNameTop - topMinus; - nameright = st::msgFileThumbPadding.left(); - statustop = st::msgFileThumbStatusTop - topMinus; - linktop = st::msgFileThumbLinkTop - topMinus; - - QRect rthumb(style::rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, paintw)); + QRect rthumb(style::rtlrect(st.padding.left(), st.padding.top() - topMinus, st.thumbSize, st.thumbSize, paintw)); if (_contact) { const auto was = (_userpic != nullptr); - _contact->paintUserpic(p, _userpic, rthumb.x(), rthumb.y(), st::msgFileThumbSize); + _contact->paintUserpic(p, _userpic, rthumb.x(), rthumb.y(), st.thumbSize); if (!was && _userpic) { history()->owner().registerHeavyViewPart(_parent); } } else { - _photoEmpty->paint(p, st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, paintw, st::msgFileThumbSize); + _photoEmpty->paint(p, st.padding.left(), st.padding.top() - topMinus, paintw, st.thumbSize); } if (selected) { PainterHighQualityEnabler hq(p); @@ -191,14 +185,9 @@ void Contact::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg)); p.drawTextLeft(nameleft, linktop, paintw, _link, _linkw); } else { - nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - nametop = st::msgFileNameTop - topMinus; - nameright = st::msgFilePadding.left(); - statustop = st::msgFileStatusTop - topMinus; - - _photoEmpty->paint(p, st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, paintw, st::msgFileSize); + _photoEmpty->paint(p, st.padding.left(), st.padding.top() - topMinus, paintw, st.thumbSize); } - auto namewidth = paintw - nameleft - nameright; + const auto namewidth = paintw - nameleft - nameright; p.setFont(st::semiboldFont); p.setPen(outbg ? (selected ? st::historyFileNameOutFgSelected : st::historyFileNameOutFg) : (selected ? st::historyFileNameInFgSelected : st::historyFileNameInFg)); @@ -213,11 +202,11 @@ void Contact::draw(Painter &p, const QRect &r, TextSelection selection, crl::tim TextState Contact::textState(QPoint point, StateRequest request) const { auto result = TextState(_parent); - auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; - auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; if (_userId) { - nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - linktop = st::msgFileThumbLinkTop - topMinus; + const auto &st = _userId ? st::msgFileThumbLayout : st::msgFileLayout; + const auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto nameleft = st.padding.left() + st.thumbSize + st.padding.right(); + const auto linktop = st.linkTop - topMinus; if (style::rtlrect(nameleft, linktop, _linkw, st::semiboldFont->height, width()).contains(point)) { result.link = _linkl; return result; diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 9d3b47582..da0c222f3 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -164,28 +164,25 @@ QSize Document::countOptimalSize() { _parent->skipBlockHeight()); } auto thumbed = Get(); + const auto &st = thumbed ? st::msgFileThumbLayout : st::msgFileLayout; if (thumbed) { const auto &location = _data->thumbnailLocation(); auto tw = style::ConvertScale(location.width()); auto th = style::ConvertScale(location.height()); if (tw > th) { - thumbed->_thumbw = (tw * st::msgFileThumbSize) / th; + thumbed->_thumbw = (tw * st.thumbSize) / th; } else { - thumbed->_thumbw = st::msgFileThumbSize; + thumbed->_thumbw = st.thumbSize; } } auto maxWidth = st::msgFileMinWidth; - auto tleft = 0; - auto tright = 0; + const auto tleft = st.padding.left() + st.thumbSize + st.padding.right(); + const auto tright = st.padding.left(); if (thumbed) { - tleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - tright = st::msgFileThumbPadding.left(); accumulate_max(maxWidth, tleft + documentMaxStatusWidth(_data) + tright); } else { - tleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - tright = st::msgFileThumbPadding.left(); auto unread = _data->isVoiceMessage() ? (st::mediaUnreadSkip + st::mediaUnreadSize) : 0; accumulate_max(maxWidth, tleft + documentMaxStatusWidth(_data) + unread + _parent->skipBlockWidth() + st::msgPadding.right()); } @@ -195,12 +192,7 @@ QSize Document::countOptimalSize() { accumulate_min(maxWidth, st::msgMaxWidth); } - auto minHeight = 0; - if (thumbed) { - minHeight = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); - } else { - minHeight = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); - } + auto minHeight = st.padding.top() + st.thumbSize + st.padding.bottom(); const auto msgsigned = item->Get(); if (!captioned && ((msgsigned && !msgsigned->isAnonymousRank) || item->Has() @@ -224,18 +216,15 @@ QSize Document::countOptimalSize() { } QSize Document::countCurrentSize(int newWidth) { - auto captioned = Get(); + const auto captioned = Get(); if (!captioned) { return File::countCurrentSize(newWidth); } accumulate_min(newWidth, maxWidth()); - auto newHeight = 0; - if (Get()) { - newHeight = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); - } else { - newHeight = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); - } + const auto thumbed = Get(); + const auto &st = thumbed ? st::msgFileThumbLayout : st::msgFileLayout; + auto newHeight = st.padding.top() + st.thumbSize + st.padding.bottom(); if (!isBubbleTop()) { newHeight -= st::msgFileTopMinus; } @@ -286,24 +275,28 @@ void Document::draw( const auto showPause = updateStatusText(); const auto radial = isRadialAnimation(); - auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; - int nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0; - if (auto thumbed = Get()) { - nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - nametop = st::msgFileThumbNameTop - topMinus; - nameright = st::msgFileThumbPadding.left(); - statustop = st::msgFileThumbStatusTop - topMinus; - linktop = st::msgFileThumbLinkTop - topMinus; - bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() - topMinus; - + const auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto thumbed = Get(); + const auto &st = (mode == LayoutMode::Full) + ? (thumbed ? st::msgFileThumbLayout : st::msgFileLayout) + : (thumbed ? st::msgFileThumbLayoutGrouped : st::msgFileLayoutGrouped); + const auto nameleft = st.padding.left() + st.thumbSize + st.padding.right(); + const auto nametop = st.nameTop - topMinus; + const auto nameright = st.padding.left(); + const auto statustop = st.statusTop - topMinus; + const auto linktop = st.linkTop - topMinus; + const auto bottom = st.padding.top() + st.thumbSize + st.padding.bottom() - topMinus; + const auto rthumb = style::rtlrect(st.padding.left(), st.padding.top() - topMinus, st.thumbSize, st.thumbSize, width); + const auto innerSize = st::msgFileLayout.thumbSize; + const auto inner = QRect(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize); + if (thumbed) { auto inWebPage = (_parent->media() != this); auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large; - QRect rthumb(style::rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width)); QPixmap thumb; if (const auto normal = _dataMedia->thumbnail()) { - thumb = normal->pixSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius); + thumb = normal->pixSingle(thumbed->_thumbw, 0, st.thumbSize, st.thumbSize, roundRadius); } else if (const auto blurred = _dataMedia->thumbnailInline()) { - thumb = blurred->pixBlurredSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius); + thumb = blurred->pixBlurredSingle(thumbed->_thumbw, 0, st.thumbSize, st.thumbSize, roundRadius); } p.drawPixmap(rthumb.topLeft(), thumb); if (selected) { @@ -313,7 +306,6 @@ void Document::draw( if (radial || (!loaded && !_data->loading())) { float64 radialOpacity = (radial && loaded && !_data->uploading()) ? _animation->radial.opacity() : 1; - QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); p.setPen(Qt::NoPen); if (selected) { p.setBrush(st::msgDateImgBgSelected); @@ -356,13 +348,6 @@ void Document::draw( p.drawTextLeft(nameleft, linktop, width, thumbed->_link, thumbed->_linkw); } } else { - nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - nametop = st::msgFileNameTop - topMinus; - nameright = st::msgFilePadding.left(); - statustop = st::msgFileStatusTop - topMinus; - bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() - topMinus; - - QRect inner(style::rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width)); p.setPen(Qt::NoPen); if (selected) { p.setBrush(outbg ? st::msgFileOutBgSelected : st::msgFileInBgSelected); @@ -398,7 +383,7 @@ void Document::draw( _animation->radial.draw(p, rinner, st::msgFileRadialLine, fg); } - drawCornerDownload(p, selected); + drawCornerDownload(p, selected, mode); } auto namewidth = width - nameleft - nameright; auto statuswidth = namewidth; @@ -448,7 +433,7 @@ void Document::draw( auto bar_count = qMin(availw / (st::msgWaveformBar + st::msgWaveformSkip), wf_size); auto max_value = 0; auto max_delta = st::msgWaveformMax - st::msgWaveformMin; - auto bottom = st::msgFilePadding.top() - topMinus + st::msgWaveformMax; + auto bottom = st.padding.top() - topMinus + st::msgWaveformMax; p.setPen(Qt::NoPen); for (auto i = 0, bar_x = 0, sum_i = 0; i < wf_size; ++i) { auto value = wf ? wf->at(i) : 0; @@ -543,7 +528,7 @@ bool Document::downloadInCorner() const { && IsServerMsgId(_parent->data()->id); } -void Document::drawCornerDownload(Painter &p, bool selected) const { +void Document::drawCornerDownload(Painter &p, bool selected, LayoutMode mode) const { if (dataLoaded() || _data->loadedInMediaCache() || !downloadInCorner()) { @@ -551,9 +536,13 @@ void Document::drawCornerDownload(Painter &p, bool selected) const { } auto outbg = _parent->hasOutLayout(); auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto thumbed = false; + const auto &st = (mode == LayoutMode::Full) + ? (thumbed ? st::msgFileThumbLayout : st::msgFileLayout) + : (thumbed ? st::msgFileThumbLayoutGrouped : st::msgFileLayoutGrouped); const auto shift = st::historyAudioDownloadShift; const auto size = st::historyAudioDownloadSize; - const auto inner = style::rtlrect(st::msgFilePadding.left() + shift, st::msgFilePadding.top() - topMinus + shift, size, size, width()); + const auto inner = style::rtlrect(st.padding.left() + shift, st.padding.top() - topMinus + shift, size, size, width()); auto pen = (selected ? (outbg ? st::msgOutBgSelected : st::msgInBgSelected) : (outbg ? st::msgOutBg : st::msgInBg))->p; @@ -584,7 +573,8 @@ void Document::drawCornerDownload(Painter &p, bool selected) const { TextState Document::cornerDownloadTextState( QPoint point, - StateRequest request) const { + StateRequest request, + LayoutMode mode) const { auto result = TextState(_parent); if (dataLoaded() || _data->loadedInMediaCache() @@ -592,14 +582,17 @@ TextState Document::cornerDownloadTextState( return result; } auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto thumbed = false; + const auto &st = (mode == LayoutMode::Full) + ? (thumbed ? st::msgFileThumbLayout : st::msgFileLayout) + : (thumbed ? st::msgFileThumbLayoutGrouped : st::msgFileLayoutGrouped); const auto shift = st::historyAudioDownloadShift; const auto size = st::historyAudioDownloadSize; - const auto inner = style::rtlrect(st::msgFilePadding.left() + shift, st::msgFilePadding.top() - topMinus + shift, size, size, width()); + const auto inner = style::rtlrect(st.padding.left() + shift, st.padding.top() - topMinus + shift, size, size, width()); if (inner.contains(point)) { result.link = _data->loading() ? _cancell : _savel; } return result; - } TextState Document::textState(QPoint point, StateRequest request) const { @@ -625,16 +618,21 @@ TextState Document::textState( bool showPause = updateStatusText(); - auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0, bottom = 0; - auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + const auto thumbed = Get(); + const auto &st = (mode == LayoutMode::Full) + ? (thumbed ? st::msgFileThumbLayout : st::msgFileLayout) + : (thumbed ? st::msgFileThumbLayoutGrouped : st::msgFileLayoutGrouped); + const auto nameleft = st.padding.left() + st.thumbSize + st.padding.right(); + const auto nametop = st.nameTop - topMinus; + const auto nameright = st.padding.left(); + const auto statustop = st.statusTop - topMinus; + const auto linktop = st.linkTop - topMinus; + const auto bottom = st.padding.top() + st.thumbSize + st.padding.bottom() - topMinus; + const auto rthumb = style::rtlrect(st.padding.left(), st.padding.top() - topMinus, st.thumbSize, st.thumbSize, width); + const auto innerSize = st::msgFileLayout.thumbSize; + const auto inner = QRect(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize); if (const auto thumbed = Get()) { - nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - nameright = st::msgFileThumbPadding.left(); - nametop = st::msgFileThumbNameTop - topMinus; - linktop = st::msgFileThumbLinkTop - topMinus; - bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() - topMinus; - - QRect rthumb(style::rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width)); if ((_data->loading() || _data->uploading()) && rthumb.contains(point)) { result.link = _cancell; return result; @@ -651,15 +649,9 @@ TextState Document::textState( } } } else { - nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - nameright = st::msgFilePadding.left(); - nametop = st::msgFileNameTop - topMinus; - bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() - topMinus; - - if (const auto state = cornerDownloadTextState(point, request); state.link) { + if (const auto state = cornerDownloadTextState(point, request, mode); state.link) { return state; } - QRect inner(style::rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width)); if ((_data->loading() || _data->uploading()) && inner.contains(point) && !downloadInCorner()) { result.link = _cancell; return result; @@ -668,7 +660,7 @@ TextState Document::textState( if (const auto voice = Get()) { auto namewidth = width - nameleft - nameright; - auto waveformbottom = st::msgFilePadding.top() - topMinus + st::msgWaveformMax + st::msgWaveformMin; + auto waveformbottom = st.padding.top() - topMinus + st::msgWaveformMax + st::msgWaveformMin; if (QRect(nameleft, nametop, namewidth, waveformbottom - nametop).contains(point)) { const auto state = ::Media::Player::instance()->getState(AudioMsgId::Type::Voice); if (state.id == AudioMsgId(_data, _parent->data()->fullId(), state.id.externalPlayId()) @@ -714,16 +706,13 @@ TextState Document::textState( } void Document::updatePressed(QPoint point) { + // LayoutMode should be passed here. if (auto voice = Get()) { if (voice->seeking()) { - auto nameleft = 0, nameright = 0; - if (auto thumbed = Get()) { - nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - nameright = st::msgFileThumbPadding.left(); - } else { - nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - nameright = st::msgFilePadding.left(); - } + const auto thumbed = Get(); + const auto &st = thumbed ? st::msgFileThumbLayout : st::msgFileLayout; + const auto nameleft = st.padding.left() + st.thumbSize + st.padding.right(); + const auto nameright = st.padding.left(); voice->setSeekingCurrent(snap((point.x() - nameleft) / float64(width() - nameleft - nameright), 0., 1.)); history()->owner().requestViewRepaint(_parent); } @@ -853,7 +842,11 @@ bool Document::updateStatusText() const { } QMargins Document::bubbleMargins() const { - return Get() ? QMargins(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbPadding.left(), st::msgFileThumbPadding.bottom()) : st::msgPadding; + if (!Has()) { + return st::msgPadding; + } + const auto padding = st::msgFileThumbLayout.padding; + return QMargins(padding.left(), padding.top(), padding.left(), padding.bottom()); } bool Document::hideForwardedFrom() const { @@ -861,13 +854,9 @@ bool Document::hideForwardedFrom() const { } QSize Document::sizeForGroupingOptimal(int maxWidth, bool last) const { - auto height = Has() - ? (st::msgFileThumbPadding.top() - + st::msgFileThumbSize - + st::msgFileThumbPadding.bottom()) - : (st::msgFilePadding.top() - + st::msgFileSize - + st::msgFilePadding.bottom()); + const auto thumbed = Get(); + const auto &st = (thumbed ? st::msgFileThumbLayoutGrouped : st::msgFileLayoutGrouped); + auto height = st.padding.top() + st.thumbSize + st.padding.bottom(); if (!last) { if (const auto captioned = Get()) { auto captionw = maxWidth @@ -881,13 +870,9 @@ QSize Document::sizeForGroupingOptimal(int maxWidth, bool last) const { } QSize Document::sizeForGrouping(int width, bool last) const { - auto height = Has() - ? (st::msgFileThumbPadding.top() - + st::msgFileThumbSize - + st::msgFileThumbPadding.bottom()) - : (st::msgFilePadding.top() - + st::msgFileSize - + st::msgFilePadding.bottom()); + const auto thumbed = Get(); + const auto &st = (thumbed ? st::msgFileThumbLayoutGrouped : st::msgFileLayoutGrouped); + auto height = st.padding.top() + st.thumbSize + st.padding.bottom(); if (!last) { if (const auto captioned = Get()) { auto captionw = width diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.h b/Telegram/SourceFiles/history/view/media/history_view_document.h index c3f8b03c1..3b70a2c5b 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.h +++ b/Telegram/SourceFiles/history/view/media/history_view_document.h @@ -134,10 +134,11 @@ private: bool updateStatusText() const; // returns showPause [[nodiscard]] bool downloadInCorner() const; - void drawCornerDownload(Painter &p, bool selected) const; + void drawCornerDownload(Painter &p, bool selected, LayoutMode mode) const; [[nodiscard]] TextState cornerDownloadTextState( QPoint point, - StateRequest request) const; + StateRequest request, + LayoutMode mode) const; not_null _data; mutable std::shared_ptr _dataMedia; diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index fed2eb912..c3475a97f 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -471,7 +471,8 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms : (radial && loaded) ? _animation->radial.opacity() : 1.; - auto inner = QRect(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + const auto innerSize = st::msgFileLayout.thumbSize; + auto inner = QRect(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize); p.setPen(Qt::NoPen); if (selected) { p.setBrush(st::msgDateImgBgSelected); diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index b4b449273..fb6939045 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -148,6 +148,10 @@ QSize GroupedMedia::countOptimalSize() { minHeight += st::msgPadding.bottom(); } } + + const auto groupPadding = groupedPadding(); + minHeight += groupPadding.top() + groupPadding.bottom(); + return { maxWidth, minHeight }; } @@ -207,6 +211,9 @@ QSize GroupedMedia::countCurrentSize(int newWidth) { } } + const auto groupPadding = groupedPadding(); + newHeight += groupPadding.top() + groupPadding.bottom(); + return { newWidth, newHeight }; } @@ -228,11 +235,26 @@ RectParts GroupedMedia::cornersFromSides(RectParts sides) const { return result; } +QMargins GroupedMedia::groupedPadding() const { + if (_mode != Mode::Column) { + return QMargins(); + } + const auto normal = st::msgFileLayout.padding; + const auto grouped = st::msgFileLayoutGrouped.padding; + const auto topMinus = isBubbleTop() ? 0 : st::msgFileTopMinus; + return QMargins( + 0, + (normal.top() - grouped.top()) - topMinus, + 0, + (normal.bottom() - grouped.bottom())); +} + void GroupedMedia::draw( Painter &p, const QRect &clip, TextSelection selection, crl::time ms) const { + const auto groupPadding = groupedPadding(); for (auto i = 0, count = int(_parts.size()); i != count; ++i) { const auto &part = _parts[i]; const auto partSelection = (selection == FullSelection) @@ -246,7 +268,7 @@ void GroupedMedia::draw( clip, partSelection, ms, - part.geometry, + part.geometry.translated(0, groupPadding.top()), part.sides, cornersFromSides(part.sides), &part.cacheKey, @@ -260,6 +282,7 @@ void GroupedMedia::draw( const auto captionw = width() - st::msgPadding.left() - st::msgPadding.right(); const auto outbg = _parent->hasOutLayout(); const auto captiony = height() + - groupPadding.bottom() - (isBubbleBottom() ? st::msgPadding.bottom() : 0) - _caption.countHeight(captionw); p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg)); @@ -303,6 +326,8 @@ PointState GroupedMedia::pointState(QPoint point) const { if (!QRect(0, 0, width(), height()).contains(point)) { return PointState::Outside; } + const auto groupPadding = groupedPadding(); + point -= QPoint(0, groupPadding.top()); for (const auto &part : _parts) { if (part.geometry.contains(point)) { return PointState::GroupPart; @@ -312,10 +337,12 @@ PointState GroupedMedia::pointState(QPoint point) const { } TextState GroupedMedia::textState(QPoint point, StateRequest request) const { - auto result = getPartState(point, request); + const auto groupPadding = groupedPadding(); + auto result = getPartState(point - QPoint(0, groupPadding.top()), request); if (!result.link && !_caption.isEmpty()) { const auto captionw = width() - st::msgPadding.left() - st::msgPadding.right(); const auto captiony = height() + - groupPadding.bottom() - (isBubbleBottom() ? st::msgPadding.bottom() : 0) - _caption.countHeight(captionw); if (QRect(st::msgPadding.left(), captiony, captionw, height() - captiony).contains(point)) { @@ -395,6 +422,14 @@ auto GroupedMedia::getBubbleSelectionIntervals( last = BubbleSelectionInterval{ newTop, newHeight }; } } + const auto groupPadding = groupedPadding(); + for (auto &part : result) { + part.top += groupPadding.top(); + } + if (IsGroupItemSelection(selection, 0)) { + result.front().top -= groupPadding.top(); + result.front().height += groupPadding.top(); + } if (IsGroupItemSelection(selection, _parts.size() - 1)) { result.back().height = height() - result.back().top; } diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h index 29b1eaedf..615c03772 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h @@ -139,6 +139,7 @@ private: StateRequest request) const; [[nodiscard]] RectParts cornersFromSides(RectParts sides) const; + [[nodiscard]] QMargins groupedPadding() const; Ui::Text::String _caption; std::vector _parts; diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 7025dea4e..6d04b23f5 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -279,7 +279,8 @@ void Photo::draw(Painter &p, const QRect &r, TextSelection selection, crl::time const auto radialOpacity = (radial && loaded && !_data->uploading()) ? _animation->radial.opacity() : 1.; - QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + const auto innerSize = st::msgFileLayout.thumbSize; + QRect inner(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize); p.setPen(Qt::NoPen); if (selected) { p.setBrush(st::msgDateImgBgSelected); @@ -389,7 +390,8 @@ void Photo::paintUserpicFrame( p.drawPixmap(rect, pix); if (_data->videoCanBePlayed() && !_streamed) { - auto inner = QRect(rect.x() + (rect.width() - st::msgFileSize) / 2, rect.y() + (rect.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + const auto innerSize = st::msgFileLayout.thumbSize; + auto inner = QRect(rect.x() + (rect.width() - innerSize) / 2, rect.y() + (rect.height() - innerSize) / 2, innerSize, innerSize); p.setPen(Qt::NoPen); if (selected) { p.setBrush(st::msgDateImgBgSelected); diff --git a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp index f6055a7fb..43938b0c4 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp @@ -156,7 +156,8 @@ void ThemeDocument::draw(Painter &p, const QRect &r, TextSelection selection, cr const auto radialOpacity = (radial && loaded && !_data->uploading()) ? _animation->radial.opacity() : 1.; - QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + const auto innerSize = st::msgFileLayout.thumbSize; + QRect inner(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize); p.setPen(Qt::NoPen); if (selected) { p.setBrush(st::msgDateImgBgSelected); diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index c36ac5937..df750a65e 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -207,7 +207,8 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons } return &st::historyFileInDownload; }(); - QRect inner((_width - st::msgFileSize) / 2, (height - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + const auto size = st::inlineRadialSize; + QRect inner((_width - size) / 2, (height - size) / 2, size, size); icon->paintInCenter(p, inner); if (radial) { p.setOpacity(1); @@ -818,8 +819,8 @@ void CancelFileClickHandler::onClickImpl() const { File::File(not_null context, not_null result) : FileBase(context, result) -, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::msgFileSize - st::inlineThumbSkip) -, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::msgFileSize - st::inlineThumbSkip) +, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineFileSize - st::inlineThumbSkip) +, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineFileSize - st::inlineThumbSkip) , _open(std::make_shared(result)) , _cancel(std::make_shared(result)) , _document(getShownDocument()) { @@ -835,7 +836,7 @@ File::File(not_null context, not_null result) void File::initDimensions() { _maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft; - int textWidth = _maxw - (st::msgFileSize + st::inlineThumbSkip); + int textWidth = _maxw - (st::inlineFileSize + st::inlineThumbSkip); TextParseOptions titleOpts = { 0, _maxw, st::semiboldFont->height, Qt::LayoutDirectionAuto }; _title.setText(st::semiboldTextStyle, TextUtilities::SingleLine(_result->getLayoutTitle()), titleOpts); @@ -843,12 +844,12 @@ void File::initDimensions() { TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, st::normalFont->height, Qt::LayoutDirectionAuto }; _description.setText(st::defaultTextStyle, _result->getLayoutDescription(), descriptionOpts); - _minh = st::msgFileSize; + _minh = st::inlineFileSize; _minh += st::inlineRowMargin * 2 + st::inlineRowBorder; } void File::paint(Painter &p, const QRect &clip, const PaintContext *context) const { - const auto left = st::msgFileSize + st::inlineThumbSkip; + const auto left = st::inlineFileSize + st::inlineThumbSkip; ensureDataMediaCreated(); const auto loaded = _documentMedia->loaded(); @@ -862,7 +863,7 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con const auto showPause = updateStatusText(); const auto radial = isRadialAnimation(); - auto inner = style::rtlrect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize, _width); + auto inner = style::rtlrect(0, st::inlineRowMargin, st::inlineFileSize, st::inlineFileSize, _width); p.setPen(Qt::NoPen); if (isThumbAnimation()) { auto over = _animation->a_thumbOver.value(1.); @@ -926,10 +927,10 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con TextState File::getState( QPoint point, StateRequest request) const { - if (QRect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize).contains(point)) { + if (QRect(0, st::inlineRowMargin, st::inlineFileSize, st::inlineFileSize).contains(point)) { return { nullptr, _document->loading() ? _cancel : _open }; } else { - auto left = st::msgFileSize + st::inlineThumbSkip; + auto left = st::inlineFileSize + st::inlineThumbSkip; if (QRect(left, 0, _width - left, _height).contains(point)) { return { nullptr, _send }; } @@ -1070,16 +1071,16 @@ void Contact::initDimensions() { _description.setText(st::defaultTextStyle, _result->getLayoutDescription(), descriptionOpts); int32 descriptionHeight = qMin(_description.countHeight(_maxw), st::normalFont->height); - _minh = st::msgFileSize; + _minh = st::inlineFileSize; _minh += st::inlineRowMargin * 2 + st::inlineRowBorder; } void Contact::paint(Painter &p, const QRect &clip, const PaintContext *context) const { int32 left = st::emojiPanHeaderLeft - st::inlineResultsLeft; - left = st::msgFileSize + st::inlineThumbSkip; - prepareThumbnail(st::msgFileSize, st::msgFileSize); - QRect rthumb(style::rtlrect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize, _width)); + left = st::inlineFileSize + st::inlineThumbSkip; + prepareThumbnail(st::inlineFileSize, st::inlineFileSize); + QRect rthumb(style::rtlrect(0, st::inlineRowMargin, st::inlineFileSize, st::inlineFileSize, _width)); p.drawPixmapLeft(rthumb.topLeft(), _width, _thumb); int titleTop = st::inlineRowMargin + st::inlineRowFileNameTop; @@ -1099,8 +1100,8 @@ void Contact::paint(Painter &p, const QRect &clip, const PaintContext *context) TextState Contact::getState( QPoint point, StateRequest request) const { - if (!QRect(0, st::inlineRowMargin, st::msgFileSize, st::inlineThumbSize).contains(point)) { - auto left = (st::msgFileSize + st::inlineThumbSkip); + if (!QRect(0, st::inlineRowMargin, st::inlineFileSize, st::inlineThumbSize).contains(point)) { + auto left = (st::inlineFileSize + st::inlineThumbSkip); if (QRect(left, 0, _width - left, _height).contains(point)) { return { nullptr, _send }; } @@ -1414,7 +1415,7 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con if (radial) { p.fillRect(rthumb, st::msgDateImgBg); - QRect inner((st::inlineThumbSize - st::msgFileSize) / 2, (st::inlineThumbSize - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + QRect inner((st::inlineThumbSize - st::inlineRadialSize) / 2, (st::inlineThumbSize - st::inlineRadialSize) / 2, st::inlineRadialSize, st::inlineRadialSize); if (radial) { p.setOpacity(1); QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine))); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp index 98b93813d..3154bc41b 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp @@ -112,10 +112,11 @@ void AlbumPreview::prepareThumbs(gsl::span items) { _thumbs ) | ranges::view::transform([](const auto &thumb) { return thumb->photoHeight(); - }), 0) + (count - 1) * st::sendMediaPreviewPhotoSkip; + }), 0) + (count - 1) * st::sendMediaRowSkip; - _filesHeight = count * st::sendMediaFileThumbSize - + (count - 1) * st::sendMediaFileThumbSkip; + const auto &st = st::attachPreviewThumbLayout; + _filesHeight = count * st.thumbSize + + (count - 1) * st::sendMediaRowSkip; } int AlbumPreview::contentLeft() const { @@ -131,16 +132,14 @@ AlbumThumbnail *AlbumPreview::findThumb(QPoint position) const { auto top = 0; const auto isPhotosWay = _sendWay.sendImagesAsPhotos(); - const auto skip = isPhotosWay - ? st::sendMediaPreviewPhotoSkip - : st::sendMediaFileThumbSkip; + const auto skip = st::sendMediaRowSkip; auto find = [&](const auto &thumb) { if (_sendWay.groupFiles() && _sendWay.sendImagesAsPhotos()) { return thumb->containsPoint(position); } else { const auto bottom = top + (isPhotosWay ? thumb->photoHeight() - : st::sendMediaFileThumbSize); + : st::attachPreviewThumbLayout.thumbSize); const auto isUnderTop = (position.y() > top); top = bottom + skip; return isUnderTop && (position.y() < bottom); @@ -304,7 +303,7 @@ void AlbumPreview::paintPhotos(Painter &p, QRect clip) const { for (const auto &thumb : _thumbs) { const auto bottom = top + thumb->photoHeight(); const auto guard = gsl::finally([&] { - top = bottom + st::sendMediaPreviewPhotoSkip; + top = bottom + st::sendMediaRowSkip; }); if (top >= clip.y() + clip.height()) { break; @@ -316,8 +315,8 @@ void AlbumPreview::paintPhotos(Painter &p, QRect clip) const { } void AlbumPreview::paintFiles(Painter &p, QRect clip) const { - const auto fileHeight = st::sendMediaFileThumbSize - + st::sendMediaFileThumbSkip; + const auto fileHeight = st::attachPreviewThumbLayout.thumbSize + + st::sendMediaRowSkip; const auto bottom = clip.y() + clip.height(); const auto from = std::clamp(clip.y() / fileHeight, 0, int(_thumbs.size())); const auto till = std::clamp((bottom + fileHeight - 1) / fileHeight, 0, int(_thumbs.size())); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp index 136a1db7e..fdbc47c77 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_thumbnail.cpp @@ -52,7 +52,8 @@ AlbumThumbnail::AlbumThumbnail( imageWidth, imageHeight)); - const auto idealSize = st::sendMediaFileThumbSize * style::DevicePixelRatio(); + const auto &st = st::attachPreviewThumbLayout; + const auto idealSize = st.thumbSize * style::DevicePixelRatio(); const auto fileThumbSize = (previewWidth > previewHeight) ? QSize(previewWidth * idealSize / previewHeight, idealSize) : QSize(idealSize, previewHeight * idealSize / previewWidth); @@ -61,13 +62,13 @@ AlbumThumbnail::AlbumThumbnail( fileThumbSize.width(), fileThumbSize.height(), Option::RoundedSmall | Option::RoundedAll, - st::sendMediaFileThumbSize, - st::sendMediaFileThumbSize + st.thumbSize, + st.thumbSize )); const auto availableFileWidth = st::sendMediaPreviewSize - - st::sendMediaFileThumbSkip - - st::sendMediaFileThumbSize + - st.thumbSize + - st.padding.right() // Right buttons. - st::sendBoxAlbumGroupButtonFile.width * 2 - st::sendBoxAlbumGroupEditInternalSkip * 2 @@ -124,8 +125,8 @@ void AlbumThumbnail::updateFileRow(int row) { _editMedia->show(); _deleteMedia->show(); - const auto fileHeight = st::sendMediaFileThumbSize - + st::sendMediaFileThumbSkip; + const auto fileHeight = st::attachPreviewThumbLayout.thumbSize + + st::sendMediaRowSkip; const auto top = row * fileHeight + st::sendBoxFileGroupSkipTop; const auto size = st::editMediaButtonSize; @@ -213,11 +214,12 @@ void AlbumThumbnail::paintInAlbum( p.drawPixmap(x, y, _albumImage); } if (_isVideo) { + const auto innerSize = st::msgFileLayout.thumbSize; const auto inner = QRect( - x + (geometry.width() - st::msgFileSize) / 2, - y + (geometry.height() - st::msgFileSize) / 2, - st::msgFileSize, - st::msgFileSize); + x + (geometry.width() - innerSize) / 2, + y + (geometry.height() - innerSize) / 2, + innerSize, + innerSize); { PainterHighQualityEnabler hq(p); p.setPen(Qt::NoPen); @@ -394,16 +396,15 @@ void AlbumThumbnail::paintPhoto(Painter &p, int left, int top, int outerWidth) { } void AlbumThumbnail::paintFile(Painter &p, int left, int top, int outerWidth) { - const auto textLeft = left - + st::sendMediaFileThumbSize - + st::sendMediaFileThumbSkip; + const auto &st = st::attachPreviewThumbLayout; + const auto textLeft = left + st.thumbSize + st.padding.right(); p.drawPixmap(left, top, _fileThumb); p.setFont(st::semiboldFont); p.setPen(st::historyFileNameInFg); p.drawTextLeft( textLeft, - top + st::sendMediaFileNameTop, + top + st.nameTop, outerWidth, _name, _nameWidth); @@ -411,7 +412,7 @@ void AlbumThumbnail::paintFile(Painter &p, int left, int top, int outerWidth) { p.setPen(st::mediaInFg); p.drawTextLeft( textLeft, - top + st::sendMediaFileStatusTop, + top + st.statusTop, outerWidth, _status, _statusWidth); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp index 220d65c1a..83cfc5ec5 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.cpp @@ -126,6 +126,34 @@ bool PreparedList::canAddCaption(bool sendingAlbum) const { return !hasFiles && !hasNotGrouped; } +bool PreparedList::hasGroupOption(bool slowmode) const { + if (slowmode || files.size() < 2) { + return false; + } + using Type = PreparedFile::AlbumType; + auto lastType = Type::None; + for (const auto &file : files) { + if ((file.type == lastType) + || (file.type == Type::Video && lastType == Type::Photo) + || (file.type == Type::Photo && lastType == Type::Video) + || (file.type == Type::File && lastType == Type::Photo) + || (file.type == Type::Photo && lastType == Type::File)) { + if (lastType != Type::None) { + return true; + } + } + lastType = file.type; + } + return false; +} + +bool PreparedList::hasSendImagesAsPhotosOption(bool slowmode) const { + using Type = PreparedFile::AlbumType; + return slowmode + ? ((files.size() == 1) && (files.front().type == Type::Photo)) + : ranges::contains(files, Type::Photo, &PreparedFile::type); +} + int MaxAlbumItems() { return kMaxAlbumCount; } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h index 94146796d..ceceb9d71 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_prepare.h @@ -92,6 +92,9 @@ struct PreparedList { [[nodiscard]] bool canBeSentInSlowmodeWith( const PreparedList &other) const; + [[nodiscard]] bool hasGroupOption(bool slowmode) const; + [[nodiscard]] bool hasSendImagesAsPhotosOption(bool slowmode) const; + Error error = Error::None; QString errorData; std::vector files; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp index ab8baddfa..480044c6e 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_file_preview.cpp @@ -32,10 +32,10 @@ SingleFilePreview::SingleFilePreview( _editMedia->setIconOverride(&st::sendBoxAlbumGroupEditButtonIconFile); _deleteMedia->setIconOverride(&st::sendBoxAlbumGroupDeleteButtonIconFile); - const auto h = _fileThumb.isNull() - ? st::msgFileSize - : st::sendMediaFileThumbSize; - resize(width(), h); + const auto &st = _fileThumb.isNull() + ? st::attachPreviewLayout + : st::attachPreviewThumbLayout; + resize(width(), st.thumbSize); } SingleFilePreview::~SingleFilePreview() = default; @@ -57,10 +57,10 @@ void SingleFilePreview::prepareThumb(const QImage &preview) { auto originalWidth = preview.width(); auto originalHeight = preview.height(); - auto thumbWidth = st::sendMediaFileThumbSize; + const auto &st = st::attachPreviewThumbLayout; + auto thumbWidth = st.thumbSize; if (originalWidth > originalHeight) { - thumbWidth = (originalWidth * st::sendMediaFileThumbSize) - / originalHeight; + thumbWidth = (originalWidth * st.thumbSize) / originalHeight; } auto options = Images::Option::Smooth | Images::Option::RoundedSmall @@ -73,8 +73,8 @@ void SingleFilePreview::prepareThumb(const QImage &preview) { thumbWidth * style::DevicePixelRatio(), 0, options, - st::sendMediaFileThumbSize, - st::sendMediaFileThumbSize)); + st.thumbSize, + st.thumbSize)); } void SingleFilePreview::preparePreview(const PreparedFile &file) { @@ -117,9 +117,15 @@ void SingleFilePreview::preparePreview(const PreparedFile &file) { _name = ComposeNameString(filename, songTitle, songPerformer); _statusText = FormatSizeText(fileinfo.size()); } + const auto &st = _fileThumb.isNull() + ? st::attachPreviewLayout + : st::attachPreviewThumbLayout; + const auto nameleft = st.thumbSize + st.padding.right(); + const auto nametop = st.nameTop; + const auto statustop = st.statusTop; const auto availableFileWidth = st::sendMediaPreviewSize - - st::sendMediaFileThumbSkip - - st::sendMediaFileThumbSize + - st.thumbSize + - st.padding.right() // Right buttons. - st::sendBoxAlbumGroupButtonFile.width * 2 - st::sendBoxAlbumGroupEditInternalSkip * 2 @@ -139,21 +145,17 @@ void SingleFilePreview::paintEvent(QPaintEvent *e) { Painter p(this); auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(); - auto h = _fileThumb.isNull() ? st::msgFileSize : st::sendMediaFileThumbSize; - auto nameleft = 0, nametop = 0, statustop = 0; - if (_fileThumb.isNull()) { - nameleft = st::msgFileSize + st::msgFilePadding.right(); - nametop = st::msgFileNameTop - st::msgFilePadding.top(); - statustop = st::msgFileStatusTop - st::msgFilePadding.top(); - } else { - nameleft = st::sendMediaFileThumbSize + st::sendMediaFileThumbSkip; - nametop = st::sendMediaFileNameTop; - statustop = st::sendMediaFileStatusTop; - } + auto h = height(); + const auto &st = _fileThumb.isNull() + ? st::attachPreviewLayout + : st::attachPreviewThumbLayout; + const auto nameleft = st.thumbSize + st.padding.right(); + const auto nametop = st.nameTop; + const auto statustop = st.statusTop; const auto x = (width() - w) / 2, y = 0; if (_fileThumb.isNull()) { - QRect inner(style::rtlrect(x, y, st::msgFileSize, st::msgFileSize, width())); + QRect inner(style::rtlrect(x, y, st.thumbSize, st.thumbSize, width())); p.setPen(Qt::NoPen); p.setBrush(st::msgFileInBg); @@ -169,7 +171,7 @@ void SingleFilePreview::paintEvent(QPaintEvent *e) { : st::historyFileInDocument; icon.paintInCenter(p, inner); } else { - QRect rthumb(style::rtlrect(x, y, st::sendMediaFileThumbSize, st::sendMediaFileThumbSize, width())); + QRect rthumb(style::rtlrect(x, y, st.thumbSize, st.thumbSize, width())); p.drawPixmap(rthumb.topLeft(), _fileThumb); } p.setFont(st::semiboldFont); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp index 5af943389..199ca9844 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp @@ -240,7 +240,8 @@ void SingleMediaPreview::paintEvent(QPaintEvent *e) { p.drawPixmap(_previewLeft, 0, _preview); } if (_animated && !_gifPreview && !_lottiePreview) { - auto inner = QRect(_previewLeft + (_previewWidth - st::msgFileSize) / 2, (_previewHeight - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); + const auto innerSize = st::msgFileLayout.thumbSize; + auto inner = QRect(_previewLeft + (_previewWidth - innerSize) / 2, (_previewHeight - innerSize) / 2, innerSize, innerSize); p.setPen(Qt::NoPen); p.setBrush(st::msgDateImgBg); diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 4364fca61..8bc2f2200 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -472,16 +472,52 @@ historyCallStatusTop: 29px; historyCallStatusSkip: 4px; historyCallArrowPosition: point(-1px, 1px); +HistoryFileLayout { + padding: margins; + nameTop: pixels; + statusTop: pixels; + linkTop: pixels; + thumbSize: pixels; +} + +msgFileLayout: HistoryFileLayout { + padding: margins(14px, 10px, 11px, 10px); + nameTop: 16px; + statusTop: 37px; + thumbSize: 44px; +} +msgFileThumbLayout: HistoryFileLayout { + padding: margins(10px, 10px, 14px, 10px); + nameTop: 12px; + statusTop: 32px; + linkTop: 60px; + thumbSize: 72px; +} +msgFileLayoutGrouped: HistoryFileLayout(msgFileLayout) { + padding: margins(14px, 7px, 11px, 7px); + nameTop: 13px; + statusTop: 34px; +} +msgFileThumbLayoutGrouped: HistoryFileLayout(msgFileThumbLayout) { + padding: margins(10px, 7px, 14px, 7px); + nameTop: 9px; + statusTop: 29px; + linkTop: 57px; +} +attachPreviewLayout: HistoryFileLayout { + padding: margins(0px, 0px, 11px, 0px); + nameTop: 6px; + statusTop: 27px; + thumbSize: 44px; +} +attachPreviewThumbLayout: HistoryFileLayout { + padding: margins(0px, 0px, 10px, 0px); + nameTop: 7px; + statusTop: 37px; + thumbSize: 64px; +} + msgFileMenuSize: size(36px, 36px); -msgFileSize: 44px; -msgFilePadding: margins(14px, 12px, 11px, 12px); -msgFileThumbSize: 72px; -msgFileThumbPadding: margins(10px, 10px, 14px, 10px); -msgFileThumbNameTop: 12px; -msgFileThumbStatusTop: 32px; -msgFileThumbLinkTop: 60px; -msgFileNameTop: 16px; -msgFileStatusTop: 37px; msgFileMinWidth: 268px; msgFileTopMinus: 6px; @@ -653,7 +689,7 @@ historyGroupAboutHeaderSkip: 10px; historyGroupAboutTextSkip: 10px; historyGroupAboutSkip: 8px; -historyVideoDownloadSize: msgFileSize; +historyVideoDownloadSize: 44px; historyVideoMuteSize: 22px; historyVideoCancel: icon {{ "playlist_cancel", historyFileThumbIconFg }}; historyVideoCancelSelected: icon {{ "playlist_cancel", historyFileThumbIconFgSelected }}; diff --git a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp index c8737cd2f..6743916ea 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp @@ -245,12 +245,13 @@ void Generator::addAudioBubble(QVector waveform, int waveactive, QString wa auto width = st::msgFileMinWidth; auto tleft = 0, tright = 0; - tleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - tright = st::msgFileThumbPadding.left(); + const auto &st = st::msgFileLayout; + tleft = st.padding.left() + st.thumbSize + st.padding.right(); + tright = st.padding.left(); accumulate_max(width, tleft + st::normalFont->width(wavestatus) + skipBlock.width() + st::msgPadding.right()); accumulate_min(width, st::msgMaxWidth); - auto height = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); + auto height = st.padding.top() + st.thumbSize + st.padding.bottom(); addBubble(std::move(bubble), width, height, date, status); } @@ -763,13 +764,14 @@ void Generator::paintBubble(const Bubble &bubble) { _p->setFont(st::msgFont); bubble.text.draw(*_p, trect.x(), trect.y(), trect.width()); } else if (!bubble.waveform.isEmpty()) { - auto nameleft = x + st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); - auto nametop = y + st::msgFileNameTop; - auto nameright = st::msgFilePadding.left(); - auto statustop = y + st::msgFileStatusTop; - auto bottom = y + st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom(); + const auto &st = st::msgFileLayout; + auto nameleft = x + st.padding.left() + st.thumbSize + st.padding.right(); + auto nametop = y + st.nameTop; + auto nameright = st.padding.left(); + auto statustop = y + st.statusTop; + auto bottom = y + st.padding.top() + st.thumbSize + st.padding.bottom(); - auto inner = style::rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _rect.width()); + auto inner = style::rtlrect(x + st.padding.left(), y + st.padding.top(), st.thumbSize, st.thumbSize, _rect.width()); _p->setPen(Qt::NoPen); _p->setBrush(bubble.outbg ? st::msgFileOutBg[_palette] : st::msgFileInBg[_palette]); @@ -790,7 +792,7 @@ void Generator::paintBubble(const Bubble &bubble) { auto bar_count = qMin(availw / (st::msgWaveformBar + st::msgWaveformSkip), wf_size); auto max_value = 0; auto max_delta = st::msgWaveformMax - st::msgWaveformMin; - auto wave_bottom = y + st::msgFilePadding.top() + st::msgWaveformMax; + auto wave_bottom = y + st::msgFileLayout.padding.top() + st::msgWaveformMax; _p->setPen(Qt::NoPen); auto norm_value = uchar(31); for (auto i = 0, bar_x = 0, sum_i = 0; i < wf_size; ++i) {