Save frame in GIFs panel.

This commit is contained in:
John Preston 2020-05-22 13:58:46 +04:00
parent 7d386b164b
commit c967a72dcb
6 changed files with 45 additions and 40 deletions

View File

@ -431,9 +431,14 @@ TabbedSelector::InnerFooter *GifsListWidget::getFooter() const {
void GifsListWidget::processHideFinished() { void GifsListWidget::processHideFinished() {
clearSelection(); clearSelection();
clearHeavyData();
} }
void GifsListWidget::processPanelHideFinished() { void GifsListWidget::processPanelHideFinished() {
clearHeavyData();
}
void GifsListWidget::clearHeavyData() {
const auto itemForget = [](const auto &item) { const auto itemForget = [](const auto &item) {
if (const auto document = item->getDocument()) { if (const auto document = item->getDocument()) {
document->unload(); document->unload();

View File

@ -102,6 +102,7 @@ private:
InlineResults results; InlineResults results;
}; };
void clearHeavyData();
void cancelGifsSearch(); void cancelGifsSearch();
void switchToSavedGifs(); void switchToSavedGifs();
void refreshSavedGifs(); void refreshSavedGifs();

View File

@ -163,8 +163,11 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
QRect r(0, 0, _width, height); QRect r(0, 0, _width, height);
if (animating) { if (animating) {
if (!_thumb.isNull()) _thumb = QPixmap(); const auto pixmap = _gif->current(frame.width(), frame.height(), _width, height, ImageRoundRadius::None, RectPart::None, context->paused ? 0 : context->ms);
auto pixmap = _gif->current(frame.width(), frame.height(), _width, height, ImageRoundRadius::None, RectPart::None, context->paused ? 0 : context->ms); if (_thumb.isNull()) {
_thumb = pixmap;
_thumbGood = true;
}
p.drawPixmap(r.topLeft(), pixmap); p.drawPixmap(r.topLeft(), pixmap);
} else { } else {
prepareThumbnail({ _width, height }, frame); prepareThumbnail({ _width, height }, frame);
@ -372,15 +375,11 @@ void Gif::radialAnimationCallback(crl::time now) const {
} }
void Gif::unloadHeavyPart() { void Gif::unloadHeavyPart() {
unloadAnimation(); _gif.reset();
getShownDocument()->unload(); getShownDocument()->unload();
_dataMedia = nullptr; _dataMedia = nullptr;
} }
void Gif::unloadAnimation() {
_gif.reset();
}
void Gif::clipCallback(Media::Clip::Notification notification) { void Gif::clipCallback(Media::Clip::Notification notification) {
using namespace Media::Clip; using namespace Media::Clip;
switch (notification) { switch (notification) {
@ -394,14 +393,14 @@ void Gif::clipCallback(Media::Clip::Notification notification) {
getShownDocument()->dimensions = QSize( getShownDocument()->dimensions = QSize(
_gif->width(), _gif->width(),
_gif->height()); _gif->height());
unloadAnimation(); _gif.reset();
} else { } else {
auto height = st::inlineMediaHeight; auto height = st::inlineMediaHeight;
auto frame = countFrameSize(); auto frame = countFrameSize();
_gif->start(frame.width(), frame.height(), _width, height, ImageRoundRadius::None, RectPart::None); _gif->start(frame.width(), frame.height(), _width, height, ImageRoundRadius::None, RectPart::None);
} }
} else if (_gif->autoPausedGif() && !context()->inlineItemVisible(this)) { } else if (_gif->autoPausedGif() && !context()->inlineItemVisible(this)) {
unloadAnimation(); unloadHeavyPart();
} }
} }
@ -1377,9 +1376,12 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
radial = isRadialAnimation(); radial = isRadialAnimation();
if (animating) { if (animating) {
if (!_thumb.isNull()) _thumb = QPixmap(); const auto pixmap = _gif->current(_frameSize.width(), _frameSize.height(), st::inlineThumbSize, st::inlineThumbSize, ImageRoundRadius::None, RectPart::None, context->paused ? 0 : context->ms);
auto animationThumb = _gif->current(_frameSize.width(), _frameSize.height(), st::inlineThumbSize, st::inlineThumbSize, ImageRoundRadius::None, RectPart::None, context->paused ? 0 : context->ms); if (_thumb.isNull()) {
p.drawPixmapLeft(rthumb.topLeft(), _width, animationThumb); _thumb = pixmap;
_thumbGood = true;
}
p.drawPixmapLeft(rthumb.topLeft(), _width, pixmap);
thumbDisplayed = true; thumbDisplayed = true;
} }
} }
@ -1518,15 +1520,11 @@ void Game::radialAnimationCallback(crl::time now) const {
} }
void Game::unloadHeavyPart() { void Game::unloadHeavyPart() {
unloadAnimation(); _gif.reset();
getResultDocument()->unload(); getResultDocument()->unload();
_dataMedia = nullptr; _dataMedia = nullptr;
} }
void Game::unloadAnimation() {
_gif.reset();
}
void Game::clipCallback(Media::Clip::Notification notification) { void Game::clipCallback(Media::Clip::Notification notification) {
using namespace Media::Clip; using namespace Media::Clip;
switch (notification) { switch (notification) {
@ -1540,7 +1538,7 @@ void Game::clipCallback(Media::Clip::Notification notification) {
getResultDocument()->dimensions = QSize( getResultDocument()->dimensions = QSize(
_gif->width(), _gif->width(),
_gif->height()); _gif->height());
unloadAnimation(); _gif.reset();
} else { } else {
_gif->start( _gif->start(
_frameSize.width(), _frameSize.width(),
@ -1551,7 +1549,7 @@ void Game::clipCallback(Media::Clip::Notification notification) {
RectPart::None); RectPart::None);
} }
} else if (_gif->autoPausedGif() && !context()->inlineItemVisible(this)) { } else if (_gif->autoPausedGif() && !context()->inlineItemVisible(this)) {
unloadAnimation(); unloadHeavyPart();
} }
} }

View File

@ -100,7 +100,6 @@ private:
}; };
void ensureDataMediaCreated(not_null<DocumentData*> document) const; void ensureDataMediaCreated(not_null<DocumentData*> document) const;
void unloadAnimation();
QSize countFrameSize() const; QSize countFrameSize() const;
void validateThumbnail( void validateThumbnail(
@ -393,7 +392,6 @@ public:
private: private:
void ensureDataMediaCreated(not_null<DocumentData*> document) const; void ensureDataMediaCreated(not_null<DocumentData*> document) const;
void unloadAnimation();
void countFrameSize(); void countFrameSize();
void prepareThumbnail(QSize size) const; void prepareThumbnail(QSize size) const;

View File

@ -292,24 +292,26 @@ void Inner::clearSelection() {
update(); update();
} }
void Inner::hideFinish(bool completely) { void Inner::hideFinished() {
if (completely) { clearHeavyData();
const auto unload = [](const auto &item) { }
if (const auto document = item->getDocument()) {
document->unload(); void Inner::clearHeavyData() {
} const auto unload = [](const auto &item) {
if (const auto photo = item->getPhoto()) { if (const auto document = item->getDocument()) {
photo->unload(); document->unload();
}
if (const auto result = item->getResult()) {
result->unload();
}
item->unloadHeavyPart();
};
clearInlineRows(false);
for (const auto &[result, layout] : _inlineLayouts) {
unload(layout);
} }
if (const auto photo = item->getPhoto()) {
photo->unload();
}
if (const auto result = item->getResult()) {
result->unload();
}
item->unloadHeavyPart();
};
clearInlineRows(false);
for (const auto &[result, layout] : _inlineLayouts) {
unload(layout);
} }
} }
@ -964,7 +966,7 @@ void Widget::hideFinished() {
_controller->disableGifPauseReason( _controller->disableGifPauseReason(
Window::GifPauseReason::InlineResults); Window::GifPauseReason::InlineResults);
_inner->hideFinish(true); _inner->hideFinished();
_a_show.stop(); _a_show.stop();
_showAnimation.reset(); _showAnimation.reset();
_cache = QPixmap(); _cache = QPixmap();

View File

@ -61,7 +61,7 @@ class Inner
public: public:
Inner(QWidget *parent, not_null<Window::SessionController*> controller); Inner(QWidget *parent, not_null<Window::SessionController*> controller);
void hideFinish(bool completely); void hideFinished();
void clearSelection(); void clearSelection();
@ -121,6 +121,7 @@ private:
void updateSelected(); void updateSelected();
void checkRestrictedPeer(); void checkRestrictedPeer();
bool isRestrictedView(); bool isRestrictedView();
void clearHeavyData();
void paintInlineItems(Painter &p, const QRect &r); void paintInlineItems(Painter &p, const QRect &r);