From cd700b16c67dc983130baec1446823ab87194735 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 19 Dec 2015 17:37:28 +0300 Subject: [PATCH] files and contacts in PhotoSendBox redesigned --- Telegram/SourceFiles/boxes/photosendbox.cpp | 123 +++++++++++--------- Telegram/SourceFiles/boxes/photosendbox.h | 14 ++- Telegram/SourceFiles/gui/images.cpp | 72 +++++++----- Telegram/SourceFiles/gui/images.h | 2 + Telegram/SourceFiles/history.cpp | 2 +- Telegram/SourceFiles/localimageloader.cpp | 1 + Telegram/SourceFiles/localimageloader.h | 1 + Telegram/SourceFiles/structs.cpp | 13 ++- Telegram/SourceFiles/structs.h | 2 + 9 files changed, 134 insertions(+), 96 deletions(-) diff --git a/Telegram/SourceFiles/boxes/photosendbox.cpp b/Telegram/SourceFiles/boxes/photosendbox.cpp index c38770a69..6c7885291 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.cpp +++ b/Telegram/SourceFiles/boxes/photosendbox.cpp @@ -29,17 +29,17 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxWideWidth) , _file(file) -, _thumbx(0) -, _thumby(0) -, _thumbw(0) -, _thumbh(0) -, _namew(0) -, _textw(0) , _caption(this, st::confirmCaptionArea, lang(lng_photo_caption)) , _compressedFromSettings(_file->type == PrepareAuto) , _compressed(this, lang(lng_send_image_compressed), _compressedFromSettings ? cCompressPastedImage() : true) , _send(this, lang(lng_send_button), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) +, _thumbx(0) +, _thumby(0) +, _thumbw(0) +, _thumbh(0) +, _statusw(0) +, _isImage(false) , _replyTo(_file->to.replyTo) , _confirmed(false) { connect(&_send, SIGNAL(clicked()), this, SLOT(onSend())); @@ -79,30 +79,23 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW _thumb.setDevicePixelRatio(cRetinaFactor()); } else { _compressed.hide(); - if (!_file->thumb.isNull()) { + if (_file->thumb.isNull()) { + _thumbw = 0; + } else { _thumb = _file->thumb; int32 tw = _thumb.width(), th = _thumb.height(); - if (_thumb.isNull() || !tw || !th) { - _thumbw = _thumbx = _thumby = 0; - } else if (tw > th) { - _thumbw = (tw * st::mediaThumbSize) / th; - _thumbx = (_thumbw - st::mediaThumbSize) / 2; - _thumby = 0; + if (tw > th) { + _thumbw = (tw * st::msgFileThumbSize) / th; } else { - _thumbw = st::mediaThumbSize; - _thumbx = 0; - _thumby = ((th * _thumbw) / tw - st::mediaThumbSize) / 2; + _thumbw = st::msgFileThumbSize; } - } - if (_thumbw) { - _thumb = QPixmap::fromImage(_thumb.toImage().scaledToWidth(_thumbw * cIntRetinaFactor(), Qt::SmoothTransformation), Qt::ColorOnly); - _thumb.setDevicePixelRatio(cRetinaFactor()); + _thumb = imagePix(_thumb.toImage(), _thumbw, 0, true, false, true, st::msgFileThumbSize, st::msgFileThumbSize); } - _name = _file->filename; - _namew = st::normalFont->width(_name); - _size = formatSizeText(_file->filesize); - _textw = qMax(_namew, st::normalFont->width(_size)); + _name.setText(st::semiboldFont, _file->filename, _textNameOptions); + _status = formatSizeText(_file->filesize); + _statusw = qMax(_name.maxWidth(), st::normalFont->width(_status)); + _isImage = fileIsImage(_file->filename, _file->filemime); } updateBoxSize(); _caption.setMaxLength(MaxPhotoCaption); @@ -115,16 +108,16 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW } PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) : AbstractBox(st::boxWideWidth) -, _thumbx(0) -, _thumby(0) -, _thumbw(0) -, _thumbh(0) -, _namew(0) -, _textw(0) , _caption(this, st::confirmCaptionArea, lang(lng_photo_caption)) , _compressed(this, lang(lng_send_image_compressed), true) , _send(this, lang(lng_send_button), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) +, _thumbx(0) +, _thumby(0) +, _thumbw(0) +, _thumbh(0) +, _statusw(0) +, _isImage(false) , _phone(phone) , _fname(fname) , _lname(lname) @@ -135,10 +128,9 @@ PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QSt _compressed.hide(); - _name = lng_full_name(lt_first_name, _fname, lt_last_name, _lname); - _namew = st::normalFont->width(_name); - _size = _phone; - _textw = qMax(_namew, st::normalFont->width(_size)); + _name.setText(st::semiboldFont, lng_full_name(lt_first_name, _fname, lt_last_name, _lname), _textNameOptions); + _status = _phone; + _statusw = qMax(_name.maxWidth(), st::normalFont->width(_status)); updateBoxSize(); prepare(); @@ -165,8 +157,10 @@ void PhotoSendBox::onCaptionResized() { void PhotoSendBox::updateBoxSize() { if (_file && _file->type == PreparePhoto) { setMaxHeight(st::boxPhotoPadding.top() + _thumbh + st::boxPhotoPadding.bottom() + st::boxPhotoCompressedPadding.top() + _compressed.height() + (_compressed.checked() ? (st::boxPhotoCompressedPadding.bottom() + _caption.height()) : 0) + st::boxButtonPadding.top() + _send.height() + st::boxButtonPadding.bottom()); + } else if (_thumbw) { + setMaxHeight(st::boxPhotoPadding.top() + st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() + st::boxPhotoPadding.bottom() + st::boxButtonPadding.top() + _send.height() + st::boxButtonPadding.bottom()); } else { - setMaxHeight(st::boxPhotoPadding.top() + st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom() + st::boxPhotoPadding.bottom() + st::boxButtonPadding.top() + _send.height() + st::boxButtonPadding.bottom()); + setMaxHeight(st::boxPhotoPadding.top() + st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() + st::boxPhotoPadding.bottom() + st::boxButtonPadding.top() + _send.height() + st::boxButtonPadding.bottom()); } } @@ -191,35 +185,54 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) { } p.drawPixmap(_thumbx, st::boxPhotoPadding.top(), _thumb); } else { - int32 w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), h = st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom(); - int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right(); - int32 twidth = w - tleft - st::mediaPadding.right(); - if (twidth > _textw) { - w -= (twidth - _textw); - twidth = _textw; + int32 w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(); + int32 h = _thumbw ? (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom()) : (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom()); + int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; + if (_thumbw) { + nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); + nametop = st::msgFileThumbNameTop; + nameright = st::msgFileThumbPadding.left(); + statustop = st::msgFileThumbStatusTop; + linktop = st::msgFileThumbLinkTop; + } else { + nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right(); + nametop = st::msgFileNameTop; + nameright = st::msgFilePadding.left(); + statustop = st::msgFileStatusTop; + } + int32 namewidth = w - nameleft - (_thumbw ? st::msgFileThumbPadding.left() : st::msgFilePadding.left()); + if (namewidth > _statusw) { + w -= (namewidth - _statusw); + namewidth = _statusw; } int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top(); 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)); + QRect rthumb(rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width())); + p.drawPixmap(rthumb.topLeft(), _thumb); } else if (_file) { - p.drawPixmap(QPoint(x + st::mediaPadding.left(), y + st::mediaPadding.top()), App::sprite(), st::mediaMusicOutImg); - } else { - p.drawPixmap(x + st::mediaPadding.left(), y + st::mediaPadding.top(), userDefPhoto(1)->pix(st::mediaThumbSize)); - } + QRect inner(rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width())); + p.setPen(Qt::NoPen); + p.setBrush(st::msgFileOutBg); - p.setFont(st::normalFont); + p.setRenderHint(QPainter::HighQualityAntialiasing); + p.drawEllipse(inner); + p.setRenderHint(QPainter::HighQualityAntialiasing, false); + + p.drawSpriteCenter(inner, _isImage ? st::msgFileOutImage : st::msgFileOutFile); + } else { + p.drawPixmapLeft(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), userDefPhoto(1)->pixRounded(st::msgFileSize)); + } + p.setFont(st::semiboldFont); p.setPen(st::black); - if (twidth < _namew) { - p.drawText(x + tleft, y + st::mediaPadding.top() + st::mediaNameTop + st::normalFont->ascent, st::normalFont->elided(_name, twidth)); - } else { - p.drawText(x + tleft, y + st::mediaPadding.top() + st::mediaNameTop + st::normalFont->ascent, _name); - } + _name.drawLeftElided(p, x + nameleft, y + nametop, namewidth, width()); - p.setPen(st::mediaOutFg); - p.drawText(x + tleft, y + st::mediaPadding.top() + st::mediaThumbSize - st::mediaDetailsShift - st::normalFont->descent, _size); + style::color status(st::mediaOutFg); + p.setFont(st::normalFont); + p.setPen(status); + p.drawTextLeft(x + nameleft, y + statustop, width(), _status); } } diff --git a/Telegram/SourceFiles/boxes/photosendbox.h b/Telegram/SourceFiles/boxes/photosendbox.h index 597c4496a..3d62b7d6e 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.h +++ b/Telegram/SourceFiles/boxes/photosendbox.h @@ -65,16 +65,22 @@ private: void updateBoxSize(); FileLoadResultPtr _file; - int32 _thumbx, _thumby, _thumbw, _thumbh; - QString _name, _size; - int32 _namew, _textw; + + QPixmap _thumb; + InputArea _caption; bool _compressedFromSettings; Checkbox _compressed; BoxButton _send, _cancel; - QPixmap _thumb; + + int32 _thumbx, _thumby, _thumbw, _thumbh; + Text _name; + QString _status; + int32 _statusw; + bool _isImage; QString _phone, _fname, _lname; + MsgId _replyTo; bool _confirmed; diff --git a/Telegram/SourceFiles/gui/images.cpp b/Telegram/SourceFiles/gui/images.cpp index 1ba8440fe..7a30eb6d5 100644 --- a/Telegram/SourceFiles/gui/images.cpp +++ b/Telegram/SourceFiles/gui/images.cpp @@ -396,6 +396,35 @@ QImage imageColored(const style::color &add, QImage img) { return img; } +QPixmap imagePix(QImage img, int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh) { + if (blurred) img = imageBlur(img); + if (w <= 0 || (w == img.width() && (h <= 0 || h == img.height()))) { + } else if (h <= 0) { + img = img.scaledToWidth(w, smooth ? Qt::SmoothTransformation : Qt::FastTransformation); + } else { + 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 * cIntRetinaFactor()), (result.height() - img.height()) / (2 * cIntRetinaFactor()), img); + } + img = result; + } + } + if (rounded) imageRound(img); + return QPixmap::fromImage(img, Qt::ColorOnly); +} + QPixmap Image::pixNoCache(int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh) const { restore(); loaded(); @@ -403,41 +432,22 @@ QPixmap Image::pixNoCache(int32 w, int32 h, bool smooth, bool blurred, bool roun const QPixmap &p(pixData()); if (p.isNull()) return blank()->pix(); - bool n = isNull(); - QImage img = p.toImage(); - if (!n || !(outerw > 0 && outerh > 0)) { - 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, smooth ? Qt::SmoothTransformation : Qt::FastTransformation); - } - } - if (outerw > 0 && outerh > 0) { + if (isNull() && outerw > 0 && outerh > 0) { outerw *= cIntRetinaFactor(); outerh *= cIntRetinaFactor(); - if (outerw != w || outerh != h || n) { - img.setDevicePixelRatio(cRetinaFactor()); - QImage result(outerw, outerh, QImage::Format_ARGB32_Premultiplied); - result.setDevicePixelRatio(cRetinaFactor()); - if (n) { - QPainter p(&result); - p.fillRect(0, 0, result.width(), result.height(), st::black->b); - } else { - QPainter p(&result); - if (w < outerw || h < outerh || n) { - p.fillRect(0, 0, result.width(), result.height(), st::black->b); - } - if (!n) { - p.drawImage((result.width() - img.width()) / (2 * cIntRetinaFactor()), (result.height() - img.height()) / (2 * cIntRetinaFactor()), img); - } - } - img = result; + + QImage result(outerw, outerh, QImage::Format_ARGB32_Premultiplied); + result.setDevicePixelRatio(cRetinaFactor()); + + { + QPainter p(&result); + p.fillRect(0, 0, result.width(), result.height(), st::black); } + + if (rounded) imageRound(result); + return QPixmap::fromImage(result, Qt::ColorOnly); } - if (rounded) imageRound(img); - return QPixmap::fromImage(img, Qt::ColorOnly); + return imagePix(p.toImage(), w, h, smooth, blurred, rounded, outerw, outerh); } QPixmap Image::pixColoredNoCache(const style::color &add, int32 w, int32 h, bool smooth) const { diff --git a/Telegram/SourceFiles/gui/images.h b/Telegram/SourceFiles/gui/images.h index 92f7115bc..be2576bfd 100644 --- a/Telegram/SourceFiles/gui/images.h +++ b/Telegram/SourceFiles/gui/images.h @@ -49,6 +49,8 @@ inline bool operator!=(const StorageImageLocation &a, const StorageImageLocation return !(a == b); } +QPixmap imagePix(QImage img, int32 w, int32 h, bool smooth, bool blurred, bool rounded, int32 outerw, int32 outerh); + class Image { public: diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index f901b6fd9..d00e5c990 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -4412,7 +4412,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r p.setFont(st::semiboldFont); p.setPen(st::black); if (namewidth < _namew) { - p.drawTextLeft(nameleft, nametop, width, st::normalFont->elided(_name, namewidth)); + p.drawTextLeft(nameleft, nametop, width, st::semiboldFont->elided(_name, namewidth)); } else { p.drawTextLeft(nameleft, nametop, width, _name, _namew); } diff --git a/Telegram/SourceFiles/localimageloader.cpp b/Telegram/SourceFiles/localimageloader.cpp index e81e1ea34..64ae1e592 100644 --- a/Telegram/SourceFiles/localimageloader.cpp +++ b/Telegram/SourceFiles/localimageloader.cpp @@ -393,6 +393,7 @@ void FileLoadTask::process() { _result->content = _content; _result->filename = filename; + _result->filemime = filemime; _result->setFileData(filedata); _result->thumbId = thumbId; diff --git a/Telegram/SourceFiles/localimageloader.h b/Telegram/SourceFiles/localimageloader.h index 669095409..52a72a0a0 100644 --- a/Telegram/SourceFiles/localimageloader.h +++ b/Telegram/SourceFiles/localimageloader.h @@ -190,6 +190,7 @@ struct FileLoadResult { QByteArray content; QString filename; + QString filemime; int32 filesize; UploadFileParts fileparts; QByteArray filemd5; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index eff4a02db..6d3afacc2 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -1080,12 +1080,10 @@ const FileLocation &DocumentData::location(bool check) { return _location; } -void DocumentData::recountIsImage() { - _isImage = false; - +bool fileIsImage(const QString &name, const QString &mime) { QString lowermime = mime.toLower(), namelower = name.toLower(); if (lowermime.startsWith(qstr("image/"))) { - _isImage = true; + return true; } else if (namelower.endsWith(qstr(".bmp")) || namelower.endsWith(qstr(".jpg")) || namelower.endsWith(qstr(".jpeg")) @@ -1096,8 +1094,13 @@ void DocumentData::recountIsImage() { || namelower.endsWith(qstr(".tif")) || namelower.endsWith(qstr(".psd")) || namelower.endsWith(qstr(".png"))) { - _isImage = true; + return true; } + return false; +} + +void DocumentData::recountIsImage() { + _isImage = fileIsImage(name, mime); } WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill) : id(id) diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 7315a44b7..8fe02f3f5 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -1070,6 +1070,8 @@ struct SongData : public DocumentAdditionalData { QString title, performer; }; +bool fileIsImage(const QString &name, const QString &mime); + struct DocumentData { DocumentData(const DocumentId &id, const uint64 &access = 0, int32 date = 0, const QVector &attributes = QVector(), const QString &mime = QString(), const ImagePtr &thumb = ImagePtr(), int32 dc = 0, int32 size = 0); void setattributes(const QVector &attributes);