/* 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 */ #pragma once #include "window/section_widget.h" #include "window/section_memento.h" namespace Notify { struct PeerUpdate; } // namespace Notify namespace Ui { class ScrollArea; class PlainShadow; } // namespace Ui namespace Profile { class BackButton; namespace CommonGroups { class SectionMemento : public Window::SectionMemento { public: SectionMemento(gsl::not_null user) : _user(user) { } object_ptr createWidget(QWidget *parent, gsl::not_null controller, const QRect &geometry) override; gsl::not_null getUser() const { return _user; } void setScrollTop(int scrollTop) { _scrollTop = scrollTop; } int getScrollTop() const { return _scrollTop; } void setCommonGroups(const QList> &groups) { _commonGroups = groups; } const QList> &getCommonGroups() const { return _commonGroups; } private: gsl::not_null _user; int _scrollTop = 0; QList> _commonGroups; }; class FixedBar final : public TWidget, private base::Subscriber { Q_OBJECT public: FixedBar(QWidget *parent); // When animating mode is enabled the content is hidden and the // whole fixed bar acts like a back button. void setAnimatingMode(bool enabled); protected: void mousePressEvent(QMouseEvent *e) override; int resizeGetHeight(int newWidth) override; public slots: void onBack(); private: object_ptr _backButton; bool _animatingMode = false; }; class InnerWidget final : public TWidget { Q_OBJECT public: InnerWidget(QWidget *parent, gsl::not_null user); gsl::not_null user() const { return _user; } // Updates the area that is visible inside the scroll container. void setVisibleTopBottom(int visibleTop, int visibleBottom) override; void resizeToWidth(int newWidth, int minHeight) { _minHeight = minHeight; return TWidget::resizeToWidth(newWidth); } void saveState(gsl::not_null memento); void restoreState(gsl::not_null memento); ~InnerWidget(); signals: void cancelled(); protected: void paintEvent(QPaintEvent *e) override; void keyPressEvent(QKeyEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; // Resizes content and counts natural widget height for the desired width. int resizeGetHeight(int newWidth) override; private: void updateSelected(QPoint localPos); void updateRow(int index); void showInitial(const QList> &list); void checkPreloadMore(); void preloadMore(); void updateSize(); void paintRow(Painter &p, int index, TimeMs ms); gsl::not_null _user; int _minHeight = 0; int _rowHeight = 0; int _contentLeft = 0; int _contentTop = 0; int _contentWidth = 0; int _visibleTop = 0; int _visibleBottom = 0; struct Item { explicit Item(PeerData *peer); ~Item(); PeerData * const peer; Text name; std::unique_ptr ripple; }; Item *computeItem(PeerData *group); QMap _dataMap; QList _items; int _selected = -1; int _pressed = -1; int32 _preloadGroupId = 0; mtpRequestId _preloadRequestId = 0; bool _allLoaded = true; }; class Widget final : public Window::SectionWidget { Q_OBJECT public: Widget(QWidget *parent, gsl::not_null controller, gsl::not_null user); gsl::not_null user() const; PeerData *peerForDialogs() const override { return user(); } bool hasTopBarShadow() const override { return true; } QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms) override; bool showInternal(gsl::not_null memento) override; std::unique_ptr createMemento() override; void setInternalState(const QRect &geometry, gsl::not_null memento); // Float player interface. bool wheelEventFromFloatPlayer(QEvent *e, Window::Column myColumn, Window::Column playerColumn) override; QRect rectForFloatPlayer(Window::Column myColumn, Window::Column playerColumn) override; protected: void resizeEvent(QResizeEvent *e) override; void showAnimatedHook() override; void showFinishedHook() override; void doSetInnerFocus() override; private slots: void onScroll(); private: void updateAdaptiveLayout(); void saveState(gsl::not_null memento); void restoreState(gsl::not_null memento); object_ptr _scroll; QPointer _inner; object_ptr _fixedBar; object_ptr _fixedBarShadow; }; } // namespace CommonGroups } // namespace Profile