Use HistoryView::Object in BottomInfo.

This commit is contained in:
John Preston 2021-12-07 17:44:15 +04:00
parent 57cb921bb9
commit 3aacd15ef2
4 changed files with 55 additions and 59 deletions

View file

@ -33,25 +33,17 @@ void BottomInfo::update(Data &&data, Context &&context, int availableWidth) {
_data = std::move(data); _data = std::move(data);
_context = std::move(context); _context = std::move(context);
layout(); layout();
if (!_size.isEmpty()) { if (width() > 0) {
resizeToWidth(std::min(optimalSize().width(), availableWidth)); resizeGetHeight(std::min(maxWidth(), availableWidth));
} }
} }
QSize BottomInfo::optimalSize() const {
return _optimalSize;
}
QSize BottomInfo::size() const {
return _size;
}
int BottomInfo::firstLineWidth() const { int BottomInfo::firstLineWidth() const {
if (_size.height() == _optimalSize.height()) { if (height() == minHeight()) {
return _size.width(); return width();
} }
const auto reactionsWidth = _reactions.maxWidth(); const auto reactionsWidth = _reactions.maxWidth();
const auto noReactionsWidth = _optimalSize.width() const auto noReactionsWidth = maxWidth()
- st::historyReactionsSkip - st::historyReactionsSkip
- reactionsWidth; - reactionsWidth;
return noReactionsWidth; return noReactionsWidth;
@ -63,24 +55,24 @@ TextState BottomInfo::textState(
auto result = TextState(item); auto result = TextState(item);
if (!_reactions.isEmpty()) { if (!_reactions.isEmpty()) {
const auto reactionsPosition = [&] { const auto reactionsPosition = [&] {
if (_size.height() == _optimalSize.height()) { if (height() == minHeight()) {
return QPoint(0, 0); return QPoint(0, 0);
} }
const auto available = _size.width(); const auto available = width();
const auto use = std::min(available, _reactions.maxWidth()); const auto use = std::min(available, _reactions.maxWidth());
return QPoint(_size.width() - use, st::msgDateFont->height); return QPoint(width() - use, st::msgDateFont->height);
}(); }();
const auto state = _reactions.getStateLeft( const auto state = _reactions.getStateLeft(
position - reactionsPosition, position - reactionsPosition,
std::min(_size.width(), _reactions.maxWidth()), std::min(width(), _reactions.maxWidth()),
_size.width()); width());
if (state.uponSymbol) { if (state.uponSymbol) {
result.link = _context.reactions; result.link = _context.reactions;
return result; return result;
} }
} }
const auto inTime = QRect( const auto inTime = QRect(
_size.width() - _dateWidth, width() - _dateWidth,
0, 0,
_dateWidth, _dateWidth,
st::msgDateFont->height st::msgDateFont->height
@ -106,7 +98,7 @@ void BottomInfo::paint(
const auto sti = context.imageStyle(); const auto sti = context.imageStyle();
const auto stm = context.messageStyle(); const auto stm = context.messageStyle();
auto right = position.x() + _size.width(); auto right = position.x() + width();
const auto firstLineBottom = position.y() + st::msgDateFont->height; const auto firstLineBottom = position.y() + st::msgDateFont->height;
if (_data.flags & Data::Flag::OutLayout) { if (_data.flags & Data::Flag::OutLayout) {
const auto &icon = (_data.flags & Data::Flag::Sending) const auto &icon = (_data.flags & Data::Flag::Sending)
@ -177,7 +169,7 @@ void BottomInfo::paint(
outerWidth); outerWidth);
} }
if (!_reactions.isEmpty()) { if (!_reactions.isEmpty()) {
if (_size.height() == _optimalSize.height()) { if (height() == minHeight()) {
_reactions.drawLeft( _reactions.drawLeft(
p, p,
position.x(), position.x(),
@ -185,11 +177,11 @@ void BottomInfo::paint(
_reactions.maxWidth(), _reactions.maxWidth(),
outerWidth); outerWidth);
} else { } else {
const auto available = _size.width(); const auto available = width();
const auto use = std::min(available, _reactions.maxWidth()); const auto use = std::min(available, _reactions.maxWidth());
_reactions.drawLeft( _reactions.drawLeft(
p, p,
position.x() + _size.width() - use, position.x() + width() - use,
position.y() + st::msgDateFont->height, position.y() + st::msgDateFont->height,
use, use,
outerWidth); outerWidth);
@ -197,20 +189,18 @@ void BottomInfo::paint(
} }
} }
int BottomInfo::resizeToWidth(int newWidth) { QSize BottomInfo::countCurrentSize(int newWidth) {
if (newWidth >= _optimalSize.width()) { if (newWidth >= maxWidth()) {
_size = _optimalSize; return optimalSize();
} else {
const auto reactionsWidth = _reactions.maxWidth();
const auto noReactionsWidth = _optimalSize.width()
- st::historyReactionsSkip
- reactionsWidth;
accumulate_min(newWidth, std::max(noReactionsWidth, reactionsWidth));
_size = QSize(
newWidth,
st::msgDateFont->height + _reactions.countHeight(newWidth));
} }
return _size.height(); const auto reactionsWidth = _reactions.maxWidth();
const auto noReactionsWidth = maxWidth()
- st::historyReactionsSkip
- reactionsWidth;
accumulate_min(newWidth, std::max(noReactionsWidth, reactionsWidth));
return QSize(
newWidth,
st::msgDateFont->height + _reactions.countHeight(newWidth));
} }
void BottomInfo::layout() { void BottomInfo::layout() {
@ -218,7 +208,7 @@ void BottomInfo::layout() {
layoutViewsText(); layoutViewsText();
layoutRepliesText(); layoutRepliesText();
layoutReactionsText(); layoutReactionsText();
countOptimalSize(); initDimensions();
} }
void BottomInfo::layoutDateText() { void BottomInfo::layoutDateText() {
@ -304,7 +294,7 @@ void BottomInfo::layoutReactionsText() {
Ui::NameTextOptions()); Ui::NameTextOptions());
} }
void BottomInfo::countOptimalSize() { QSize BottomInfo::countOptimalSize() {
auto width = 0; auto width = 0;
if (_data.flags & (Data::Flag::OutLayout | Data::Flag::Sending)) { if (_data.flags & (Data::Flag::OutLayout | Data::Flag::Sending)) {
width += st::historySendStateSpace; width += st::historySendStateSpace;
@ -323,7 +313,7 @@ void BottomInfo::countOptimalSize() {
if (!_reactions.isEmpty()) { if (!_reactions.isEmpty()) {
width += st::historyReactionsSkip + _reactions.maxWidth(); width += st::historyReactionsSkip + _reactions.maxWidth();
} }
_optimalSize = QSize(width, st::msgDateFont->height); return QSize(width, st::msgDateFont->height);
} }
BottomInfo::Data BottomInfoDataFromMessage(not_null<Message*> message) { BottomInfo::Data BottomInfoDataFromMessage(not_null<Message*> message) {

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "history/view/history_view_object.h"
#include "ui/text/text.h" #include "ui/text/text.h"
#include "base/flags.h" #include "base/flags.h"
@ -21,7 +22,7 @@ using PaintContext = Ui::ChatPaintContext;
class Message; class Message;
struct TextState; struct TextState;
class BottomInfo { class BottomInfo final : public Object {
public: public:
struct Data { struct Data {
enum class Flag { enum class Flag {
@ -50,8 +51,6 @@ public:
void update(Data &&data, Context &&context, int availableWidth); void update(Data &&data, Context &&context, int availableWidth);
[[nodiscard]] QSize optimalSize() const;
[[nodiscard]] QSize size() const;
[[nodiscard]] int firstLineWidth() const; [[nodiscard]] int firstLineWidth() const;
[[nodiscard]] TextState textState( [[nodiscard]] TextState textState(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
@ -66,20 +65,18 @@ public:
bool inverted, bool inverted,
const PaintContext &context) const; const PaintContext &context) const;
int resizeToWidth(int newWidth);
private: private:
void layout(); void layout();
void layoutDateText(); void layoutDateText();
void layoutViewsText(); void layoutViewsText();
void layoutRepliesText(); void layoutRepliesText();
void layoutReactionsText(); void layoutReactionsText();
void countOptimalSize();
QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override;
Data _data; Data _data;
Context _context; Context _context;
QSize _optimalSize;
QSize _size;
Ui::Text::String _authorEditedDate; Ui::Text::String _authorEditedDate;
Ui::Text::String _views; Ui::Text::String _views;
Ui::Text::String _replies; Ui::Text::String _replies;

View file

@ -610,7 +610,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
auto trect = inner.marginsRemoved(st::msgPadding); auto trect = inner.marginsRemoved(st::msgPadding);
if (_viewButton) { if (_viewButton) {
const auto belowInfo = _viewButton->belowMessageInfo(); const auto belowInfo = _viewButton->belowMessageInfo();
const auto infoHeight = _bottomInfo.size().height(); const auto infoHeight = _bottomInfo.height();
const auto heightMargins = QMargins(0, 0, 0, infoHeight); const auto heightMargins = QMargins(0, 0, 0, infoHeight);
_viewButton->draw( _viewButton->draw(
p, p,
@ -642,7 +642,8 @@ void Message::draw(Painter &p, const PaintContext &context) const {
trect.setHeight(trect.height() - entry->height()); trect.setHeight(trect.height() - entry->height());
} }
if (needDrawInfo) { if (needDrawInfo) {
trect.setHeight(trect.height() - (_bottomInfo.size().height() - st::msgDateFont->height)); trect.setHeight(trect.height()
- (_bottomInfo.height() - st::msgDateFont->height));
} }
paintText(p, trect, context); paintText(p, trect, context);
if (mediaDisplayed) { if (mediaDisplayed) {
@ -1219,7 +1220,7 @@ TextState Message::textState(
} }
if (_viewButton) { if (_viewButton) {
const auto belowInfo = _viewButton->belowMessageInfo(); const auto belowInfo = _viewButton->belowMessageInfo();
const auto infoHeight = _bottomInfo.size().height(); const auto infoHeight = _bottomInfo.height();
const auto heightMargins = QMargins(0, 0, 0, infoHeight); const auto heightMargins = QMargins(0, 0, 0, infoHeight);
if (_viewButton->getState( if (_viewButton->getState(
point, point,
@ -1765,7 +1766,7 @@ void Message::drawInfo(
break; break;
} }
const auto size = _bottomInfo.size(); const auto size = _bottomInfo.currentSize();
const auto dateX = infoRight - size.width(); const auto dateX = infoRight - size.width();
const auto dateY = infoBottom - size.height(); const auto dateY = infoBottom - size.height();
if (type == InfoDisplayType::Image) { if (type == InfoDisplayType::Image) {
@ -1807,7 +1808,7 @@ TextState Message::bottomInfoTextState(
infoBottom -= st::msgDateImgPadding.y(); infoBottom -= st::msgDateImgPadding.y();
break; break;
} }
const auto size = _bottomInfo.size(); const auto size = _bottomInfo.currentSize();
const auto infoLeft = infoRight - size.width(); const auto infoLeft = infoRight - size.width();
const auto infoTop = infoBottom - size.height(); const auto infoTop = infoBottom - size.height();
return _bottomInfo.textState( return _bottomInfo.textState(
@ -1828,12 +1829,13 @@ bool Message::isSignedAuthorElided() const {
} }
void Message::itemDataChanged() { void Message::itemDataChanged() {
const auto was = _bottomInfo.size(); const auto wasInfo = _bottomInfo.currentSize();
_bottomInfo.update( _bottomInfo.update(
BottomInfoDataFromMessage(this), BottomInfoDataFromMessage(this),
BottomInfoContextFromMessage(this), BottomInfoContextFromMessage(this),
width()); width());
if (was != _bottomInfo.size()) { const auto nowInfo = _bottomInfo.currentSize();
if (wasInfo != nowInfo) {
history()->owner().requestViewResize(this); history()->owner().requestViewResize(this);
} else { } else {
history()->owner().requestViewRepaint(this); history()->owner().requestViewRepaint(this);
@ -2488,7 +2490,7 @@ int Message::resizeContentGetHeight(int newWidth) {
} }
} }
} }
const auto bottomInfoHeight = _bottomInfo.resizeToWidth( const auto bottomInfoHeight = _bottomInfo.resizeGetHeight(
std::min( std::min(
_bottomInfo.optimalSize().width(), _bottomInfo.optimalSize().width(),
contentWidth - st::msgPadding.left() - st::msgPadding.right() - 2 * st::msgDateDelta.x())); contentWidth - st::msgPadding.left() - st::msgPadding.right() - 2 * st::msgDateDelta.x()));

View file

@ -23,16 +23,23 @@ public:
return _height; return _height;
} }
int maxWidth() const { [[nodiscard]] QSize optimalSize() const {
return { _maxWidth, _minHeight };
}
[[nodiscard]] QSize currentSize() const {
return { _width, _height };
}
[[nodiscard]] int maxWidth() const {
return _maxWidth; return _maxWidth;
} }
int minHeight() const { [[nodiscard]] int minHeight() const {
return _minHeight; return _minHeight;
} }
int width() const { [[nodiscard]] int width() const {
return _width; return _width;
} }
int height() const { [[nodiscard]] int height() const {
return _height; return _height;
} }