/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "ui/wrap/slide_wrap.h" #include #include 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::toggle( bool shown, anim::type animated) { auto animate = (animated == anim::type::normal) && _duration; auto changed = (_toggled != shown); if (changed) { _toggled = shown; if (animate) { _animation.start( [this] { animationStep(); }, _toggled ? 0. : 1., _toggled ? 1. : 0., _duration, anim::linear); } } if (animate) { animationStep(); } else { finishAnimating(); } if (changed) { _toggledChanged.fire_copy(_toggled); } return this; } SlideWrap *SlideWrap::finishAnimating() { _animation.stop(); animationStep(); return this; } SlideWrap *SlideWrap::toggleOn( rpl::producer &&shown) { std::move( shown ) | rpl::start_with_next([this](bool shown) { toggle(shown, anim::type::normal); }, lifetime()); finishAnimating(); 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 = _animation.value(_toggled ? 1. : 0.); auto newHeight = wrapped() ? (_animation.animating() ? anim::interpolate(0, wrapped()->heightNoMargins(), current) : (_toggled ? wrapped()->height() : 0)) : 0; if (newWidth != width() || newHeight != height()) { resize(newWidth, newHeight); } auto shouldBeHidden = !_toggled && !_animation.animating(); if (shouldBeHidden != isHidden()) { const auto guard = make_weak(this); setVisible(!shouldBeHidden); if (shouldBeHidden && guard) { SendPendingMoveResizeEvents(this); } } } QMargins SlideWrap::getMargins() const { auto result = wrapped()->getMargins(); return (animating() || !_toggled) ? 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 (_animation.animating()) { animationStep(); } else if (_toggled) { resize(size); } } rpl::producer MultiSlideTracker::atLeastOneShownValue() const { auto shown = std::vector>(); shown.reserve(_widgets.size()); for (auto &widget : _widgets) { shown.push_back(widget->toggledValue()); } return rpl::combine( std::move(shown), [](const std::vector &values) { return ranges::find(values, true) != values.end(); }); } } // namespace Ui