added webvideo and article layouts for inline bots

This commit is contained in:
John Preston 2015-12-31 15:57:11 +08:00
parent 5830e0f657
commit 945d9b1883
7 changed files with 337 additions and 31 deletions

View File

@ -1991,11 +1991,6 @@ stickerPreviewDuration: 150;
stickerPreviewBg: #FFFFFFB0;
stickerPreviewMin: 0.1;
inlineResultsLeft: 15px;
inlineResultsSkip: 3px;
inlineMediaHeight: 96px;
inlineResultsMinWidth: 64px;
verifiedCheckProfile: sprite(285px, 235px, 18px, 18px);
verifiedCheckProfilePos: point(7px, 6px);
verifiedCheck: sprite(285px, 221px, 14px, 14px);
@ -2346,9 +2341,21 @@ linksMaxWidth: 520px;
linksLetterFont: font(24px);
linksMargin: 5px;
linksBorder: 1px;
linksBorderColor: #eaeaea;
linksBorderFg: #eaeaea;
linksDateColor: #000;
linksDateMargin: 15px;
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
inlineResultsLeft: 15px;
inlineResultsSkip: 3px;
inlineMediaHeight: 96px;
inlineThumbSize: 64px;
inlineThumbSkip: 10px;
inlineDescriptionFg: #8a8a8a;
inlineRowMargin: 6px;
inlineRowBorder: linksBorder;
inlineRowBorderFg: linksBorderFg;
inlineResultsMinWidth: 64px;
inlineDurationMargin: 3px;

View File

@ -1216,6 +1216,7 @@ StickerPanInner::StickerPanInner() : TWidget()
, _showingSavedGifs(cShowingSavedGifs())
, _showingInlineItems(_showingSavedGifs)
, _lastScrolled(0)
, _inlineWithThumb(false)
, _selected(-1)
, _pressedSel(-1)
, _settings(this, lang(lng_stickers_you_have))
@ -1301,7 +1302,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
}
void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
InlinePaintContext context(getms(), false, _previewShown);
InlinePaintContext context(getms(), false, _previewShown, false);
int32 top = st::emojiPanHeader;
int32 fromx = rtl() ? (width() - r.x() - r.width()) : r.x(), tox = rtl() ? (width() - r.x()) : (r.x() + r.width());
@ -1310,6 +1311,7 @@ void StickerPanInner::paintInlineItems(Painter &p, const QRect &r) {
if (top >= r.top() + r.height()) break;
if (top + inlineRow.height > r.top()) {
int32 left = st::inlineResultsLeft;
if (row == rows - 1) context.lastRow = true;
for (int32 col = 0, cols = inlineRow.items.size(); col < cols; ++col) {
if (left >= tox) break;
@ -1750,9 +1752,9 @@ LayoutInlineItem *StickerPanInner::layoutPrepareInlineResult(InlineResult *resul
} else if (result->type == qstr("photo")) {
layout = new LayoutInlinePhoto(result, 0);
} else if (result->type == qstr("web_player_video")) {
// layout = new LayoutInlineWebVideo(result, 0);
layout = new LayoutInlineWebVideo(result);
} else if (result->type == qstr("article")) {
// layout = new LayoutInlineArticle(result, 0);
layout = new LayoutInlineArticle(result, _inlineWithThumb);
}
if (!layout) return 0;
@ -1927,6 +1929,16 @@ void StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &resu
}
_inlineRows.resize(untilrow);
if (_inlineRows.isEmpty()) {
_inlineWithThumb = false;
for (int32 i = until; i < count; ++i) {
if (!results.at(i)->thumb->isNull()) {
_inlineWithThumb = true;
break;
}
}
}
_inlineRows.reserve(count);
InlineRow row;
row.items.reserve(SavedGifsMaxPerRow);
@ -3072,6 +3084,10 @@ void EmojiPan::step_appearance(float64 ms, bool timer) {
void EmojiPan::hideStart() {
if (_removingSetId || s_inner.inlineResultsShown()) return;
hideAnimated();
}
void EmojiPan::hideAnimated() {
if (_cache.isNull()) {
QPixmap from = _fromCache, to = _toCache;
_fromCache = _toCache = QPixmap();
@ -3412,7 +3428,7 @@ void EmojiPan::onDelayedHide() {
void EmojiPan::inlineBotChanged() {
if (!_inlineBot) return;
if (!isHidden()) hideStart();
if (!isHidden()) hideAnimated();
if (_inlineRequestId) MTP::cancel(_inlineRequestId);
_inlineRequestId = 0;
@ -3572,7 +3588,7 @@ void EmojiPan::showInlineRows(bool newResults) {
s_inner.refreshInlineRows(_inlineBot, clear ? InlineResults() : i.value()->results, false);
if (newResults) s_scroll.scrollToY(0);
if (clear && !isHidden() && _stickersShown && s_inner.inlineResultsShown()) {
hideStart();
hideAnimated();
} else if (!clear) {
_hideTimer.stop();
if (!isHidden() || _hiding) {

View File

@ -430,6 +430,7 @@ private:
QString _inlineBotTitle;
uint64 _lastScrolled;
QTimer _updateInlineItems;
bool _inlineWithThumb;
typedef QVector<LayoutInlineItem*> InlineItems;
struct InlineRow {
@ -617,6 +618,7 @@ private:
bool _horizontal;
void leaveToChildEvent(QEvent *e);
void hideAnimated();
void updateSelected();
void updateIcons();

View File

@ -1031,6 +1031,9 @@ public:
_y = top;
_yFrom = yFrom + top;
_yTo = (yTo < 0) ? -1 : (yTo + top);
if (_elideLast) {
_yToElide = _yTo;
}
_selectedFrom = selectedFrom;
_selectedTo = selectedTo;
_wLeft = _w = w;
@ -1081,7 +1084,7 @@ public:
last_rBearing = _rb;
last_rPadding = b->f_rpadding();
_wLeft = _w - (b->f_width() - last_rBearing);
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
_wLeft -= _elideRemoveFromEnd;
}
@ -1135,7 +1138,7 @@ public:
}
int32 elidedLineHeight = qMax(_lineHeight, blockHeight);
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yTo);
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yToElide);
if (elidedLine) {
_lineHeight = elidedLineHeight;
} else if (f != j) {
@ -1154,7 +1157,7 @@ public:
last_rBearing = j->f_rbearing();
last_rPadding = j->rpadding;
_wLeft = _w - (j_width - last_rBearing);
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
_wLeft -= _elideRemoveFromEnd;
}
@ -1165,7 +1168,7 @@ public:
}
if (lpadding > 0) { // no words in this block, spaces only
int32 elidedLineHeight = qMax(_lineHeight, blockHeight);
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yTo);
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yToElide);
if (elidedLine) {
_lineHeight = elidedLineHeight;
}
@ -1179,7 +1182,7 @@ public:
last_rBearing = _rb;
last_rPadding = b->rpadding();
_wLeft = _w;
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
_wLeft -= _elideRemoveFromEnd;
}
@ -1189,7 +1192,7 @@ public:
}
int32 elidedLineHeight = qMax(_lineHeight, blockHeight);
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yTo);
bool elidedLine = _elideLast && (_y + elidedLineHeight >= _yToElide);
if (elidedLine) {
_lineHeight = elidedLineHeight;
}
@ -1202,7 +1205,7 @@ public:
last_rBearing = _rb;
last_rPadding = b->f_rpadding();
_wLeft = _w - (b->f_width() - last_rBearing);
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yTo)) {
if (_elideLast && _elideRemoveFromEnd > 0 && (_y + blockHeight >= _yToElide)) {
_wLeft -= _elideRemoveFromEnd;
}
@ -1301,7 +1304,7 @@ public:
}
ITextBlock *_endBlock = (_endBlockIter == _end) ? 0 : (*_endBlockIter);
bool elidedLine = _elideLast && _endBlock && (_y + _lineHeight >= _yTo);
bool elidedLine = _elideLast && _endBlock && (_y + _lineHeight >= _yToElide);
int blockIndex = _lineStartBlock;
ITextBlock *currentBlock = _t->_blocks[blockIndex];
@ -2409,7 +2412,7 @@ private:
int32 _elideRemoveFromEnd;
style::align _align;
QPen _originalPen;
int32 _yFrom, _yTo;
int32 _yFrom, _yTo, _yToElide;
uint16 _selectedFrom, _selectedTo;
const QChar *_str;

View File

@ -4345,9 +4345,8 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
_saveDraftStart = getms();
onDraftSave();
if (!_attachMention.isHidden()) _attachMention.hideStart();
onCheckMentionDropdown();
if (!_attachType.isHidden()) _attachType.hideStart();
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
if (replyTo < 0) cancelReply(lastKeyboardUsed);
if (_previewData && _previewData->pendingTill) previewCancel();
@ -6357,6 +6356,7 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
_history->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(_history->peer->id), MTPPeer(), MTPint(), MTP_int(bot ? peerToUser(bot->id) : 0), MTP_int(replyToId()), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(photo, MTP_string(result->caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread);
}
} else {
flags |= MTPDmessage::flag_entities;
if (result->noWebPage) {
sendFlags |= MTPmessages_SendMessage::flag_no_webpage;
}
@ -6373,9 +6373,8 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
_saveDraftStart = getms();
onDraftSave();
if (!_attachMention.isHidden()) _attachMention.hideStart();
onCheckMentionDropdown();
if (!_attachType.isHidden()) _attachType.hideStart();
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
_field.setFocus();
}

View File

@ -824,7 +824,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
QRect shadow(rtlrect(nameleft, 0, _width - nameleft, st::linksBorder, _width));
if (clip.intersects(shadow)) {
p.fillRect(clip.intersected(shadow), st::linksBorderColor);
p.fillRect(clip.intersected(shadow), st::linksBorderFg);
}
QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
@ -1242,7 +1242,7 @@ void LayoutOverviewLink::paint(Painter &p, const QRect &clip, uint32 selection,
}
if (clip.intersects(rtlrect(left, 0, w, st::linksBorder, _width))) {
p.fillRect(clip.intersected(rtlrect(left, 0, w, st::linksBorder, _width)), st::linksBorderColor);
p.fillRect(clip.intersected(rtlrect(left, 0, w, st::linksBorder, _width)), st::linksBorderFg);
}
}
@ -1394,7 +1394,7 @@ void LayoutInlineGif::paint(Painter &p, const QRect &clip, uint32 selection, con
QRect r(0, 0, _width, height);
if (animating) {
if (!_thumb.isNull()) const_cast<LayoutInlineGif*>(this)->_thumb = QPixmap();
if (!_thumb.isNull()) _thumb = QPixmap();
const InlinePaintContext *ctx = context->toInlinePaintContext();
t_assert(ctx);
p.drawPixmap(r.topLeft(), _gif->current(frame.width(), frame.height(), _width, height, ctx->paused ? 0 : context->ms));
@ -1532,7 +1532,7 @@ void LayoutInlineGif::prepareThumb(int32 width, int32 height, const QSize &frame
if (_doc && !_doc->thumb->isNull()) {
if (_doc->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
const_cast<LayoutInlineGif*>(this)->_thumb = _doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
_thumb = _doc->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
}
} else {
_doc->thumb->load();
@ -1540,7 +1540,7 @@ void LayoutInlineGif::prepareThumb(int32 width, int32 height, const QSize &frame
} else if (_result && !_result->thumb_url.isEmpty()) {
if (_result->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
const_cast<LayoutInlineGif*>(this)->_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
_thumb = _result->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), true, false, false, width, height);
}
} else {
_result->thumb->load();
@ -1804,3 +1804,233 @@ void LayoutInlinePhoto::content_forget() {
_result->forget();
}
}
LayoutInlineWebVideo::LayoutInlineWebVideo(InlineResult *result) : LayoutInlineItem(result, 0, 0)
, _send(new SendInlineItemLink())
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
if (_result->duration) {
_duration = formatDurationText(_result->duration);
}
}
void LayoutInlineWebVideo::initDimensions() {
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
int32 textWidth = _maxw - (_result->thumb->isNull() ? 0 : (st::inlineThumbSize + st::inlineThumbSkip));
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
_title.setText(st::semiboldFont, textOneLine(_result->title), titleOpts);
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
int32 descriptionLines = _result->thumb->isNull() ? 3 : (titleHeight > st::semiboldFont->height ? 1 : 2);
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
_description.setText(st::normalFont, _result->description, descriptionOpts);
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
_minh = _result->thumb->isNull() ? titleHeight + descriptionHeight : st::inlineThumbSize;
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
}
void LayoutInlineWebVideo::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
int32 left = 0;
if (!_result->thumb->isNull()) {
left = st::inlineThumbSize + st::inlineThumbSkip;
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
if (_thumb.isNull()) {
p.fillRect(rtlrect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize, _width), _result->thumb->isNull() ? st::black : st::overviewPhotoBg);
} else {
p.drawPixmapLeft(0, st::inlineRowMargin, _width, _thumb);
}
if (!_duration.isEmpty()) {
int32 durationTop = st::inlineRowMargin + st::inlineThumbSize - st::normalFont->height - st::inlineDurationMargin;
p.fillRect(rtlrect(0, durationTop - st::inlineDurationMargin, st::inlineThumbSize, st::normalFont->height + 2 * st::inlineDurationMargin, _width), st::msgDateImgBg);
p.setPen(st::white);
p.setFont(st::normalFont);
p.drawTextRight(_width - st::inlineThumbSize + st::inlineDurationMargin, durationTop, _width, _duration);
}
}
p.setPen(st::black);
_title.drawLeftElided(p, left, st::inlineRowMargin, _width - left, _width, 2);
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
p.setPen(st::inlineDescriptionFg);
int32 descriptionLines = _result->thumb->isNull() ? 3 : (titleHeight > st::semiboldFont->height ? 1 : 2);
_description.drawLeftElided(p, left, st::inlineRowMargin + titleHeight, _width - left, _width, descriptionLines);
const InlinePaintContext *ctx = context->toInlinePaintContext();
t_assert(ctx);
if (!ctx->lastRow) {
p.fillRect(rtlrect(left, _height - st::inlineRowBorder, _width - left, st::inlineRowBorder, _width), st::inlineRowBorderFg);
}
}
void LayoutInlineWebVideo::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
if (x >= 0 && x < _width && y >= 0 && y < _height) {
link = _send;
}
}
void LayoutInlineWebVideo::prepareThumb(int32 width, int32 height) const {
if (_result->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
int32 w = qMax(_result->thumb->width(), 1), h = qMax(_result->thumb->height(), 1);
if (w * height > h * width) {
if (height < h) {
w = w * height / h;
h = height;
}
} else {
if (width < w) {
h = h * width / w;
w = width;
}
}
_thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), true, false, false, width, height);
}
} else {
_result->thumb->load();
}
}
LayoutInlineArticle::LayoutInlineArticle(InlineResult *result, bool withThumb) : LayoutInlineItem(result, 0, 0)
, _send(new SendInlineItemLink())
, _url(result->url.isEmpty() ? 0 : linkFromUrl(result->url))
, _withThumb(withThumb)
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
QVector<QStringRef> parts = _result->url.splitRef('/');
if (!parts.isEmpty()) {
QStringRef domain = parts.at(0);
if (parts.size() > 2 && domain.endsWith(':') && parts.at(1).isEmpty()) { // http:// and others
domain = parts.at(2);
}
parts = domain.split('@').back().split('.');
if (parts.size() > 1) {
_letter = parts.at(parts.size() - 2).at(0).toUpper();
}
}
if (_letter.isEmpty() && !_result->title.isEmpty()) {
_letter = _result->title.at(0).toUpper();
}
}
void LayoutInlineArticle::initDimensions() {
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
int32 textWidth = _maxw - (_withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
_title.setText(st::semiboldFont, textOneLine(_result->title), titleOpts);
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
int32 descriptionLines = (_withThumb || _url) ? 2 : 3;
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
_description.setText(st::normalFont, _result->description, descriptionOpts);
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
_minh = titleHeight + descriptionHeight;
if (_url) _minh += st::normalFont->height;
if (_withThumb) _minh = qMax(_minh, int32(st::inlineThumbSize));
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
}
int32 LayoutInlineArticle::resizeGetHeight(int32 width) {
_width = qMin(width, _maxw);
if (_url) {
_urlText = _result->url;
_urlWidth = st::normalFont->width(_urlText);
if (_urlWidth > _width - st::inlineThumbSize - st::inlineThumbSkip) {
_urlText = st::normalFont->elided(_result->url, _width - st::inlineThumbSize - st::inlineThumbSkip);
_urlWidth = st::normalFont->width(_urlText);
}
}
_height = _minh;
return _height;
}
void LayoutInlineArticle::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
int32 left = 0;
if (_withThumb) {
left = st::inlineThumbSize + st::inlineThumbSkip;
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
QRect rthumb(rtlrect(0, st::inlineRowMargin, st::inlineThumbSize, st::inlineThumbSize, _width));
if (_thumb.isNull()) {
if (_result->thumb->isNull() && !_letter.isEmpty()) {
int32 index = (_letter.at(0).unicode() % 4);
style::color colors[] = { st::msgFileRedColor, st::msgFileYellowColor, st::msgFileGreenColor, st::msgFileBlueColor };
p.fillRect(rthumb, colors[index]);
if (!_letter.isEmpty()) {
p.setFont(st::linksLetterFont);
p.setPen(st::white);
p.drawText(rthumb, _letter, style::al_center);
}
} else {
p.fillRect(rthumb, st::overviewPhotoBg);
}
} else {
p.drawPixmapLeft(rthumb.topLeft(), _width, _thumb);
}
}
p.setPen(st::black);
_title.drawLeftElided(p, left, st::inlineRowMargin, _width - left, _width, 2);
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
p.setPen(st::inlineDescriptionFg);
int32 descriptionLines = (_withThumb || _url) ? 2 : 3;
_description.drawLeftElided(p, left, st::inlineRowMargin + titleHeight, _width - left, _width, descriptionLines);
if (_url) {
int32 descriptionHeight = qMin(_description.countHeight(_width - left), st::normalFont->height * descriptionLines);
p.drawTextLeft(left, st::inlineRowMargin + titleHeight + descriptionHeight, _width, _urlText, _urlWidth);
}
const InlinePaintContext *ctx = context->toInlinePaintContext();
t_assert(ctx);
if (!ctx->lastRow) {
p.fillRect(rtlrect(left, _height - st::inlineRowBorder, _width - left, st::inlineRowBorder, _width), st::inlineRowBorderFg);
}
}
void LayoutInlineArticle::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
if (x >= 0 && x < _width && y >= 0 && y < _height) {
if (_url) {
int32 left = st::inlineThumbSize + st::inlineThumbSkip;
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
int32 descriptionLines = 2;
int32 descriptionHeight = qMin(_description.countHeight(_width - left), st::normalFont->height * descriptionLines);
if (rtlrect(left, st::inlineRowMargin + titleHeight + descriptionHeight, _urlWidth, st::normalFont->height, _width).contains(x, y)) {
link = _url;
return;
}
}
link = _send;
}
}
void LayoutInlineArticle::prepareThumb(int32 width, int32 height) const {
if (_result->thumb->isNull()) return;
if (_result->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
int32 w = qMax(_result->thumb->width(), 1), h = qMax(_result->thumb->height(), 1);
if (w * height > h * width) {
if (height < h) {
w = w * height / h;
h = height;
}
} else {
if (width < w) {
h = h * width / w;
w = width;
}
}
_thumb = _result->thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), true, false, false, width, height);
}
} else {
_result->thumb->load();
}
}

View File

@ -477,12 +477,15 @@ private:
class InlinePaintContext : public PaintContext {
public:
InlinePaintContext(uint64 ms, bool selecting, bool paused) : PaintContext(ms, selecting), paused(paused) {
InlinePaintContext(uint64 ms, bool selecting, bool paused, bool lastRow)
: PaintContext(ms, selecting)
, paused(paused)
, lastRow(lastRow) {
}
virtual const InlinePaintContext *toInlinePaintContext() const {
return this;
}
bool paused;
bool paused, lastRow;
};
class LayoutInlineItem : public LayoutItem {
@ -629,3 +632,49 @@ private:
void prepareThumb(int32 width, int32 height, const QSize &frame) const;
};
class LayoutInlineWebVideo : public LayoutInlineItem {
public:
LayoutInlineWebVideo(InlineResult *result);
virtual void initDimensions();
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
private:
TextLinkPtr _send;
mutable QPixmap _thumb;
Text _title, _description;
QString _duration;
int32 _durationWidth;
void prepareThumb(int32 width, int32 height) const;
};
class LayoutInlineArticle : public LayoutInlineItem {
public:
LayoutInlineArticle(InlineResult *result, bool withThumb);
virtual void initDimensions();
virtual int32 resizeGetHeight(int32 width);
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
private:
TextLinkPtr _send, _url;
bool _withThumb;
mutable QPixmap _thumb;
Text _title, _description;
QString _letter, _urlText;
int32 _urlWidth;
void prepareThumb(int32 width, int32 height) const;
};