/* 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 "window/window_chat_switch_process.h" #include "core/shortcuts.h" #include "data/components/recent_peers.h" #include "data/data_forum_topic.h" #include "data/data_peer.h" #include "data/data_saved_sublist.h" #include "data/data_thread.h" #include "info/profile/info_profile_cover.h" #include "main/main_session.h" #include "ui/widgets/labels.h" #include "ui/widgets/shadow.h" #include "ui/controls/userpic_button.h" #include "ui/painter.h" #include "ui/rp_widget.h" #include "styles/style_boxes.h" #include "styles/style_layers.h" #include "styles/style_window.h" namespace Window { namespace { class Button final : public Ui::AbstractButton { public: Button( QWidget *parent, not_null thread, base::flat_map, Ui::PeerUserpicView> &userpics); [[nodiscard]] rpl::producer<> selectRequests() const; void setSelected( bool selected, anim::type animated = anim::type::normal); private: void setup( not_null thread, base::flat_map, Ui::PeerUserpicView> &userpics); void paintEvent(QPaintEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; rpl::event_stream<> _selectRequests; Ui::Animations::Simple _overAnimation; bool _selected = false; }; Button::Button( QWidget *parent, not_null thread, base::flat_map, Ui::PeerUserpicView> &userpics) : AbstractButton(parent) { setup(thread, userpics); } void Button::setup( not_null thread, base::flat_map, Ui::PeerUserpicView> &userpics) { resize(st::chatSwitchSize); auto userpicSt = &st::chatSwitchUserpic; const auto userpicSize = userpicSt->size; if (const auto topic = thread->asTopic()) { using namespace Info::Profile; const auto userpic = Ui::CreateChild( this, topic, [] { return true; }); // paused userpic->show(); userpic->move( ((width() - userpic->width()) / 2), st::chatSwitchUserpicTop); userpic->setAttribute(Qt::WA_TransparentForMouseEvents); userpicSt = &st::chatSwitchUserpicSmall; } else if (const auto sublist = thread->asSublist()) { const auto sublistPeer = sublist->sublistPeer(); const auto userpic = Ui::CreateChild( this, sublistPeer, st::chatSwitchUserpicSublist); userpic->show(); userpic->move( ((width() - userpicSize.width()) / 2), st::chatSwitchUserpicTop); userpic->setAttribute(Qt::WA_TransparentForMouseEvents); userpics.emplace(sublistPeer, sublistPeer->createUserpicView()); userpicSt = &st::chatSwitchUserpicSmall; } const auto peer = thread->peer(); const auto userpic = Ui::CreateChild( this, peer, *userpicSt); userpic->show(); userpic->move( (((width() - userpicSize.width()) / 2) + (userpicSize.width() - userpicSt->size.width())), (st::chatSwitchUserpicTop + (userpicSize.height() - userpicSt->size.height()))); userpic->setAttribute(Qt::WA_TransparentForMouseEvents); userpics.emplace(peer, peer->createUserpicView()); const auto label = Ui::CreateChild( this, thread->chatListName(), st::chatSwitchNameLabel); label->setBreakEverywhere(true); label->show(); label->resizeToNaturalWidth( width() - 2 * st::chatSwitchNameSkip); label->move( (width() - label->width()) / 2, (height() + userpic->y() + userpic->height() - label->height()) / 2); show(); } rpl::producer<> Button::selectRequests() const { return _selectRequests.events(); } void Button::setSelected(bool selected, anim::type animated) { if (_selected == selected) { if (animated == anim::type::instant) { _overAnimation.stop(); } return; } _selected = selected; if (animated == anim::type::instant) { _overAnimation.stop(); update(); } else { _overAnimation.start( [=] { update(); }, selected ? 0. : 1., selected ? 1. : 0., st::slideWrapDuration); } } void Button::paintEvent(QPaintEvent *e) { const auto selected = _selected ? 1. : 0.; const auto selection = _overAnimation.value(selected); if (selection <= 0.) { return; } auto p = QPainter(this); auto hq = PainterHighQualityEnabler(p); const auto radius = st::boxRadius; const auto line = st::chatSwitchSelectLine; auto pen = st::defaultRoundCheckbox.bgActive->p; pen.setWidthF(line * selection); p.setPen(pen); const auto r = QRectF(rect()).marginsRemoved( { line / 2., line / 2., line / 2., line / 2. }); p.drawRoundedRect(r, radius, radius); } void Button::mouseMoveEvent(QMouseEvent *e) { if (!_selected) { _selectRequests.fire({}); } } } // namespace struct ChatSwitchProcess::Entry { std::unique_ptr