/* This file is part of Telegram Desktop, the official desktop version of Telegram messaging app, see https://telegram.org Telegram Desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library. Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org */ #include "ui/wrap/slide_wrap.h" namespace Ui { SlideWrap::SlideWrap( QWidget *parent, object_ptr child) : SlideWrap( parent, std::move(child), style::margins()) { } SlideWrap::SlideWrap( QWidget *parent, const style::margins &padding) : SlideWrap(parent, nullptr, padding) { } SlideWrap::SlideWrap( QWidget *parent, object_ptr child, const style::margins &padding) : Parent( parent, object_ptr>( parent, std::move(child), padding)) , _duration(st::slideWrapDuration) { } SlideWrap *SlideWrap::setDuration(int duration) { _duration = duration; return this; } SlideWrap *SlideWrap::toggleAnimated( bool shown) { if (_shown != shown) { setShown(shown); _slideAnimation.start( [this] { animationStep(); }, _shown ? 0. : 1., _shown ? 1. : 0., _duration, anim::linear); } animationStep(); return this; } SlideWrap *SlideWrap::toggleFast(bool shown) { setShown(shown); finishAnimations(); return this; } SlideWrap *SlideWrap::finishAnimations() { _slideAnimation.finish(); animationStep(); return this; } SlideWrap *SlideWrap::toggleOn( rpl::producer &&shown) { _toggleOnLifetime.destroy(); std::move(shown) | rpl::start([this](bool shown) { toggleAnimated(shown); }, _toggleOnLifetime); finishAnimations(); return this; } void SlideWrap::animationStep() { auto newWidth = width(); if (auto weak = wrapped()) { auto margins = getMargins(); weak->moveToLeft(margins.left(), margins.top()); newWidth = weak->width(); } auto current = _slideAnimation.current(_shown ? 1. : 0.); auto newHeight = wrapped() ? (_slideAnimation.animating() ? anim::interpolate(0, wrapped()->heightNoMargins(), current) : (_shown ? wrapped()->height() : 0)) : 0; if (newWidth != width() || newHeight != height()) { resize(newWidth, newHeight); } auto shouldBeHidden = !_shown && !_slideAnimation.animating(); if (shouldBeHidden != isHidden()) { setVisible(!shouldBeHidden); if (shouldBeHidden) { myEnsureResized(this); } } } void SlideWrap::setShown(bool shown) { _shown = shown; _shownUpdated.fire_copy(_shown); } QMargins SlideWrap::getMargins() const { auto result = wrapped()->getMargins(); return (animating() || !_shown) ? QMargins(result.left(), 0, result.right(), 0) : result; } int SlideWrap::resizeGetHeight(int newWidth) { if (wrapped()) { wrapped()->resizeToWidth(newWidth); } return heightNoMargins(); } void SlideWrap::wrappedSizeUpdated(QSize size) { if (_slideAnimation.animating()) { animationStep(); } else if (_shown) { resize(size); } } } // namespace Ui