mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
photo and video overview rewritten on layouts
This commit is contained in:
parent
62723f7576
commit
d3896ff53b
8 changed files with 616 additions and 267 deletions
|
@ -2011,6 +2011,11 @@ botKbScroll: flatScroll(solidScroll) {
|
|||
width: 10px;
|
||||
}
|
||||
|
||||
minPhotoSize: 104px;
|
||||
maxMediaSize: 420px;
|
||||
maxStickerSize: 256px;
|
||||
maxGifSize: 320px;
|
||||
|
||||
mvBgColor: #222;
|
||||
mvBgOpacity: 0.92;
|
||||
mvThickFont: semiboldFont;
|
||||
|
@ -2132,7 +2137,8 @@ medviewSaveMsg: #000000b2;
|
|||
mvTransparentBrush: sprite(9px, 124px, 8px, 8px);
|
||||
|
||||
overviewPhotoSkip: 10px;
|
||||
overviewPhotoMinSize: 100px;
|
||||
overviewPhotoBg: #F1F1F1;
|
||||
overviewPhotoMinSize: minPhotoSize;
|
||||
overviewPhotoCheck: sprite(245px, 308px, 32px, 32px);
|
||||
overviewPhotoChecked: sprite(278px, 308px, 32px, 32px);
|
||||
overviewPhotoSelectOverlay: #0a7bb03f;
|
||||
|
@ -2193,11 +2199,6 @@ mediaviewLoader: size(78px, 33px);
|
|||
mediaviewLoaderPoint: size(9px, 9px);
|
||||
mediaviewLoaderSkip: 9px;
|
||||
|
||||
minPhotoSize: 104px;
|
||||
maxMediaSize: 420px;
|
||||
maxStickerSize: 256px;
|
||||
maxGifSize: 320px;
|
||||
|
||||
downloadPathSkip: 10px;
|
||||
|
||||
usernamePadding: margins(23px, 22px, 21px, 12px);
|
||||
|
|
|
@ -3026,8 +3026,8 @@ HistoryItem *regItem(HistoryItem *item, bool returnExisting) {
|
|||
return item;
|
||||
}
|
||||
|
||||
RadialAnimation::RadialAnimation(int32 thickness, AnimationCallbacks *callbacks) : _thickness(thickness)
|
||||
, _firstStart(0)
|
||||
RadialAnimation::RadialAnimation(AnimationCallbacks *callbacks)
|
||||
: _firstStart(0)
|
||||
, _lastStart(0)
|
||||
, _lastTime(0)
|
||||
, _opacity(0)
|
||||
|
@ -3078,12 +3078,12 @@ void RadialAnimation::step(uint64 ms) {
|
|||
_animation.step(ms);
|
||||
}
|
||||
|
||||
void RadialAnimation::draw(Painter &p, const QRect &inner, const style::color &color) {
|
||||
void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, const style::color &color) {
|
||||
float64 o = p.opacity();
|
||||
p.setOpacity(o * _opacity);
|
||||
|
||||
QPen pen(color->p), was(p.pen());
|
||||
pen.setWidth(_thickness);
|
||||
pen.setWidth(thickness);
|
||||
p.setPen(pen);
|
||||
|
||||
int32 len = MinArcLength + a_arcEnd.current();
|
||||
|
@ -3651,7 +3651,7 @@ void HistoryVideo::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
|
|||
p.drawSpriteCenter(inner, icon);
|
||||
if (radial) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
_animation->radial.draw(p, rinner, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
}
|
||||
|
||||
int32 statusX = skipx + st::msgDateImgDelta + st::msgDateImgPadding.x(), statusY = skipy + st::msgDateImgDelta + st::msgDateImgPadding.y();
|
||||
|
@ -3836,7 +3836,7 @@ void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
|
|||
if (radial) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
style::color bg(outbg ? (selected ? st::msgOutBgSelected : st::msgOutBg) : (selected ? st::msgInBgSelected : st::msgInBg));
|
||||
_animation->radial.draw(p, rinner, bg);
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, bg);
|
||||
}
|
||||
|
||||
style::sprite icon;
|
||||
|
@ -4091,7 +4091,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
|||
p.setOpacity(1);
|
||||
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
_animation->radial.draw(p, rinner, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4127,7 +4127,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
|
|||
if (radial) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
style::color bg(outbg ? (selected ? st::msgOutBgSelected : st::msgOutBg) : (selected ? st::msgInBgSelected : st::msgInBg));
|
||||
_animation->radial.draw(p, rinner, bg);
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, bg);
|
||||
}
|
||||
|
||||
style::sprite icon;
|
||||
|
@ -4485,7 +4485,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
|
|||
p.drawSpriteCenter(inner, icon);
|
||||
if (radial) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
_animation->radial.draw(p, rinner, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
_animation->radial.draw(p, rinner, st::msgFileRadialLine, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
}
|
||||
|
||||
if (!animating) {
|
||||
|
|
|
@ -1106,7 +1106,7 @@ HistoryItem *regItem(HistoryItem *item, bool returnExisting = false);
|
|||
class RadialAnimation {
|
||||
public:
|
||||
|
||||
RadialAnimation(int32 thickness, AnimationCallbacks *callbacks);
|
||||
RadialAnimation(AnimationCallbacks *callbacks);
|
||||
|
||||
float64 opacity() const {
|
||||
return _opacity;
|
||||
|
@ -1124,11 +1124,10 @@ public:
|
|||
step(getms());
|
||||
}
|
||||
|
||||
void draw(Painter &p, const QRect &inner, const style::color &color);
|
||||
void draw(Painter &p, const QRect &inner, int32 thickness, const style::color &color);
|
||||
|
||||
private:
|
||||
|
||||
int32 _thickness;
|
||||
uint64 _firstStart, _lastStart, _lastTime;
|
||||
float64 _opacity;
|
||||
anim::ivalue a_arcEnd, a_arcStart;
|
||||
|
@ -1341,7 +1340,7 @@ protected:
|
|||
struct AnimationData {
|
||||
AnimationData(AnimationCallbacks *thumbOverCallbacks, AnimationCallbacks *radialCallbacks) : a_thumbOver(0, 0)
|
||||
, _a_thumbOver(thumbOverCallbacks)
|
||||
, radial(st::msgFileRadialLine, radialCallbacks) {
|
||||
, radial(radialCallbacks) {
|
||||
}
|
||||
anim::fvalue a_thumbOver;
|
||||
Animation _a_thumbOver;
|
||||
|
|
|
@ -203,14 +203,14 @@ RoundCorners documentCorners(int32 colorIndex) {
|
|||
}
|
||||
|
||||
void LayoutRadialProgressItem::linkOver(const TextLinkPtr &lnk) {
|
||||
if (lnk == _savel || lnk == _cancell) {
|
||||
if (lnk == _openl || lnk == _savel || lnk == _cancell) {
|
||||
a_iconOver.start(1);
|
||||
_a_iconOver.start();
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutRadialProgressItem::linkOut(const TextLinkPtr &lnk) {
|
||||
if (lnk == _savel || lnk == _cancell) {
|
||||
if (lnk == _openl || lnk == _savel || lnk == _cancell) {
|
||||
a_iconOver.start(0);
|
||||
_a_iconOver.start();
|
||||
}
|
||||
|
@ -247,9 +247,7 @@ void LayoutRadialProgressItem::step_radial(uint64 ms, bool timer) {
|
|||
|
||||
void LayoutRadialProgressItem::ensureRadial() const {
|
||||
if (!_radial) {
|
||||
_radial = new RadialAnimation(
|
||||
st::msgFileRadialLine,
|
||||
animation(const_cast<LayoutRadialProgressItem*>(this), &LayoutRadialProgressItem::step_radial));
|
||||
_radial = new RadialAnimation(animation(const_cast<LayoutRadialProgressItem*>(this), &LayoutRadialProgressItem::step_radial));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,7 +291,7 @@ void LayoutOverviewDate::initDimensions() {
|
|||
_minh = st::linksDateMargin + st::normalFont->height + st::linksDateMargin + st::linksBorder;
|
||||
}
|
||||
|
||||
void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const {
|
||||
void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
if (clip.intersects(QRect(0, st::linksDateMargin, _width, st::normalFont->height))) {
|
||||
p.setPen(st::linksDateColor);
|
||||
p.setFont(st::normalFont);
|
||||
|
@ -301,6 +299,215 @@ void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection,
|
|||
}
|
||||
}
|
||||
|
||||
LayoutOverviewPhoto::LayoutOverviewPhoto(PhotoData *photo, HistoryItem *parent) : LayoutMediaItem(parent)
|
||||
, _data(photo)
|
||||
, _link(new PhotoLink(photo))
|
||||
, _goodLoaded(false) {
|
||||
|
||||
}
|
||||
|
||||
void LayoutOverviewPhoto::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
bool good = _data->full->loaded();
|
||||
if (!good) {
|
||||
_data->medium->load(false, false);
|
||||
good = _data->medium->loaded();
|
||||
}
|
||||
if ((good && !_goodLoaded) || _pix.width() != _width * cIntRetinaFactor()) {
|
||||
_goodLoaded = good;
|
||||
|
||||
int32 size = _width * cIntRetinaFactor();
|
||||
if (_goodLoaded || _data->thumb->loaded()) {
|
||||
QImage img = (_data->full->loaded() ? _data->full : (_data->medium->loaded() ? _data->medium : _data->thumb))->pix().toImage();
|
||||
if (!_goodLoaded) {
|
||||
img = imageBlur(img);
|
||||
}
|
||||
if (img.width() == img.height()) {
|
||||
if (img.width() != _width) {
|
||||
img = img.scaled(_width, _width, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
}
|
||||
} else if (img.width() > img.height()) {
|
||||
img = img.copy((img.width() - img.height()) / 2, 0, img.height(), img.height()).scaled(_width, _width, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
} else {
|
||||
img = img.copy(0, (img.height() - img.width()) / 2, img.width(), img.width()).scaled(_width, _width, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
}
|
||||
img.setDevicePixelRatio(cRetinaFactor());
|
||||
_data->forget();
|
||||
|
||||
_pix = QPixmap::fromImage(img, Qt::ColorOnly);
|
||||
} else if (!_pix.isNull()) {
|
||||
_pix = QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
if (_pix.isNull()) {
|
||||
p.fillRect(0, 0, _width, _height, st::overviewPhotoBg);
|
||||
} else {
|
||||
p.drawPixmap(0, 0, _pix);
|
||||
}
|
||||
|
||||
if (selection == FullSelection) {
|
||||
p.fillRect(QRect(0, 0, _width, _height), st::overviewPhotoSelectOverlay);
|
||||
p.drawSprite(QPoint(rtl() ? 0 : (_width - st::overviewPhotoChecked.pxWidth()), _height - st::overviewPhotoChecked.pxHeight()), st::overviewPhotoChecked);
|
||||
} else if (context->selecting) {
|
||||
p.drawSprite(QPoint(rtl() ? 0 : (_width - st::overviewPhotoCheck.pxWidth()), _height - st::overviewPhotoCheck.pxHeight()), st::overviewPhotoCheck);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutOverviewPhoto::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||
if (hasPoint(x, y)) {
|
||||
link = _link;
|
||||
}
|
||||
}
|
||||
|
||||
LayoutOverviewVideo::LayoutOverviewVideo(VideoData *video, HistoryItem *parent) : LayoutAbstractFileItem(parent)
|
||||
, _data(video)
|
||||
, _duration(formatDurationText(_data->duration))
|
||||
, _thumbLoaded(false) {
|
||||
setLinks(new VideoOpenLink(_data), new VideoSaveLink(_data), new VideoCancelLink(_data));
|
||||
}
|
||||
|
||||
void LayoutOverviewVideo::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
bool selected = (selection == FullSelection), thumbLoaded = _data->thumb->loaded();
|
||||
bool already = !_data->already().isEmpty();
|
||||
if (_data->loader) {
|
||||
ensureRadial();
|
||||
if (!_radial->animating()) {
|
||||
_radial->start(_data->progress());
|
||||
}
|
||||
}
|
||||
updateStatusText();
|
||||
bool radial = isRadialAnimation(context->ms);
|
||||
|
||||
if ((thumbLoaded && !_thumbLoaded) || (_pix.width() != _width * cIntRetinaFactor())) {
|
||||
_thumbLoaded = thumbLoaded;
|
||||
|
||||
if (_thumbLoaded && !_data->thumb->isNull()) {
|
||||
int32 size = _width * cIntRetinaFactor();
|
||||
QImage img = _data->thumb->pix().toImage();
|
||||
img = imageBlur(img);
|
||||
if (img.width() == img.height()) {
|
||||
if (img.width() != _width) {
|
||||
img = img.scaled(_width, _width, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
}
|
||||
} else if (img.width() > img.height()) {
|
||||
img = img.copy((img.width() - img.height()) / 2, 0, img.height(), img.height()).scaled(_width, _width, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
} else {
|
||||
img = img.copy(0, (img.height() - img.width()) / 2, img.width(), img.width()).scaled(_width, _width, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
|
||||
}
|
||||
img.setDevicePixelRatio(cRetinaFactor());
|
||||
_data->forget();
|
||||
|
||||
_pix = QPixmap::fromImage(img, Qt::ColorOnly);
|
||||
} else if (!_pix.isNull()) {
|
||||
_pix = QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
if (_pix.isNull()) {
|
||||
p.fillRect(0, 0, _width, _height, st::overviewPhotoBg);
|
||||
} else {
|
||||
p.drawPixmap(0, 0, _pix);
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
p.fillRect(QRect(0, 0, _width, _height), st::overviewPhotoSelectOverlay);
|
||||
}
|
||||
|
||||
if (clip.intersects(QRect(0, _height - st::normalFont->height, _width, st::normalFont->height))) {
|
||||
int32 statusX = st::msgDateImgPadding.x(), statusY = _height - st::normalFont->height - st::msgDateImgPadding.y();
|
||||
int32 statusW = st::normalFont->width(_statusText) + 2 * st::msgDateImgPadding.x();
|
||||
int32 statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
||||
statusX = _width - statusW + statusX;
|
||||
p.fillRect(rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, _width), selected ? st::msgDateImgBgSelected : st::msgDateImgBg);
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::white);
|
||||
p.drawTextLeft(statusX, statusY, _width, _statusText, statusW - 2 * st::msgDateImgPadding.x());
|
||||
}
|
||||
if (clip.intersects(QRect(0, 0, _width, st::normalFont->height))) {
|
||||
int32 statusX = st::msgDateImgPadding.x(), statusY = st::msgDateImgPadding.y();
|
||||
int32 statusW = st::normalFont->width(_duration) + 2 * st::msgDateImgPadding.x();
|
||||
int32 statusH = st::normalFont->height + 2 * st::msgDateImgPadding.y();
|
||||
p.fillRect(rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, _width), selected ? st::msgDateImgBgSelected : st::msgDateImgBg);
|
||||
p.setFont(st::normalFont);
|
||||
p.setPen(st::white);
|
||||
p.drawTextLeft(statusX, statusY, _width, _duration, statusW - 2 * st::msgDateImgPadding.x());
|
||||
}
|
||||
|
||||
QRect inner((_width - st::msgFileSize) / 2, (_height - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
||||
if (clip.intersects(inner)) {
|
||||
p.setPen(Qt::NoPen);
|
||||
if (selected) {
|
||||
p.setBrush(st::msgDateImgBgSelected);
|
||||
} else if (_a_iconOver.animating()) {
|
||||
_a_iconOver.step(context->ms);
|
||||
float64 over = a_iconOver.current();
|
||||
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
|
||||
p.setBrush(st::black);
|
||||
} else {
|
||||
bool over = textlnkDrawOver(already ? _openl : (_data->loader ? _cancell : _savel));
|
||||
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
|
||||
}
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
p.drawEllipse(inner);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
|
||||
style::sprite icon;
|
||||
if (radial) {
|
||||
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
||||
} else if (already) {
|
||||
icon = (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
|
||||
} else {
|
||||
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
|
||||
}
|
||||
p.setOpacity(radial ? _radial->opacity() : 1);
|
||||
p.drawSpriteCenter(inner, icon);
|
||||
if (radial) {
|
||||
p.setOpacity(1);
|
||||
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
_radial->draw(p, rinner, st::msgFileRadialLine, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
p.drawSprite(QPoint(rtl() ? 0 : (_width - st::overviewPhotoChecked.pxWidth()), _height - st::overviewPhotoChecked.pxHeight()), st::overviewPhotoChecked);
|
||||
} else if (context->selecting) {
|
||||
p.drawSprite(QPoint(rtl() ? 0 : (_width - st::overviewPhotoCheck.pxWidth()), _height - st::overviewPhotoCheck.pxHeight()), st::overviewPhotoCheck);
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutOverviewVideo::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||
if (hasPoint(x, y)) {
|
||||
link = _data->already().isEmpty() ? (_data->loader ? _cancell : _savel) : _openl;
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutOverviewVideo::updateStatusText() const {
|
||||
bool showPause = false;
|
||||
int32 statusSize = 0;
|
||||
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
|
||||
statusSize = FileStatusSizeFailed;
|
||||
} else if (_data->status == FileUploading) {
|
||||
statusSize = _data->uploadOffset;
|
||||
} else if (_data->loader) {
|
||||
statusSize = _data->loader->currentOffset();
|
||||
} else if (!_data->already().isEmpty()) {
|
||||
statusSize = FileStatusSizeLoaded;
|
||||
} else {
|
||||
statusSize = FileStatusSizeReady;
|
||||
}
|
||||
if (statusSize != _statusSize) {
|
||||
int32 status = statusSize, size = _data->size;
|
||||
if (statusSize >= 0 && statusSize < 0x7F000000) {
|
||||
size = status;
|
||||
status = FileStatusSizeReady;
|
||||
}
|
||||
setStatusSize(status, size, -1, 0);
|
||||
_statusSize = statusSize;
|
||||
}
|
||||
}
|
||||
|
||||
LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent, int32 top) : LayoutAbstractFileItem(parent)
|
||||
, _info(top)
|
||||
, _data(document)
|
||||
|
@ -338,7 +545,7 @@ void LayoutOverviewDocument::initDimensions() {
|
|||
_minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() + st::lineWidth;
|
||||
}
|
||||
|
||||
void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const {
|
||||
void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||
bool selected = (selection == FullSelection);
|
||||
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
|
||||
if (_data->loader) {
|
||||
|
@ -348,7 +555,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
|||
}
|
||||
}
|
||||
updateStatusText();
|
||||
bool radial = isRadialAnimation(ms);
|
||||
bool radial = isRadialAnimation(context->ms);
|
||||
|
||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
|
||||
bool wthumb = withThumb();
|
||||
|
@ -386,7 +593,6 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
|||
}
|
||||
if (selected) {
|
||||
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
|
||||
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::linksPhotoCheck.pxWidth()), rthumb.height() - st::linksPhotoCheck.pxHeight()), st::linksPhotoChecked);
|
||||
}
|
||||
|
||||
if (!radial && (already || hasdata)) {
|
||||
|
@ -400,7 +606,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
|||
p.setOpacity(st::msgDateImgBg->c.alphaF() * _radial->opacity());
|
||||
p.setBrush(st::black);
|
||||
} else if (_a_iconOver.animating()) {
|
||||
_a_iconOver.step(ms);
|
||||
_a_iconOver.step(context->ms);
|
||||
float64 over = a_iconOver.current();
|
||||
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
|
||||
p.setBrush(st::black);
|
||||
|
@ -425,10 +631,15 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
|||
p.setOpacity(1);
|
||||
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
_radial->draw(p, rinner, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
_radial->draw(p, rinner, st::msgFileRadialLine, selected ? st::msgInBgSelected : st::msgInBg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::linksPhotoChecked.pxWidth()), rthumb.height() - st::linksPhotoChecked.pxHeight()), st::linksPhotoChecked);
|
||||
} else if (context->selecting) {
|
||||
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::linksPhotoCheck.pxWidth()), rthumb.height() - st::linksPhotoCheck.pxHeight()), st::linksPhotoCheck);
|
||||
}
|
||||
}
|
||||
|
||||
int32 namewidth = _width - nameleft - nameright;
|
||||
|
|
|
@ -81,6 +81,16 @@ RoundCorners documentCorners(int32 colorIndex);
|
|||
class LayoutMediaItem;
|
||||
class OverviewItemInfo;
|
||||
|
||||
class PaintContext {
|
||||
public:
|
||||
|
||||
PaintContext(uint64 ms, bool selecting) : ms(ms), selecting(selecting) {
|
||||
}
|
||||
uint64 ms;
|
||||
bool selecting;
|
||||
|
||||
};
|
||||
|
||||
class LayoutItem {
|
||||
public:
|
||||
LayoutItem() : _maxw(0), _minh(0) {
|
||||
|
@ -99,7 +109,7 @@ public:
|
|||
return _height;
|
||||
}
|
||||
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const = 0;
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const = 0;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||
link = TextLinkPtr();
|
||||
cursor = HistoryDefaultCursorState;
|
||||
|
@ -264,7 +274,7 @@ public:
|
|||
LayoutOverviewDate(const QDate &date, int32 top);
|
||||
|
||||
virtual void initDimensions();
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const;
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
|
||||
virtual OverviewItemInfo *getOverviewItemInfo() {
|
||||
return &_info;
|
||||
|
@ -281,12 +291,120 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class LayoutOverviewPhoto : public LayoutMediaItem {
|
||||
public:
|
||||
LayoutOverviewPhoto(PhotoData *photo, HistoryItem *parent);
|
||||
|
||||
virtual void initDimensions() {
|
||||
_maxw = 2 * st::overviewPhotoMinSize;
|
||||
_minh = _maxw;
|
||||
}
|
||||
virtual int32 resizeGetHeight(int32 width) {
|
||||
width = qMin(width, _maxw);
|
||||
if (width != _width || width != _height) {
|
||||
_width = qMin(width, _maxw);
|
||||
_height = _width;
|
||||
}
|
||||
return _height;
|
||||
}
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
|
||||
|
||||
private:
|
||||
PhotoData *_data;
|
||||
TextLinkPtr _link;
|
||||
|
||||
mutable QPixmap _pix;
|
||||
mutable bool _goodLoaded;
|
||||
|
||||
};
|
||||
|
||||
class LayoutOverviewVideo : public LayoutAbstractFileItem {
|
||||
public:
|
||||
LayoutOverviewVideo(VideoData *photo, HistoryItem *parent);
|
||||
|
||||
virtual void initDimensions() {
|
||||
_maxw = 2 * st::minPhotoSize;
|
||||
_minh = _maxw;
|
||||
}
|
||||
virtual int32 resizeGetHeight(int32 width) {
|
||||
_width = qMin(width, _maxw);
|
||||
_height = _width;
|
||||
return _height;
|
||||
}
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
|
||||
|
||||
protected:
|
||||
virtual float64 dataProgress() const {
|
||||
return _data->progress();
|
||||
}
|
||||
virtual bool dataFinished() const {
|
||||
return !_data->loader;
|
||||
}
|
||||
virtual bool dataLoaded() const {
|
||||
return !_data->already().isEmpty();
|
||||
}
|
||||
virtual bool iconAnimated() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
VideoData *_data;
|
||||
|
||||
QString _duration;
|
||||
mutable QPixmap _pix;
|
||||
mutable bool _thumbLoaded;
|
||||
|
||||
void updateStatusText() const;
|
||||
|
||||
};
|
||||
|
||||
class LayoutOverviewAudio : public LayoutAbstractFileItem {
|
||||
public:
|
||||
LayoutOverviewAudio(AudioData *audio, HistoryItem *parent, int32 top);
|
||||
|
||||
virtual void initDimensions();
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
|
||||
|
||||
virtual OverviewItemInfo *getOverviewItemInfo() {
|
||||
return &_info;
|
||||
}
|
||||
virtual const OverviewItemInfo *getOverviewItemInfo() const {
|
||||
return &_info;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual float64 dataProgress() const {
|
||||
return _data->progress();
|
||||
}
|
||||
virtual bool dataFinished() const {
|
||||
return !_data->loader;
|
||||
}
|
||||
virtual bool dataLoaded() const {
|
||||
return !_data->already().isEmpty() || !_data->data.isEmpty();
|
||||
}
|
||||
virtual bool iconAnimated() const {
|
||||
return !dataLoaded() || (_radial && _radial->animating());
|
||||
}
|
||||
|
||||
private:
|
||||
OverviewItemInfo _info;
|
||||
AudioData *_data;
|
||||
|
||||
Text _name, _details;
|
||||
|
||||
void updateStatusText() const;
|
||||
|
||||
};
|
||||
|
||||
class LayoutOverviewDocument : public LayoutAbstractFileItem {
|
||||
public:
|
||||
LayoutOverviewDocument(DocumentData *document, HistoryItem *parent, int32 top);
|
||||
|
||||
virtual void initDimensions();
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const;
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
|
||||
|
||||
virtual DocumentData *getDocument() const {
|
||||
|
@ -328,3 +446,44 @@ private:
|
|||
void updateStatusText() const;
|
||||
|
||||
};
|
||||
|
||||
class LayoutOverviewLink : public LayoutMediaItem {
|
||||
public:
|
||||
LayoutOverviewLink(HistoryItem *parent, int32 top);
|
||||
|
||||
virtual void initDimensions();
|
||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const;
|
||||
|
||||
virtual OverviewItemInfo *getOverviewItemInfo() {
|
||||
return &_info;
|
||||
}
|
||||
virtual const OverviewItemInfo *getOverviewItemInfo() const {
|
||||
return &_info;
|
||||
}
|
||||
|
||||
private:
|
||||
OverviewItemInfo _info;
|
||||
TextLinkPtr _msgl;
|
||||
|
||||
QString title, letter;
|
||||
int32 titleWidth;
|
||||
WebPageData *page;
|
||||
int32 pixw, pixh;
|
||||
Text text;
|
||||
|
||||
struct Link {
|
||||
Link() : width(0) {
|
||||
}
|
||||
Link(const QString &url, const QString &text)
|
||||
: text(text)
|
||||
, width(st::normalFont->width(text))
|
||||
, lnk(new TextLink(url)) {
|
||||
}
|
||||
QString text;
|
||||
int32 width;
|
||||
TextLinkPtr lnk;
|
||||
};
|
||||
QVector<Link> urls;
|
||||
|
||||
};
|
||||
|
|
|
@ -788,6 +788,7 @@ void MainWidget::ui_redrawHistoryItem(const HistoryItem *item) {
|
|||
|
||||
void MainWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
|
||||
history.notify_historyItemLayoutChanged(item);
|
||||
if (overview) overview->notify_historyItemLayoutChanged(item);
|
||||
}
|
||||
|
||||
void MainWidget::notify_historyItemResized(const HistoryItem *item, bool scrollToIt) {
|
||||
|
|
|
@ -143,15 +143,16 @@ OverviewInner::OverviewInner(OverviewWidget *overview, ScrollArea *scroll, PeerD
|
|||
, _resizeSkip(0)
|
||||
, _peer(peer->migrateTo() ? peer->migrateTo() : peer)
|
||||
, _type(type)
|
||||
, _reversed(_type != OverviewDocuments && _type != OverviewLinks)
|
||||
, _migrated(_peer->migrateFrom() ? App::history(_peer->migrateFrom()->id) : 0)
|
||||
, _history(App::history(_peer->id))
|
||||
, _channel(peerToChannel(_peer->id))
|
||||
, _selMode(false)
|
||||
, _rowsLeft(0)
|
||||
, _rowWidth(st::msgMinWidth)
|
||||
, _rowHeight(0)
|
||||
, _photosInRow(1)
|
||||
, _photosToAdd(0)
|
||||
, _selMode(false)
|
||||
, _search(this, st::dlgFilter, lang(lng_dlg_filter))
|
||||
, _cancelSearch(this, st::btnCancelSearch)
|
||||
, _cachedItemsToBeLoaded(LinksOverviewPerPage * 2)
|
||||
|
@ -292,7 +293,7 @@ int32 OverviewInner::migratedIndexSkip() const {
|
|||
void OverviewInner::fixItemIndex(int32 ¤t, MsgId msgId) const {
|
||||
if (!msgId) {
|
||||
current = -1;
|
||||
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments) {
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
History *history = itemMigrated(msgId) ? _migrated : _history;
|
||||
int32 l = history->overview[_type].size(), indexskip = migratedIndexSkip();
|
||||
int32 index = (current >= 0 && history == _history) ? (current - indexskip) : current;
|
||||
|
@ -306,7 +307,7 @@ void OverviewInner::fixItemIndex(int32 ¤t, MsgId msgId) const {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (_type == OverviewDocuments) {
|
||||
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
|
||||
int32 l = _items.size();
|
||||
if (current < 0 || current >= l || complexMsgId(_items.at(current)->getItem()) != msgId) {
|
||||
current = -1;
|
||||
|
@ -501,7 +502,7 @@ void OverviewInner::moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32
|
|||
}
|
||||
|
||||
index += delta;
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments) {
|
||||
if (_type == OverviewAudioDocuments) {
|
||||
int32 indexskip = migratedIndexSkip();
|
||||
if (index < 0 || index >= indexskip + _history->overview[_type].size()) {
|
||||
msgId = 0;
|
||||
|
@ -509,7 +510,7 @@ void OverviewInner::moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32
|
|||
} else {
|
||||
msgId = (index >= indexskip) ? _history->overview[_type][index - indexskip] : (-_migrated->overview[_type][index]);
|
||||
}
|
||||
} else if (_type == OverviewDocuments) {
|
||||
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
|
||||
while (index >= 0 && index < _items.size() && !_items.at(index)->toLayoutMediaItem()) {
|
||||
index += (delta > 0) ? 1 : -1;
|
||||
}
|
||||
|
@ -536,9 +537,10 @@ void OverviewInner::redrawItem(MsgId itemId, int32 itemIndex) {
|
|||
fixItemIndex(itemIndex, itemId);
|
||||
if (itemIndex >= 0) {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
int32 shownAtIndex = _items.size() - itemIndex - 1;
|
||||
float64 w = (float64(_width - st::overviewPhotoSkip) / _photosInRow);
|
||||
int32 vsize = (_vsize + st::overviewPhotoSkip);
|
||||
int32 row = (_photosToAdd + itemIndex) / _photosInRow, col = (_photosToAdd + itemIndex) % _photosInRow;
|
||||
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
|
||||
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
update(_rowsLeft, _addToY + int32(itemIndex * _rowHeight), _rowWidth, _rowHeight);
|
||||
|
@ -916,9 +918,9 @@ void OverviewInner::addSelectionRange(int32 selFrom, int32 selTo, History *histo
|
|||
if (selFrom < 0 || selTo < 0) return;
|
||||
for (int32 i = selFrom; i <= selTo; ++i) {
|
||||
MsgId msgid = 0;
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments) {
|
||||
if (_type == OverviewAudioDocuments) {
|
||||
msgid = ((history == _history) ? 1 : -1) * history->overview[_type][i];
|
||||
} else if (_type == OverviewDocuments) {
|
||||
} else if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
|
||||
msgid = complexMsgId(_items.at(i)->getItem());
|
||||
} else if (_type == OverviewLinks) {
|
||||
msgid = _cachedItems[i].msgid;
|
||||
|
@ -948,7 +950,7 @@ void OverviewInner::applyDragSelection() {
|
|||
_selected.clear();
|
||||
}
|
||||
int32 selfrom = _dragSelToIndex, selto = _dragSelFromIndex;
|
||||
if (_migrated && (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments)) {
|
||||
if (_migrated && (_type == OverviewAudioDocuments)) {
|
||||
int32 indexskip = migratedIndexSkip();
|
||||
if (selfrom < indexskip) {
|
||||
if (selto < indexskip) {
|
||||
|
@ -978,7 +980,8 @@ QPoint OverviewInner::mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex) {
|
|||
if (itemIndex < 0) return QPoint(0, 0);
|
||||
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
int32 row = (_photosToAdd + itemIndex) / _photosInRow, col = (_photosToAdd + itemIndex) % _photosInRow;
|
||||
int32 shownAtIndex = _items.size() - itemIndex - 1;
|
||||
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
|
||||
float64 w = (_width - st::overviewPhotoSkip) / float64(_photosInRow);
|
||||
p.setX(p.x() - int32(col * w) - st::overviewPhotoSkip);
|
||||
p.setY(p.y() - _addToY - row * (_vsize + st::overviewPhotoSkip) - st::overviewPhotoSkip);
|
||||
|
@ -1003,7 +1006,15 @@ void OverviewInner::activate() {
|
|||
}
|
||||
|
||||
void OverviewInner::clear() {
|
||||
_cached.clear();
|
||||
_selected.clear();
|
||||
_dragItemIndex = _mousedItemIndex = _dragSelFromIndex = _dragSelToIndex = -1;
|
||||
_dragItem = _mousedItem = _dragSelFrom = _dragSelTo = 0;
|
||||
_lnkOverIndex = _lnkDownIndex = 0;
|
||||
for (int32 i = 0, l = _items.size(); i != l; ++i) {
|
||||
delete _items.at(i);
|
||||
}
|
||||
_items.clear();
|
||||
_cachedItems.clear();
|
||||
}
|
||||
|
||||
int32 OverviewInner::itemTop(const FullMsgId &msgId) const {
|
||||
|
@ -1046,7 +1057,7 @@ void OverviewInner::preloadMore() {
|
|||
}
|
||||
|
||||
bool OverviewInner::preloadLocal() {
|
||||
if (_type != OverviewLinks && _type != OverviewDocuments) return false;
|
||||
if (_type != OverviewLinks && _type != OverviewDocuments && _type != OverviewPhotos && _type != OverviewVideos) return false;
|
||||
if (_cachedItemsToBeLoaded >= migratedIndexSkip() + _history->overview[_type].size()) return false;
|
||||
_cachedItemsToBeLoaded += LinksOverviewPerPage;
|
||||
mediaOverviewUpdated();
|
||||
|
@ -1087,6 +1098,25 @@ QPixmap OverviewInner::genPix(VideoData *video, int32 size) {
|
|||
return result;
|
||||
}
|
||||
|
||||
uint32 OverviewInner::itemSelectedValue(int32 index) const {
|
||||
int32 selfrom = -1, selto = -1;
|
||||
if (_dragSelFromIndex >= 0 && _dragSelToIndex >= 0) {
|
||||
selfrom = _dragSelToIndex;
|
||||
selto = _dragSelFromIndex;
|
||||
}
|
||||
if (_items.at(index)->toLayoutMediaItem()) { // draw item
|
||||
if (index >= _dragSelToIndex && index <= _dragSelFromIndex && _dragSelToIndex >= 0) {
|
||||
return (_dragSelecting && _items.at(index)->msgId() > 0) ? FullSelection : 0;
|
||||
} else if (!_selected.isEmpty()) {
|
||||
SelectedItems::const_iterator j = _selected.constFind(complexMsgId(_items.at(index)->getItem()));
|
||||
if (j != _selected.cend()) {
|
||||
return j.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OverviewInner::paintEvent(QPaintEvent *e) {
|
||||
if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return;
|
||||
|
||||
|
@ -1098,6 +1128,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
|||
p.setClipRect(r);
|
||||
}
|
||||
uint64 ms = getms();
|
||||
PaintContext context(ms, _selMode);
|
||||
|
||||
if (_history->overview[_type].isEmpty() && (!_migrated || !_history->overviewLoaded(_type) || _migrated->overview[_type].isEmpty())) {
|
||||
QPoint dogPos((_width - st::msgDogImg.pxWidth()) / 2, ((height() - st::msgDogImg.pxHeight()) * 4) / 9);
|
||||
|
@ -1120,111 +1151,21 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
|||
bool hasSel = !_selected.isEmpty();
|
||||
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
|
||||
int32 migratedCount = migratedIndexSkip();
|
||||
int32 count = migratedCount + overview.size();
|
||||
int32 rowFrom = floorclamp(r.y() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, count);
|
||||
int32 rowTo = ceilclamp(r.y() + r.height() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, count);
|
||||
int32 count = _items.size(), rowsCount = (_photosToAdd + count) / _photosInRow + (((_photosToAdd + count) % _photosInRow) ? 1 : 0);
|
||||
int32 rowFrom = floorclamp(r.y() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, rowsCount);
|
||||
int32 rowTo = ceilclamp(r.y() + r.height() - _addToY - st::overviewPhotoSkip, _vsize + st::overviewPhotoSkip, 0, rowsCount);
|
||||
float64 w = float64(_width - st::overviewPhotoSkip) / _photosInRow;
|
||||
for (int32 row = rowFrom; row < rowTo; ++row) {
|
||||
if (row * _photosInRow >= _photosToAdd + count) break;
|
||||
for (int32 i = 0; i < _photosInRow; ++i) {
|
||||
int32 index = row * _photosInRow + i - _photosToAdd;
|
||||
if (index < 0) continue;
|
||||
if (index >= count) break;
|
||||
for (int32 col = 0; col < _photosInRow; ++col) {
|
||||
int32 i = count - (row * _photosInRow + col - _photosToAdd) - 1;
|
||||
if (i < 0) continue;
|
||||
if (i >= count) break;
|
||||
|
||||
bool migratedindex = (index < migratedCount);
|
||||
int32 bareindex = migratedindex ? index : (index - migratedCount);
|
||||
|
||||
HistoryItem *item = App::histItemById(migratedindex ? _migrated->channelId() : _channel, (migratedindex ? *migratedOverview : overview)[bareindex]);
|
||||
HistoryMedia *m = item ? item->getMedia(true) : 0;
|
||||
|
||||
QPoint pos(int32(i * w + st::overviewPhotoSkip), _addToY + row * (_vsize + st::overviewPhotoSkip) + st::overviewPhotoSkip);
|
||||
if (m) switch (m->type()) {
|
||||
case MediaTypePhoto: {
|
||||
PhotoData *photo = static_cast<HistoryPhoto*>(m)->photo();
|
||||
bool quality = photo->full->loaded();
|
||||
if (!quality) {
|
||||
if (photo->thumb->loaded()) {
|
||||
photo->medium->load(false, false);
|
||||
quality = photo->medium->loaded();
|
||||
} else {
|
||||
photo->thumb->load();
|
||||
}
|
||||
}
|
||||
CachedSizes::iterator it = _cached.find(photo);
|
||||
if (it == _cached.cend()) {
|
||||
CachedSize size;
|
||||
size.medium = quality;
|
||||
size.vsize = _vsize;
|
||||
size.pix = genPix(photo, _vsize);
|
||||
it = _cached.insert(photo, size);
|
||||
} else if (it->medium != quality || it->vsize != _vsize) {
|
||||
it->medium = quality;
|
||||
it->vsize = _vsize;
|
||||
it->pix = genPix(photo, _vsize);
|
||||
}
|
||||
p.drawPixmap(pos, it->pix);
|
||||
if (!quality) {
|
||||
uint64 dt = itemAnimations().animate(item, ms);
|
||||
int32 cnt = int32(st::photoLoaderCnt), period = int32(st::photoLoaderPeriod), t = dt % period, delta = int32(st::photoLoaderDelta);
|
||||
|
||||
int32 x = pos.x() + (_vsize - st::overviewLoader.width()) / 2, y = pos.y() + (_vsize - st::overviewLoader.height()) / 2;
|
||||
p.fillRect(x, y, st::overviewLoader.width(), st::overviewLoader.height(), st::photoLoaderBg->b);
|
||||
x += (st::overviewLoader.width() - cnt * st::overviewLoaderPoint.width() - (cnt - 1) * st::overviewLoaderSkip) / 2;
|
||||
y += (st::overviewLoader.height() - st::overviewLoaderPoint.height()) / 2;
|
||||
QColor c(st::white->c);
|
||||
QBrush b(c);
|
||||
for (int32 i = 0; i < cnt; ++i) {
|
||||
t -= delta;
|
||||
while (t < 0) t += period;
|
||||
|
||||
float64 alpha = (t >= st::photoLoaderDuration1 + st::photoLoaderDuration2) ? 0 : ((t > st::photoLoaderDuration1 ? ((st::photoLoaderDuration1 + st::photoLoaderDuration2 - t) / st::photoLoaderDuration2) : (t / st::photoLoaderDuration1)));
|
||||
c.setAlphaF(st::photoLoaderAlphaMin + alpha * (1 - st::photoLoaderAlphaMin));
|
||||
b.setColor(c);
|
||||
p.fillRect(x + i * (st::overviewLoaderPoint.width() + st::overviewLoaderSkip), y, st::overviewLoaderPoint.width(), st::overviewLoaderPoint.height(), b);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case MediaTypeVideo: {
|
||||
VideoData *video = static_cast<HistoryVideo*>(m)->video();
|
||||
CachedSizes::iterator it = _cached.find(video);
|
||||
if (it == _cached.cend()) {
|
||||
CachedSize size;
|
||||
size.medium = 0;
|
||||
size.vsize = _vsize;
|
||||
size.pix = genPix(video, _vsize);
|
||||
it = _cached.insert(video, size);
|
||||
} else if (it->vsize != _vsize) {
|
||||
it->vsize = _vsize;
|
||||
it->pix = genPix(video, _vsize);
|
||||
}
|
||||
p.drawPixmap(pos, it->pix);
|
||||
} break;
|
||||
}
|
||||
|
||||
uint32 sel = 0;
|
||||
if (index >= selfrom && index <= selto) {
|
||||
sel = (_dragSelecting && item->id > 0) ? FullSelection : 0;
|
||||
} else if (hasSel) {
|
||||
SelectedItems::const_iterator i = _selected.constFind(migratedindex ? -item->id : item->id);
|
||||
if (i != selEnd) {
|
||||
sel = i.value();
|
||||
}
|
||||
}
|
||||
if (sel == FullSelection) {
|
||||
p.fillRect(QRect(pos.x(), pos.y(), _vsize, _vsize), st::overviewPhotoSelectOverlay);
|
||||
p.drawSprite(QPoint(pos.x() + _vsize - st::overviewPhotoCheck.pxWidth(), pos.y() + _vsize - st::overviewPhotoCheck.pxHeight()), st::overviewPhotoChecked);
|
||||
} else if (_selMode/* || (selfrom < count && selfrom <= selto && 0 <= selto)*/) {
|
||||
p.drawSprite(QPoint(pos.x() + _vsize - st::overviewPhotoCheck.pxWidth(), pos.y() + _vsize - st::overviewPhotoCheck.pxHeight()), st::overviewPhotoCheck);
|
||||
}
|
||||
|
||||
if (m) {
|
||||
p.translate(pos.x(), pos.y());
|
||||
// m->drawOverview(p, _vsize, item, r.translated(-pos.x(), -pos.y()), sel == FullSelection, ms);
|
||||
p.translate(-pos.x(), -pos.y());
|
||||
}
|
||||
QPoint pos(int32(col * w + st::overviewPhotoSkip), _addToY + row * (_vsize + st::overviewPhotoSkip) + st::overviewPhotoSkip);
|
||||
p.translate(pos.x(), pos.y());
|
||||
_items.at(i)->paint(p, r.translated(-pos.x(), -pos.y()), itemSelectedValue(i), &context);
|
||||
p.translate(-pos.x(), -pos.y());
|
||||
}
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
|
@ -1358,18 +1299,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
|||
if (_addToY + curY >= r.y() + r.height()) break;
|
||||
|
||||
p.translate(0, curY - y);
|
||||
uint32 sel = 0;
|
||||
if (_items.at(i)->toLayoutMediaItem()) { // draw item
|
||||
if (i >= selfrom && i <= selto) {
|
||||
sel = (_dragSelecting && _items.at(i)->msgId() > 0) ? FullSelection : 0;
|
||||
} else if (hasSel) {
|
||||
SelectedItems::const_iterator j = _selected.constFind(complexMsgId(_items.at(i)->getItem()));
|
||||
if (j != selEnd) {
|
||||
sel = j.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
_items.at(i)->paint(p, r.translated(-_rowsLeft, -_addToY - curY), sel, ms);
|
||||
_items.at(i)->paint(p, r.translated(-_rowsLeft, -_addToY - curY), itemSelectedValue(i), &context);
|
||||
y = curY;
|
||||
}
|
||||
}
|
||||
|
@ -1433,15 +1363,13 @@ void OverviewInner::onUpdateSelected() {
|
|||
HistoryCursorState cursorState = HistoryDefaultCursorState;
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
float64 w = (float64(_width - st::overviewPhotoSkip) / _photosInRow);
|
||||
int32 inRow = int32((m.x() - (st::overviewPhotoSkip / 2)) / w), vsize = (_vsize + st::overviewPhotoSkip);
|
||||
int32 col = int32((m.x() - (st::overviewPhotoSkip / 2)) / w), vsize = (_vsize + st::overviewPhotoSkip);
|
||||
int32 row = int32((m.y() - _addToY - (st::overviewPhotoSkip / 2)) / vsize);
|
||||
if (inRow < 0) inRow = 0;
|
||||
if (col < 0) col = 0;
|
||||
if (row < 0) row = 0;
|
||||
bool upon = true;
|
||||
|
||||
History::MediaOverview &overview(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
|
||||
int32 migratedCount = migratedIndexSkip();
|
||||
int32 i = row * _photosInRow + inRow - _photosToAdd, count = migratedCount + overview.size();
|
||||
int32 count = _items.size(), i = count - (row * _photosInRow + col - _photosToAdd) - 1;
|
||||
if (i < 0) {
|
||||
i = 0;
|
||||
upon = false;
|
||||
|
@ -1451,18 +1379,11 @@ void OverviewInner::onUpdateSelected() {
|
|||
upon = false;
|
||||
}
|
||||
if (i >= 0) {
|
||||
MsgId msgid = (i >= migratedCount) ? overview[i - migratedCount] : (*migratedOverview)[i];
|
||||
HistoryItem *histItem = App::histItemById((i >= migratedCount) ? _channel : _migrated->channelId(), msgid);
|
||||
if (histItem) {
|
||||
item = histItem;
|
||||
if (LayoutMediaItem *media = _items.at(i)->toLayoutMediaItem()) {
|
||||
item = media->getItem();
|
||||
index = i;
|
||||
if (upon && m.x() >= inRow * w + st::overviewPhotoSkip && m.x() < inRow * w + st::overviewPhotoSkip + _vsize) {
|
||||
if (m.y() >= _addToY + row * vsize + st::overviewPhotoSkip && m.y() < _addToY + (row + 1) * vsize + st::overviewPhotoSkip) {
|
||||
HistoryMedia *media = item->getMedia(true);
|
||||
if (media) {
|
||||
// media->getStateOverview(lnk, m.x() - inRow * w - st::overviewPhotoSkip, m.y() - _addToY - row * vsize - st::overviewPhotoSkip, item, _vsize);
|
||||
}
|
||||
}
|
||||
if (upon) {
|
||||
media->getState(lnk, cursorState, m.x() - col * w - st::overviewPhotoSkip, m.y() - _addToY - row * vsize - st::overviewPhotoSkip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1618,11 +1539,32 @@ void OverviewInner::onUpdateSelected() {
|
|||
bool lnkChanged = false;
|
||||
if (lnk != textlnkOver()) {
|
||||
lnkChanged = true;
|
||||
redrawItem(App::hoveredLinkItem());
|
||||
if (textlnkOver()) {
|
||||
if (HistoryItem *item = App::hoveredLinkItem()) {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
|
||||
MsgId itemId = complexMsgId(item);
|
||||
int32 itemIndex = oldMousedItemIndex;
|
||||
fixItemIndex(itemIndex, itemId);
|
||||
if (itemIndex >= 0) {
|
||||
_items.at(itemIndex)->linkOut(textlnkOver());
|
||||
redrawItem(itemId, itemIndex);
|
||||
}
|
||||
} else {
|
||||
redrawItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
textlnkOver(lnk);
|
||||
App::hoveredLinkItem(lnk ? item : 0);
|
||||
redrawItem(App::hoveredLinkItem());
|
||||
QToolTip::hideText();
|
||||
App::hoveredLinkItem(lnk ? item : 0);
|
||||
if (textlnkOver()) {
|
||||
if (item && index >= 0) {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewDocuments) {
|
||||
_items.at(index)->linkOver(textlnkOver());
|
||||
}
|
||||
redrawItem(complexMsgId(item), index);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
App::mousedItem(item);
|
||||
}
|
||||
|
@ -1671,44 +1613,28 @@ void OverviewInner::onUpdateSelected() {
|
|||
_selected[_dragItem] = 0;
|
||||
updateDragSelection(0, -1, 0, -1, false);
|
||||
} else if (canSelectMany) {
|
||||
bool selectingDown = ((_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments || _type == OverviewLinks || _type == OverviewDocuments) ? (_mousedItemIndex > _dragItemIndex) : (_mousedItemIndex < _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && ((_type == OverviewPhotos || _type == OverviewVideos) ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
|
||||
bool selectingDown = (_reversed ? (_mousedItemIndex < _dragItemIndex) : (_mousedItemIndex > _dragItemIndex)) || (_mousedItemIndex == _dragItemIndex && ((_type == OverviewPhotos || _type == OverviewVideos) ? (_dragStartPos.x() < m.x()) : (_dragStartPos.y() < m.y())));
|
||||
MsgId dragSelFrom = _dragItem, dragSelTo = _mousedItem;
|
||||
int32 dragSelFromIndex = _dragItemIndex, dragSelToIndex = _mousedItemIndex;
|
||||
if (!itemHasPoint(dragSelFrom, dragSelFromIndex, _dragStartPos.x(), _dragStartPos.y())) { // maybe exclude dragSelFrom
|
||||
if (selectingDown) {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
if (_dragStartPos.x() >= _vsize || ((_mousedItem == dragSelFrom) && (m.x() < _dragStartPos.x() + QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (_dragStartPos.y() >= itemHeight(dragSelFrom, dragSelFromIndex) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
|
||||
}
|
||||
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
|
||||
} else {
|
||||
if (_dragStartPos.y() >= itemHeight(dragSelFrom, dragSelFromIndex) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
|
||||
}
|
||||
} else if (_type == OverviewAudios) {
|
||||
if (_dragStartPos.y() >= itemHeight(dragSelFrom, dragSelFromIndex) || ((_mousedItem == dragSelFrom) && (m.y() < _dragStartPos.y() + QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, _reversed ? -1 : 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
if (_dragStartPos.x() < 0 || ((_mousedItem == dragSelFrom) && (m.x() >= _dragStartPos.x() - QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (_dragStartPos.y() < 0 || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
|
||||
}
|
||||
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
|
||||
} else {
|
||||
if (_dragStartPos.y() < 0 || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, -1);
|
||||
}
|
||||
} else if (_type == OverviewAudios) {
|
||||
if (_dragStartPos.y() < 0 || ((_mousedItem == dragSelFrom) && (m.y() >= _dragStartPos.y() - QApplication::startDragDistance()))) {
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, 1);
|
||||
moveToNextItem(dragSelFrom, dragSelFromIndex, dragSelTo, _reversed ? 1 : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1717,37 +1643,21 @@ void OverviewInner::onUpdateSelected() {
|
|||
if (selectingDown) {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
if (m.x() < 0) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (m.y() < 0) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
}
|
||||
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
|
||||
} else {
|
||||
if (m.y() < 0) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
|
||||
}
|
||||
} else if (_type == OverviewAudios) {
|
||||
if (m.y() < 0) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, _reversed ? 1 : -1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
if (m.x() >= _vsize) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex)) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
|
||||
}
|
||||
} else if (_type == OverviewLinks || _type == OverviewDocuments) {
|
||||
} else {
|
||||
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex)) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, 1);
|
||||
}
|
||||
} else if (_type == OverviewAudios) {
|
||||
if (m.y() >= itemHeight(dragSelTo, dragSelToIndex)) {
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, -1);
|
||||
moveToNextItem(dragSelTo, dragSelToIndex, dragSelFrom, _reversed ? -1 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1756,7 +1666,7 @@ void OverviewInner::onUpdateSelected() {
|
|||
MsgId dragFirstAffected = dragSelFrom;
|
||||
int32 dragFirstAffectedIndex = dragSelFromIndex;
|
||||
while (dragFirstAffectedIndex >= 0 && itemMsgId(dragFirstAffected) <= 0) {
|
||||
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, ((selectingDown && (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments)) || (!selectingDown && (_type != OverviewPhotos && _type != OverviewVideos && _type != OverviewAudioDocuments))) ? -1 : 1);
|
||||
moveToNextItem(dragFirstAffected, dragFirstAffectedIndex, dragSelTo, selectingDown ? (_reversed ? -1 : 1) : (_reversed ? 1 : -1));
|
||||
}
|
||||
if (dragFirstAffectedIndex >= 0) {
|
||||
SelectedItems::const_iterator i = _selected.constFind(dragFirstAffected);
|
||||
|
@ -2029,8 +1939,10 @@ int32 OverviewInner::resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeigh
|
|||
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
|
||||
}
|
||||
if ((_type == OverviewPhotos || _type == OverviewVideos) && _resizeIndex < 0) {
|
||||
_resizeIndex = _photosInRow * ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) + _photosInRow - 1;
|
||||
_resizeSkip = (scrollTop + minHeight) - ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) * int32(_vsize + st::overviewPhotoSkip);
|
||||
if (_resizeIndex < 0) {
|
||||
_resizeIndex = _photosInRow * ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) + _photosInRow - 1;
|
||||
_resizeSkip = (scrollTop + minHeight) - ((scrollTop + minHeight) / int32(_vsize + st::overviewPhotoSkip)) * int32(_vsize + st::overviewPhotoSkip);
|
||||
}
|
||||
}
|
||||
resize(nwidth, height() > _minHeight ? height() : _minHeight);
|
||||
showAll();
|
||||
|
@ -2059,17 +1971,9 @@ MediaOverviewType OverviewInner::type() const {
|
|||
|
||||
void OverviewInner::switchType(MediaOverviewType type) {
|
||||
if (_type != type) {
|
||||
_selected.clear();
|
||||
_dragItemIndex = _mousedItemIndex = _dragSelFromIndex = _dragSelToIndex = -1;
|
||||
_dragItem = _mousedItem = _dragSelFrom = _dragSelTo = 0;
|
||||
_lnkOverIndex = _lnkDownIndex = 0;
|
||||
for (int32 i = 0, l = _items.size(); i != l; ++i) {
|
||||
delete _items.at(i);
|
||||
}
|
||||
_items.clear();
|
||||
_cachedItems.clear();
|
||||
_cached.clear();
|
||||
clear();
|
||||
_type = type;
|
||||
_reversed = (_type != OverviewLinks && _type != OverviewDocuments);
|
||||
if (_type == OverviewLinks || _type == OverviewDocuments) {
|
||||
_search.show();
|
||||
} else {
|
||||
|
@ -2348,17 +2252,71 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
|
|||
}
|
||||
|
||||
int32 oldHeight = _height;
|
||||
if (_type == OverviewDocuments) {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
|
||||
int32 migrateCount = migratedIndexSkip();
|
||||
int32 wasCount = _items.size(), fullCount = (migrateCount + o.size());
|
||||
int32 tocheck = qMin(fullCount, _cachedItemsToBeLoaded);
|
||||
_items.reserve(tocheck);
|
||||
|
||||
int32 index = 0;
|
||||
bool allGood = true;
|
||||
for (int32 i = fullCount, l = fullCount - tocheck; i > l;) {
|
||||
--i;
|
||||
MsgId msgid = ((i < migrateCount) ? -migratedOverview->at(i) : o.at(i - migrateCount));
|
||||
if (allGood) {
|
||||
if (_items.size() > index && complexMsgId(_items.at(index)->getItem()) == msgid) {
|
||||
++index;
|
||||
continue;
|
||||
}
|
||||
allGood = false;
|
||||
}
|
||||
HistoryItem *item = App::histItemById(itemChannel(msgid), itemMsgId(msgid));
|
||||
HistoryMedia *media = item ? item->getMedia(true) : 0;
|
||||
LayoutItem *layout = 0;
|
||||
if (_type == OverviewPhotos) {
|
||||
PhotoData *photo = (media && media->type() == MediaTypePhoto) ? static_cast<HistoryPhoto*>(media)->photo() : 0;
|
||||
if (photo) layout = new LayoutOverviewPhoto(photo, item);
|
||||
} else if (_type == OverviewVideos) {
|
||||
VideoData *video = (media && media->type() == MediaTypeVideo) ? static_cast<HistoryVideo*>(media)->video() : 0;
|
||||
if (video) layout = new LayoutOverviewVideo(video, item);
|
||||
}
|
||||
if (!layout) continue;
|
||||
|
||||
QDate date = item->date.date();
|
||||
if (_items.size() > index) {
|
||||
delete _items.at(index);
|
||||
_items[index] = layout;
|
||||
} else {
|
||||
_items.push_back(layout);
|
||||
}
|
||||
layout->initDimensions();
|
||||
layout->resizeGetHeight(_vsize);
|
||||
++index;
|
||||
}
|
||||
for (int32 l = _items.size(); l > index;) {
|
||||
delete _items.at(--l);
|
||||
}
|
||||
_items.resize(index);
|
||||
if (!fromResize && _items.size() != wasCount) {
|
||||
_height = qMax(recountHeight(), _minHeight);
|
||||
if (height() != _height) {
|
||||
resize(width(), _height);
|
||||
}
|
||||
}
|
||||
dragActionUpdate(QCursor::pos());
|
||||
update();
|
||||
} else if (_type == OverviewDocuments) {
|
||||
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
|
||||
int32 migrateCount = migratedIndexSkip();
|
||||
int32 l = _inSearch ? _searchResults.size() : (migrateCount + o.size()), tocheck = qMin(l, _cachedItemsToBeLoaded);
|
||||
_items.reserve(2 * l); // day items
|
||||
_items.reserve(2 * tocheck); // day items
|
||||
|
||||
int32 top = 0, in = 0, addtoheight = _addToY + st::linksSearchMargin.top();
|
||||
bool allGood = true;
|
||||
QDate prevDate;
|
||||
for (int32 i = 0; i < tocheck; ++i) {
|
||||
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -(*migratedOverview)[l - i - 1] : o.at(l - i - 1 - migrateCount));
|
||||
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -migratedOverview->at(l - i - 1) : o.at(l - i - 1 - migrateCount));
|
||||
if (allGood) {
|
||||
if (_items.size() > in && complexMsgId(_items.at(in)->getItem()) == msgid) {
|
||||
prevDate = _items.at(in)->getItem()->date.date();
|
||||
|
@ -2391,7 +2349,8 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
|
|||
}
|
||||
HistoryItem *item = App::histItemById(itemChannel(msgid), itemMsgId(msgid));
|
||||
HistoryMedia *media = item ? item->getMedia(true) : 0;
|
||||
if (!media) continue;
|
||||
DocumentData *document = media ? media->getDocument() : 0;
|
||||
if (!document) continue;
|
||||
|
||||
QDate date = item->date.date();
|
||||
if (!in || (in > 0 && date != prevDate)) {
|
||||
|
@ -2409,9 +2368,9 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
|
|||
|
||||
if (_items.size() > in) {
|
||||
delete _items.at(in);
|
||||
_items[in] = new LayoutOverviewDocument(media->getDocument(), item, top);
|
||||
_items[in] = new LayoutOverviewDocument(document, item, top);
|
||||
} else {
|
||||
_items.push_back(new LayoutOverviewDocument(media->getDocument(), item, top));
|
||||
_items.push_back(new LayoutOverviewDocument(document, item, top));
|
||||
}
|
||||
_items.at(in)->initDimensions();
|
||||
top += _items.at(in)->resizeGetHeight(_rowWidth);
|
||||
|
@ -2435,13 +2394,13 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) {
|
|||
History::MediaOverview &o(_history->overview[_type]), *migratedOverview = _migrated ? &_migrated->overview[_type] : 0;
|
||||
int32 migrateCount = migratedIndexSkip();
|
||||
int32 l = _inSearch ? _searchResults.size() : (migrateCount + o.size()), tocheck = qMin(l, _cachedItemsToBeLoaded);
|
||||
_cachedItems.reserve(2 * l); // day items
|
||||
_cachedItems.reserve(2 * tocheck); // day items
|
||||
|
||||
int32 y = 0, in = 0, addtoheight = _addToY + st::linksSearchMargin.top();
|
||||
bool allGood = true;
|
||||
QDate prevDate;
|
||||
for (int32 i = 0; i < tocheck; ++i) {
|
||||
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -(*migratedOverview)[l - i - 1] : o.at(l - i - 1 - migrateCount));
|
||||
MsgId msgid = _inSearch ? _searchResults.at(l - i - 1) : ((l - i - 1 < migrateCount) ? -migratedOverview->at(l - i - 1) : o.at(l - i - 1 - migrateCount));
|
||||
if (allGood) {
|
||||
if (_cachedItems.size() > in && _cachedItems.at(in).msgid == msgid) {
|
||||
prevDate = _cachedItems.at(in).date;
|
||||
|
@ -2684,13 +2643,16 @@ void OverviewInner::redrawItem(const HistoryItem *msg) {
|
|||
MsgId msgid = msg->id;
|
||||
if (history->overviewHasMsgId(_type, msgid) && (history == _history || migrateindex > 0)) {
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
int32 index = history->overview[_type].indexOf(msgid);
|
||||
if (index >= 0) {
|
||||
if (history == _history) index += migrateindex;
|
||||
float64 w = (float64(width() - st::overviewPhotoSkip) / _photosInRow);
|
||||
int32 vsize = (_vsize + st::overviewPhotoSkip);
|
||||
int32 row = (_photosToAdd + index) / _photosInRow, col = (_photosToAdd + index) % _photosInRow;
|
||||
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
|
||||
if (history == _migrated) msgid = -msgid;
|
||||
for (int32 i = 0, l = _items.size(); i != l; ++i) {
|
||||
if (complexMsgId(_items.at(i)->getItem()) == msgid) {
|
||||
int32 shownAtIndex = _items.size() - i - 1;
|
||||
float64 w = (float64(width() - st::overviewPhotoSkip) / _photosInRow);
|
||||
int32 vsize = (_vsize + st::overviewPhotoSkip);
|
||||
int32 row = (_photosToAdd + shownAtIndex) / _photosInRow, col = (_photosToAdd + shownAtIndex) % _photosInRow;
|
||||
update(int32(col * w), _addToY + int32(row * vsize), qCeil(w), vsize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
int32 index = history->overview[_type].indexOf(msgid);
|
||||
|
@ -2726,12 +2688,10 @@ void OverviewInner::redrawItem(const HistoryItem *msg) {
|
|||
}
|
||||
}
|
||||
|
||||
void OverviewInner::showAll(bool recountHeights) {
|
||||
int32 newHeight = height();
|
||||
int32 OverviewInner::recountHeight() {
|
||||
int32 result = _height;
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
_photosInRow = int32(width() - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip);
|
||||
_vsize = (int32(width() - st::overviewPhotoSkip) / _photosInRow) - st::overviewPhotoSkip;
|
||||
int32 migratedCount = migratedIndexSkip(), count = migratedCount + _history->overview[_type].size();
|
||||
int32 count = _items.size();
|
||||
int32 migratedFullCount = _migrated ? _migrated->overviewCount(_type) : 0;
|
||||
int32 fullCount = migratedFullCount + _history->overviewCount(_type);
|
||||
if (fullCount > 0 && migratedFullCount >= 0) {
|
||||
|
@ -2742,8 +2702,21 @@ void OverviewInner::showAll(bool recountHeights) {
|
|||
_photosToAdd = 0;
|
||||
}
|
||||
int32 rows = ((_photosToAdd + count) / _photosInRow) + (((_photosToAdd + count) % _photosInRow) ? 1 : 0);
|
||||
newHeight = _height = (_vsize + st::overviewPhotoSkip) * rows + st::overviewPhotoSkip;
|
||||
_addToY = (_height < _minHeight) ? (_minHeight - _height) : 0;
|
||||
result = (_vsize + st::overviewPhotoSkip) * rows + st::overviewPhotoSkip;
|
||||
_addToY = (result < _minHeight) ? (_minHeight - result) : 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void OverviewInner::showAll(bool recountHeights) {
|
||||
int32 newHeight = height();
|
||||
if (_type == OverviewPhotos || _type == OverviewVideos) {
|
||||
_photosInRow = int32(width() - st::overviewPhotoSkip) / int32(st::overviewPhotoMinSize + st::overviewPhotoSkip);
|
||||
_vsize = (int32(width() - st::overviewPhotoSkip) / _photosInRow) - st::overviewPhotoSkip;
|
||||
for (int32 i = 0, l = _items.size(); i < l; ++i) {
|
||||
_items.at(i)->resizeGetHeight(_vsize);
|
||||
}
|
||||
newHeight = _height = recountHeight();
|
||||
} else if (_type == OverviewAudioDocuments) {
|
||||
int32 migratedCount = migratedIndexSkip(), count = migratedCount + _history->overview[_type].size();
|
||||
newHeight = _height = count * _rowHeight + 2 * st::playlistPadding;
|
||||
|
@ -2834,6 +2807,7 @@ void OverviewWidget::onScroll() {
|
|||
}
|
||||
|
||||
void OverviewWidget::resizeEvent(QResizeEvent *e) {
|
||||
_noDropResizeIndex = true;
|
||||
int32 st = _scroll.scrollTop();
|
||||
_scroll.resize(size());
|
||||
int32 newScrollTop = _inner.resizeToWidth(width(), st, height());
|
||||
|
@ -2841,10 +2815,9 @@ void OverviewWidget::resizeEvent(QResizeEvent *e) {
|
|||
newScrollTop += addToY;
|
||||
}
|
||||
if (newScrollTop != _scroll.scrollTop()) {
|
||||
_noDropResizeIndex = true;
|
||||
_scroll.scrollToY(newScrollTop);
|
||||
_noDropResizeIndex = false;
|
||||
}
|
||||
_noDropResizeIndex = false;
|
||||
|
||||
_topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth);
|
||||
_topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0);
|
||||
|
@ -3079,9 +3052,15 @@ void OverviewWidget::changingMsgId(HistoryItem *row, MsgId newId) {
|
|||
}
|
||||
}
|
||||
|
||||
void OverviewWidget::ui_redrawHistoryItem(const HistoryItem *msg) {
|
||||
if (peer() == msg->history()->peer || migratePeer() == msg->history()->peer) {
|
||||
_inner.redrawItem(msg);
|
||||
void OverviewWidget::ui_redrawHistoryItem(const HistoryItem *item) {
|
||||
if (peer() == item->history()->peer || migratePeer() == item->history()->peer) {
|
||||
_inner.redrawItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewWidget::notify_historyItemLayoutChanged(const HistoryItem *item) {
|
||||
if (peer() == item->history()->peer || migratePeer() == item->history()->peer) {
|
||||
_inner.onUpdateSelected();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ private:
|
|||
QPixmap genPix(PhotoData *photo, int32 size);
|
||||
QPixmap genPix(VideoData *video, int32 size);
|
||||
void showAll(bool recountHeights = false);
|
||||
int32 recountHeight();
|
||||
|
||||
OverviewWidget *_overview;
|
||||
ScrollArea *_scroll;
|
||||
|
@ -143,22 +144,18 @@ private:
|
|||
|
||||
PeerData *_peer;
|
||||
MediaOverviewType _type;
|
||||
bool _reversed;
|
||||
History *_migrated, *_history;
|
||||
ChannelId _channel;
|
||||
|
||||
bool _selMode;
|
||||
uint32 itemSelectedValue(int32 index) const;
|
||||
|
||||
// for audio files, files, voice messages and links
|
||||
int32 _rowsLeft, _rowWidth, _rowHeight;
|
||||
|
||||
// photos
|
||||
int32 _photosInRow, _photosToAdd, _vsize;
|
||||
struct CachedSize {
|
||||
int32 vsize;
|
||||
bool medium;
|
||||
QPixmap pix;
|
||||
};
|
||||
typedef QMap<void*, CachedSize> CachedSizes;
|
||||
CachedSizes _cached;
|
||||
bool _selMode;
|
||||
|
||||
// shared links
|
||||
struct Link {
|
||||
|
@ -343,7 +340,9 @@ public:
|
|||
resizeEvent(0);
|
||||
}
|
||||
|
||||
void ui_redrawHistoryItem(const HistoryItem *msg);
|
||||
void ui_redrawHistoryItem(const HistoryItem *item);
|
||||
|
||||
void notify_historyItemLayoutChanged(const HistoryItem *item);
|
||||
|
||||
~OverviewWidget();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue