This commit is contained in:
John Preston 2015-05-20 22:29:08 +03:00
commit a46bb46e54
22 changed files with 620 additions and 283 deletions

View File

@ -774,6 +774,8 @@ historyToEndSkip: 10px;
activeFadeInDuration: 500;
activeFadeOutDuration: 3000;
msgRadius: 3px;
msgMaxWidth: 550px;
msgFont: font(fsize);
msgNameFont: font(fsize semibold);
@ -788,12 +790,11 @@ msgPadding: margins(13px, 7px, 13px, 8px);
msgMargin: margins(13px, 4px, 53px, 4px);
msgLnkPadding: 2px; // for media open / save links
msgBorder: #f0f0f0;
msgOutBG: #effdde;
msgInBG: #fff;
msgOutSelectBG: #b7dbdb;
msgInSelectBG: #c2dcf2; // #358cd4 with 30% opacity
msgOutSelectOverlay: #358cd44c;
msgInSelectOverlay: #358cd44c;
msgOutBg: #effdde;
msgInBg: #fff;
msgOutSelectBg: #b7dbdb;
msgInSelectBg: #c2dcf2; // #358cd4 with 30% opacity
msgSelectOverlay: #358cd44c;
msgStickerOverlay: #358cd47f;
msgOutServiceColor: #3a8e26;
msgInServiceColor: #0e7acd;
@ -818,10 +819,8 @@ msgInReplyBarColor: #2fa9e2;
msgOutReplyBarSelColor: #4da79f;
msgInReplyBarSelColor: #2fa9e2;
msgServiceSelectBG: #fff4;
msgServiceRadius: 2px;
msgServiceBG: #89a0b47f;
msgServiceBg: #89a0b47f;
msgServiceSelectBg: #bbc8d4a2;
msgServiceColor: #FFF;
msgServicePadding: margins(12px, 3px, 12px, 4px);
msgServiceMargin: margins(10px, 7px, 80px, 7px);
@ -851,6 +850,7 @@ msgImgDblCheckRect: sprite(300px, 65px, 20px, 20px);
msgDateImgDelta: 4px;
msgDateImgColor: #fff;
msgDateImgBg: #00000054;
msgDateImgSelectBg: #1c4a7187;
msgDateImgPadding: point(8px, 2px);
msgDateImgCheckSpace: 4px;
@ -862,23 +862,23 @@ defaultTextStyle: textStyle {
lnkOverFlags: font(fsize underline);
lnkColor: btnYesColor;
lnkDownColor: btnYesHover;
selectBG: msgInSelectBG;
selectOverlay: msgInSelectOverlay;
selectBg: msgInSelectBg;
selectOverlay: msgSelectOverlay;
lineHeight: 0px;
}
serviceTextStyle: textStyle(defaultTextStyle) {
lnkColor: msgServiceColor;
lnkDownColor: msgServiceColor;
selectBG: msgServiceSelectBG;
selectOverlay: msgServiceSelectBG;
selectBg: msgServiceSelectBg;
selectOverlay: msgServiceSelectBg;
}
inTextStyle: textStyle(defaultTextStyle) {
selectBG: msgInSelectBG;
selectOverlay: msgInSelectOverlay;
selectBg: msgInSelectBg;
selectOverlay: msgSelectOverlay;
}
outTextStyle: textStyle(defaultTextStyle) {
selectBG: msgOutSelectBG;
selectOverlay: msgOutSelectOverlay;
selectBg: msgOutSelectBg;
selectOverlay: msgSelectOverlay;
}
medviewSaveAsTextStyle: textStyle(defaultTextStyle) {
lnkColor: #91d9ff;
@ -1177,10 +1177,9 @@ btnShareContact: flatButton(btnDefNext, btnDefBig) {
}
forwardWidth: 364px;
forwardRadius: 2px;
forwardMargins: margins(30px, 10px, 30px, 10px);
forwardFont: font(16px);
forwardBG: rgba(0, 0, 0, 76);
forwardBg: rgba(0, 0, 0, 76);
btnProfileCancel: flatButton(btnDefFlat, btnDefBig) {
color: #666d78;
overColor: #666d78;
@ -1618,7 +1617,6 @@ emojiPanSize: size(39px, 35px);
emojiPanFullSize: size(300px, 321px);
emojiPanDuration: 200;
emojiPanHover: #f0f4f7;
emojiPanRound: 2px;
emojiPanHeader: 42px;
emojiPanHeaderFont: font(fsize semibold);
@ -1638,7 +1636,6 @@ emojiSwitchEmoji: sprite(310px, 328px, 8px, 12px);
emojiSwitchColor: #42a8db;
stickerPanSize: size(55px, 55px);
stickerPanRound: 3px;
stickerPanPadding: 11px;
stickerPanDelete: sprite(123px, 132px, 12px, 12px);
stickerPanDeleteOpacity: 0.5;
@ -1730,11 +1727,16 @@ mvDocLink: linkButton(btnDefLink) {
mvDeltaFromLastAction: 5px;
mvSwipeDistance: 80px;
mvCaptionPadding: margins(18px, 10px, 18px, 10px);
mvCaptionMargin: size(11px, 11px);
mvCaptionRadius: 2px;
mvCaptionBg: #11111180;
mvCaptionFont: font(fsize);
medviewSaveMsgCheck: sprite(311px, 309px, 22px, 18px);
medviewSaveMsgFont: font(16px);
medviewSaveMsgPadding: margins(55px, 19px, 29px, 20px);
medviewSaveMsgCheckPos: point(23px, 21px);
medviewSaveMsgRadius: 3px;
medviewSaveMsgShowing: 200;
medviewSaveMsgShown: 2000;
medviewSaveMsgHiding: 2500;

View File

@ -20,7 +20,7 @@ textStyle {
lnkOverFlags: font;
lnkColor: color;
lnkDownColor: color;
selectBG: color;
selectBg: color;
selectOverlay: color;
lineHeight: number;
}

View File

@ -75,6 +75,9 @@ namespace {
QPixmap *sprite = 0, *emojis = 0, *emojisLarge = 0;
QPixmap *corners[RoundCornersCount][4] = { { 0 } };
QImage *cornersMask[4] = { 0 };
typedef QMap<uint64, QPixmap> EmojisMap;
EmojisMap mainEmojisMap;
QMap<int32, EmojisMap> otherEmojisMap;
@ -86,7 +89,8 @@ namespace {
typedef QHash<PhotoData*, LastPhotosList::iterator> LastPhotosMap;
LastPhotosMap lastPhotosMap;
style::color _msgServiceBG;
style::color _msgServiceBg;
style::color _msgServiceSelectBg;
style::color _historyScrollBarColor;
style::color _historyScrollBgColor;
style::color _historyScrollBarOverColor;
@ -934,7 +938,11 @@ namespace App {
WebPageData *feedWebPage(const MTPWebPage &webpage) {
switch (webpage.type()) {
case mtpc_webPage: return App::feedWebPage(webpage.c_webPage());
case mtpc_webPageEmpty: return App::webPage(webpage.c_webPageEmpty().vid.v);
case mtpc_webPageEmpty: {
WebPageData *page = App::webPage(webpage.c_webPageEmpty().vid.v);
if (page->pendingTill > 0) page->pendingTill = -1; // failed
return page;
} break;
case mtpc_webPagePending: return App::feedWebPage(webpage.c_webPagePending());
}
return 0;
@ -1572,6 +1580,34 @@ namespace App {
return 0;
}
void prepareCorners(RoundCorners index, int32 radius, const style::color &color, const style::color *shadow = 0, QImage *cors = 0) {
int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor();
QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4];
{
QPainter p(&rect);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillRect(QRect(0, 0, rect.width(), rect.height()), st::transparent->b);
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
p.setRenderHint(QPainter::HighQualityAntialiasing);
p.setPen(Qt::NoPen);
if (shadow) {
p.setBrush((*shadow)->b);
p.drawRoundedRect(0, s, r * 3, r * 3, r, r);
}
p.setBrush(color->b);
p.drawRoundedRect(0, 0, r * 3, r * 3, r, r);
}
if (!cors) cors = localCors;
cors[0] = rect.copy(0, 0, r, r);
cors[1] = rect.copy(r * 2, 0, r, r);
cors[2] = rect.copy(0, r * 2, r, r + (shadow ? s : 0));
cors[3] = rect.copy(r * 2, r * 2, r, r + (shadow ? s : 0));
for (int i = 0; i < 4; ++i) {
::corners[index][i] = new QPixmap(QPixmap::fromImage(cors[i], Qt::ColorOnly));
::corners[index][i]->setDevicePixelRatio(cRetinaFactor());
}
}
void initMedia() {
deinitMedia(false);
audioInit();
@ -1593,6 +1629,33 @@ namespace App {
::emojisLarge = new QPixmap(QLatin1String(EmojiNames[EIndex + 1]));
if (cRetina()) ::emojisLarge->setDevicePixelRatio(cRetinaFactor());
}
QImage mask[4];
prepareCorners(MaskCorners, st::msgRadius, st::white, 0, mask);
for (int i = 0; i < 4; ++i) {
::cornersMask[i] = new QImage(mask[i]);
::cornersMask[i]->convertToFormat(QImage::Format_ARGB32_Premultiplied);
::cornersMask[i]->setDevicePixelRatio(cRetinaFactor());
}
prepareCorners(BlackCorners, st::msgRadius, st::black);
prepareCorners(ServiceCorners, st::msgRadius, st::msgServiceBg);
prepareCorners(ServiceSelectedCorners, st::msgRadius, st::msgServiceSelectBg);
prepareCorners(SelectedOverlayCorners, st::msgRadius, st::msgSelectOverlay);
prepareCorners(DateCorners, st::msgRadius, st::msgDateImgBg);
prepareCorners(DateSelectedCorners, st::msgRadius, st::msgDateImgSelectBg);
prepareCorners(InShadowCorners, st::msgRadius, st::msgInShadow);
prepareCorners(InSelectedShadowCorners, st::msgRadius, st::msgInSelectShadow);
prepareCorners(ForwardCorners, st::msgRadius, st::emojiPanHover);
prepareCorners(MediaviewSaveCorners, st::msgRadius, st::emojiPanHover);
prepareCorners(EmojiHoverCorners, st::msgRadius, st::emojiPanHover);
prepareCorners(StickerHoverCorners, st::msgRadius, st::emojiPanHover);
prepareCorners(MessageInCorners, st::msgRadius, st::msgInBg, &st::msgInShadow);
prepareCorners(MessageInSelectedCorners, st::msgRadius, st::msgInSelectBg, &st::msgInSelectShadow);
prepareCorners(MessageOutCorners, st::msgRadius, st::msgOutBg, &st::msgOutShadow);
prepareCorners(MessageOutSelectedCorners, st::msgRadius, st::msgOutSelectBg, &st::msgOutSelectShadow);
prepareCorners(ButtonHoverCorners, st::msgRadius, st::mediaSaveButton.overBgColor, &st::msgInShadow);
}
void deinitMedia(bool completely) {
@ -1610,6 +1673,12 @@ namespace App {
::emojis = 0;
delete ::emojisLarge;
::emojisLarge = 0;
for (int32 j = 0; j < 4; ++j) {
for (int32 i = 0; i < RoundCornersCount; ++i) {
delete ::corners[i][j]; ::corners[i][j] = 0;
}
delete ::cornersMask[j]; ::cornersMask[j] = 0;
}
mainEmojisMap.clear();
otherEmojisMap.clear();
@ -1922,6 +1991,31 @@ namespace App {
}
}
QImage **cornersMask() {
return ::cornersMask;
}
QPixmap **corners(RoundCorners index) {
return ::corners[index];
}
void roundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, RoundCorners index, const style::color *sh) {
QPixmap **c = ::corners[index];
int32 cw = c[0]->width() / cIntRetinaFactor(), ch = c[0]->height() / cIntRetinaFactor();
if (w < 2 * cw || h < 2 * ch) return;
if (w > 2 * cw) {
p.fillRect(QRect(x + cw, y, w - 2 * cw, ch), bg->b);
p.fillRect(QRect(x + cw, y + h - ch, w - 2 * cw, ch), bg->b);
if (sh) p.fillRect(QRect(x + cw, y + h, w - 2 * cw, st::msgShadow), (*sh)->b);
}
if (h > 2 * ch) {
p.fillRect(QRect(x, y + ch, w, h - 2 * ch), bg->b);
}
p.drawPixmap(QPoint(x, y), *c[0]);
p.drawPixmap(QPoint(x + w - cw, y), *c[1]);
p.drawPixmap(QPoint(x, y + h - ch), *c[2]);
p.drawPixmap(QPoint(x + w - cw, y + h - ch), *c[3]);
}
void initBackground(int32 id, const QImage &p, bool nowrite) {
if (Local::readBackground()) return;
@ -2064,7 +2158,17 @@ namespace App {
components[maxtomin[0]] = max;
uchar r = uchar(components[0]), g = uchar(components[1]), b = uchar(components[2]);
_msgServiceBG = style::color(r, g, b, qRound(st::msgServiceBG->c.alphaF() * 0xFF));
float64 alpha = st::msgServiceBg->c.alphaF();
_msgServiceBg = style::color(r, g, b, qRound(alpha * 0xFF));
float64 alphaSel = alphaSel = st::msgServiceSelectBg->c.alphaF(), addSel = (1. - ((1. - alphaSel) / (1. - alpha))) * 0xFF;
uchar rsel = snap(qRound(((1. - alphaSel) * r + addSel) / alphaSel), 0, 0xFF);
uchar gsel = snap(qRound(((1. - alphaSel) * g + addSel) / alphaSel), 0, 0xFF);
uchar bsel = snap(qRound(((1. - alphaSel) * b + addSel) / alphaSel), 0, 0xFF);
_msgServiceSelectBg = style::color(r, g, b, qRound(alphaSel * 0xFF));
prepareCorners(ServiceCorners, st::msgRadius, _msgServiceBg);
prepareCorners(ServiceSelectedCorners, st::msgRadius, _msgServiceSelectBg);
uchar rScroll = uchar(componentsScroll[0]), gScroll = uchar(componentsScroll[1]), bScroll = uchar(componentsScroll[2]);
_historyScrollBarColor = style::color(rScroll, gScroll, bScroll, qRound(st::historyScroll.barColor->c.alphaF() * 0xFF));
@ -2077,8 +2181,12 @@ namespace App {
if (App::main()) App::main()->updateScrollColors();
}
style::color msgServiceBG() {
return _msgServiceBG;
style::color msgServiceBg() {
return _msgServiceBg;
}
style::color msgServiceSelectBg() {
return _msgServiceSelectBg;
}
style::color historyScrollBarColor() {

View File

@ -36,6 +36,31 @@ typedef QHash<AudioData*, HistoryItemsMap> AudioItems;
typedef QHash<DocumentData*, HistoryItemsMap> DocumentItems;
typedef QHash<WebPageData*, HistoryItemsMap> WebPageItems;
enum RoundCorners {
MaskCorners = 0x00, // for images
BlackCorners,
ServiceCorners,
ServiceSelectedCorners,
SelectedOverlayCorners,
DateCorners,
DateSelectedCorners,
ForwardCorners,
MediaviewSaveCorners,
EmojiHoverCorners,
StickerHoverCorners,
InShadowCorners, // for photos without bg
InSelectedShadowCorners,
MessageInCorners, // with shadow
MessageInSelectedCorners,
MessageOutCorners,
MessageOutSelectedCorners,
ButtonHoverCorners,
RoundCornersCount
};
namespace App {
Application *app();
Window *wnd();
@ -205,9 +230,17 @@ namespace App {
void stickersBox(const QString &name);
void openLocalUrl(const QString &url);
QImage **cornersMask();
QPixmap **corners(RoundCorners index);
void roundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, const style::color &bg, RoundCorners index, const style::color *sh = 0);
inline void roundRect(QPainter &p, const QRect &rect, const style::color &bg, RoundCorners index, const style::color *sh = 0) {
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, sh);
}
void initBackground(int32 id = DefaultChatBackground, const QImage &p = QImage(), bool nowrite = false);
style::color msgServiceBG();
style::color msgServiceBg();
style::color msgServiceSelectBg();
style::color historyScrollBarColor();
style::color historyScrollBgColor();
style::color historyScrollBarOverColor();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

After

Width:  |  Height:  |  Size: 215 KiB

View File

@ -147,8 +147,7 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) {
}
int32 x = (width() - w) / 2, y = st::boxPadding.top() * 2 + st::boxFont->height;
p.fillRect(QRect(x, y, w, h), st::msgOutBG->b);
p.fillRect(x, y + h, w, st::msgShadow, st::msgOutShadow->b);
App::roundRect(p, x, y, w, h, st::msgOutBg, MessageOutCorners, &st::msgOutShadow);
if (_thumbw) {
int32 rf(cIntRetinaFactor());
p.drawPixmap(QPoint(x + st::mediaPadding.left(), y + st::mediaPadding.top()), _thumb, QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));

View File

@ -144,7 +144,7 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
}
}
float64 coef = qMin((st::stickersSize.width() - st::stickerPanRound * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::stickerPanRound * 2) / float64(doc->dimensions.height()));
float64 coef = qMin((st::stickersSize.width() - st::msgRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::msgRadius * 2) / float64(doc->dimensions.height()));
if (coef > 1) coef = 1;
int32 w = qRound(coef * doc->dimensions.width()), h = qRound(coef * doc->dimensions.height());
if (w < 1) w = 1;

View File

@ -675,11 +675,9 @@ void EmojiColorPicker::drawVariant(Painter &p, int variant) {
QPoint w(st::dropdownDef.shadow.pxWidth() + st::emojiColorsPadding + variant * st::emojiPanSize.width() + (variant ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::dropdownDef.shadow.pxHeight() + st::emojiColorsPadding);
if (hover > 0) {
p.setOpacity(hover);
p.setBrush(st::emojiPanHover->b);
p.setPen(Qt::NoPen);
QPoint tl(w);
if (rtl()) tl.setX(width() - tl.x() - st::emojiPanSize.width());
p.drawRoundedRect(QRect(tl, st::emojiPanSize), st::emojiPanRound, st::emojiPanRound);
App::roundRect(p, QRect(tl, st::emojiPanSize), st::emojiPanHover, StickerHoverCorners);
p.setOpacity(1);
}
int esize = EmojiSizes[EIndex + 1];
@ -786,11 +784,9 @@ void EmojiPanInner::paintEvent(QPaintEvent *e) {
QPoint w(st::emojiPanPadding + j * st::emojiPanSize.width(), y + i * st::emojiPanSize.height());
if (hover > 0) {
p.setOpacity(hover);
p.setBrush(st::emojiPanHover->b);
p.setPen(Qt::NoPen);
QPoint tl(w);
if (rtl()) tl.setX(width() - tl.x() - st::emojiPanSize.width());
p.drawRoundedRect(QRect(tl, st::emojiPanSize), st::emojiPanRound, st::emojiPanRound);
App::roundRect(p, QRect(tl, st::emojiPanSize), st::emojiPanHover, StickerHoverCorners);
p.setOpacity(1);
}
p.drawPixmapLeft(w.x() + (st::emojiPanSize.width() - (_esize / cIntRetinaFactor())) / 2, w.y() + (st::emojiPanSize.height() - (_esize / cIntRetinaFactor())) / 2, width(), App::emojisLarge(), QRect(_emojis[c][index]->x * _esize, _emojis[c][index]->y * _esize, _esize, _esize));
@ -928,9 +924,9 @@ void EmojiPanInner::onShowPicker() {
int32 size = (c == tab) ? (sel - (sel % EmojiPanPerRow)) : _counts[c], rows = (size / EmojiPanPerRow) + ((size % EmojiPanPerRow) ? 1 : 0);
y += st::emojiPanHeader + (rows * st::emojiPanSize.height());
}
y -= _picker.height() - st::emojiPanRound;
y -= _picker.height() - st::msgRadius;
if (y < _top) {
y += _picker.height() - st::emojiPanRound + st::emojiPanSize.height() - st::emojiPanRound;
y += _picker.height() - st::msgRadius + st::emojiPanSize.height() - st::msgRadius;
}
int xmax = width() - _picker.width();
float64 coef = float64(sel % EmojiPanPerRow) / float64(EmojiPanPerRow - 1);
@ -1211,11 +1207,9 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
QPoint pos(st::stickerPanPadding + j * st::stickerPanSize.width(), y + i * st::stickerPanSize.height());
if (hover > 0) {
p.setOpacity(hover);
p.setBrush(st::emojiPanHover->b);
p.setPen(Qt::NoPen);
QPoint tl(pos);
if (rtl()) tl.setX(width() - tl.x() - st::stickerPanSize.width());
p.drawRoundedRect(QRect(tl, st::stickerPanSize), st::stickerPanRound, st::stickerPanRound);
App::roundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, StickerHoverCorners);
p.setOpacity(1);
}
@ -1236,7 +1230,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
}
}
float64 coef = qMin((st::stickerPanSize.width() - st::stickerPanRound * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::stickerPanRound * 2) / float64(sticker->dimensions.height()));
float64 coef = qMin((st::stickerPanSize.width() - st::msgRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::msgRadius * 2) / float64(sticker->dimensions.height()));
if (coef > 1) coef = 1;
int32 w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height());
if (w < 1) w = 1;
@ -2012,9 +2006,9 @@ void EmojiPan::onSwitch() {
hideAll();
_moveStart = getms();
a_toCoord = _stickersShown ? anim::ivalue(st::emojiPanFullSize.width(), 0) : anim::ivalue(-st::emojiPanFullSize.width(), 0);
a_toCoord = (_stickersShown != rtl()) ? anim::ivalue(st::emojiPanFullSize.width(), 0) : anim::ivalue(-st::emojiPanFullSize.width(), 0);
a_toAlpha = anim::fvalue(0, 1);
a_fromCoord = _stickersShown ? anim::ivalue(0, -st::emojiPanFullSize.width()) : anim::ivalue(0, st::emojiPanFullSize.width());
a_fromCoord = (_stickersShown != rtl()) ? anim::ivalue(0, -st::emojiPanFullSize.width()) : anim::ivalue(0, st::emojiPanFullSize.width());
a_fromAlpha = anim::fvalue(1, 0);
if (!animating()) anim::start(this);
@ -2110,7 +2104,7 @@ void MentionsInner::paintEvent(QPaintEvent *e) {
}
}
user->photo->load();
p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pix(st::mentionPhotoSize));
p.drawPixmap(st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), user->photo->pixRounded(st::mentionPhotoSize));
user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth);
p.setFont(st::mentionFont->f);

View File

@ -34,6 +34,11 @@ namespace {
StorageImages storageImages;
int64 globalAquiredSize = 0;
static const uint64 BlurredCacheSkip = 0x1000000000000000LLU;
static const uint64 ColoredCacheSkip = 0x2000000000000000LLU;
static const uint64 BlurredColoredCacheSkip = 0x3000000000000000LLU;
static const uint64 RoundedCacheSkip = 0x4000000000000000LLU;
}
bool Image::isNull() const {
@ -70,6 +75,29 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
return i.value();
}
const QPixmap &Image::pixRounded(int32 w, int32 h) const {
restore();
checkload();
if (w <= 0 || !width() || !height()) {
w = width();
} else if (cRetina()) {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
uint64 k = RoundedCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
QPixmap p(pixNoCache(w, h, true, false, true));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
globalAquiredSize += int64(p.width()) * p.height() * 4;
}
}
return i.value();
}
const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
restore();
checkload();
@ -80,10 +108,10 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
uint64 k = 0x1000000000000000LL | (uint64(w) << 32) | uint64(h);
uint64 k = BlurredCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
QPixmap p(pixBlurredNoCache(w, h));
QPixmap p(pixNoCache(w, h, true, true));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -103,7 +131,7 @@ const QPixmap &Image::pixColored(const style::color &add, int32 w, int32 h) cons
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
uint64 k = 0x2000000000000000LL | (uint64(w) << 32) | uint64(h);
uint64 k = ColoredCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
QPixmap p(pixColoredNoCache(add, w, h, true));
@ -126,7 +154,7 @@ const QPixmap &Image::pixBlurredColored(const style::color &add, int32 w, int32
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
uint64 k = 0x3000000000000000LL | (uint64(w) << 32) | uint64(h);
uint64 k = BlurredColoredCacheSkip | (uint64(w) << 32) | uint64(h);
Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
QPixmap p(pixBlurredColoredNoCache(add, w, h));
@ -139,7 +167,7 @@ const QPixmap &Image::pixBlurredColored(const style::color &add, int32 w, int32
return i.value();
}
const QPixmap &Image::pixSingle(int32 w, int32 h) const {
const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh) const {
restore();
checkload();
@ -155,7 +183,7 @@ const QPixmap &Image::pixSingle(int32 w, int32 h) const {
if (i != _sizesCache.cend()) {
globalAquiredSize -= int64(i->width()) * i->height() * 4;
}
QPixmap p(pixNoCache(w, h, true));
QPixmap p(pixNoCache(w, h, true, false, true, outerw, outerh));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -165,7 +193,7 @@ const QPixmap &Image::pixSingle(int32 w, int32 h) const {
return i.value();
}
const QPixmap &Image::pixBlurredSingle(int32 w, int32 h) const {
const QPixmap &Image::pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh) const {
restore();
checkload();
@ -175,13 +203,13 @@ const QPixmap &Image::pixBlurredSingle(int32 w, int32 h) const {
w *= cIntRetinaFactor();
h *= cIntRetinaFactor();
}
uint64 k = 0x1000000000000000LL | 0LL;
uint64 k = BlurredCacheSkip | 0LL;
Sizes::const_iterator i = _sizesCache.constFind(k);
if (i == _sizesCache.cend() || i->width() != w || (h && i->height() != h)) {
if (i != _sizesCache.cend()) {
globalAquiredSize -= int64(i->width()) * i->height() * 4;
}
QPixmap p(pixBlurredNoCache(w, h));
QPixmap p(pixNoCache(w, h, true, true, true, outerw, outerh));
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -309,6 +337,39 @@ yi += stride;
return img;
}
void imageRound(QImage &img) {
img.setDevicePixelRatio(cRetinaFactor());
img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
QImage **masks = App::cornersMask();
int32 w = masks[0]->width(), h = masks[0]->height();
int32 tw = img.width(), th = img.height();
uchar *bits = img.bits();
const uchar *c0 = masks[0]->constBits(), *c1 = masks[1]->constBits(), *c2 = masks[2]->constBits(), *c3 = masks[3]->constBits();
int32 s0 = 0, s1 = (tw - w) * 4, s2 = (th - h) * tw * 4, s3 = ((th - h + 1) * tw - w) * 4;
for (int32 i = 0; i < w; ++i) {
for (int32 j = 0; j < h; ++j) {
#define update(s, c) \
{ \
uint64 color = _blurGetColors(bits + s + (j * tw + i) * 4); \
color *= (c[(j * w + i) * 4 + 3] + 1); \
color = (color >> 8); \
bits[s + (j * tw + i) * 4] = color & 0xFF; \
bits[s + (j * tw + i) * 4 + 1] = (color >> 16) & 0xFF; \
bits[s + (j * tw + i) * 4 + 2] = (color >> 32) & 0xFF; \
bits[s + (j * tw + i) * 4 + 3] = (color >> 48) & 0xFF; \
}
update(s0, c0);
update(s1, c1);
update(s2, c2);
update(s3, c3);
#undef update
}
}
}
QImage imageColored(const style::color &add, QImage img) {
QImage::Format fmt = img.format();
if (fmt != QImage::Format_RGB32 && fmt != QImage::Format_ARGB32_Premultiplied) {
@ -330,35 +391,39 @@ QImage imageColored(const style::color &add, QImage img) {
return img;
}
QPixmap Image::pixNoCache(int32 w, int32 h, bool smooth) const {
restore();
loaded();
const QPixmap &p(pixData());
if (p.isNull()) {
return blank()->pix();
}
if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) return p;
if (h <= 0) {
return QPixmap::fromImage(p.toImage().scaledToWidth(w, smooth ? Qt::SmoothTransformation : Qt::FastTransformation), Qt::ColorOnly);
}
return QPixmap::fromImage(p.toImage().scaled(w, h, Qt::IgnoreAspectRatio, smooth ? Qt::SmoothTransformation : Qt::FastTransformation), Qt::ColorOnly);
}
QPixmap Image::pixBlurredNoCache(int32 w, int32 h) const {
QPixmap Image::pixNoCache(int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh) const {
restore();
loaded();
const QPixmap &p(pixData());
if (p.isNull()) return blank()->pix();
QImage img = imageBlur(p.toImage());
if (h <= 0) {
img = img.scaledToWidth(w, Qt::SmoothTransformation);
QImage img = p.toImage();
if (blurred) img = imageBlur(img);
if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) {
} else if (h <= 0) {
img = img.scaledToWidth(w, smooth ? Qt::SmoothTransformation : Qt::FastTransformation);
} else {
img = img.scaled(w, h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
img = img.scaled(w, h, Qt::IgnoreAspectRatio, smooth ? Qt::SmoothTransformation : Qt::FastTransformation);
}
if (outerw > 0 && outerh > 0) {
outerw *= cIntRetinaFactor();
outerh *= cIntRetinaFactor();
if (outerw != w || outerh != h) {
img.setDevicePixelRatio(cRetinaFactor());
QImage result(outerw, outerh, QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor());
{
QPainter p(&result);
if (w < outerw || h < outerh) {
p.fillRect(0, 0, result.width(), result.height(), st::black->b);
}
p.drawImage((result.width() - img.width()) / 2, (result.height() - img.height()) / 2, img);
}
img = result;
}
}
if (rounded) imageRound(img);
return QPixmap::fromImage(img, Qt::ColorOnly);
}

View File

@ -47,13 +47,13 @@ public:
return false;
}
const QPixmap &pix(int32 w = 0, int32 h = 0) const;
const QPixmap &pixRounded(int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const;
const QPixmap &pixColored(const style::color &add, int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurredColored(const style::color &add, int32 w = 0, int32 h = 0) const;
const QPixmap &pixSingle(int32 w = 0, int32 h = 0) const;
const QPixmap &pixBlurredSingle(int32 w = 0, int32 h = 0) const;
QPixmap pixNoCache(int32 w = 0, int32 h = 0, bool smooth = false) const;
QPixmap pixBlurredNoCache(int32 w, int32 h = 0) const;
const QPixmap &pixSingle(int32 w, int32 y, int32 outerw, int32 outerh) const;
const QPixmap &pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh) const;
QPixmap pixNoCache(int32 w = 0, int32 h = 0, bool smooth = false, bool blurred = false, bool rounded = false, int32 outerw = -1, int32 outerh = -1) const;
QPixmap pixColoredNoCache(const style::color &add, int32 w = 0, int32 h = 0, bool smooth = false) const;
QPixmap pixBlurredColoredNoCache(const style::color &add, int32 w, int32 h = 0) const;

View File

@ -1129,12 +1129,12 @@ public:
if ((selectFromStart && _parDirection == Qt::LeftToRight) || (selectTillEnd && _parDirection == Qt::RightToLeft)) {
if (x > _x) {
_p->fillRect(QRectF(_x.toReal(), _y + _yDelta, (x - _x).toReal(), _fontHeight), _textStyle->selectBG->b);
_p->fillRect(QRectF(_x.toReal(), _y + _yDelta, (x - _x).toReal(), _fontHeight), _textStyle->selectBg->b);
}
}
if ((selectTillEnd && _parDirection == Qt::LeftToRight) || (selectFromStart && _parDirection == Qt::RightToLeft)) {
if (x < _x + _wLeft) {
_p->fillRect(QRectF((x + _w - _wLeft).toReal(), _y + _yDelta, (_x + _wLeft - x).toReal(), _fontHeight), _textStyle->selectBG->b);
_p->fillRect(QRectF((x + _w - _wLeft).toReal(), _y + _yDelta, (_x + _wLeft - x).toReal(), _fontHeight), _textStyle->selectBg->b);
}
}
@ -1292,15 +1292,15 @@ public:
const QChar *chFrom = _str + currentBlock->from(), *chTo = chFrom + ((nextBlock ? nextBlock->from() : _t->_text.size()) - currentBlock->from());
if (_localFrom + si.position >= _selectedFrom) { // could be without space
if (chTo == chFrom || (chTo - 1)->unicode() != QChar::Space || _selectedTo >= (chTo - _str)) {
_p->fillRect(QRectF(x.toReal(), _y + _yDelta, si.width.toReal(), _fontHeight), _textStyle->selectBG->b);
_p->fillRect(QRectF(x.toReal(), _y + _yDelta, si.width.toReal(), _fontHeight), _textStyle->selectBg->b);
} else { // or with space
_p->fillRect(QRectF(glyphX.toReal(), _y + _yDelta, currentBlock->f_width().toReal(), _fontHeight), _textStyle->selectBG->b);
_p->fillRect(QRectF(glyphX.toReal(), _y + _yDelta, currentBlock->f_width().toReal(), _fontHeight), _textStyle->selectBg->b);
}
} else if (chTo > chFrom && (chTo - 1)->unicode() == QChar::Space && (chTo - 1 - _str) >= _selectedFrom) {
if (rtl) { // rtl space only
_p->fillRect(QRectF(x.toReal(), _y + _yDelta, (glyphX - x).toReal(), _fontHeight), _textStyle->selectBG->b);
_p->fillRect(QRectF(x.toReal(), _y + _yDelta, (glyphX - x).toReal(), _fontHeight), _textStyle->selectBg->b);
} else { // ltr space only
_p->fillRect(QRectF((x + currentBlock->f_width()).toReal(), _y + _yDelta, (si.width - currentBlock->f_width()).toReal(), _fontHeight), _textStyle->selectBG->b);
_p->fillRect(QRectF((x + currentBlock->f_width()).toReal(), _y + _yDelta, (si.width - currentBlock->f_width()).toReal(), _fontHeight), _textStyle->selectBg->b);
}
}
}
@ -1426,7 +1426,7 @@ public:
}
}
if (rtl) selX = x + itemWidth - (selX - x) - selWidth;
_p->fillRect(QRectF(selX.toReal(), _y + _yDelta, selWidth.toReal(), _fontHeight), _textStyle->selectBG->b);
_p->fillRect(QRectF(selX.toReal(), _y + _yDelta, selWidth.toReal(), _fontHeight), _textStyle->selectBg->b);
}
_p->drawTextItem(QPointF(x.toReal(), textY), gf);
@ -2243,6 +2243,21 @@ _startDir(other._startDir)
}
}
Text &Text::operator=(const Text &other) {
_minResizeWidth = other._minResizeWidth;
_maxWidth = other._maxWidth;
_minHeight = other._minHeight;
_text = other._text;
_font = other._font;
_blocks = TextBlocks(other._blocks.size());
_links = other._links;
_startDir = other._startDir;
for (int32 i = 0, l = _blocks.size(); i < l; ++i) {
_blocks[i] = other._blocks.at(i)->clone();
}
return *this;
}
void Text::setText(style::font font, const QString &text, const TextParseOptions &options) {
if (!_textStyle) _initDefault();
_font = font;

View File

@ -426,6 +426,7 @@ public:
Text(int32 minResizeWidth = QFIXED_MAX);
Text(style::font font, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false);
Text(const Text &other);
Text &operator=(const Text &other);
int32 countHeight(int32 width) const;
void setText(style::font font, const QString &text, const TextParseOptions &options = _defaultOptions);
@ -434,6 +435,10 @@ public:
void setLink(uint16 lnkIndex, const TextLinkPtr &lnk);
bool hasLinks() const;
bool hasSkipBlock() const {
return _blocks.isEmpty() ? false : _blocks.back()->type() == TextBlockSkip;
}
int32 maxWidth() const {
return _maxWidth.ceil().toInt();
}

View File

@ -1597,7 +1597,7 @@ void HistoryPhoto::initDimensions(const HistoryItem *parent) {
_minh += st::msgPadding.top() + st::msgNameFont->height;
}
if (!_caption.isEmpty()) {
_minh += _caption.minHeight();
_minh += st::webPagePhotoSkip + _caption.minHeight();
}
_minh += st::mediaPadding.bottom();
}
@ -1666,6 +1666,10 @@ const QString HistoryPhoto::inHistoryText() const {
return qsl("[ ") + lang(lng_in_dlg_photo) + qsl(" ]");
}
const Text &HistoryPhoto::captionForClone() const {
return _caption;
}
bool HistoryPhoto::hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width) const {
if (width < 0) width = w;
return (x >= 0 && y >= 0 && x < width && y < _height);
@ -1765,15 +1769,20 @@ void HistoryPhoto::updateFrom(const MTPMessageMedia &media) {
void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
const HistoryReply *reply = toHistoryReply(parent);
const HistoryForwarded *fwd = reply ? 0 : toHistoryForwarded(parent);
bool out = parent->out();
if (width < 0) width = w;
int skipx = 0, skipy = 0, height = _height;
if (reply || !_caption.isEmpty()) {
skipx = st::mediaPadding.left();
style::color bg(selected ? (parent->out() ? st::msgOutSelectBG : st::msgInSelectBG) : (parent->out() ? st::msgOutBG : st::msgInBG));
p.fillRect(QRect(0, 0, width, _height), bg->b);
style::color bg(selected ? (out ? st::msgOutSelectBg : st::msgInSelectBg) : (out ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
int replyFrom = 0, fwdFrom = 0;
if (!parent->out() && parent->history()->peer->chat) {
if (!out && parent->history()->peer->chat) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -1797,20 +1806,25 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
if (!_caption.isEmpty()) {
height -= st::webPagePhotoSkip + _caption.countHeight(width);
}
} else {
QPixmap **cors = App::corners(selected ? InSelectedShadowCorners : InShadowCorners);
int32 cw = cors[0]->width() / cIntRetinaFactor(), ch = cors[0]->height();
style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
p.fillRect(cw, _height, width - 2 * cw, st::msgShadow, shadow->b);
p.fillRect(0, _height - ch, cw, st::msgShadow, shadow->b);
p.fillRect(width - cw, _height - ch, cw, st::msgShadow, shadow->b);
p.drawPixmap(0, _height - ch + st::msgShadow, *cors[2]);
p.drawPixmap(width - cw, _height - ch + st::msgShadow, *cors[3]);
}
data->full->load(false, false);
bool out = parent->out();
bool full = data->full->loaded();
QPixmap pix;
if (full) {
pix = data->full->pixSingle(pixw, pixh);
pix = data->full->pixSingle(pixw, pixh, width, height);
} else {
pix = data->thumb->pixBlurredSingle(pixw, pixh);
pix = data->thumb->pixBlurredSingle(pixw, pixh, width, height);
}
if (pixw < width || pixh < height) {
p.fillRect(QRect(skipx, skipy, width, height), st::black->b);
}
p.drawPixmap(QPoint(skipx + (width - pixw) / 2, skipy + (height - pixh) / 2), pix);
p.drawPixmap(skipx, skipy, pix);
if (!full) {
uint64 dt = itemAnimations().animate(parent, getms());
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
@ -1833,10 +1847,8 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
}
if (selected) {
p.fillRect(skipx, skipy, width, height, textstyleCurrent()->selectOverlay->b);
App::roundRect(p, skipx, skipy, width, height, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
p.fillRect(0, _height, width + (skipx ? (st::mediaPadding.left() + st::mediaPadding.right()) : 0), st::msgShadow, shadow->b);
// date
QString time(parent->time());
@ -1850,10 +1862,8 @@ void HistoryPhoto::draw(QPainter &p, const HistoryItem *parent, bool selected, i
int32 dateW = skipx + width - dateX - st::msgDateImgDelta;
int32 dateH = skipy + height - dateY - st::msgDateImgDelta;
p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
if (selected) {
p.fillRect(dateX, dateY, dateW, dateH, textstyleCurrent()->selectOverlay->b);
}
App::roundRect(p, dateX, dateY, dateW, dateH, selected ? st::msgDateImgSelectBg : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
p.setFont(st::msgDateFont->f);
p.setPen(st::msgDateImgColor->p);
p.drawText(dateX + st::msgDateImgPadding.x(), dateY + st::msgDateImgPadding.y() + st::msgDateFont->ascent, time);
@ -1945,6 +1955,10 @@ HistoryVideo::HistoryVideo(const MTPDvideo &video, const QString &caption, Histo
, _dldDone(0)
, _uplDone(0)
{
if (!caption.isEmpty()) {
_caption.setText(st::msgFont, caption + textcmdSkipBlock(parent->timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), _historyTextOptions);
}
_size = formatDurationAndSizeText(data->duration, data->size);
if (!_openWithWidth) {
@ -1988,7 +2002,11 @@ void HistoryVideo::initDimensions(const HistoryItem *parent) {
}
_minh += st::msgServiceNameFont->height;
}
_height = _minh;
if (_caption.isEmpty()) {
_height = _minh;
} else {
_minh += st::webPagePhotoSkip + _caption.minHeight();
}
}
void HistoryVideo::regItem(HistoryItem *item) {
@ -2042,7 +2060,11 @@ void HistoryVideo::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, co
}
if (!out) { // draw Download / Save As button
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
int32 h = _height;
if (!_caption.isEmpty()) {
h -= st::webPagePhotoSkip + _caption.countHeight(width - _buttonWidth - st::mediaSaveDelta - st::mediaPadding.left() - st::mediaPadding.right());
}
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (h - skipy - btnh) / 2;
if (x >= btnx && y >= btny && x < btnx + btnw && y < btny + btnh) {
lnk = data->loader ? _cancell : _savel;
return;
@ -2067,10 +2089,14 @@ void HistoryVideo::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, co
}
}
if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
int32 tw = width - st::mediaPadding.left() - st::mediaPadding.right();
if (x >= st::mediaPadding.left() && y >= skipy + st::mediaPadding.top() && x < st::mediaPadding.left() + tw && y < skipy + st::mediaPadding.top() + st::mediaThumbSize && !data->loader && data->access) {
lnk = _openl;
return;
}
if (!_caption.isEmpty() && x >= st::mediaPadding.left() && x < st::mediaPadding.left() + tw && y >= skipy + st::mediaPadding.top() + st::mediaThumbSize + st::webPagePhotoSkip) {
return _caption.getState(lnk, inText, x - st::mediaPadding.left(), y - skipy - st::mediaPadding.top() - st::mediaThumbSize - st::webPagePhotoSkip, tw);
}
}
HistoryMedia *HistoryVideo::clone() const {
@ -2110,11 +2136,16 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
pressed = hovered && ((data->loader ? _cancell : _savel) == textlnkDown());
if (hovered && !pressed && textlnkDown()) hovered = false;
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
p.fillRect(QRect(btnx, btny, btnw, btnh), (selected ? st::msgInSelectBG : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor))->b);
int32 h = _height;
if (!_caption.isEmpty()) {
h -= st::webPagePhotoSkip + _caption.countHeight(width - _buttonWidth - st::mediaSaveDelta - st::mediaPadding.left() - st::mediaPadding.right());
}
style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
p.fillRect(btnx, btny + btnh, btnw, st::msgShadow, shadow->b);
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (h - skipy - btnh) / 2;
style::color bg(selected ? st::msgInSelectBg : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor));
style::color sh(selected ? st::msgInSelectShadow : st::msgInShadow);
RoundCorners cors(selected ? MessageInSelectedCorners : (hovered ? ButtonHoverCorners : MessageInCorners));
App::roundRect(p, btnx, btny, btnw, btnh, bg, cors, &sh);
p.setPen((hovered ? st::mediaSaveButton.overColor : st::mediaSaveButton.color)->p);
p.setFont(st::mediaSaveButton.font->f);
@ -2124,11 +2155,10 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
width -= btnw + st::mediaSaveDelta;
}
style::color bg(selected ? (out ? st::msgOutSelectBG : st::msgInSelectBG) : (out ? st::msgOutBG : st::msgInBG));
p.fillRect(QRect(0, 0, width, _height), bg->b);
style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
p.fillRect(0, _height, width, st::msgShadow, shadow->b);
style::color bg(selected ? (out ? st::msgOutSelectBg : st::msgInSelectBg) : (out ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
p.setFont(st::msgNameFont->f);
@ -2142,13 +2172,12 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
}
if (_thumbw) {
int32 rf(cIntRetinaFactor());
p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), data->thumb->pix(_thumbw), QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));
p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), data->thumb->pixSingle(_thumbw, 0, st::mediaThumbSize, st::mediaThumbSize));
} else {
p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), App::sprite(), (out ? st::mediaDocOutImg : st::mediaDocInImg));
}
if (selected) {
p.fillRect(st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, (out ? st::msgOutSelectOverlay : st::msgInSelectOverlay)->b);
App::roundRect(p, st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
@ -2198,6 +2227,11 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
}
p.setFont(st::msgDateFont->f);
if (!_caption.isEmpty()) {
p.setPen(st::black->p);
_caption.draw(p, st::mediaPadding.left(), skipy + st::mediaPadding.top() + st::mediaThumbSize + st::webPagePhotoSkip, width - st::mediaPadding.left() - st::mediaPadding.right());
}
style::color date(selected ? (out ? st::msgOutSelectDateColor : st::msgInSelectDateColor) : (out ? st::msgOutDateColor : st::msgInDateColor));
p.setPen(date->p);
@ -2218,6 +2252,32 @@ void HistoryVideo::draw(QPainter &p, const HistoryItem *parent, bool selected, i
}
}
int32 HistoryVideo::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
w = qMin(width, _maxw);
if (_caption.isEmpty()) return _height;
_height = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom();
if (!parent->out() && parent->history()->peer->chat) {
_height += st::msgPadding.top() + st::msgNameFont->height;
}
if (const HistoryReply *reply = toHistoryReply(parent)) {
_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
} else if (const HistoryForwarded *fwd = toHistoryForwarded(parent)) {
if (parent->out() || !parent->history()->peer->chat) {
_height += st::msgPadding.top();
}
_height += st::msgServiceNameFont->height;
}
if (!_caption.isEmpty()) {
int32 textw = w - st::mediaPadding.left() - st::mediaPadding.right();
if (!parent->out()) { // substract Download / Save As button
textw -= st::mediaSaveDelta + _buttonWidth;
}
_height += st::webPagePhotoSkip + _caption.countHeight(textw);
}
return _height;
}
ImagePtr HistoryVideo::replyPreview() {
if (data->replyPreview->isNull() && !data->thumb->isNull()) {
if (data->thumb->loaded()) {
@ -2309,11 +2369,11 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
if (hovered && !pressed && textlnkDown()) hovered = false;
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
p.fillRect(QRect(btnx, btny, btnw, btnh), (selected ? st::msgInSelectBG : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor))->b);
style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
p.fillRect(btnx, btny + btnh, btnw, st::msgShadow, shadow->b);
style::color bg(selected ? st::msgInSelectBg : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor));
style::color sh(selected ? st::msgInSelectShadow : st::msgInShadow);
RoundCorners cors(selected ? MessageInSelectedCorners : (hovered ? ButtonHoverCorners : MessageInCorners));
App::roundRect(p, btnx, btny, btnw, btnh, bg, cors, &sh);
p.setPen((hovered ? st::mediaSaveButton.overColor : st::mediaSaveButton.color)->p);
p.setFont(st::mediaSaveButton.font->f);
QString btnText(lang(data->loader ? lng_media_cancel : (already ? lng_media_open_with : lng_media_download)));
@ -2322,11 +2382,10 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
width -= btnw + st::mediaSaveDelta;
}
style::color bg(selected ? (out ? st::msgOutSelectBG : st::msgInSelectBG) : (out ? st::msgOutBG : st::msgInBG));
p.fillRect(QRect(0, 0, width, _height), bg->b);
style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
p.fillRect(0, _height, width, st::msgShadow, shadow->b);
style::color bg(selected ? (out ? st::msgOutSelectBg : st::msgInSelectBg) : (out ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
p.setFont(st::msgNameFont->f);
@ -2354,7 +2413,7 @@ void HistoryAudio::draw(QPainter &p, const HistoryItem *parent, bool selected, i
}
p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), App::sprite(), img);
if (selected) {
p.fillRect(st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay->b);
App::roundRect(p, st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
@ -2639,10 +2698,10 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
if (hovered && !pressed && textlnkDown()) hovered = false;
int32 btnw = _buttonWidth, btnh = st::mediaSaveButton.height, btnx = width - _buttonWidth, btny = skipy + (_height - skipy - btnh) / 2;
p.fillRect(QRect(btnx, btny, btnw, btnh), (selected ? st::msgInSelectBG : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor))->b);
style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
p.fillRect(btnx, btny + btnh, btnw, st::msgShadow, shadow->b);
style::color bg(selected ? st::msgInSelectBg : (hovered ? st::mediaSaveButton.overBgColor : st::mediaSaveButton.bgColor));
style::color sh(selected ? st::msgInSelectShadow : st::msgInShadow);
RoundCorners cors(selected ? MessageInSelectedCorners : (hovered ? ButtonHoverCorners : MessageInCorners));
App::roundRect(p, btnx, btny, btnw, btnh, bg, cors, &sh);
p.setPen((hovered ? st::mediaSaveButton.overColor : st::mediaSaveButton.color)->p);
p.setFont(st::mediaSaveButton.font->f);
@ -2652,11 +2711,10 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
width -= btnw + st::mediaSaveDelta;
}
style::color bg(selected ? (out ? st::msgOutSelectBG : st::msgInSelectBG) : (out ? st::msgOutBG : st::msgInBG));
p.fillRect(QRect(0, 0, width, _height), bg->b);
style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
p.fillRect(0, _height, width, st::msgShadow, shadow->b);
style::color bg(selected ? (out ? st::msgOutSelectBg : st::msgInSelectBg) : (out ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
p.setFont(st::msgNameFont->f);
@ -2669,13 +2727,12 @@ void HistoryDocument::draw(QPainter &p, const HistoryItem *parent, bool selected
fwd->drawForwardedFrom(p, st::mediaPadding.left(), fwdFrom, width - st::mediaPadding.left() - st::mediaPadding.right(), selected);
}
if (_thumbw) {
int32 rf(cIntRetinaFactor());
p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), data->thumb->pix(_thumbw), QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));
p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), data->thumb->pixSingle(_thumbw, 0, st::mediaThumbSize, st::mediaThumbSize));
} else {
p.drawPixmap(QPoint(st::mediaPadding.left(), skipy + st::mediaPadding.top()), App::sprite(), (out ? st::mediaDocOutImg : st::mediaDocInImg));
}
if (selected) {
p.fillRect(st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay->b);
App::roundRect(p, st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
@ -2980,10 +3037,8 @@ void HistorySticker::draw(QPainter &p, const HistoryItem *parent, bool selected,
int32 dateW = usex + usew - dateX - st::msgDateImgDelta;
int32 dateH = _height - dateY - st::msgDateImgDelta;
p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
if (selected) {
p.fillRect(dateX, dateY, dateW, dateH, textstyleCurrent()->selectOverlay->b);
}
App::roundRect(p, dateX, dateY, dateW, dateH, selected ? st::msgDateImgSelectBg : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
p.setFont(st::msgDateFont->f);
p.setPen(st::msgDateImgColor->p);
p.drawText(dateX + st::msgDateImgPadding.x(), dateY + st::msgDateImgPadding.y() + st::msgDateFont->ascent, time);
@ -3006,14 +3061,7 @@ void HistorySticker::draw(QPainter &p, const HistoryItem *parent, bool selected,
int32 rw = width - usew, rh = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
int32 rx = parent->out() ? 0 : usew, ry = _height - rh;
p.setPen(Qt::NoPen);
QRect r(rx, ry, rw, rh);
p.setBrush(App::msgServiceBG()->b);
p.drawRoundedRect(r, st::msgServiceRadius, st::msgServiceRadius);
if (selected) {
p.setBrush(textstyleCurrent()->selectOverlay->b);
p.drawRoundedRect(r, st::msgServiceRadius, st::msgServiceRadius);
}
App::roundRect(p, rx, ry, rw, rh, App::msgServiceBg(), selected ? ServiceSelectedCorners : ServiceCorners, &App::msgServiceSelectBg());
reply->drawReplyTo(p, rx + st::msgReplyPadding.left(), ry, rw - st::msgReplyPadding.left() - st::msgReplyPadding.right(), selected, true);
}
@ -3217,11 +3265,10 @@ void HistoryContact::draw(QPainter &p, const HistoryItem *parent, bool selected,
width = _maxw;
}
style::color bg(selected ? (out ? st::msgOutSelectBG : st::msgInSelectBG) : (out ? st::msgOutBG : st::msgInBG));
p.fillRect(QRect(0, 0, width, _height), bg->b);
style::color shadow(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
p.fillRect(0, _height, width, st::msgShadow, shadow->b);
style::color bg(selected ? (out ? st::msgOutSelectBg : st::msgInSelectBg) : (out ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
if (!parent->out() && parent->history()->peer->chat) {
p.setFont(st::msgNameFont->f);
@ -3234,7 +3281,10 @@ void HistoryContact::draw(QPainter &p, const HistoryItem *parent, bool selected,
fwd->drawForwardedFrom(p, st::mediaPadding.left(), fwdFrom, width - st::mediaPadding.left() - st::mediaPadding.right(), selected);
}
p.drawPixmap(st::mediaPadding.left(), skipy + st::mediaPadding.top(), (contact ? contact->photo : userDefPhoto(1))->pix(st::mediaThumbSize));
p.drawPixmap(st::mediaPadding.left(), skipy + st::mediaPadding.top(), (contact ? contact->photo : userDefPhoto(1))->pixRounded(st::mediaThumbSize));
if (selected) {
App::roundRect(p, st::mediaPadding.left(), skipy + st::mediaPadding.top(), st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
int32 twidth = width - tleft - st::mediaPadding.right();
@ -3307,9 +3357,10 @@ HistoryWebPage::HistoryWebPage(WebPageData *data) : HistoryMedia()
void HistoryWebPage::initDimensions(const HistoryItem *parent) {
if (data->pendingTill) {
_maxw = st::webPageLeft + st::linkFont->m.width(lang((data->pendingTill < 0) ? lng_attach_failed : lng_profile_loading));
_minh = st::replyHeight;
_height = _minh;
_maxw = _minh = _height = 0;
//_maxw = st::webPageLeft + st::linkFont->m.width(lang((data->pendingTill < 0) ? lng_attach_failed : lng_profile_loading));
//_minh = st::replyHeight;
//_height = _minh;
return;
}
if (!_openl && !data->url.isEmpty()) _openl = TextLinkPtr(new TextLink(data->url));
@ -3404,29 +3455,29 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width) const {
if (width < 0) width = w;
if (width < 1) return;
if (width < 1 || data->pendingTill) return;
int32 bottomSkip = 0;
if (!data->pendingTill) {
//if (!data->pendingTill) {
if (data->photo) {
bottomSkip += st::webPagePhotoSkip;
if (_asArticle || (st::webPageLeft + qMax(_pixw, int16(st::minPhotoSize)) + parent->timeWidth(true) > width)) {
bottomSkip += (st::msgDateFont->height - st::msgDateDelta.y());
}
}
}
//}
style::color bar = (selected ? (parent->out() ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (parent->out() ? st::msgOutReplyBarColor : st::msgInReplyBarColor));
style::color semibold = (selected ? (parent->out() ? st::msgOutServiceSelColor : st::msgInServiceSelColor) : (parent->out() ? st::msgOutServiceColor : st::msgInServiceColor));
style::color regular = (selected ? (parent->out() ? st::msgOutSelectDateColor : st::msgInSelectDateColor) : (parent->out() ? st::msgOutDateColor : st::msgInDateColor));
p.fillRect(0, 0, st::webPageBar, _height - bottomSkip, bar->b);
if (data->pendingTill) {
p.setFont(st::linkFont->f);
p.setPen(regular->p);
p.drawText(st::webPageLeft, (_minh - st::linkFont->height) / 2 + st::linkFont->ascent, lang(data->pendingTill < 0 ? lng_attach_failed : lng_profile_loading));
return;
}
//if (data->pendingTill) {
// p.setFont(st::linkFont->f);
// p.setPen(regular->p);
// p.drawText(st::webPageLeft, (_minh - st::linkFont->height) / 2 + st::linkFont->ascent, lang(data->pendingTill < 0 ? lng_attach_failed : lng_profile_loading));
// return;
//}
p.save();
p.translate(st::webPageLeft, 0);
@ -3440,19 +3491,13 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
bool full = data->photo->medium->loaded();
QPixmap pix;
if (full) {
pix = data->photo->medium->pixSingle(_pixw, _pixh);
pix = data->photo->medium->pixSingle(_pixw, _pixh, pixwidth, pixheight);
} else {
pix = data->photo->thumb->pixBlurredSingle(_pixw, _pixh);
pix = data->photo->thumb->pixBlurredSingle(_pixw, _pixh, pixwidth, pixheight);
}
if (_pixw < pixwidth || _pixh < pixheight) {
p.fillRect(QRect(width - pixwidth, 0, pixwidth, pixheight), st::black->b);
}
if (_pixw > pixwidth) {
p.drawPixmap(QRect(width - pixwidth, (pixheight - _pixh) / 2, pixwidth, _pixh), pix, QRect(cIntRetinaFactor() * (_pixw - pixwidth) / 2, 0, cIntRetinaFactor() * pixwidth, cIntRetinaFactor() * _pixh));
} else if (_pixh > pixheight) {
p.drawPixmap(QRect(width - pixwidth + (pixwidth - _pixw) / 2, 0, _pixw, pixheight), pix, QRect(0, cIntRetinaFactor() * (_pixh - pixheight) / 2, cIntRetinaFactor() * _pixw, cIntRetinaFactor() * pixheight));
} else {
p.drawPixmap(QPoint(width - pixwidth + (pixwidth - _pixw) / 2, (pixheight - _pixh) / 2), pix);
p.drawPixmap(width - pixwidth, 0, pix);
if (selected) {
App::roundRect(p, width - pixwidth, 0, pixwidth, pixheight, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
}
int32 articleLines = 5;
@ -3511,14 +3556,11 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
bool full = data->photo->full->loaded();
QPixmap pix;
if (full) {
pix = data->photo->full->pixSingle(_pixw, _pixh);
pix = data->photo->full->pixSingle(_pixw, _pixh, pixwidth, pixheight);
} else {
pix = data->photo->thumb->pixBlurredSingle(_pixw, _pixh);
pix = data->photo->thumb->pixBlurredSingle(_pixw, _pixh, pixwidth, pixheight);
}
if (_pixw < pixwidth || _pixh < pixheight) {
p.fillRect(QRect(0, 0, pixwidth, pixheight), st::black->b);
}
p.drawPixmap(QPoint((pixwidth - _pixw) / 2, (pixheight - _pixh) / 2), pix);
p.drawPixmap(0, 0, pix);
if (!full) {
uint64 dt = itemAnimations().animate(parent, getms());
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
@ -3541,7 +3583,7 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
}
if (selected) {
p.fillRect(0, 0, pixwidth, pixheight, textstyleCurrent()->selectOverlay->b);
App::roundRect(p, 0, 0, pixwidth, pixheight, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
if (data->type == WebPageVideo) {
@ -3556,10 +3598,8 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
int32 dateW = pixwidth - dateX - st::msgDateImgDelta;
int32 dateH = pixheight - dateY - st::msgDateImgDelta;
p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
if (selected) {
p.fillRect(dateX, dateY, dateW, dateH, textstyleCurrent()->selectOverlay->b);
}
App::roundRect(p, dateX, dateY, dateW, dateH, selected ? st::msgDateImgSelectBg : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
p.setFont(st::msgDateFont->f);
p.setPen(st::msgDateImgColor->p);
p.drawText(dateX + st::msgDateImgPadding.x(), dateY + st::msgDateImgPadding.y() + st::msgDateFont->ascent, _duration);
@ -4214,13 +4254,18 @@ void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selecte
int skipx = 0, skipy = 0, height = _height;
const HistoryReply *reply = toHistoryReply(parent);
const HistoryForwarded *fwd = toHistoryForwarded(parent);
bool out = parent->out();
if (reply || !_title.isEmpty() || !_description.isEmpty()) {
skipx = st::mediaPadding.left();
style::color bg(selected ? (parent->out() ? st::msgOutSelectBG : st::msgInSelectBG) : (parent->out() ? st::msgOutBG : st::msgInBG));
p.fillRect(QRect(0, 0, width, _height), bg->b);
style::color bg(selected ? (out ? st::msgOutSelectBg : st::msgInSelectBg) : (out ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (out ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out ? st::msgOutShadow : st::msgInShadow));
RoundCorners cors(selected ? (out ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out ? MessageOutCorners : MessageInCorners));
App::roundRect(p, 0, 0, width, _height, bg, cors, &sh);
int replyFrom = 0, fwdFrom = 0;
if (!parent->out() && parent->history()->peer->chat) {
if (!out && parent->history()->peer->chat) {
replyFrom = st::msgPadding.top() + st::msgNameFont->height;
fwdFrom = st::msgPadding.top() + st::msgNameFont->height;
skipy += replyFrom;
@ -4255,27 +4300,37 @@ void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selecte
skipy += st::webPagePhotoSkip;
}
height -= skipy + st::mediaPadding.bottom();
} else {
QPixmap **cors = App::corners(selected ? InSelectedShadowCorners : InShadowCorners);
int32 cw = cors[0]->width() / cIntRetinaFactor(), ch = cors[0]->height();
style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
p.fillRect(cw, _height, width - 2 * cw, st::msgShadow, shadow->b);
p.fillRect(0, _height - ch, cw, st::msgShadow, shadow->b);
p.fillRect(width - cw, _height - ch, cw, st::msgShadow, shadow->b);
p.drawPixmap(0, _height - ch + st::msgShadow, *cors[2]);
p.drawPixmap(width - cw, _height - ch + st::msgShadow, *cors[3]);
}
data->load();
bool out = parent->out();
QPixmap toDraw;
if (data && !data->thumb->isNull()) {
int32 w = data->thumb->width(), h = data->thumb->height();
QPixmap pix;
if (width * h == height * w || (w == convertScale(fullWidth()) && h == convertScale(fullHeight()))) {
p.drawPixmap(QPoint(skipx, skipy), data->thumb->pixSingle(width, height));
pix = data->thumb->pixSingle(width, height, width, height);
} else {
p.fillRect(QRect(skipx, skipy, width, height), st::black->b);
if (width * h > height * w) {
int32 nw = height * w / h;
p.drawPixmap(QPoint(skipx + (width - nw) / 2, skipy), data->thumb->pixSingle(nw, height));
pix = data->thumb->pixSingle(nw, height, width, height);
} else {
int32 nh = width * h / w;
p.drawPixmap(QPoint(skipx, skipy + (height - nh) / 2), data->thumb->pixSingle(width, nh));
pix = data->thumb->pixSingle(width, nh, width, height);
}
}
p.drawPixmap(QPoint(skipx, skipy), pix);
} else {
p.fillRect(QRect(skipx, skipy, width, height), st::black->b);
App::roundRect(p, skipx, skipy, width, height, st::black, BlackCorners);
}
if (data) {
switch (data->type) {
@ -4298,10 +4353,8 @@ void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selecte
}
}
if (selected) {
p.fillRect(skipx, skipy, width, height, textstyleCurrent()->selectOverlay->b);
App::roundRect(p, skipx, skipy, width, height, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
style::color shadow(selected ? st::msgInSelectShadow : st::msgInShadow);
p.fillRect(0, _height, width + (skipx ? (st::mediaPadding.left() + st::mediaPadding.right()) : 0), st::msgShadow, shadow->b);
// date
QString time(parent->time());
@ -4314,10 +4367,8 @@ void HistoryImageLink::draw(QPainter &p, const HistoryItem *parent, bool selecte
int32 dateW = skipx + width - dateX - st::msgDateImgDelta;
int32 dateH = skipy + height - dateY - st::msgDateImgDelta;
p.fillRect(dateX, dateY, dateW, dateH, st::msgDateImgBg->b);
if (selected) {
p.fillRect(dateX, dateY, dateW, dateH, textstyleCurrent()->selectOverlay->b);
}
App::roundRect(p, dateX, dateY, dateW, dateH, selected ? st::msgDateImgSelectBg : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners);
p.setFont(st::msgDateFont->f);
p.setPen(st::msgDateImgColor->p);
p.drawText(dateX + st::msgDateImgPadding.x(), dateY + st::msgDateImgPadding.y() + st::msgDateFont->ascent, time);
@ -4616,7 +4667,7 @@ void HistoryMessage::initMediaFromDocument(DocumentData *doc) {
void HistoryMessage::initDimensions(const QString &text) {
if (!_media || !text.isEmpty()) { // !justMedia()
if (_media) {
if (_media && _media->isDisplayed()) {
_text.setText(st::msgFont, text, _historyTextOptions);
} else {
_text.setText(st::msgFont, text + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), _historyTextOptions);
@ -4635,9 +4686,26 @@ void HistoryMessage::initDimensions(const HistoryItem *parent) {
_maxw += st::msgPadding.left() + st::msgPadding.right();
if (_media) {
_media->initDimensions(this);
int32 maxw = _media->maxWidth() + st::msgPadding.left() + st::msgPadding.right();
if (maxw > _maxw) _maxw = maxw;
_minh += st::msgPadding.bottom() + _media->minHeight();
if (_media->isDisplayed() && _text.hasSkipBlock()) {
QString was = HistoryMessage::selectedText(FullItemSel);
if (!was.isEmpty()) {
_text.setText(st::msgFont, was, _historyTextOptions); // without date skip
_textWidth = 0;
_textHeight = 0;
}
} else if (!_media->isDisplayed() && !_text.hasSkipBlock()) {
QString was = HistoryMessage::selectedText(FullItemSel);
if (!was.isEmpty()) {
_text.setText(st::msgFont, was + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), _historyTextOptions); // without date skip
_textWidth = 0;
_textHeight = 0;
}
}
if (_media->isDisplayed()) {
int32 maxw = _media->maxWidth() + st::msgPadding.left() + st::msgPadding.right();
if (maxw > _maxw) _maxw = maxw;
_minh += st::msgPadding.bottom() + _media->minHeight();
}
}
}
fromNameUpdated();
@ -4674,21 +4742,28 @@ HistoryMedia *HistoryMessage::getMedia(bool inOverview) const {
void HistoryMessage::setMedia(const MTPmessageMedia &media) {
if ((!_media || _media->isImageLink()) && media.type() == mtpc_messageMediaEmpty) return;
bool wasMedia = false;
bool mediaWasDisplayed = false;
if (_media) {
wasMedia = true;
mediaWasDisplayed = _media->isDisplayed();
delete _media;
_media = 0;
}
QString t;
initMedia(media, t);
if (_media && !wasMedia) {
if (_media && _media->isDisplayed() && !mediaWasDisplayed) {
QString was = HistoryMessage::selectedText(FullItemSel);
if (!was.isEmpty()) {
_text.setText(st::msgFont, was, _historyTextOptions); // without date skip
_textWidth = 0;
_textHeight = 0;
}
} else if (mediaWasDisplayed && (!_media || !_media->isDisplayed())) {
QString was = HistoryMessage::selectedText(FullItemSel);
if (!was.isEmpty()) {
_text.setText(st::msgFont, was + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), _historyTextOptions); // without date skip
_textWidth = 0;
_textHeight = 0;
}
}
initDimensions(0);
if (App::main()) App::main()->itemResized(this);
@ -4728,7 +4803,7 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
}
if (!out() && _history->peer->chat) {
p.drawPixmap(left, _height - st::msgMargin.bottom() - st::msgPhotoSize, _from->photo->pix(st::msgPhotoSize));
p.drawPixmap(left, _height - st::msgMargin.bottom() - st::msgPhotoSize, _from->photo->pixRounded(st::msgPhotoSize));
// width -= st::msgPhotoSkip;
left += st::msgPhotoSkip;
}
@ -4746,11 +4821,10 @@ void HistoryMessage::draw(QPainter &p, uint32 selection) const {
} else {
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
style::color bg(selected ? (out() ? st::msgOutSelectBG : st::msgInSelectBG) : (out() ? st::msgOutBG : st::msgInBG));
p.fillRect(r, bg->b);
style::color shadow(selected ? (out() ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out() ? st::msgOutShadow : st::msgInShadow));
p.fillRect(left, _height - st::msgMargin.bottom(), width, st::msgShadow, shadow->b);
style::color bg(selected ? (out() ? st::msgOutSelectBg : st::msgInSelectBg) : (out() ? st::msgOutBg : st::msgInBg));
style::color sh(selected ? (out() ? st::msgOutSelectShadow : st::msgInSelectShadow) : (out() ? st::msgOutShadow : st::msgInShadow));
RoundCorners cors(selected ? (out() ? MessageOutSelectedCorners : MessageInSelectedCorners) : (out() ? MessageOutCorners : MessageInCorners));
App::roundRect(p, r, bg, cors, &sh);
if (!out() && _history->peer->chat) {
p.setFont(st::msgNameFont->f);
@ -4822,7 +4896,7 @@ int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryIte
if (_media) _media->resize(_maxw - st::msgPadding.left() - st::msgPadding.right(), dontRecountText, this);
} else {
_height = _textHeight;
if (_media) _height += st::msgPadding.bottom() + _media->resize(nwidth, dontRecountText, this);
if (_media && _media->isDisplayed()) _height += st::msgPadding.bottom() + _media->resize(nwidth, dontRecountText, this);
}
if (!out() && _history->peer->chat) {
_height += st::msgNameFont->height;
@ -4906,7 +4980,7 @@ void HistoryMessage::getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y)
void HistoryMessage::getStateFromMessageText(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const QRect &r) const {
QRect trect(r.marginsAdded(-st::msgPadding));
TextLinkPtr medialnk;
if (_media) {
if (_media && _media->isDisplayed()) {
if (y >= trect.bottom() - _media->height() && y < trect.bottom()) {
_media->getState(lnk, inText, x - trect.left(), y + _media->height() - trect.bottom(), this);
return;
@ -4943,7 +5017,7 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
r.setTop(r.top() + st::msgNameFont->height);
}
QRect trect(r.marginsAdded(-st::msgPadding));
if (_media) {
if (_media && _media->isDisplayed()) {
trect.setBottom(trect.bottom() - _media->height() - st::msgPadding.bottom());
}
_text.getSymbol(symbol, after, upon, x - trect.x(), y - trect.y(), trect.width());
@ -5323,14 +5397,9 @@ void HistoryReply::drawReplyTo(QPainter &p, int32 x, int32 y, int32 w, bool sele
ImagePtr replyPreview = replyToMsg->getMedia()->replyPreview();
if (!replyPreview->isNull()) {
QRect to(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (replyPreview->width() == replyPreview->height()) {
p.drawPixmap(to.x(), to.y(), replyPreview->pix());
} else {
QRect from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width());
p.drawPixmap(to, replyPreview->pix(), from);
}
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height()));
if (selected) {
p.fillRect(to, textstyleCurrent()->selectOverlay->b);
App::roundRect(p, to, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
}
}
@ -5653,16 +5722,8 @@ void HistoryServiceMsg::draw(QPainter &p, uint32 selection) const {
left += (width - _maxw) / 2;
width = _maxw;
}
// QRect r(0, st::msgServiceMargin.top(), _history->width, height);
QRect r(left, st::msgServiceMargin.top(), width, height);
p.setBrush(App::msgServiceBG()->b);
p.setPen(Qt::NoPen);
// p.fillRect(r, App::msgServiceBG()->b);
p.drawRoundedRect(r, st::msgServiceRadius, st::msgServiceRadius);
if (selection == FullItemSel) {
p.setBrush(st::msgServiceSelectBG->b);
p.drawRoundedRect(r, st::msgServiceRadius, st::msgServiceRadius);
}
App::roundRect(p, left, st::msgServiceMargin.top(), width, height, App::msgServiceBg(), (selection == FullItemSel) ? ServiceSelectedCorners : ServiceCorners);
p.setBrush(Qt::NoBrush);
p.setPen(st::msgServiceColor->p);
p.setFont(st::msgServiceFont->f);

View File

@ -805,6 +805,9 @@ public:
virtual const QString inDialogsText() const = 0;
virtual const QString inHistoryText() const = 0;
virtual bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const = 0;
virtual bool isDisplayed() const {
return true;
}
virtual int32 countHeight(const HistoryItem *parent, int32 width = -1) const {
return height();
}
@ -873,6 +876,7 @@ public:
}
const QString inDialogsText() const;
const QString inHistoryText() const;
const Text &captionForClone() const;
bool hasPoint(int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
void getState(TextLinkPtr &lnk, bool &inText, int32 x, int32 y, const HistoryItem *parent, int32 width = -1) const;
HistoryMedia *clone() const;
@ -914,6 +918,7 @@ public:
void initDimensions(const HistoryItem *parent);
void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const;
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
HistoryMediaType type() const {
return MediaTypeVideo;
}
@ -1097,6 +1102,9 @@ public:
void initDimensions(const HistoryItem *parent);
void draw(QPainter &p, const HistoryItem *parent, bool selected, int32 width = -1) const;
bool isDisplayed() const {
return !data->pendingTill;
}
int32 resize(int32 width, bool dontRecountText = false, const HistoryItem *parent = 0);
HistoryMediaType type() const {
return MediaTypeWebPage;
@ -1252,7 +1260,9 @@ public:
QString notificationText() const;
void updateMedia(const MTPMessageMedia &media) {
if (_media) _media->updateFrom(media);
if (_media) {
_media->updateFrom(media);
}
}
void updateStickerEmoji();

View File

@ -1424,10 +1424,8 @@ void HistoryHider::paintEvent(QPaintEvent *e) {
p.setPen(st::black->p);
toText.drawElided(p, box.left() + (box.width() - toTextWidth) / 2, box.top() + st::boxPadding.top(), toTextWidth + 1);
} else {
p.setBrush(st::forwardBG->b);
p.setPen(Qt::NoPen);
int32 w = st::forwardMargins.left() + _chooseWidth + st::forwardMargins.right(), h = st::forwardMargins.top() + st::forwardFont->height + st::forwardMargins.bottom();
p.drawRoundedRect((width() - w) / 2, (height() - h) / 2, w, h, st::forwardRadius, st::forwardRadius);
App::roundRect(p, (width() - w) / 2, (height() - h) / 2, w, h, st::forwardBg, ForwardCorners);
p.setPen(st::white->p);
p.drawText(box, lang(lng_forward_choose), QTextOption(style::al_center));
@ -4096,12 +4094,7 @@ void HistoryWidget::drawFieldBackground(QPainter &p) {
ImagePtr replyPreview = _replyTo->getMedia()->replyPreview();
if (!replyPreview->isNull()) {
QRect to(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (replyPreview->width() == replyPreview->height()) {
p.drawPixmap(to.x(), to.y(), replyPreview->pix());
} else {
QRect from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width());
p.drawPixmap(to, replyPreview->pix(), from);
}
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height()));
}
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
}
@ -4230,9 +4223,7 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
style::font font(st::msgServiceFont);
int32 w = font->m.width(lang(lng_willbe_history)) + st::msgPadding.left() + st::msgPadding.right(), h = font->height + st::msgServicePadding.top() + st::msgServicePadding.bottom() + 2;
QRect tr((width() - w) / 2, (height() - _field.height() - 2 * st::sendPadding - h) / 2, w, h);
p.setPen(Qt::NoPen);
p.setBrush(App::msgServiceBG()->b);
p.drawRoundedRect(tr, st::msgServiceRadius, st::msgServiceRadius);
App::roundRect(p, tr, App::msgServiceBg(), ServiceCorners);
p.setPen(st::msgServiceColor->p);
p.setFont(font->f);

View File

@ -1013,6 +1013,7 @@ void MainWidget::stopAnimActive() {
}
void MainWidget::searchMessages(const QString &query) {
App::wnd()->hideMediaview();
dialogs.searchMessages(query);
if (!cWideMode()) onShowDialogs();
}
@ -2507,6 +2508,8 @@ void MainWidget::openLocalUrl(const QString &url) {
}
void MainWidget::openUserByName(const QString &username, bool toProfile) {
App::wnd()->hideMediaview();
UserData *user = App::userByName(username);
if (user) {
if (toProfile) {
@ -2520,10 +2523,12 @@ void MainWidget::openUserByName(const QString &username, bool toProfile) {
}
void MainWidget::joinGroupByHash(const QString &hash) {
App::wnd()->hideMediaview();
MTP::send(MTPmessages_CheckChatInvite(MTP_string(hash)), rpcDone(&MainWidget::inviteCheckDone, hash), rpcFail(&MainWidget::inviteCheckFail));
}
void MainWidget::stickersBox(const MTPInputStickerSet &set) {
App::wnd()->hideMediaview();
StickerSetBox *box = new StickerSetBox(set);
connect(box, SIGNAL(installed(uint64)), this, SLOT(onStickersInstalled(uint64)));
App::wnd()->showLayer(box);

View File

@ -41,6 +41,14 @@ namespace {
MediaView *_view;
};
TextParseOptions _captionTextOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
}
MediaView::MediaView() : TWidget(App::wnd()),
@ -282,6 +290,14 @@ void MediaView::updateControls() {
} else {
_leftNavVisible = _rightNavVisible = false;
}
if (!_caption.isEmpty()) {
int32 skipw = qMax(_dateNav.left() + _dateNav.width(), _headerNav.left() + _headerNav.width());
int32 maxw = qMin(qMax(width() - 2 * skipw - st::mvCaptionPadding.left() - st::mvCaptionPadding.right() - 2 * st::mvCaptionMargin.width(), int(st::msgMinWidth)), _caption.maxWidth());
int32 maxh = qMin(_caption.countHeight(maxw), int(height() / 4 - st::mvCaptionPadding.top() - st::mvCaptionPadding.bottom() - 2 * st::mvCaptionMargin.height()));
_captionRect = QRect((width() - maxw) / 2, height() - maxh - st::mvCaptionPadding.bottom() - st::mvCaptionMargin.height(), maxw, maxh);
} else {
_captionRect = QRect();
}
updateOver(mapFromGlobal(QCursor::pos()));
update();
}
@ -336,7 +352,7 @@ bool MediaView::animStep(float64 msp) {
} else {
a_cOpacity.update(dt, anim::linear);
}
QRegion toUpdate = QRegion() + (_over == OverLeftNav ? _leftNav : _leftNavIcon) + (_over == OverRightNav ? _rightNav : _rightNavIcon) + (_over == OverClose ? _closeNav : _closeNavIcon) + _saveNavIcon + _moreNavIcon + _headerNav + _nameNav + _dateNav;
QRegion toUpdate = QRegion() + (_over == OverLeftNav ? _leftNav : _leftNavIcon) + (_over == OverRightNav ? _rightNav : _rightNavIcon) + (_over == OverClose ? _closeNav : _closeNavIcon) + _saveNavIcon + _moreNavIcon + _headerNav + _nameNav + _dateNav + _captionRect.marginsAdded(st::mvCaptionPadding);
update(toUpdate);
if (dt < 1) result = true;
}
@ -641,7 +657,7 @@ void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) {
findCurrent();
}
displayPhoto(photo);
displayPhoto(photo, context);
preloadData(0);
activateControls();
}
@ -679,7 +695,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) {
loadBack();
}
}
displayPhoto(photo);
displayPhoto(photo, 0);
preloadData(0);
activateControls();
}
@ -722,11 +738,18 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
activateControls();
}
void MediaView::displayPhoto(PhotoData *photo) {
void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
_photo = photo;
_doc = 0;
_zoom = 0;
_caption = Text();
if (HistoryMessage *itemMsg = item ? item->toHistoryMessage() : 0) {
if (HistoryPhoto *photoMsg = dynamic_cast<HistoryPhoto*>(itemMsg->getMedia())) {
_caption.setText(st::mvCaptionFont, photoMsg->captionForClone().original(0, 0xFFFF), _captionTextOptions);
}
}
_zoomToScreen = 0;
MTP::clearLoaderPriorities();
_full = -1;
@ -774,6 +797,7 @@ void MediaView::displayPhoto(PhotoData *photo) {
void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) {
_doc = doc;
_caption = Text();
QString already = _doc->already(true);
if (_doc->sticker && !_doc->sticker->img->isNull() && _doc->sticker->img->loaded()) {
_currentGif.stop();
@ -966,12 +990,12 @@ void MediaView::paintEvent(QPaintEvent *e) {
_full = 1;
} else if (_full < 0 && _photo->medium->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->medium->pixBlurredNoCache(w, h);
_current = _photo->medium->pixNoCache(w, h, true, true);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_full = 0;
} else if (_current.isNull() && _photo->thumb->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->thumb->pixBlurredNoCache(w, h);
_current = _photo->thumb->pixNoCache(w, h, true, true);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
}
}
@ -1028,9 +1052,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
_saveMsgOpacity.update(qMin(progress, 1.), anim::linear);
if (_saveMsgOpacity.current() > 0) {
p.setOpacity(_saveMsgOpacity.current());
p.setBrush(st::medviewSaveMsg->b);
p.setPen(Qt::NoPen);
p.drawRoundedRect(_saveMsg, st::medviewSaveMsgRadius, st::medviewSaveMsgRadius);
App::roundRect(p, _saveMsg, st::medviewSaveMsg, MediaviewSaveCorners);
p.drawPixmap(_saveMsg.topLeft() + st::medviewSaveMsgCheckPos, App::sprite(), st::medviewSaveMsgCheck);
p.setPen(st::white->p);
@ -1216,6 +1238,23 @@ void MediaView::paintEvent(QPaintEvent *e) {
p.drawLine(_dateNav.left(), _dateNav.top() + st::mvFont->ascent + 1, _dateNav.right(), _dateNav.top() + st::mvFont->ascent + 1);
}
}
// caption
if (!_caption.isEmpty()) {
QRect outer(_captionRect.marginsAdded(st::mvCaptionPadding));
if (outer.intersects(r)) {
p.setOpacity(co);
p.setBrush(st::mvCaptionBg->b);
p.setPen(Qt::NoPen);
p.drawRoundedRect(outer, st::mvCaptionRadius, st::mvCaptionRadius);
if (_captionRect.intersects(r)) {
textstyleSet(&st::medviewSaveAsTextStyle);
p.setPen(st::white->p);
_caption.drawElided(p, _captionRect.x(), _captionRect.y(), _captionRect.width(), _captionRect.height() / st::mvCaptionFont->height);
textstyleRestore();
}
}
}
}
// static uint64 t = getms();
@ -1334,7 +1373,7 @@ void MediaView::moveToNext(int32 delta) {
if (HistoryItem *item = App::histItemById(_history->_overview[_overview][_index])) {
_msgid = item->id;
switch (item->getMedia()->type()) {
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo()); preloadData(delta); break;
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
case MediaTypeDocument: displayDocument(static_cast<HistoryDocument*>(item->getMedia())->document(), item); preloadData(delta); break;
case MediaTypeSticker: displayDocument(static_cast<HistorySticker*>(item->getMedia())->document(), item); preloadData(delta); break;
}
@ -1346,7 +1385,7 @@ void MediaView::moveToNext(int32 delta) {
} else if (_user) {
if (newIndex >= 0 && newIndex < _user->photos.size()) {
_index = newIndex;
displayPhoto(_user->photos[_index]);
displayPhoto(_user->photos[_index], 0);
preloadData(delta);
}
if (delta > 0 && _index > _user->photos.size() - MediaOverviewStartPerPage) {
@ -1405,7 +1444,10 @@ void MediaView::preloadData(int32 delta) {
void MediaView::mousePressEvent(QMouseEvent *e) {
updateOver(e->pos());
if (_menu || !_receiveMouse) return;
textlnkDown(textlnkOver());
if (textlnkDown() != textlnkOver()) {
textlnkDown(textlnkOver());
}
if (e->button() == Qt::LeftButton) {
_down = OverNone;
@ -1540,9 +1582,12 @@ bool MediaView::updateOverState(OverState newState) {
void MediaView::updateOver(QPoint pos) {
TextLinkPtr lnk;
bool inText;
if (_saveMsgStarted) {
if (_saveMsgStarted && _saveMsg.contains(pos)) {
_saveMsgText.getState(lnk, inText, pos.x() - _saveMsg.x() - st::medviewSaveMsgPadding.left(), pos.y() - _saveMsg.y() - st::medviewSaveMsgPadding.top(), _saveMsg.width() - st::medviewSaveMsgPadding.left() - st::medviewSaveMsgPadding.right());
}
} else if (_captionRect.contains(pos)) {
_caption.getState(lnk, inText, pos.x() - _captionRect.x(), pos.y() - _captionRect.y(), _captionRect.width());
}
// retina
if (pos.x() == width()) {
@ -1555,7 +1600,7 @@ void MediaView::updateOver(QPoint pos) {
if (lnk != textlnkOver()) {
textlnkOver(lnk);
setCursor((textlnkOver() || textlnkDown()) ? style::cur_pointer : style::cur_default);
updateImage();
update(QRegion(_saveMsg) + _captionRect);
}
if (_pressed || _dragging) return;

View File

@ -99,7 +99,7 @@ public slots:
private:
void displayPhoto(PhotoData *photo);
void displayPhoto(PhotoData *photo, HistoryItem *item);
void displayDocument(DocumentData *doc, HistoryItem *item);
void findCurrent();
void loadBack();
@ -124,6 +124,9 @@ private:
QString _dateText;
QString _headerText;
Text _caption;
QRect _captionRect;
uint64 _animStarted;
int32 _width, _x, _y, _w, _h, _xStart, _yStart;

View File

@ -688,7 +688,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
bool out = item->out();
int32 mw = media->maxWidth(), left = (out ? st::msgMargin.right() : st::msgMargin.left()) + (out && mw < w ? (w - mw) : 0);
if (!out && _hist->peer->chat) {
p.drawPixmap(left, media->countHeight(item, w) - st::msgPhotoSize, item->from()->photo->pix(st::msgPhotoSize));
p.drawPixmap(left, media->countHeight(item, w) - st::msgPhotoSize, item->from()->photo->pixRounded(st::msgPhotoSize));
left += st::msgPhotoSkip;
}
@ -720,9 +720,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
width = strwidth;
QRect r(left, st::msgServiceMargin.top(), width, height);
p.setBrush(App::msgServiceBG()->b);
p.setPen(Qt::NoPen);
p.drawRoundedRect(r, st::msgServiceRadius, st::msgServiceRadius);
App::roundRect(p, r, App::msgServiceBg(), ServiceCorners);
p.setBrush(Qt::NoBrush);
p.setPen(st::msgServiceColor->p);

View File

@ -810,9 +810,7 @@ void Window::hideLayer(bool fast) {
layerBG = 0;
}
}
if (_mediaView && !_mediaView->isHidden()) {
_mediaView->hide();
}
hideMediaview();
}
bool Window::hideInnerLayer() {
@ -843,10 +841,14 @@ void Window::layerHidden() {
layerBG->deleteLater();
}
layerBG = 0;
if (_mediaView && !_mediaView->isHidden()) _mediaView->hide();
hideMediaview();
setInnerFocus();
}
void Window::hideMediaview() {
if (_mediaView && !_mediaView->isHidden()) _mediaView->hide();
}
void Window::setInnerFocus() {
if (_passcode) {
_passcode->setInnerFocus();
@ -1691,7 +1693,7 @@ QImage Window::iconWithCounter(int size, int count, style::color bg, bool smallI
void Window::sendPaths() {
if (App::passcoded()) return;
if (_mediaView && !_mediaView->isHidden()) _mediaView->hide();
hideMediaview();
if (settings) {
hideSettings();
} else {

View File

@ -231,6 +231,7 @@ public:
void changingMsgId(HistoryItem *row, MsgId newId);
bool isActive(bool cached = true) const;
void hideMediaview();
public slots: